diff --git a/ASTree.cpp b/ASTree.cpp index 6635808e1..fc20fc998 100644 --- a/ASTree.cpp +++ b/ASTree.cpp @@ -1576,13 +1576,36 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) ASTFunction::defarg_t defArgs, kwDefArgs; const int defCount = operand & 0xFF; const int kwDefCount = (operand >> 8) & 0xFF; - for (int i = 0; i < defCount; ++i) { - defArgs.push_front(stack.top()); - stack.pop(); - } - for (int i = 0; i < kwDefCount; ++i) { - kwDefArgs.push_front(stack.top()); - stack.pop(); + const int annotationCount = (operand >> 16) & 0x7FFF; + + /* Docs for 3.3 say KW Pairs come first, but reality disagrees */ + if (mod->verCompare(3, 3) <= 0) { + for (int i = 0; i < defCount; ++i) { + defArgs.push_front(stack.top()); + stack.pop(); + } + /* KW Defaults not mentioned in docs, but they come after the positional args */ + for (int i = 0; i < kwDefCount; ++i) { + kwDefArgs.push_front(stack.top()); + stack.pop(); // KW Pair object + stack.pop(); // KW Pair name + } + } else { + if(annotationCount) { + stack.pop(); // Tuple of param names for annotations + for (int i = 0; i < annotationCount; ++i) { + stack.pop(); // Pop annotation objects and ignore + } + } + for (int i = 0; i < kwDefCount; ++i) { + kwDefArgs.push_front(stack.top()); + stack.pop(); // KW Pair object + stack.pop(); // KW Pair name + } + for (int i = 0; i < defCount; ++i) { + defArgs.push_front(stack.top()); + stack.pop(); + } } stack.push(new ASTFunction(fun_code, defArgs, kwDefArgs)); } diff --git a/tests/compiled/test_functions_py3.3.0.pyc b/tests/compiled/test_functions_py3.3.0.pyc index f29f67148..56b7c9f80 100644 Binary files a/tests/compiled/test_functions_py3.3.0.pyc and b/tests/compiled/test_functions_py3.3.0.pyc differ diff --git a/tests/compiled/test_functions_py3.3.4.pyc b/tests/compiled/test_functions_py3.3.4.pyc index 6c0fe16ae..a8aff048e 100644 Binary files a/tests/compiled/test_functions_py3.3.4.pyc and b/tests/compiled/test_functions_py3.3.4.pyc differ diff --git a/tests/input/test_functions_py3.py b/tests/input/test_functions_py3.py index f11c75c78..502c13f73 100644 --- a/tests/input/test_functions_py3.py +++ b/tests/input/test_functions_py3.py @@ -57,3 +57,6 @@ def x7c(foo = 1, *, bar, **kwargs): def x7d(foo = 1, *, bar = 2, **kwargs): pass + +def x7e(foo = 1, *, bar = 2, baz = 3, **kwargs): + pass diff --git a/tests/tokenized/test_functions_py3.txt b/tests/tokenized/test_functions_py3.txt index 8308e0b70..0cfae7a5d 100644 --- a/tests/tokenized/test_functions_py3.txt +++ b/tests/tokenized/test_functions_py3.txt @@ -34,18 +34,50 @@ def x4c ( foo , bar = 1 , bla = 2 , * args , ** kwargs ) : pass -def x5a ( * , bar = 1 ) : +def x5a ( * , bar ) : pass -def x5b ( * , bar = 1 , ** kwargs ) : +def x5b ( * , bar = 1 ) : pass -def x6a ( foo , * , bar = 1 ) : +def x5c ( * , bar = 1 , ** kwargs ) : pass -def x7a ( foo , * , bar = 1 , ** kwargs ) : +def x6a ( foo , * , bar ) : + +pass + +def x6b ( foo , * , bar = 1 ) : + +pass + +def x6c ( foo = 1 , * , bar ) : + +pass + +def x6d ( foo = 1 , * , bar = 2 ) : + +pass + +def x7a ( foo , * , bar , ** kwargs ) : + +pass + +def x7b ( foo , * , bar = 1 , ** kwargs ) : + +pass + +def x7c ( foo = 1 , * , bar , ** kwargs ) : + +pass + +def x7d ( foo = 1 , * , bar = 2 , ** kwargs ) : + +pass + +def x7e ( foo = 1 , * , bar = 2 , baz = 3 , ** kwargs ) : pass