Merge pull request #251 from rocky/annotation-types

x0ret's code in decompile3 for annotation types
This commit is contained in:
R. Bernstein
2019-06-06 11:26:48 -04:00
committed by GitHub
3 changed files with 46 additions and 11 deletions

Binary file not shown.

View File

@@ -18,13 +18,29 @@ def div(a: dict(type=float, help='the dividend'),
"""Divide a by b""" """Divide a by b"""
return a / b return a / b
class TestSignatureObject(unittest.TestCase): class TestSignatureObject():
def test_signature_on_wkwonly(self): def test_signature_on_wkwonly(self):
def test(*, a:float, b:str) -> int: def test(*, a:float, b:str) -> int:
pass pass
class SupportsInt(_Protocol): class SupportsInt():
@abstractmethod
def __int__(self) -> int: def __int__(self) -> int:
pass pass
def foo2(a, b: 'annotating b', c: int, *args: str) -> float:
assert foo2.__annotations__['b'] == 'annotating b'
assert foo2.__annotations__['c'] == int
assert foo2.__annotations__['args'] == str
assert foo2.__annotations__['return'] == float
def foo3(a, b: int = 5, **kwargs: float) -> float:
assert foo3.__annotations__['b'] == int
assert foo3.__annotations__['kwargs'] == float
assert foo3.__annotations__['return'] == float
assert b == 5
foo2(1, 'test', 5)
foo3(1)

View File

@@ -476,7 +476,7 @@ def make_function3(self, node, is_lambda, nested=1, code_node=None):
# Thank you, Python. # Thank you, Python.
def build_param(ast, name, default): def build_param(ast, name, default, annotation=None):
"""build parameters: """build parameters:
- handle defaults - handle defaults
- handle format tuple parameters - handle format tuple parameters
@@ -486,7 +486,10 @@ def make_function3(self, node, is_lambda, nested=1, code_node=None):
else: else:
value = self.traverse(default, indent='') value = self.traverse(default, indent='')
maybe_show_tree_param_default(self.showast, name, value) maybe_show_tree_param_default(self.showast, name, value)
result = '%s=%s' % (name, value) if annotation:
result = '%s: %s=%s' % (name, annotation, value)
else:
result = '%s=%s' % (name, value)
# The below can probably be removed. This is probably # The below can probably be removed. This is probably
# a holdover from days when LOAD_CONST erroneously # a holdover from days when LOAD_CONST erroneously
@@ -681,17 +684,30 @@ def make_function3(self, node, is_lambda, nested=1, code_node=None):
params = [] params = []
if defparams: if defparams:
for i, defparam in enumerate(defparams): for i, defparam in enumerate(defparams):
params.append(build_param(ast, paramnames[i], defparam)) params.append(build_param(ast, paramnames[i], defparam,
annotate_dict.get(paramnames[i])))
params += paramnames[i+1:] for param in paramnames[i+1:]:
if param in annotate_dict:
params.append("%s: %s" % (param, annotate_dict[param]))
else:
params.append(param)
else: else:
params = paramnames for param in paramnames:
if param in annotate_dict:
params.append("%s: %s" % (param, annotate_dict[param]))
else:
params.append(param)
params.reverse() # back to correct order params.reverse() # back to correct order
if code_has_star_arg(code): if code_has_star_arg(code):
if self.version > 3.0: if self.version > 3.0:
params.append('*%s' % code.co_varnames[argc + kw_pairs]) star_arg = code.co_varnames[argc + kw_pairs]
if star_arg in annotate_dict:
params.append('*%s: %s' %(star_arg, annotate_dict[star_arg]))
else:
params.append('*%s' % star_arg)
else: else:
params.append('*%s' % code.co_varnames[argc]) params.append('*%s' % code.co_varnames[argc])
argc += 1 argc += 1
@@ -716,7 +732,6 @@ def make_function3(self, node, is_lambda, nested=1, code_node=None):
ast[-1] = ast_expr ast[-1] = ast_expr
pass pass
else: else:
# FIXME: add annotations here
self.write("(", ", ".join(params)) self.write("(", ", ".join(params))
# self.println(indent, '#flags:\t', int(code.co_flags)) # self.println(indent, '#flags:\t', int(code.co_flags))
@@ -810,7 +825,11 @@ def make_function3(self, node, is_lambda, nested=1, code_node=None):
if code_has_star_star_arg(code): if code_has_star_star_arg(code):
if argc > 0 and not ends_in_comma: if argc > 0 and not ends_in_comma:
self.write(', ') self.write(', ')
self.write('**%s' % code.co_varnames[argc + kw_pairs]) star_star_arg = code.co_varnames[argc + kw_pairs]
if annotate_dict and star_star_arg and star_star_arg in annotate_dict:
self.write('**%s: %s' %(star_star_arg, annotate_dict[star_star_arg]))
else:
self.write('**%s' % star_star_arg)
if is_lambda: if is_lambda:
self.write(": ") self.write(": ")