summaryrefslogtreecommitdiffstats
path: root/Lib/compiler/transformer.py
diff options
context:
space:
mode:
authorNeal Norwitz <nnorwitz@gmail.com>2006-12-28 06:47:50 (GMT)
committerNeal Norwitz <nnorwitz@gmail.com>2006-12-28 06:47:50 (GMT)
commitc150536b5efadf71fcb4187cad7258be7268e157 (patch)
treeaeb17f5e0ecc6cc8ccdecb2b64e3f46a0a3af85c /Lib/compiler/transformer.py
parentf6657e67b3cf89649d14d9012b3964a3490d45b0 (diff)
downloadcpython-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.py118
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):