diff options
Diffstat (limited to 'Lib/compiler/symbols.py')
| -rw-r--r-- | Lib/compiler/symbols.py | 44 | 
1 files changed, 35 insertions, 9 deletions
diff --git a/Lib/compiler/symbols.py b/Lib/compiler/symbols.py index 40fd127bfd..946a8b1a3a 100644 --- a/Lib/compiler/symbols.py +++ b/Lib/compiler/symbols.py @@ -25,6 +25,7 @@ class Scope:          # nested is true if the class could contain free variables,          # i.e. if it is nested within another function.          self.nested = None +        self.generator = None          self.klass = None          if klass is not None:              for i in range(len(klass)): @@ -287,6 +288,27 @@ class SymbolVisitor:                  name = name[:i]              scope.add_def(asname or name) +    def visitGlobal(self, node, scope): +        for name in node.names: +            scope.add_global(name) + +    def visitAssign(self, node, scope): +        """Propagate assignment flag down to child nodes. + +        The Assign node doesn't itself contains the variables being +        assigned to.  Instead, the children in node.nodes are visited +        with the assign flag set to true.  When the names occur in +        those nodes, they are marked as defs. + +        Some names that occur in an assignment target are not bound by +        the assignment, e.g. a name occurring inside a slice.  The +        visitor handles these nodes specially; they do not propagate +        the assign flag to their children. +        """ +        for n in node.nodes: +            self.visit(n, scope, 1) +        self.visit(node.expr, scope) +      def visitAssName(self, node, scope, assign=1):          scope.add_def(node.name) @@ -297,6 +319,13 @@ class SymbolVisitor:          self.visit(node.expr, scope, 0)          for n in node.subs:              self.visit(n, scope, 0) + +    def visitSlice(self, node, scope, assign=0): +        self.visit(node.expr, scope, assign) +        if node.lower: +            self.visit(node.lower, scope, 0) +        if node.upper: +            self.visit(node.upper, scope, 0)      def visitAugAssign(self, node, scope):          # If the LHS is a name, then this counts as assignment. @@ -306,15 +335,6 @@ class SymbolVisitor:              self.visit(node.node, scope, 1) # XXX worry about this          self.visit(node.expr, scope) -    def visitAssign(self, node, scope): -        for n in node.nodes: -            self.visit(n, scope, 1) -        self.visit(node.expr, scope) - -    def visitGlobal(self, node, scope): -        for name in node.names: -            scope.add_global(name) -      # prune if statements if tests are false      _const_types = types.StringType, types.IntType, types.FloatType @@ -330,6 +350,12 @@ class SymbolVisitor:          if node.else_:              self.visit(node.else_, scope) +    # a yield statement signals a generator + +    def visitYield(self, node, scope): +        self.generator = 1 +        self.visit(node.value, scope) +  def sort(l):      l = l[:]      l.sort()  | 
