python - Exception TypeError warning sometimes shown, sometimes not when using throw method of generator -
there code:
class myexception(exception): pass def gen(): in range(3): try: yield except myexception: print("myexception!") = gen() next(a) a.throw(myexception)
running code:
$ python3.3 main.py myexception! $ python3.3 main.py myexception! exception typeerror: typeerror('catching classes not inherit baseexception not allowed',) in <generator object gen @ 0xb712efa4> ignored $ python3.3 main.py myexception! $ python3.3 main.py myexception! $ python3.3 main.py myexception! exception typeerror: typeerror('catching classes not inherit baseexception not allowed',) in <generator object gen @ 0xb714afa4> ignored
the thing don't understand why there printed exception typeerror
warning. there wrong custom exception?
you seeing __del__
hook misbehaving somewhere.
the typeerror
being thrown while shutting down, python interpreter exiting deleted , exceptions thrown in __del__
deconstructor hook being ignored (but are printed).
on exit, python clears in namespace rebinding none
, order in happens not set. still running generator closed (a.close()
called) when deleted, triggers generatorexit
exception in generator, python tests against except myexception:
line. if, however, myexception
has already been cleared , python sees except none:
typeerror
thrown , see message printed.
you can trigger error without exiting python adding:
myexception = none del
if use list(a)
, consume rest of generator, or explicitly close generator a.close()
before python exits , deletes myexception
, error message goes away.
another work-around handle generatorexit
first:
def gen(): in range(3): try: yield except generatorexit: return except myexception: print("myexception!")
and python not evaluate next except
handler.
the error cannot reproduced python 3.2 or earlier, looks hash randomization (introduced in python 3.3) randomizes order objects cleared; explains why see error on some of runs, not on earlier python runs hash order fixed.
note interaction of .__del__()
hooks , other global objects in python documented big red warning in .__del__()
documentation:
warning: due precarious circumstances under
__del__()
methods invoked, exceptions occur during execution ignored, , warning printedsys.stderr
instead. also, when__del__()
invoked in response module being deleted (e.g., when execution of program done), other globals referenced__del__()
method may have been deleted or in process of being torn down (e.g. import machinery shutting down). reason,__del__()
methods should absolute minimum needed maintain external invariants. starting version 1.5, python guarantees globals name begins single underscore deleted module before other globals deleted; if no other references such globals exist, may in assuring imported modules still available @ time when__del__()
method called.
Comments
Post a Comment