Created
April 7, 2014 19:12
-
-
Save hazelybell/10032964 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def inlineCallbacks(f): | |
from functools import wraps | |
@wraps(f) | |
def _(*args, **kwargs): | |
gen = f(*args, **kwargs) | |
stop_running = [False] | |
def cancelled(df_): | |
assert df_ is df | |
stop_running[0] = True | |
if currently_waiting_on: | |
currently_waiting_on[0].cancel() | |
df = defer.Deferred(cancelled) | |
currently_waiting_on = [] | |
def it(cur): | |
while True: | |
try: | |
if isinstance(cur, failure.Failure): | |
res = cur.throwExceptionIntoGenerator(gen) # external code is run here | |
else: | |
res = gen.send(cur) # external code is run here | |
if stop_running[0]: | |
return | |
except StopIteration: | |
df.callback(None) | |
except defer._DefGen_Return as e: | |
# XXX should make sure direct child threw | |
df.callback(e.value) | |
except: | |
df.errback() | |
else: | |
if isinstance(res, defer.Deferred): | |
called, res2 = deferred_has_been_called(res) | |
if called: | |
cur = res2 | |
continue | |
else: | |
currently_waiting_on[:] = [res] | |
def gotResult(res2): | |
assert currently_waiting_on[0] is res | |
currently_waiting_on[:] = [] | |
if stop_running[0]: | |
return | |
it(res2) | |
res.addBoth(gotResult) # external code is run between this and gotResult | |
else: | |
cur = res | |
continue | |
break | |
it(None) | |
return df | |
return _ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment