Skip to content

Commit

Permalink
pythongh-125038: Tests on generator modifying through gi_frame.f_loca…
Browse files Browse the repository at this point in the history
…ls are added
  • Loading branch information
efimov-mikhail committed Oct 9, 2024
1 parent c353cf1 commit 3e0b12f
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 10 deletions.
54 changes: 54 additions & 0 deletions Lib/test/test_frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,60 @@ def make_frame():
with self.assertRaises(TypeError):
FrameLocalsProxy(frame=sys._getframe()) # no keyword arguments

def test_generator_f_locals(self):
def get_generator_genexpr(new_value):
g = (x for x in range(10))
g.gi_frame.f_locals['.0'] = new_value
return g

def get_generator_fn_call(new_value):
def gen(it):
for x in it:
yield x

g = gen(range(10))
g.gi_frame.f_locals['it'] = new_value
return g

err_msg_pattern_genexpr = "'for' requires an object with __iter__ method, got %s"
err_msg_pattern_fn_call = "'%s' object is not iterable"

sequences = [
range(0),
range(20),
[1, 2, 3],
(1, 2, 3),
(2,),
set((13, 48, 211)),
frozenset((15, 8, 6)),
dict([(1, 2), (3, 4)]),
]

for seq in sequences:
self.assertListEqual(list(get_generator_genexpr(iter(seq))), list(seq))
err_msg_genexpr = err_msg_pattern_genexpr % type(seq).__name__
with self.assertRaisesRegex(TypeError, err_msg_genexpr):
list(get_generator_genexpr(seq))

for seq in sequences:
self.assertListEqual(list(get_generator_fn_call(iter(seq))), list(seq))
self.assertListEqual(list(get_generator_fn_call(seq)), list(seq))

non_sequences = [
None,
42,
3.0,
2j,
]

for obj in non_sequences:
err_msg_fn_call = err_msg_pattern_fn_call % type(obj).__name__
with self.assertRaisesRegex(TypeError, err_msg_fn_call):
list(get_generator_fn_call(obj))
err_msg_genexpr = err_msg_pattern_genexpr % type(obj).__name__
with self.assertRaisesRegex(TypeError, err_msg_genexpr):
list(get_generator_genexpr(obj))


class FrameLocalsProxyMappingTests(mapping_tests.TestHashMappingProtocol):
"""Test that FrameLocalsProxy behaves like a Mapping (with exceptions)"""
Expand Down
10 changes: 0 additions & 10 deletions Lib/test/test_generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,16 +268,6 @@ def loop():
#This should not raise
loop()

def test_issue125038(self):
def get_generator():
g = (x for x in range(10))
g.gi_frame.f_locals['.0'] = range(20)
return g

err_msg = "'for' requires an object with __iter__ method, got range"
with self.assertRaisesRegex(TypeError, err_msg):
l = list(get_generator())

class ExceptionTest(unittest.TestCase):
# Tests for the issue #23353: check that the currently handled exception
# is correctly saved/restored in PyEval_EvalFrameEx().
Expand Down

0 comments on commit 3e0b12f

Please sign in to comment.