diff options
author | Neal Norwitz <nnorwitz@gmail.com> | 2006-12-28 06:47:50 (GMT) |
---|---|---|
committer | Neal Norwitz <nnorwitz@gmail.com> | 2006-12-28 06:47:50 (GMT) |
commit | c150536b5efadf71fcb4187cad7258be7268e157 (patch) | |
tree | aeb17f5e0ecc6cc8ccdecb2b64e3f46a0a3af85c /Lib/compiler/transformer.py | |
parent | f6657e67b3cf89649d14d9012b3964a3490d45b0 (diff) | |
download | cpython-c150536b5efadf71fcb4187cad7258be7268e157.zip cpython-c150536b5efadf71fcb4187cad7258be7268e157.tar.gz cpython-c150536b5efadf71fcb4187cad7258be7268e157.tar.bz2 |
PEP 3107 - Function Annotations thanks to Tony Lownds
Diffstat (limited to 'Lib/compiler/transformer.py')
-rw-r--r-- | Lib/compiler/transformer.py | 118 |
1 files changed, 79 insertions, 39 deletions
diff --git a/Lib/compiler/transformer.py b/Lib/compiler/transformer.py index dc88222..4a8e623 100644 --- a/Lib/compiler/transformer.py +++ b/Lib/compiler/transformer.py @@ -234,25 +234,24 @@ class Transformer: return Decorators(items) def funcdef(self, nodelist): - # -6 -5 -4 -3 -2 -1 - # funcdef: [decorators] 'def' NAME parameters ':' suite - # parameters: '(' [varargslist] ')' - - if len(nodelist) == 6: - assert nodelist[0][0] == symbol.decorators + # 0 1 2 4 -1 + # funcdef: [decorators] 'def' NAME parameters ['->' test] ':' suite + # parameters: '(' [typedargslist] ')' + if nodelist[0][0] == symbol.decorators: decorators = self.decorators(nodelist[0][1:]) + nodelist = nodelist[1:] else: - assert len(nodelist) == 5 decorators = None + assert len(nodelist) in (5, 7) - lineno = nodelist[-4][2] - name = nodelist[-4][1] - args = nodelist[-3][2] + lineno = nodelist[0][2] + name = nodelist[1][1] + args = nodelist[2][2] - if args[0] == symbol.varargslist: - names, defaults, kwonlyargs, flags = self.com_arglist(args[1:]) + if args[0] == symbol.varargslist or args[0] == symbol.typedargslist: + arguments, defaults, kwonly, flags = self.com_arglist(args[1:]) else: - names = defaults = kwonlyargs = () + arguments = defaults = kwonly = () flags = 0 doc = self.get_docstring(nodelist[-1]) @@ -263,22 +262,28 @@ class Transformer: assert isinstance(code, Stmt) assert isinstance(code.nodes[0], Discard) del code.nodes[0] - return Function(decorators, name, names, defaults, - kwonlyargs, flags, doc, code, lineno=lineno) + + if len(nodelist) == 7: + returns = self.com_node(nodelist[4]) + else: + returns = None + + return Function(decorators, name, arguments, defaults, + kwonly, returns, flags, doc, code, lineno=lineno) def lambdef(self, nodelist): # lambdef: 'lambda' [varargslist] ':' test if nodelist[2][0] == symbol.varargslist: - names, defaults, kwonlyargs, flags = \ + arguments, defaults, kwonlyargs, flags = \ self.com_arglist(nodelist[2][1:]) else: - names = defaults = kwonlyargs = () + arguments = defaults = kwonlyargs = () flags = 0 # code for lambda code = self.com_node(nodelist[-1]) - return Lambda(names, defaults, kwonlyargs, + return Lambda(arguments, defaults, kwonlyargs, flags, code, lineno=nodelist[1][2]) old_lambdef = lambdef @@ -324,10 +329,25 @@ class Transformer: def varargslist(self, nodelist): raise WalkerError - def fpdef(self, nodelist): + def vfpdef(self, nodelist): raise WalkerError - def fplist(self, nodelist): + def vfplist(self, nodelist): + raise WalkerError + + def vname(self, nodelist): + raise WalkerError + + def typedargslist(self, nodelist): + raise WalkerError + + def tfpdef(self, nodelist): + raise WalkerError + + def tfplist(self, nodelist): + raise WalkerError + + def tname(self, nodelist): raise WalkerError def dotted_name(self, nodelist): @@ -786,9 +806,10 @@ class Transformer: return Discard(Const(None)) def keywordonlyargs(self, nodelist): - # (',' NAME ['=' test])* + # (',' tname ['=' test])* # ^^^ # ------+ + # tname and vname are handled. kwonlyargs = [] i = 0 while i < len(nodelist): @@ -802,10 +823,25 @@ class Transformer: i += 2 if node[0] == token.DOUBLESTAR: return kwonlyargs, i - elif node[0] == token.NAME: - kwonlyargs.append(Keyword(node[1], default, lineno=node[2])) + elif node[0] in (symbol.vname, symbol.tname): + lineno = extractLineNo(node) + kwarg = Kwarg(self._simplearg(node), default, lineno=lineno) + kwonlyargs.append(kwarg) i += 2 return kwonlyargs, i + + def _simplearg(self, node): + # tname: NAME [':' test] + # vname: NAME + assert node[0] == symbol.vname or node[0] == symbol.tname + name = node[1][1] + lineno = node[1][2] + assert isinstance(name, str) + if len(node) > 2: + annotation = self.com_node(node[3]) + else: + annotation = None + return SimpleArg(name, annotation, lineno) def com_arglist(self, nodelist): # varargslist: @@ -814,7 +850,7 @@ class Transformer: # | fpdef ['=' test] (',' fpdef ['=' test])* [','] # fpdef: NAME | '(' fplist ')' # fplist: fpdef (',' fpdef)* [','] - names = [] + arguments = [] kwonlyargs = [] defaults = [] flags = 0 @@ -825,14 +861,15 @@ class Transformer: if node[0] == token.STAR or node[0] == token.DOUBLESTAR: if node[0] == token.STAR: node = nodelist[i+1] - if node[0] == token.NAME: # vararg - names.append(node[1]) + if node[0] in (symbol.tname, symbol.vname): # vararg + arguments.append(self._simplearg(node)) flags = flags | CO_VARARGS i = i + 3 else: # no vararg assert node[0] == token.COMMA i += 2 - if i < len(nodelist) and nodelist[i][0] == token.NAME: + if i < len(nodelist) and \ + nodelist[i][0] in (symbol.tname, symbol.vname): kwonlyargs, skip = self.keywordonlyargs(nodelist[i:]) i += skip @@ -843,13 +880,13 @@ class Transformer: node = nodelist[i+1] else: raise ValueError, "unexpected token: %s" % t - names.append(node[1]) + arguments.append(self._simplearg(node)) flags = flags | CO_VARKEYWORDS break - # fpdef: NAME | '(' fplist ')' - names.append(self.com_fpdef(node)) + # tfpdef: tname | '(' tfplist ')' + arguments.append(self.com_tfpdef(node)) i = i + 1 if i < len(nodelist) and nodelist[i][0] == token.EQUAL: @@ -863,21 +900,24 @@ class Transformer: # skip the comma i = i + 1 - return names, defaults, kwonlyargs, flags + return arguments, defaults, kwonlyargs, flags - def com_fpdef(self, node): - # fpdef: NAME | '(' fplist ')' + def com_tfpdef(self, node): + # tfpdef: tname | '(' tfplist ')' + # def f((x)): -- x is not nested + while node[1][0] == token.LPAR and len(node[2]) == 2: + node = node[2][1] if node[1][0] == token.LPAR: - return self.com_fplist(node[2]) - return node[1][1] + return NestedArgs(self.com_tfplist(node[2])) + return self._simplearg(node[1]) - def com_fplist(self, node): - # fplist: fpdef (',' fpdef)* [','] + def com_tfplist(self, node): + # tfplist: tfpdef (',' tfpdef)* [','] if len(node) == 2: - return self.com_fpdef(node[1]) + return self.com_tfpdef(node[1]), list = [] for i in range(1, len(node), 2): - list.append(self.com_fpdef(node[i])) + list.append(self.com_tfpdef(node[i])) return tuple(list) def com_dotted_name(self, node): |