Skip to content

Commit 4dce2de

Browse files
committed
Add more tests for generator frame access
1 parent ad3978f commit 4dce2de

File tree

1 file changed

+80
-1
lines changed

1 file changed

+80
-1
lines changed

graalpython/com.oracle.graal.python.test/src/tests/test_generators.py

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -506,4 +506,83 @@ def b():
506506
assert gen_b.gi_yieldfrom.gi_code.co_name == 'q'
507507

508508
gen_b.send(None)
509-
assert gen_b.gi_yieldfrom is None
509+
assert gen_b.gi_yieldfrom is None
510+
511+
512+
def test_generator_frame():
513+
def gen():
514+
a = 1
515+
yield sys._getframe()
516+
b = 2
517+
518+
g = gen()
519+
assert not g.gi_running
520+
assert not g.gi_suspended
521+
assert g.gi_frame
522+
assert g.gi_frame.f_back is None
523+
assert g.gi_frame.f_globals == globals()
524+
assert g.gi_frame.f_locals == {}
525+
assert g.gi_frame.f_lineno == gen.__code__.co_firstlineno
526+
f = next(g)
527+
assert f
528+
assert not g.gi_running
529+
assert g.gi_suspended
530+
assert f is g.gi_frame
531+
assert f.f_back is None
532+
assert f.f_globals == globals()
533+
assert f.f_locals == {'a': 1}
534+
assert f.f_lineno == gen.__code__.co_firstlineno + 2
535+
try:
536+
next(g)
537+
assert False
538+
except StopIteration:
539+
pass
540+
assert not g.gi_running
541+
assert not g.gi_suspended
542+
assert not g.gi_frame
543+
# CPython is inconsistent here that the backref is set for a generator that finished. Let's assume it's just an implementation accident
544+
# assert f.f_back is None
545+
assert f.f_globals is globals()
546+
assert f.f_locals == {'a': 1, 'b': 2}
547+
assert f.f_lineno == gen.__code__.co_firstlineno + 3
548+
549+
550+
def test_generator_frame_in_running_generator():
551+
def gen():
552+
self = yield
553+
assert self.gi_running
554+
assert not self.gi_suspended
555+
assert self.gi_frame.f_lineno == gen.__code__.co_firstlineno + 4
556+
assert self.gi_frame.f_globals == globals()
557+
assert self.gi_frame.f_locals.get('self') is self
558+
assert self.gi_frame is sys._getframe()
559+
560+
g = gen()
561+
next(g)
562+
try:
563+
g.send(g)
564+
assert False
565+
except StopIteration:
566+
pass
567+
568+
569+
def test_generator_frame_in_generator_up_stack():
570+
def validate(self):
571+
assert self.gi_running
572+
assert not self.gi_suspended
573+
assert self.gi_frame.f_lineno == gen.__code__.co_firstlineno + 2
574+
assert self.gi_frame.f_globals == globals()
575+
assert self.gi_frame.f_locals.get('self') is self
576+
assert self.gi_frame is sys._getframe(1)
577+
578+
def gen():
579+
self = yield
580+
validate(self)
581+
582+
g = gen()
583+
next(g)
584+
try:
585+
g.send(g)
586+
assert False
587+
except StopIteration:
588+
pass

0 commit comments

Comments
 (0)