Fix bug in 3.6 handling kwonly params ...

when there are annotation args
This commit is contained in:
rocky
2020-01-24 05:47:41 -05:00
parent 5616f56442
commit 5c31fdc362
5 changed files with 48 additions and 33 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -59,3 +59,14 @@ assert p == Point(**dict(x=11, y=22))
def posonly_sum(pos_arg1, *arg, **kwarg):
return pos_arg1 + sum(arg) + sum(kwarg.values())
assert 1+2+3+4 == posonly_sum(1,*(2,3),**{"4":4})
# From 3.7 test_grammar.py
# Bug was in handling keyword-only parameters when there are annotations.
# The stack order from least- to most-recent is:
# default, keyword, annotation, closure
# This changes in between Python 3.5 and 3.6.
def f(a, b: 1, c: 2, d, e: 3=4, f=5, *g: 6, h: 7, i=8, j: 9=10,
**k: 11) -> 12: pass
assert f.__annotations__ == {'b': 1, 'c': 2, 'e': 3, 'g': 6, 'h': 7, 'j': 9,
'k': 11, 'return': 12}

View File

@@ -94,10 +94,6 @@ def make_function36(self, node, is_lambda, nested=1, code_node=None):
i = -4
kw_pairs = 0
if closure:
# FIXME: fill in
i -= 1
if annotate_argc:
# Turn into subroutine and DRY with other use
annotate_node = node[i]
@@ -118,8 +114,14 @@ def make_function36(self, node, is_lambda, nested=1, code_node=None):
pass
pass
i -= 1
if closure:
# FIXME: fill in
# annotate = node[i]
i -= 1
if kw_args:
kw_node = node[i]
kw_node = node[pos_args]
if kw_node == "expr":
kw_node = kw_node[0]
if kw_node == "dict":
@@ -323,7 +325,9 @@ def make_function36(self, node, is_lambda, nested=1, code_node=None):
self.write(" -> %s" % annotate_dict["return"])
self.println(":")
if node[-2] == "docstring" and not is_lambda:
if (
node[-2] == "docstring" and not is_lambda
):
# docstring exists, dump it
self.println(self.traverse(node[-2]))
@@ -351,7 +355,7 @@ def make_function36(self, node, is_lambda, nested=1, code_node=None):
# was optimized away. Here, we need to put in unreachable code to
# add in "yield" just so that the compiler will mark
# the GENERATOR bit of the function. See for example
# Python 3.x's test_generator.py test program.
# Python 3.x's test_connection.py and test_contexlib_async test programs.
if code.co_flags & (CO_GENERATOR | CO_ASYNC_GENERATOR):
need_bogus_yield = True
for token in scanner_code._tokens: