py/objgenerator: Fix handling of None passed as 2nd arg to throw().
Fixes issue #4527.
This commit is contained in:
parent
29865e3e58
commit
dac9d47671
|
@ -252,7 +252,22 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(gen_instance_send_obj, gen_instance_send);
|
|||
|
||||
STATIC mp_obj_t gen_instance_close(mp_obj_t self_in);
|
||||
STATIC mp_obj_t gen_instance_throw(size_t n_args, const mp_obj_t *args) {
|
||||
mp_obj_t exc = (n_args == 2) ? args[1] : args[2];
|
||||
// The signature of this function is: throw(type[, value[, traceback]])
|
||||
// CPython will pass all given arguments through the call chain and process them
|
||||
// at the point they are used (native generators will handle them differently to
|
||||
// user-defined generators with a throw() method). To save passing multiple
|
||||
// values, MicroPython instead does partial processing here to reduce it down to
|
||||
// one argument and passes that through:
|
||||
// - if only args[1] is given, or args[2] is given but is None, args[1] is
|
||||
// passed through (in the standard case it is an exception class or instance)
|
||||
// - if args[2] is given and not None it is passed through (in the standard
|
||||
// case it would be an exception instance and args[1] its corresponding class)
|
||||
// - args[3] is always ignored
|
||||
|
||||
mp_obj_t exc = args[1];
|
||||
if (n_args > 2 && args[2] != mp_const_none) {
|
||||
exc = args[2];
|
||||
}
|
||||
|
||||
mp_obj_t ret = gen_resume_and_raise(args[0], mp_const_none, exc);
|
||||
if (ret == MP_OBJ_STOP_ITERATION) {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
def gen():
|
||||
try:
|
||||
yield 1
|
||||
except ValueError:
|
||||
print("got ValueError from upstream!")
|
||||
except ValueError as e:
|
||||
print("got ValueError from upstream!", repr(e.args))
|
||||
yield "str1"
|
||||
raise TypeError
|
||||
|
||||
|
@ -16,3 +16,21 @@ try:
|
|||
print(next(g))
|
||||
except TypeError:
|
||||
print("got TypeError from downstream!")
|
||||
|
||||
# passing None as second argument to throw
|
||||
g = gen2()
|
||||
print(next(g))
|
||||
print(g.throw(ValueError, None))
|
||||
try:
|
||||
print(next(g))
|
||||
except TypeError:
|
||||
print("got TypeError from downstream!")
|
||||
|
||||
# passing an exception instance as second argument to throw
|
||||
g = gen2()
|
||||
print(next(g))
|
||||
print(g.throw(ValueError, ValueError(123)))
|
||||
try:
|
||||
print(next(g))
|
||||
except TypeError:
|
||||
print("got TypeError from downstream!")
|
||||
|
|
|
@ -28,8 +28,8 @@ except StopIteration:
|
|||
def gen():
|
||||
try:
|
||||
yield 123
|
||||
except GeneratorExit:
|
||||
print('GeneratorExit')
|
||||
except GeneratorExit as e:
|
||||
print('GeneratorExit', repr(e.args))
|
||||
yield 456
|
||||
|
||||
# thrown a class
|
||||
|
@ -41,3 +41,13 @@ print(g.throw(GeneratorExit))
|
|||
g = gen()
|
||||
print(next(g))
|
||||
print(g.throw(GeneratorExit()))
|
||||
|
||||
# thrown an instance with None as second arg
|
||||
g = gen()
|
||||
print(next(g))
|
||||
print(g.throw(GeneratorExit(), None))
|
||||
|
||||
# thrown a class and instance
|
||||
g = gen()
|
||||
print(next(g))
|
||||
print(g.throw(GeneratorExit, GeneratorExit(123)))
|
||||
|
|
Loading…
Reference in New Issue