Bang on 3.x annotations

This commit is contained in:
rocky
2017-04-11 17:09:10 -04:00
parent 6acec471e3
commit bb24df596d
6 changed files with 60 additions and 14 deletions

View File

@@ -18,6 +18,11 @@ def div(a: dict(type=float, help='the dividend'),
"""Divide a by b"""
return a / b
class TestSignatureObject(unittest.TestCase):
def test_signature_on_wkwonly(self):
def test(*, a:float, b:str) -> int:
pass
class SupportsInt(_Protocol):
@abstractmethod

View File

@@ -79,7 +79,9 @@ from uncompyle6.semantics.consts import (
TABLE_DIRECT, escape, minint, MAP
)
from uncompyle6.semantics.make_function import find_all_globals, find_none
from uncompyle6.semantics.make_function import (
find_all_globals, find_none, code_has_star_arg, code_has_star_star_arg
)
if PYTHON3:
from itertools import zip_longest
@@ -1659,10 +1661,10 @@ class FragmentsWalker(pysource.SourceWalker, object):
params.reverse() # back to correct order
if 4 & code.co_flags: # flag 2 -> variable number of args
if code_has_star_arg(code):
params.append('*%s' % code.co_varnames[argc])
argc += 1
if 8 & code.co_flags: # flag 3 -> keyword args
if code_has_star_star_arg(code):
params.append('**%s' % code.co_varnames[argc])
argc += 1

View File

@@ -1,4 +1,4 @@
# Copyright (c) 2015, 2016 by Rocky Bernstein
# Copyright (c) 2015-2017 by Rocky Bernstein
# Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com>
"""
All the crazy things we have to do to handle Python functions
@@ -45,6 +45,17 @@ def find_none(node):
return True
return False
# FIXME: put this in xdis
def code_has_star_arg(code):
"""Return True iff
the code object has a variable positional parameter (*args-like)"""
return (code.co_flags & 4) != 0
def code_has_star_star_arg(code):
"""Return True iff
The code object has a variable keyword parameter (**kwargs-like)."""
return (code.co_flags & 8) != 0
# FIXME: DRY the below code...
def make_function3_annotate(self, node, isLambda, nested=1,
@@ -87,7 +98,7 @@ def make_function3_annotate(self, node, isLambda, nested=1,
l = -len(node)
while j >= l and node[j].type in ('annotate_arg' 'annotate_tuple'):
annotate_args[annotate_tup[i]] = (node[j][0].attr,
node[j][0] == 'LOAD_CONST')
node[j][0] in ('LOAD_CONST', 'LOAD_GLOBAL'))
i -= 1
j -= 1
@@ -96,9 +107,12 @@ def make_function3_annotate(self, node, isLambda, nested=1,
# positional args are before kwargs
defparams = node[:args_node.attr[0]]
pos_args, kw_args, annotate_argc = args_node.attr
if 'return' in annotate_args.keys():
annotate_argc = len(annotate_args) - 1
else:
defparams = node[:args_node.attr]
kw_args = 0
annotate_argc = 0
pass
if 3.0 <= self.version <= 3.2:
@@ -144,7 +158,7 @@ def make_function3_annotate(self, node, isLambda, nested=1,
indent = ' ' * l
line_number = self.line_number
if 4 & code.co_flags: # flag 2 -> variable number of args
if code_has_star_arg(code):
self.write('*%s' % code.co_varnames[argc + kw_pairs])
argc += 1
@@ -186,10 +200,12 @@ def make_function3_annotate(self, node, isLambda, nested=1,
else:
suffix = ', '
# self.println(indent, '#flags:\t', int(code.co_flags))
if kw_args > 0:
if not (4 & code.co_flags):
if kw_args + annotate_argc > 0:
if not code_has_star_arg(code):
if argc > 0:
self.write(", *, ")
else:
self.write("*, ")
@@ -211,10 +227,32 @@ def make_function3_annotate(self, node, isLambda, nested=1,
self.write(', ')
i += 1
pass
elif n == 'annotate_arg':
from trepan.api import debug; debug()
pass
pass
annotate_args = []
for n in node:
if n == 'annotate_arg':
annotate_args.append(n[0].attr)
elif n == 'annotate_tuple':
t = n[0].attr
if t[-1] == 'return':
t = t[0:-1]
annotate_args = annotate_args[:-1]
pass
last = len(annotate_args) - 1
for i in range(len(annotate_args)):
self.write("%s: %s" % (annotate_args[i], t[i]))
if i < last:
self.write(', ')
pass
pass
break
pass
pass
if 8 & code.co_flags: # flag 3 -> keyword args
if code_has_star_star_arg(code):
if argc > 0:
self.write(', ')
self.write('**%s' % code.co_varnames[argc + kw_pairs])
@@ -297,6 +335,7 @@ def make_function2(self, node, isLambda, nested=1, codeNode=None):
else:
defparams = node[:args_node.attr]
kw_args = 0
annotate_argc = 0
pass
lambda_index = None
@@ -335,7 +374,7 @@ def make_function2(self, node, isLambda, nested=1, codeNode=None):
name, default in zip_longest(paramnames, defparams, fillvalue=None)]
params.reverse() # back to correct order
if 4 & code.co_flags: # flag 2 -> variable number of args
if code_has_star_arg(code):
params.append('*%s' % code.co_varnames[argc])
argc += 1
@@ -363,7 +402,7 @@ def make_function2(self, node, isLambda, nested=1, codeNode=None):
break
pass
if 8 & code.co_flags: # flag 3 -> keyword args
if code_has_star_star_arg(code):
if argc > 0:
self.write(', ')
self.write('**%s' % code.co_varnames[argc + kw_pairs])
@@ -472,7 +511,7 @@ def make_function3(self, node, isLambda, nested=1, codeNode=None):
name, default in zip_longest(paramnames, defparams, fillvalue=None)]
params.reverse() # back to correct order
if 4 & code.co_flags: # flag 2 -> variable number of args
if code_has_star_arg(code):
if self.version > 3.0:
params.append('*%s' % code.co_varnames[argc + kw_pairs])
else:
@@ -498,7 +537,7 @@ def make_function3(self, node, isLambda, nested=1, codeNode=None):
indent = ' ' * l
line_number = self.line_number
if 4 & code.co_flags: # flag 2 -> variable number of args
if code_has_star_arg(code):
self.write('*%s' % code.co_varnames[argc + kw_pairs])
argc += 1
@@ -552,7 +591,7 @@ def make_function3(self, node, isLambda, nested=1, codeNode=None):
pass
pass
if 8 & code.co_flags: # flag 3 -> keyword args
if code_has_star_star_arg(code):
if argc > 0:
self.write(', ')
self.write('**%s' % code.co_varnames[argc + kw_pairs])