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 printed sys.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

Popular posts from this blog

css - Which browser returns the correct result for getBoundingClientRect of an SVG element? -

gcc - Calling fftR4() in c from assembly -

Function that returns a formatted array in VBA -