From 05252c87f42109baa0b7200c3d3f57377f23a3b9 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Mon, 17 Oct 2022 09:08:17 -0500 Subject: [PATCH] Don't crash when assigning attributes of the GeneratorExit const singleton --- py/objexcept.c | 3 +++ tests/basics/gen_yield_from_close.py | 23 ++++++++++++++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/py/objexcept.c b/py/objexcept.c index 12408c0d1f..32dacbb17a 100644 --- a/py/objexcept.c +++ b/py/objexcept.c @@ -218,6 +218,9 @@ void mp_obj_exception_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { mp_obj_exception_t *self = MP_OBJ_TO_PTR(self_in); if (dest[0] != MP_OBJ_NULL) { // store/delete attribute + if (self == &mp_const_GeneratorExit_obj) { + mp_raise_AttributeError(MP_ERROR_TEXT("can't set attribute")); + } if (attr == MP_QSTR___traceback__) { if (dest[1] == mp_const_none) { self->traceback = (mp_obj_traceback_t *)&mp_const_empty_traceback_obj; diff --git a/tests/basics/gen_yield_from_close.py b/tests/basics/gen_yield_from_close.py index e3e0116ff7..08e0d41beb 100644 --- a/tests/basics/gen_yield_from_close.py +++ b/tests/basics/gen_yield_from_close.py @@ -37,8 +37,12 @@ def gen4(): yield -1 try: print((yield from gen3())) - except GeneratorExit: + except GeneratorExit as e: print("delegating caught GeneratorExit") + try: + e.__traceback__ = None + except AttributeError: + pass # generated in micropython, not in python3 raise yield 10 yield 11 @@ -121,3 +125,20 @@ def gen9(): g = gen9() print(next(g)) g.close() + +# Test that, when chaining to a GeneratorExit exception generated internally, +# no exception or crash occurs +def gen10(): + try: + yield 1/0 + except Exception as e: + yield 1 + yield 2 + yield 3 +g = gen10() +print(next(g)) +g.close() +try: + print(next(g)) +except StopIteration: + print("StopIteration")