You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-04 09:22:40 +08:00
Merge branch 'python-3.3-to-3.5' into python-3.0-to-3.2
This commit is contained in:
10
.github/ISSUE_TEMPLATE/bug-report.md
vendored
10
.github/ISSUE_TEMPLATE/bug-report.md
vendored
@@ -5,11 +5,11 @@ about: Tell us about uncompyle6 bugs
|
|||||||
---
|
---
|
||||||
|
|
||||||
<!-- __Note:__ If you are using this program to do something illegal - don't.
|
<!-- __Note:__ If you are using this program to do something illegal - don't.
|
||||||
The issue may flagged to make it easier for those looking for illegal activity.
|
The issue may be flagged to make it easier for those looking for illegal activity.
|
||||||
|
|
||||||
Bugs are not for asking questions about a problem you
|
Bugs are not for asking questions about a problem you
|
||||||
are trying to solve that involve the use of uncompyle6 along the way,
|
are trying to solve that involve the use of uncompyle6 along the way,
|
||||||
although I may be more tolerent of this if you sponsor the project.
|
although I may be more tolerant of this if you sponsor the project.
|
||||||
|
|
||||||
Bugs are also not for general or novice kind help on how to install
|
Bugs are also not for general or novice kind help on how to install
|
||||||
this Python program in your environment in the way you would like to
|
this Python program in your environment in the way you would like to
|
||||||
@@ -33,7 +33,7 @@ Funding the project was added to partially address the problem that there are
|
|||||||
lots of people seeking help and reporting bugs, but few people who are
|
lots of people seeking help and reporting bugs, but few people who are
|
||||||
willing or capable of providing help or fixing bugs.
|
willing or capable of providing help or fixing bugs.
|
||||||
|
|
||||||
Tasks or the kinds of things others can do but you can't do or don't
|
Tasks or the kinds of things others can do, but you can't do or don't
|
||||||
want to do yourself are typically the kind of thing that you pay
|
want to do yourself are typically the kind of thing that you pay
|
||||||
someone to do, especially when you are the primary beneficiary of the
|
someone to do, especially when you are the primary beneficiary of the
|
||||||
work, or the task is complex, long, or tedious. If your code is over
|
work, or the task is complex, long, or tedious. If your code is over
|
||||||
@@ -56,7 +56,7 @@ Prerequisites/Caveats
|
|||||||
contact me by email and explain who you are and the need for privacy.
|
contact me by email and explain who you are and the need for privacy.
|
||||||
But be mindful that you may be asked to sponsor the project for the
|
But be mindful that you may be asked to sponsor the project for the
|
||||||
personal and private help that you are requesting.
|
personal and private help that you are requesting.
|
||||||
* If the legitimacy of the activity is deemed suspicous, I may flag it as suspicious,
|
* If the legitimacy of the activity is deemed suspicious, I may flag it as suspicious,
|
||||||
making the issue even more easy to detect.
|
making the issue even more easy to detect.
|
||||||
|
|
||||||
Bug reports that violate the above may be discarded.
|
Bug reports that violate the above may be discarded.
|
||||||
@@ -80,7 +80,7 @@ $ uncompyle6 <command-line-options>
|
|||||||
$
|
$
|
||||||
```
|
```
|
||||||
|
|
||||||
Provide links to the Python bytecode. For example you can create a
|
Provide links to the Python bytecode. For example, you can create a
|
||||||
gist with the information. If you have the correct source code, you
|
gist with the information. If you have the correct source code, you
|
||||||
can add that too.
|
can add that too.
|
||||||
|
|
||||||
|
11
.isort.cfg
Normal file
11
.isort.cfg
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
[settings]
|
||||||
|
multi_line_output = 3
|
||||||
|
include_trailing_comma = True
|
||||||
|
force_grid_wrap = 0
|
||||||
|
use_parentheses = True
|
||||||
|
line_length = 88
|
||||||
|
known_crunch = cr, zz9d, zz9lib, pycrunch, silhouette
|
||||||
|
sections = FUTURE,STDLIB,THIRDPARTY,FIRSTPARTY,CRUNCH,LOCALFOLDER
|
||||||
|
default_section = THIRDPARTY
|
||||||
|
combine_as_imports = 1
|
||||||
|
profile = black
|
BIN
test/bytecode_3.7/02_while1_if_while1.pyc
Normal file
BIN
test/bytecode_3.7/02_while1_if_while1.pyc
Normal file
Binary file not shown.
@@ -194,9 +194,9 @@ def main_bin():
|
|||||||
try:
|
try:
|
||||||
result = main(src_base, out_base, pyc_paths, source_paths, outfile,
|
result = main(src_base, out_base, pyc_paths, source_paths, outfile,
|
||||||
**options)
|
**options)
|
||||||
result = list(result) + [options.get('do_verify', None)]
|
result = [options.get('do_verify', None)] + list(result)
|
||||||
if len(pyc_paths) > 1:
|
if len(pyc_paths) > 1:
|
||||||
mess = status_msg(do_verify, *result)
|
mess = status_msg(*result)
|
||||||
print('# ' + mess)
|
print('# ' + mess)
|
||||||
pass
|
pass
|
||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
|
@@ -546,13 +546,13 @@ if __name__ == "__main__":
|
|||||||
# Check grammar
|
# Check grammar
|
||||||
p = Python26Parser()
|
p = Python26Parser()
|
||||||
p.check_grammar()
|
p.check_grammar()
|
||||||
from uncompyle6 import PYTHON_VERSION, IS_PYPY
|
from xdis.version_info import PYTHON_VERSION_TRIPLE, IS_PYPY
|
||||||
|
|
||||||
if PYTHON_VERSION == 2.6:
|
if PYTHON_VERSION_TRIPLE[:2] == (2, 6):
|
||||||
lhs, rhs, tokens, right_recursive, dup_rhs = p.check_sets()
|
lhs, rhs, tokens, right_recursive, dup_rhs = p.check_sets()
|
||||||
from uncompyle6.scanner import get_scanner
|
from uncompyle6.scanner import get_scanner
|
||||||
|
|
||||||
s = get_scanner(PYTHON_VERSION, IS_PYPY)
|
s = get_scanner(PYTHON_VERSION_TRIPLE, IS_PYPY)
|
||||||
opcode_set = set(s.opc.opname).union(
|
opcode_set = set(s.opc.opname).union(
|
||||||
set(
|
set(
|
||||||
"""JUMP_BACK CONTINUE RETURN_END_IF COME_FROM
|
"""JUMP_BACK CONTINUE RETURN_END_IF COME_FROM
|
||||||
|
@@ -375,11 +375,11 @@ if __name__ == "__main__":
|
|||||||
# Check grammar
|
# Check grammar
|
||||||
p = Python27Parser()
|
p = Python27Parser()
|
||||||
p.check_grammar()
|
p.check_grammar()
|
||||||
from uncompyle6 import PYTHON_VERSION, IS_PYPY
|
from xdis.version_info import PYTHON_VERSION_TRIPLE, IS_PYPY
|
||||||
if PYTHON_VERSION == 2.7:
|
if PYTHON_VERSION_TRIPLE[:2] == (2, 7):
|
||||||
lhs, rhs, tokens, right_recursive, dup_rhs = p.check_sets()
|
lhs, rhs, tokens, right_recursive, dup_rhs = p.check_sets()
|
||||||
from uncompyle6.scanner import get_scanner
|
from uncompyle6.scanner import get_scanner
|
||||||
s = get_scanner(PYTHON_VERSION, IS_PYPY)
|
s = get_scanner(PYTHON_VERSION_TRIPLE, IS_PYPY)
|
||||||
opcode_set = set(s.opc.opname).union(set(
|
opcode_set = set(s.opc.opname).union(set(
|
||||||
"""JUMP_BACK CONTINUE RETURN_END_IF COME_FROM
|
"""JUMP_BACK CONTINUE RETURN_END_IF COME_FROM
|
||||||
LOAD_GENEXPR LOAD_ASSERT LOAD_SETCOMP LOAD_DICTCOMP
|
LOAD_GENEXPR LOAD_ASSERT LOAD_SETCOMP LOAD_DICTCOMP
|
||||||
|
@@ -365,11 +365,11 @@ if __name__ == '__main__':
|
|||||||
p = Python30Parser()
|
p = Python30Parser()
|
||||||
p.remove_rules_30()
|
p.remove_rules_30()
|
||||||
p.check_grammar()
|
p.check_grammar()
|
||||||
from uncompyle6 import PYTHON_VERSION, IS_PYPY
|
from xdis.version_info import PYTHON_VERSION_TRIPLE, IS_PYPY
|
||||||
if PYTHON_VERSION == 3.0:
|
if PYTHON_VERSION_TRIPLE[:2] == (3, 0):
|
||||||
lhs, rhs, tokens, right_recursive, dup_rhs = p.check_sets()
|
lhs, rhs, tokens, right_recursive, dup_rhs = p.check_sets()
|
||||||
from uncompyle6.scanner import get_scanner
|
from uncompyle6.scanner import get_scanner
|
||||||
s = get_scanner(PYTHON_VERSION, IS_PYPY)
|
s = get_scanner(PYTHON_VERSION_TRIPLE, IS_PYPY)
|
||||||
opcode_set = set(s.opc.opname).union(set(
|
opcode_set = set(s.opc.opname).union(set(
|
||||||
"""JUMP_BACK CONTINUE RETURN_END_IF COME_FROM
|
"""JUMP_BACK CONTINUE RETURN_END_IF COME_FROM
|
||||||
LOAD_GENEXPR LOAD_ASSERT LOAD_SETCOMP LOAD_DICTCOMP LOAD_CLASSNAME
|
LOAD_GENEXPR LOAD_ASSERT LOAD_SETCOMP LOAD_DICTCOMP LOAD_CLASSNAME
|
||||||
|
@@ -56,11 +56,11 @@ if __name__ == '__main__':
|
|||||||
p = Python31Parser()
|
p = Python31Parser()
|
||||||
p.remove_rules_31()
|
p.remove_rules_31()
|
||||||
p.check_grammar()
|
p.check_grammar()
|
||||||
from uncompyle6 import PYTHON_VERSION, IS_PYPY
|
from xdis.version_info import PYTHON_VERSION_TRIPLE, IS_PYPY
|
||||||
if PYTHON_VERSION == 3.1:
|
if PYTHON_VERSION_TRIPLE[:2] == (3, 1):
|
||||||
lhs, rhs, tokens, right_recursive, dup_rhs = p.check_sets()
|
lhs, rhs, tokens, right_recursive, dup_rhs = p.check_sets()
|
||||||
from uncompyle6.scanner import get_scanner
|
from uncompyle6.scanner import get_scanner
|
||||||
s = get_scanner(PYTHON_VERSION, IS_PYPY)
|
s = get_scanner(PYTHON_VERSION_TRIPLE, IS_PYPY)
|
||||||
opcode_set = set(s.opc.opname).union(set(
|
opcode_set = set(s.opc.opname).union(set(
|
||||||
"""JUMP_BACK CONTINUE RETURN_END_IF COME_FROM
|
"""JUMP_BACK CONTINUE RETURN_END_IF COME_FROM
|
||||||
LOAD_GENEXPR LOAD_ASSERT LOAD_SETCOMP LOAD_DICTCOMP LOAD_CLASSNAME
|
LOAD_GENEXPR LOAD_ASSERT LOAD_SETCOMP LOAD_DICTCOMP LOAD_CLASSNAME
|
||||||
|
@@ -70,11 +70,11 @@ if __name__ == '__main__':
|
|||||||
# Check grammar
|
# Check grammar
|
||||||
p = Python34Parser()
|
p = Python34Parser()
|
||||||
p.check_grammar()
|
p.check_grammar()
|
||||||
from uncompyle6 import PYTHON_VERSION, IS_PYPY
|
from xdis.version_info import PYTHON_VERSION_TRIPLE, IS_PYPY
|
||||||
if PYTHON_VERSION == 3.4:
|
if PYTHON_VERSION_TRIPLE[:2] == (3, 4):
|
||||||
lhs, rhs, tokens, right_recursive, dup_rhs = p.check_sets()
|
lhs, rhs, tokens, right_recursive, dup_rhs = p.check_sets()
|
||||||
from uncompyle6.scanner import get_scanner
|
from uncompyle6.scanner import get_scanner
|
||||||
s = get_scanner(PYTHON_VERSION, IS_PYPY)
|
s = get_scanner(PYTHON_VERSION_TRIPLE, IS_PYPY)
|
||||||
opcode_set = set(s.opc.opname).union(set(
|
opcode_set = set(s.opc.opname).union(set(
|
||||||
"""JUMP_BACK CONTINUE RETURN_END_IF COME_FROM
|
"""JUMP_BACK CONTINUE RETURN_END_IF COME_FROM
|
||||||
LOAD_GENEXPR LOAD_ASSERT LOAD_SETCOMP LOAD_DICTCOMP LOAD_CLASSNAME
|
LOAD_GENEXPR LOAD_ASSERT LOAD_SETCOMP LOAD_DICTCOMP LOAD_CLASSNAME
|
||||||
|
@@ -273,11 +273,11 @@ if __name__ == '__main__':
|
|||||||
# Check grammar
|
# Check grammar
|
||||||
p = Python35Parser()
|
p = Python35Parser()
|
||||||
p.check_grammar()
|
p.check_grammar()
|
||||||
from uncompyle6 import PYTHON_VERSION, IS_PYPY
|
from xdis.version_info import PYTHON_VERSION_TRIPLE, IS_PYPY
|
||||||
if PYTHON_VERSION == 3.5:
|
if PYTHON_VERSION_TRIPLE[:2] == (3, 5):
|
||||||
lhs, rhs, tokens, right_recursive, dup_rhs = p.check_sets()
|
lhs, rhs, tokens, right_recursive, dup_rhs = p.check_sets()
|
||||||
from uncompyle6.scanner import get_scanner
|
from uncompyle6.scanner import get_scanner
|
||||||
s = get_scanner(PYTHON_VERSION, IS_PYPY)
|
s = get_scanner(PYTHON_VERSION_TRIPLE, IS_PYPY)
|
||||||
opcode_set = set(s.opc.opname).union(set(
|
opcode_set = set(s.opc.opname).union(set(
|
||||||
"""JUMP_BACK CONTINUE RETURN_END_IF COME_FROM
|
"""JUMP_BACK CONTINUE RETURN_END_IF COME_FROM
|
||||||
LOAD_GENEXPR LOAD_ASSERT LOAD_SETCOMP LOAD_DICTCOMP LOAD_CLASSNAME
|
LOAD_GENEXPR LOAD_ASSERT LOAD_SETCOMP LOAD_DICTCOMP LOAD_CLASSNAME
|
||||||
|
@@ -673,11 +673,11 @@ if __name__ == '__main__':
|
|||||||
# Check grammar
|
# Check grammar
|
||||||
p = Python36Parser()
|
p = Python36Parser()
|
||||||
p.check_grammar()
|
p.check_grammar()
|
||||||
from uncompyle6 import PYTHON_VERSION, IS_PYPY
|
from xdis.version_info import PYTHON_VERSION_TRIPLE, IS_PYPY
|
||||||
if PYTHON_VERSION == 3.6:
|
if PYTHON_VERSION_TRIPLE[:2] == (3, 6):
|
||||||
lhs, rhs, tokens, right_recursive, dup_rhs = p.check_sets()
|
lhs, rhs, tokens, right_recursive, dup_rhs = p.check_sets()
|
||||||
from uncompyle6.scanner import get_scanner
|
from uncompyle6.scanner import get_scanner
|
||||||
s = get_scanner(PYTHON_VERSION, IS_PYPY)
|
s = get_scanner(PYTHON_VERSION_TRIPLE, IS_PYPY)
|
||||||
opcode_set = set(s.opc.opname).union(set(
|
opcode_set = set(s.opc.opname).union(set(
|
||||||
"""JUMP_BACK CONTINUE RETURN_END_IF COME_FROM
|
"""JUMP_BACK CONTINUE RETURN_END_IF COME_FROM
|
||||||
LOAD_GENEXPR LOAD_ASSERT LOAD_SETCOMP LOAD_DICTCOMP LOAD_CLASSNAME
|
LOAD_GENEXPR LOAD_ASSERT LOAD_SETCOMP LOAD_DICTCOMP LOAD_CLASSNAME
|
||||||
|
@@ -1740,13 +1740,13 @@ if __name__ == "__main__":
|
|||||||
# FIXME: DRY this with other parseXX.py routines
|
# FIXME: DRY this with other parseXX.py routines
|
||||||
p = Python37Parser()
|
p = Python37Parser()
|
||||||
p.check_grammar()
|
p.check_grammar()
|
||||||
from uncompyle6 import PYTHON_VERSION, IS_PYPY
|
from xdis.version_info import PYTHON_VERSION_TRIPLE, IS_PYPY
|
||||||
|
|
||||||
if PYTHON_VERSION == 3.7:
|
if PYTHON_VERSION_TRIPLE[:2] == (3, 7):
|
||||||
lhs, rhs, tokens, right_recursive, dup_rhs = p.check_sets()
|
lhs, rhs, tokens, right_recursive, dup_rhs = p.check_sets()
|
||||||
from uncompyle6.scanner import get_scanner
|
from uncompyle6.scanner import get_scanner
|
||||||
|
|
||||||
s = get_scanner(PYTHON_VERSION, IS_PYPY)
|
s = get_scanner(PYTHON_VERSION_TRIPLE, IS_PYPY)
|
||||||
opcode_set = set(s.opc.opname).union(
|
opcode_set = set(s.opc.opname).union(
|
||||||
set(
|
set(
|
||||||
"""JUMP_BACK CONTINUE RETURN_END_IF COME_FROM
|
"""JUMP_BACK CONTINUE RETURN_END_IF COME_FROM
|
||||||
|
@@ -610,13 +610,13 @@ if __name__ == "__main__":
|
|||||||
p = Python38Parser()
|
p = Python38Parser()
|
||||||
p.remove_rules_38()
|
p.remove_rules_38()
|
||||||
p.check_grammar()
|
p.check_grammar()
|
||||||
from uncompyle6 import PYTHON_VERSION, IS_PYPY
|
from xdis.version_info import PYTHON_VERSION_TRIPLE, IS_PYPY
|
||||||
|
|
||||||
if PYTHON_VERSION == 3.8:
|
if PYTHON_VERSION_TRIPLE[:2] == (3, 8):
|
||||||
lhs, rhs, tokens, right_recursive, dup_rhs = p.check_sets()
|
lhs, rhs, tokens, right_recursive, dup_rhs = p.check_sets()
|
||||||
from uncompyle6.scanner import get_scanner
|
from uncompyle6.scanner import get_scanner
|
||||||
|
|
||||||
s = get_scanner(PYTHON_VERSION, IS_PYPY)
|
s = get_scanner(PYTHON_VERSION_TRIPLE, IS_PYPY)
|
||||||
opcode_set = set(s.opc.opname).union(
|
opcode_set = set(s.opc.opname).union(
|
||||||
set(
|
set(
|
||||||
"""JUMP_BACK CONTINUE RETURN_END_IF COME_FROM
|
"""JUMP_BACK CONTINUE RETURN_END_IF COME_FROM
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
# Copyright (c) 2020 Rocky Bernstein
|
# Copyright (c) 2020, 2022 Rocky Bernstein
|
||||||
|
|
||||||
|
|
||||||
def while1stmt(self, lhs, n, rule, ast, tokens, first, last):
|
def while1stmt(self, lhs, n, rule, ast, tokens, first, last):
|
||||||
@@ -37,15 +37,14 @@ def while1stmt(self, lhs, n, rule, ast, tokens, first, last):
|
|||||||
if tokens[loop_end] == "JUMP_BACK":
|
if tokens[loop_end] == "JUMP_BACK":
|
||||||
loop_end += 1
|
loop_end += 1
|
||||||
loop_end_offset = tokens[loop_end].off2int(prefer_last=False)
|
loop_end_offset = tokens[loop_end].off2int(prefer_last=False)
|
||||||
for t in range(first+1, loop_end):
|
for t in range(first + 1, loop_end):
|
||||||
token = tokens[t]
|
token = tokens[t]
|
||||||
# token could be a pseudo-op like "LOAD_STR", which is not in
|
# token could be a pseudo-op like "LOAD_STR", which is not in
|
||||||
# self.opc. We will replace that with LOAD_CONST as an
|
# token.opc. We will replace that with LOAD_CONST as an
|
||||||
# example of an instruction that is not in self.opc.JUMP_OPS
|
# example of an instruction that is not in token.opc.JUMP_OPS
|
||||||
if self.opc.opmap.get(token.kind, "LOAD_CONST") in self.opc.JUMP_OPS:
|
if token.opc.opmap.get(token.kind, "LOAD_CONST") in token.opc.JUMP_OPS:
|
||||||
if token.attr >= loop_end_offset:
|
if token.attr >= loop_end_offset:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
# SETUP_LOOP location must jump either to the last token or the token after the last one
|
# SETUP_LOOP location must jump either to the last token or the token after the last one
|
||||||
return tokens[first].attr not in (offset, offset + 2)
|
return tokens[first].attr not in (offset, offset + 2)
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
# Copyright (c) 2019-2021 by Rocky Bernstein
|
# Copyright (c) 2019-2022 by Rocky Bernstein
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# This program is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
@@ -40,7 +40,7 @@ def make_function36(self, node, is_lambda, nested=1, code_node=None):
|
|||||||
Python version 3.6 and above.
|
Python version 3.6 and above.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# MAKE_CLOSURE adds an additional closure slot
|
# MAKE_CLOSURE adds a closure slot
|
||||||
|
|
||||||
# In Python 3.6 and above stack change again. I understand
|
# In Python 3.6 and above stack change again. I understand
|
||||||
# 3.7 changes some of those changes, although I don't
|
# 3.7 changes some of those changes, although I don't
|
||||||
@@ -150,13 +150,13 @@ def make_function36(self, node, is_lambda, nested=1, code_node=None):
|
|||||||
kwonlyargcount = code.co_kwonlyargcount
|
kwonlyargcount = code.co_kwonlyargcount
|
||||||
|
|
||||||
paramnames = list(scanner_code.co_varnames[:argc])
|
paramnames = list(scanner_code.co_varnames[:argc])
|
||||||
kwargs = list(scanner_code.co_varnames[argc : argc + kwonlyargcount])
|
kwargs = list(scanner_code.co_varnames[argc: argc + kwonlyargcount])
|
||||||
|
|
||||||
paramnames.reverse()
|
paramnames.reverse()
|
||||||
defparams.reverse()
|
defparams.reverse()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
ast = self.build_ast(
|
tree = self.build_ast(
|
||||||
scanner_code._tokens,
|
scanner_code._tokens,
|
||||||
scanner_code._customize,
|
scanner_code._customize,
|
||||||
scanner_code,
|
scanner_code,
|
||||||
@@ -176,10 +176,12 @@ def make_function36(self, node, is_lambda, nested=1, code_node=None):
|
|||||||
if defparams:
|
if defparams:
|
||||||
for i, defparam in enumerate(defparams):
|
for i, defparam in enumerate(defparams):
|
||||||
params.append(
|
params.append(
|
||||||
build_param(paramnames[i], defparam, annotate_dict.get(paramnames[i]))
|
build_param(
|
||||||
|
tree, paramnames[i], defparam, annotate_dict.get(paramnames[i])
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
for param in paramnames[i + 1 :]:
|
for param in paramnames[i + 1:]:
|
||||||
if param in annotate_dict:
|
if param in annotate_dict:
|
||||||
params.append("%s: %s" % (param, annotate_dict[param]))
|
params.append("%s: %s" % (param, annotate_dict[param]))
|
||||||
else:
|
else:
|
||||||
@@ -204,7 +206,13 @@ def make_function36(self, node, is_lambda, nested=1, code_node=None):
|
|||||||
|
|
||||||
# dump parameter list (with default values)
|
# dump parameter list (with default values)
|
||||||
if is_lambda:
|
if is_lambda:
|
||||||
self.write("lambda ", ", ".join(params))
|
self.write("lambda")
|
||||||
|
if len(params):
|
||||||
|
self.write(" ", ", ".join(params))
|
||||||
|
elif kwonlyargcount > 0 and not (4 & code.co_flags):
|
||||||
|
assert argc == 0
|
||||||
|
self.write(" ")
|
||||||
|
|
||||||
# If the last statement is None (which is the
|
# If the last statement is None (which is the
|
||||||
# same thing as "return None" in a lambda) and the
|
# same thing as "return None" in a lambda) and the
|
||||||
# next to last statement is a "yield". Then we want to
|
# next to last statement is a "yield". Then we want to
|
||||||
@@ -212,16 +220,16 @@ def make_function36(self, node, is_lambda, nested=1, code_node=None):
|
|||||||
# to have something to after the yield finishes.
|
# to have something to after the yield finishes.
|
||||||
# FIXME: this is a bit hoaky and not general
|
# FIXME: this is a bit hoaky and not general
|
||||||
if (
|
if (
|
||||||
len(ast) > 1
|
len(tree) > 1
|
||||||
and self.traverse(ast[-1]) == "None"
|
and self.traverse(tree[-1]) == "None"
|
||||||
and self.traverse(ast[-2]).strip().startswith("yield")
|
and self.traverse(tree[-2]).strip().startswith("yield")
|
||||||
):
|
):
|
||||||
del ast[-1]
|
del tree[-1]
|
||||||
# Now pick out the expr part of the last statement
|
# Now pick out the expr part of the last statement
|
||||||
ast_expr = ast[-1]
|
tree_expr = tree[-1]
|
||||||
while ast_expr.kind != "expr":
|
while tree_expr.kind != "expr":
|
||||||
ast_expr = ast_expr[0]
|
tree_expr = tree_expr[0]
|
||||||
ast[-1] = ast_expr
|
tree[-1] = tree_expr
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
self.write("(", ", ".join(params))
|
self.write("(", ", ".join(params))
|
||||||
@@ -235,11 +243,9 @@ def make_function36(self, node, is_lambda, nested=1, code_node=None):
|
|||||||
else:
|
else:
|
||||||
self.write("*, ")
|
self.write("*, ")
|
||||||
pass
|
pass
|
||||||
ends_in_comma = True
|
|
||||||
else:
|
else:
|
||||||
if argc > 0:
|
if argc > 0:
|
||||||
self.write(", ")
|
self.write(", ")
|
||||||
ends_in_comma = True
|
|
||||||
|
|
||||||
# ann_dict = kw_dict = default_tup = None
|
# ann_dict = kw_dict = default_tup = None
|
||||||
kw_dict = None
|
kw_dict = None
|
||||||
@@ -331,11 +337,11 @@ def make_function36(self, node, is_lambda, nested=1, code_node=None):
|
|||||||
# docstring exists, dump it
|
# docstring exists, dump it
|
||||||
self.println(self.traverse(node[-2]))
|
self.println(self.traverse(node[-2]))
|
||||||
|
|
||||||
assert ast == "stmts"
|
assert tree in ("stmts", "lambda_start")
|
||||||
|
|
||||||
all_globals = find_all_globals(ast, set())
|
all_globals = find_all_globals(tree, set())
|
||||||
globals, nonlocals = find_globals_and_nonlocals(
|
globals, nonlocals = find_globals_and_nonlocals(
|
||||||
ast, set(), set(), code, self.version
|
tree, set(), set(), code, self.version
|
||||||
)
|
)
|
||||||
|
|
||||||
for g in sorted((all_globals & self.mod_globs) | globals):
|
for g in sorted((all_globals & self.mod_globs) | globals):
|
||||||
@@ -346,9 +352,9 @@ def make_function36(self, node, is_lambda, nested=1, code_node=None):
|
|||||||
|
|
||||||
self.mod_globs -= all_globals
|
self.mod_globs -= all_globals
|
||||||
has_none = "None" in code.co_names
|
has_none = "None" in code.co_names
|
||||||
rn = has_none and not find_none(ast)
|
rn = has_none and not find_none(tree)
|
||||||
self.gen_source(
|
self.gen_source(
|
||||||
ast,
|
tree,
|
||||||
code.co_name,
|
code.co_name,
|
||||||
scanner_code._customize,
|
scanner_code._customize,
|
||||||
is_lambda=is_lambda,
|
is_lambda=is_lambda,
|
||||||
|
@@ -893,7 +893,7 @@ class SourceWalker(GenericASTTraversal, NonterminalActions, ComprehensionMixin):
|
|||||||
p2 = (1, -2, ", ")
|
p2 = (1, -2, ", ")
|
||||||
if op == "CALL_FUNCTION_VAR":
|
if op == "CALL_FUNCTION_VAR":
|
||||||
# Python 3.5 only puts optional args (the VAR part)
|
# Python 3.5 only puts optional args (the VAR part)
|
||||||
# lowest down the stack
|
# the lowest down the stack
|
||||||
if self.version == (3, 5):
|
if self.version == (3, 5):
|
||||||
if str == "%c(%C, ":
|
if str == "%c(%C, ":
|
||||||
entry = ("%c(*%C, %c)", 0, p2, -2)
|
entry = ("%c(*%C, %c)", 0, p2, -2)
|
||||||
@@ -917,7 +917,7 @@ class SourceWalker(GenericASTTraversal, NonterminalActions, ComprehensionMixin):
|
|||||||
elif op == "CALL_FUNCTION_VAR_KW":
|
elif op == "CALL_FUNCTION_VAR_KW":
|
||||||
str += "*%c, **%c)"
|
str += "*%c, **%c)"
|
||||||
# Python 3.5 only puts optional args (the VAR part)
|
# Python 3.5 only puts optional args (the VAR part)
|
||||||
# lowest down the stack
|
# the lowest down the stack
|
||||||
na = v & 0xFF # positional parameters
|
na = v & 0xFF # positional parameters
|
||||||
if self.version == (3, 5) and na == 0:
|
if self.version == (3, 5) and na == 0:
|
||||||
if p2[2]:
|
if p2[2]:
|
||||||
@@ -1194,7 +1194,7 @@ class SourceWalker(GenericASTTraversal, NonterminalActions, ComprehensionMixin):
|
|||||||
return transform_tree
|
return transform_tree
|
||||||
|
|
||||||
# The bytecode for the end of the main routine has a
|
# The bytecode for the end of the main routine has a
|
||||||
# "return None". However you can't issue a "return" statement in
|
# "return None". However, you can't issue a "return" statement in
|
||||||
# main. So as the old cigarette slogan goes: I'd rather switch (the token stream)
|
# main. So as the old cigarette slogan goes: I'd rather switch (the token stream)
|
||||||
# than fight (with the grammar to not emit "return None").
|
# than fight (with the grammar to not emit "return None").
|
||||||
if self.hide_internal:
|
if self.hide_internal:
|
||||||
|
Reference in New Issue
Block a user