mirror of
https://github.com/python/cpython.git
synced 2025-10-17 04:08:28 +00:00
PEP-0318, @decorator-style. In Guido's words:
"@ seems the syntax that everybody can hate equally" Implementation by Mark Russell, from SF #979728.
This commit is contained in:
parent
fd7dc5169c
commit
c2a5a63654
28 changed files with 2965 additions and 2335 deletions
|
@ -185,29 +185,81 @@ class Transformer:
|
|||
### is this sufficient?
|
||||
return Expression(self.com_node(nodelist[0]))
|
||||
|
||||
def decorator_name(self, nodelist):
|
||||
listlen = len(nodelist)
|
||||
assert listlen >= 1 and listlen % 2 == 1
|
||||
|
||||
item = self.atom_name(nodelist)
|
||||
i = 1
|
||||
while i < listlen:
|
||||
assert nodelist[i][0] == token.DOT
|
||||
assert nodelist[i + 1][0] == token.NAME
|
||||
item = Getattr(item, nodelist[i + 1][1])
|
||||
i += 2
|
||||
|
||||
return item
|
||||
|
||||
def decorator(self, nodelist):
|
||||
# '@' dotted_name [ '(' [arglist] ')' ]
|
||||
assert len(nodelist) in (2, 4, 5)
|
||||
assert nodelist[0][0] == token.AT
|
||||
|
||||
assert nodelist[1][0] == symbol.dotted_name
|
||||
funcname = self.decorator_name(nodelist[1][1:])
|
||||
|
||||
if len(nodelist) > 2:
|
||||
assert nodelist[2][0] == token.LPAR
|
||||
expr = self.com_call_function(funcname, nodelist[3])
|
||||
else:
|
||||
expr = funcname
|
||||
|
||||
return expr
|
||||
|
||||
def decorators(self, nodelist):
|
||||
# decorators: decorator ([NEWLINE] decorator)* NEWLINE
|
||||
listlen = len(nodelist)
|
||||
i = 0
|
||||
items = []
|
||||
while i < listlen:
|
||||
assert nodelist[i][0] == symbol.decorator
|
||||
items.append(self.decorator(nodelist[i][1:]))
|
||||
i += 1
|
||||
|
||||
if i < listlen and nodelist[i][0] == token.NEWLINE:
|
||||
i += 1
|
||||
return Decorators(items)
|
||||
|
||||
def funcdef(self, nodelist):
|
||||
# funcdef: 'def' NAME parameters ':' suite
|
||||
# -6 -5 -4 -3 -2 -1
|
||||
# funcdef: [decorators] 'def' NAME parameters ':' suite
|
||||
# parameters: '(' [varargslist] ')'
|
||||
|
||||
lineno = nodelist[1][2]
|
||||
name = nodelist[1][1]
|
||||
args = nodelist[2][2]
|
||||
if len(nodelist) == 6:
|
||||
assert nodelist[0][0] == symbol.decorators
|
||||
decorators = self.decorators(nodelist[0][1:])
|
||||
else:
|
||||
assert len(nodelist) == 5
|
||||
decorators = None
|
||||
|
||||
lineno = nodelist[-4][2]
|
||||
name = nodelist[-4][1]
|
||||
args = nodelist[-3][2]
|
||||
|
||||
if args[0] == symbol.varargslist:
|
||||
names, defaults, flags = self.com_arglist(args[1:])
|
||||
else:
|
||||
names = defaults = ()
|
||||
flags = 0
|
||||
doc = self.get_docstring(nodelist[4])
|
||||
doc = self.get_docstring(nodelist[-1])
|
||||
|
||||
# code for function
|
||||
code = self.com_node(nodelist[4])
|
||||
code = self.com_node(nodelist[-1])
|
||||
|
||||
if doc is not None:
|
||||
assert isinstance(code, Stmt)
|
||||
assert isinstance(code.nodes[0], Discard)
|
||||
del code.nodes[0]
|
||||
n = Function(name, names, defaults, flags, doc, code)
|
||||
n = Function(decorators, name, names, defaults, flags, doc, code)
|
||||
n.lineno = lineno
|
||||
return n
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue