In lambda code we, no stinking bogus yield

This commit is contained in:
rocky 2020-02-09 07:32:06 -05:00
parent 5355cb5404
commit 6cbb631aa6
7 changed files with 35 additions and 3 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,32 @@
# Adapted from 3.7.6 test_contains
# The bug was in reconstructing something equivalent to
# "while False: yelid None" which is *needed* in __iter__().
# Sheeh!
# RUNNABLE!
def test_block_fallback():
# blocking fallback with __contains__ = None
class ByContains(object):
def __contains__(self, other):
return False
c = ByContains()
class BlockContains(ByContains):
"""Is not a container
This class is a perfectly good iterable (as tested by
list(bc)), as well as inheriting from a perfectly good
container, but __contains__ = None prevents the usual
fallback to iteration in the container protocol. That
is, normally, 0 in bc would fall back to the equivalent
of any(x==0 for x in bc), but here it's blocked from
doing so.
"""
def __iter__(self):
while False:
yield None
__contains__ = None
bc = BlockContains()
assert not (0 in c)
assert not (0 in list(bc))
test_block_fallback()

View File

@ -30,7 +30,7 @@ SKIP_TESTS=(
[test_compileall.py]=1 # fails on its own
[test_compile.py]=1 # Code introspects on co_consts in a non-decompilable way
[test_concurrent_futures.py]=1 # too long
[test_coroutines.py]=1 # test
[test_coroutines.py]=1 # parse error
[test_codecs.py]=1 # test assert failures; encoding/decoding stuff
[test_ctypes.py]=1 # it fails on its own
[test_curses.py]=1 # probably byte string not handled properly

View File

@ -677,7 +677,7 @@ def make_function3(self, node, is_lambda, nested=1, code_node=None):
# 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:
if not is_lambda code.co_flags & CO_GENERATOR:
need_bogus_yield = True
for token in scanner_code._tokens:
if token in ("YIELD_VALUE", "YIELD_FROM"):

View File

@ -356,7 +356,7 @@ def make_function36(self, node, is_lambda, nested=1, code_node=None):
# add in "yield" just so that the compiler will mark
# the GENERATOR bit of the function. See for example
# Python 3.x's test_connection.py and test_contexlib_async test programs.
if code.co_flags & (CO_GENERATOR | CO_ASYNC_GENERATOR):
if not is_lambda and code.co_flags & (CO_GENERATOR | CO_ASYNC_GENERATOR):
need_bogus_yield = True
for token in scanner_code._tokens:
if token == "YIELD_VALUE":