Seomtiems we need to add "yield"...

in order to get the generator bit flag set, such as in 3.x where the
yield is optimized away.
This commit is contained in:
rocky
2020-01-06 14:57:11 -05:00
parent 63a88b8eea
commit 078cca335a
4 changed files with 55 additions and 10 deletions

View File

@@ -1,4 +1,4 @@
# Copyright (c) 2015-2019 by Rocky Bernstein
# Copyright (c) 2015-2020 by Rocky Bernstein
# Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com>
#
# This program is free software: you can redistribute it and/or modify
@@ -18,6 +18,7 @@ All the crazy things we have to do to handle Python functions in Python before 3
The saga of changes continues in 3.0 and above and in other files.
"""
from xdis.code import iscode, code_has_star_arg, code_has_star_star_arg
from xdis.util import CO_GENERATOR
from uncompyle6.scanner import Code
from uncompyle6.parsers.treenode import SyntaxTree
from uncompyle6 import PYTHON3
@@ -182,7 +183,6 @@ def make_function2(self, node, is_lambda, nested=1, code_node=None):
# docstring exists, dump it
print_docstring(self, indent, code.co_consts[0])
code._tokens = None # save memory
if not is_lambda:
assert ast == "stmts"
@@ -203,5 +203,21 @@ def make_function2(self, node, is_lambda, nested=1, code_node=None):
self.gen_source(
ast, code.co_name, code._customize, is_lambda=is_lambda, returnNone=rn
)
code._tokens = None
# In obscure cases, a function may be a generator but the "yield"
# 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.
if code.co_flags & CO_GENERATOR:
need_bogus_yield = True
for token in scanner_code._tokens:
if token == "YIELD_VALUE":
need_bogus_yield = False
break
pass
if need_bogus_yield:
self.template_engine(("%|if False:\n%+%|yield None%-",), node)
code._tokens = None # save memory
code._customize = None # save memory