Re: [Twisted-Python] Re: A Python metaclass for Twisted allowing __init__ to return a Deferred
Hi Nicola!
"Nicola" == Nicola Larosa
writes: Nicola> Terry Jones wrote: BTW, I spent an interesting morning getting my head around *exactly* how inlineCallbacks does its thing... No summary of my thoughts could do it justice. I wonder how many people on the planet have been down that rabbit hole.
Nicola> Not me, man, not me. I just use the bloody thing, and curse it when Nicola> it shortens tracebacks. I know exactly what you're talking about, and I hated that too. But I dug into that and found out where the problem was: I didn't know Python well enough :-) I bet you're doing something like this: @inlineCallbacks def f(): # Whatever try: # Your code here except Exception, e: # Do some cleaning up, maybe write to the log, maybe call another # function that uses inlineCallbacks raise e or just @inlineCallbacks def f(): # Whatever try: # Your code here except Exception: # Do some cleaning up, maybe write to the log, maybe call another # function that uses inlineCallbacks raise The problem here is that you're not using the 3-argument form of raise. So you're either dropping information (with the raise e) or pulling out the last exception (with the no-arg raise). Consider the latter case. Suppose your cleanup code calls another function that uses inlineCallbacks. That function will eventually raise StopIteration or raise via calling defer.returnValue. So by the time control returns to your code, your raise (which implicitly uses sys.exc_info()) raises the wrong exception! So you get e.g., a StopIteration exception coming at you out of your inlineCallbacks function and you curse the thing :-) This applies if your cleanup code calls any iterator, or if you call something that try/except catches a KeyError, etc. So just use @inlineCallbacks def f(): # Whatever try: # Your code here except Exception: info = sys.exc_info() # Do some cleaning up, maybe write to the log, maybe call another # function that uses inlineCallbacks raise info[0], info[1], info[2] and it just works. Try it :-) You cant do anything nice like raise *info because Python's parser doesn't like that (AFAIR). I nearly posted about this to the list, but I figured it might help if I had more of a clue about Python itself, seeing as what I was doing was nothing to do with Twisted.
I hope people don't mind my peanut gallery commentary. We're all in this together, after all. A little gallows humor occasionally seems in order. Nicola> Again, certainly not me. Go right ahead! ;-)
Don't encourage me... Terry
participants (1)
-
Terry Jones