diff options
Diffstat (limited to 'Lib/compiler')
| -rw-r--r-- | Lib/compiler/ast.py | 24 | ||||
| -rw-r--r-- | Lib/compiler/pyassem.py | 3 | ||||
| -rw-r--r-- | Lib/compiler/pycodegen.py | 16 | ||||
| -rw-r--r-- | Lib/compiler/symbols.py | 2 | ||||
| -rw-r--r-- | Lib/compiler/transformer.py | 11 | 
5 files changed, 35 insertions, 21 deletions
| diff --git a/Lib/compiler/ast.py b/Lib/compiler/ast.py index 4794d66da6..fb9be2a21a 100644 --- a/Lib/compiler/ast.py +++ b/Lib/compiler/ast.py @@ -311,9 +311,12 @@ class CallFunc(Node):          return "CallFunc(%s, %s, %s, %s)" % (repr(self.node), repr(self.args), repr(self.star_args), repr(self.dstar_args))  class Class(Node): -    def __init__(self, name, bases, doc, code, lineno=None): +    def __init__(self, name, args, star_args, dstar_args, +                 doc, code, lineno=None):          self.name = name -        self.bases = bases +        self.args = args +        self.star_args = star_args +        self.dstar_args = dstar_args          self.doc = doc          self.code = code          self.lineno = lineno @@ -321,19 +324,30 @@ class Class(Node):      def getChildren(self):          children = []          children.append(self.name) -        children.extend(flatten(self.bases)) +        children.extend(flatten(self.args)) +        children.extend(self.star_args) +        children.extend(self.dstar_args)          children.append(self.doc)          children.append(self.code)          return tuple(children)      def getChildNodes(self):          nodelist = [] -        nodelist.extend(flatten_nodes(self.bases)) +        nodelist.extend(flatten_nodes(self.args)) +        if self.star_args is not None: +            nodelist.append(self.star_args) +        if self.dstar_args is not None: +            nodelist.append(self.dstar_args)          nodelist.append(self.code)          return tuple(nodelist)      def __repr__(self): -        return "Class(%s, %s, %s, %s)" % (repr(self.name), repr(self.bases), repr(self.doc), repr(self.code)) +        return "Class(%r, %r, %r, %r, %r, %r)" % (self.name, +                                                  self.args, +                                                  self.star_args, +                                                  self.dstar_args, +                                                  self.doc, +                                                  self.code)  class Compare(Node):      def __init__(self, expr, ops, lineno=None): diff --git a/Lib/compiler/pyassem.py b/Lib/compiler/pyassem.py index f665c543b0..2dcc8dbfc9 100644 --- a/Lib/compiler/pyassem.py +++ b/Lib/compiler/pyassem.py @@ -786,7 +786,6 @@ class StackDepthTracker:          'PRINT_EXPR': -1,          'RETURN_VALUE': -1,          'YIELD_VALUE': -1, -        'BUILD_CLASS': -2,          'STORE_NAME': -1,          'STORE_ATTR': -2,          'DELETE_ATTR': -1, @@ -804,6 +803,8 @@ class StackDepthTracker:          'SETUP_FINALLY': 3,          'FOR_ITER': 1,          'WITH_CLEANUP': -1, +        'LOAD_BUILD_CLASS': 1, +        'STORE_LOCALS': -1,          }      # use pattern match      patterns = [ diff --git a/Lib/compiler/pycodegen.py b/Lib/compiler/pycodegen.py index 83fbc173ca..cc24650cfd 100644 --- a/Lib/compiler/pycodegen.py +++ b/Lib/compiler/pycodegen.py @@ -435,13 +435,10 @@ class CodeGenerator:          walk(node.code, gen)          gen.finish()          self.set_lineno(node) -        self.emit('LOAD_CONST', node.name) -        for base in node.bases: -            self.visit(base) -        self.emit('BUILD_TUPLE', len(node.bases)) +        self.emit('LOAD_BUILD_CLASS')          self._makeClosure(gen, 0) -        self.emit('CALL_FUNCTION', 0) -        self.emit('BUILD_CLASS') +        self.emit('LOAD_CONST', node.name) +        self.finish_visit_call(node, 2)          self.storeName(node.name)      # The rest are standard visitor methods @@ -1115,10 +1112,11 @@ class CodeGenerator:              self.emit('STORE_SUBSCR')      def visitCallFunc(self, node): -        pos = 0 -        kw = 0          self.set_lineno(node)          self.visit(node.node) +        self.finish_visit_call(node) + +    def finish_visit_call(self, node, pos=0, kw=0):          for arg in node.args:              self.visit(arg)              if isinstance(arg, ast.Keyword): @@ -1467,7 +1465,7 @@ class AbstractClassCode:      def finish(self):          self.graph.startExitBlock() -        self.emit('LOAD_LOCALS') +        self.emit('LOAD_CONST', None)          self.emit('RETURN_VALUE')  class ClassCodeGenerator(NestedScopeMixin, AbstractClassCode, CodeGenerator): diff --git a/Lib/compiler/symbols.py b/Lib/compiler/symbols.py index 6c19b5ba76..e22294e3d2 100644 --- a/Lib/compiler/symbols.py +++ b/Lib/compiler/symbols.py @@ -299,7 +299,7 @@ class SymbolVisitor:      def visitClass(self, node, parent):          parent.add_def(node.name) -        for n in node.bases: +        for n in node.args:              self.visit(n, parent)          scope = ClassScope(node.name, self.module)          if parent.nested or isinstance(parent, FunctionScope): diff --git a/Lib/compiler/transformer.py b/Lib/compiler/transformer.py index f07ec97fba..3d4bb4fab8 100644 --- a/Lib/compiler/transformer.py +++ b/Lib/compiler/transformer.py @@ -288,16 +288,16 @@ class Transformer:      old_lambdef = lambdef      def classdef(self, nodelist): -        # classdef: 'class' NAME ['(' [testlist] ')'] ':' suite +        # classdef: 'class' NAME ['(' [arglist] ')'] ':' suite          name = nodelist[1][1]          doc = self.get_docstring(nodelist[-1])          if nodelist[2][0] == token.COLON: -            bases = [] +            arglist = CallFunc(None, [])          elif nodelist[3][0] == token.RPAR: -            bases = [] +            arglist = CallFunc(None, [])          else: -            bases = self.com_bases(nodelist[3]) +            arglist = self.com_call_function(None, nodelist[3])          # code for class          code = self.com_node(nodelist[-1]) @@ -307,7 +307,8 @@ class Transformer:              assert isinstance(code.nodes[0], Discard)              del code.nodes[0] -        return Class(name, bases, doc, code, lineno=nodelist[1][2]) +        return Class(name, arglist.args, arglist.star_args, arglist.dstar_args, +                     doc, code, lineno=nodelist[1][2])      def stmt(self, nodelist):          return self.com_stmt(nodelist[0]) | 
