mirror of
https://github.com/JamesonHuang/OpenWrt_Luci_Lua.git
synced 2025-06-21 10:30:38 +00:00
some source code about twisted
This commit is contained in:
@ -0,0 +1,18 @@
|
||||
from twisted.internet.defer import Deferred
|
||||
|
||||
def got_poem(res):
|
||||
print 'Your poem is served:'
|
||||
print res
|
||||
|
||||
def poem_failed(err):
|
||||
print 'No poetry for you.'
|
||||
|
||||
d = Deferred()
|
||||
|
||||
# add a callback/errback pair to the chain
|
||||
d.addCallbacks(got_poem, poem_failed)
|
||||
|
||||
# fire the chain with a normal result
|
||||
d.callback('This poem is short.')
|
||||
|
||||
print "Finished"
|
@ -0,0 +1,102 @@
|
||||
from twisted.internet.defer import Deferred
|
||||
|
||||
print """
|
||||
This example illustrates how callbacks in a deferred
|
||||
chain can return deferreds themselves.
|
||||
"""
|
||||
|
||||
# three simple callbacks
|
||||
|
||||
def callback_1(res):
|
||||
print 'callback_1 got', res
|
||||
return 1
|
||||
|
||||
def callback_2(res):
|
||||
print 'callback_2 got', res
|
||||
return 2
|
||||
|
||||
def callback_3(res):
|
||||
print 'callback_3 got', res
|
||||
return 3
|
||||
|
||||
|
||||
# We add them all to a deferred and fire it:
|
||||
|
||||
d = Deferred()
|
||||
|
||||
d.addCallback(callback_1)
|
||||
d.addCallback(callback_2)
|
||||
d.addCallback(callback_3)
|
||||
|
||||
print """
|
||||
Here we are firing a deferred with three callbacks that just print
|
||||
their argument and return simple values:
|
||||
"""
|
||||
|
||||
d.callback(0)
|
||||
|
||||
# And you get output like this:
|
||||
# callback_1 got 0
|
||||
# callback_2 got 1
|
||||
# callback_3 got 2
|
||||
|
||||
|
||||
# Now we make a callback that returns a deferred:
|
||||
|
||||
deferred_2 = None # NOTE: because we aren't using a reactor, we have
|
||||
# to fire this deferred from the 'outside'.
|
||||
# We store it in a global variable for this
|
||||
# purpose. In a normal Twisted program you
|
||||
# would never store a deferred in a global or
|
||||
# fire it from the outside. By 'outside' we
|
||||
# mean the deferred is not being fired by an
|
||||
# action set in motion by the callback that
|
||||
# created and returned the deferred, as is
|
||||
# normally the case.
|
||||
|
||||
def callback_2_async(res):
|
||||
print 'callback_2 got', res
|
||||
global deferred_2 # never do this in a real program
|
||||
deferred_2 = Deferred()
|
||||
return deferred_2
|
||||
|
||||
|
||||
# We do the same thing, but use the async callback:
|
||||
|
||||
d = Deferred()
|
||||
|
||||
d.addCallback(callback_1)
|
||||
d.addCallback(callback_2_async)
|
||||
d.addCallback(callback_3)
|
||||
|
||||
print """
|
||||
Here we are firing a deferred as above but the middle callback is
|
||||
returning a deferred:
|
||||
"""
|
||||
|
||||
d.callback(0)
|
||||
|
||||
# And you get output like this:
|
||||
# callback_1 got 0
|
||||
# callback_2 got 1
|
||||
|
||||
print """
|
||||
Notice the output from the third callback is missing. That's because
|
||||
the second callback returned a deferred and now the 'outer' deferred
|
||||
is paused. It's not waiting in a thread or anything like that, it just
|
||||
stopped invoking the callbacks in the chain. Instead, it registered
|
||||
some callbacks on the 'inner' deferred which will start the outer
|
||||
deferred back up when the inner deferred is fired.
|
||||
|
||||
We can see this in action by firing the inner deferred:
|
||||
"""
|
||||
|
||||
deferred_2.callback(2)
|
||||
|
||||
# And you get output like this:
|
||||
# callback_3 got 2
|
||||
|
||||
print """
|
||||
Note the argument to the inner deferred's callback() method became
|
||||
the result passed to the next callback in the outer deferred.
|
||||
"""
|
@ -0,0 +1,63 @@
|
||||
from twisted.internet.defer import Deferred
|
||||
|
||||
print """\
|
||||
This example illustrates how deferreds can
|
||||
be fired before they are returned. First we
|
||||
make a new deferred, fire it, then add some
|
||||
callbacks.
|
||||
"""
|
||||
|
||||
# three simple callbacks
|
||||
|
||||
def callback_1(res):
|
||||
print 'callback_1 got', res
|
||||
return 1
|
||||
|
||||
def callback_2(res):
|
||||
print 'callback_2 got', res
|
||||
return 2
|
||||
|
||||
def callback_3(res):
|
||||
print 'callback_3 got', res
|
||||
return 3
|
||||
|
||||
# We create a deferred and fire it immediately:
|
||||
d = Deferred()
|
||||
|
||||
print 'Firing empty deferred.'
|
||||
d.callback(0)
|
||||
|
||||
# Now we add the callbacks to the deferred.
|
||||
# Notice how each callback fires immediately.
|
||||
|
||||
print 'Adding first callback.'
|
||||
d.addCallback(callback_1)
|
||||
|
||||
print 'Adding second callback.'
|
||||
d.addCallback(callback_2)
|
||||
|
||||
print 'Adding third callback.'
|
||||
d.addCallback(callback_3)
|
||||
|
||||
print"""
|
||||
Because the deferred was already fired, it
|
||||
invoked each callback as soon as it was added.
|
||||
|
||||
Now we create a deferred and fire it, but
|
||||
pause it first with the pause() method.
|
||||
"""
|
||||
|
||||
# We do the same thing, but pause the deferred:
|
||||
|
||||
d = Deferred()
|
||||
print 'Pausing, then firing deferred.'
|
||||
d.pause()
|
||||
d.callback(0)
|
||||
|
||||
print 'Adding callbacks.'
|
||||
d.addCallback(callback_1)
|
||||
d.addCallback(callback_2)
|
||||
d.addCallback(callback_3)
|
||||
|
||||
print 'Unpausing the deferred.'
|
||||
d.unpause()
|
@ -0,0 +1,19 @@
|
||||
from twisted.internet.defer import Deferred
|
||||
from twisted.python.failure import Failure
|
||||
|
||||
def got_poem(res):
|
||||
print 'Your poem is served:'
|
||||
print res
|
||||
|
||||
def poem_failed(err):
|
||||
print 'No poetry for you.'
|
||||
|
||||
d = Deferred()
|
||||
|
||||
# add a callback/errback pair to the chain
|
||||
d.addCallbacks(got_poem, poem_failed)
|
||||
|
||||
# fire the chain with an error result
|
||||
d.errback(Failure(Exception('I have failed.')))
|
||||
|
||||
print "Finished"
|
@ -0,0 +1,18 @@
|
||||
from twisted.internet.defer import Deferred
|
||||
|
||||
def got_poem(res):
|
||||
print 'Your poem is served:'
|
||||
print res
|
||||
|
||||
def poem_failed(err):
|
||||
print err.__class__
|
||||
print err
|
||||
print 'No poetry for you.'
|
||||
|
||||
d = Deferred()
|
||||
|
||||
# add a callback/errback pair to the chain
|
||||
d.addCallbacks(got_poem, poem_failed)
|
||||
|
||||
# fire the chain with an error result
|
||||
d.errback(Exception('I have failed.'))
|
@ -0,0 +1,7 @@
|
||||
from twisted.internet.defer import Deferred
|
||||
def out(s): print s
|
||||
d = Deferred()
|
||||
d.addCallbacks(out, out)
|
||||
d.callback('First result')
|
||||
d.callback('Second result')
|
||||
print 'Finished'
|
@ -0,0 +1,7 @@
|
||||
from twisted.internet.defer import Deferred
|
||||
def out(s): print s
|
||||
d = Deferred()
|
||||
d.addCallbacks(out, out)
|
||||
d.callback('First result')
|
||||
d.errback(Exception('First error'))
|
||||
print 'Finished'
|
@ -0,0 +1,7 @@
|
||||
from twisted.internet.defer import Deferred
|
||||
def out(s): print s
|
||||
d = Deferred()
|
||||
d.addCallbacks(out, out)
|
||||
d.errback(Exception('First error'))
|
||||
d.errback(Exception('Second error'))
|
||||
print 'Finished'
|
@ -0,0 +1,7 @@
|
||||
from twisted.internet.defer import Deferred
|
||||
def out(s): print s
|
||||
d = Deferred()
|
||||
d.addCallbacks(out, out)
|
||||
d.errback(Exception('First error'))
|
||||
d.callback('First result')
|
||||
print 'Finished'
|
@ -0,0 +1,25 @@
|
||||
import sys
|
||||
|
||||
from twisted.internet.defer import Deferred
|
||||
|
||||
def got_poem(poem):
|
||||
print poem
|
||||
from twisted.internet import reactor
|
||||
reactor.stop()
|
||||
|
||||
def poem_failed(err):
|
||||
print >>sys.stderr, 'poem download failed'
|
||||
print >>sys.stderr, 'I am terribly sorry'
|
||||
print >>sys.stderr, 'try again later?'
|
||||
from twisted.internet import reactor
|
||||
reactor.stop()
|
||||
|
||||
d = Deferred()
|
||||
|
||||
d.addCallbacks(got_poem, poem_failed)
|
||||
|
||||
from twisted.internet import reactor
|
||||
|
||||
reactor.callWhenRunning(d.callback, 'Another short poem.')
|
||||
|
||||
reactor.run()
|
@ -0,0 +1,26 @@
|
||||
import sys
|
||||
|
||||
from twisted.internet.defer import Deferred
|
||||
|
||||
def got_poem(poem):
|
||||
print poem
|
||||
|
||||
def poem_failed(err):
|
||||
print >>sys.stderr, 'poem download failed'
|
||||
print >>sys.stderr, 'I am terribly sorry'
|
||||
print >>sys.stderr, 'try again later?'
|
||||
|
||||
def poem_done(_):
|
||||
from twisted.internet import reactor
|
||||
reactor.stop()
|
||||
|
||||
d = Deferred()
|
||||
|
||||
d.addCallbacks(got_poem, poem_failed)
|
||||
d.addBoth(poem_done)
|
||||
|
||||
from twisted.internet import reactor
|
||||
|
||||
reactor.callWhenRunning(d.callback, 'Another short poem.')
|
||||
|
||||
reactor.run()
|
@ -0,0 +1,53 @@
|
||||
import sys, time
|
||||
|
||||
from twisted.internet.defer import Deferred
|
||||
|
||||
def start_chain(_):
|
||||
print "The start of the callback chain."
|
||||
|
||||
def blocking_poem(_):
|
||||
def delayed_write(s, delay):
|
||||
time.sleep(delay)
|
||||
sys.stdout.write(s)
|
||||
sys.stdout.flush()
|
||||
|
||||
delayed_write('\n', 0)
|
||||
delayed_write('I', .6)
|
||||
delayed_write(' block', .4)
|
||||
delayed_write('\n and', 1)
|
||||
delayed_write(' the', .4)
|
||||
delayed_write(' deferred', .6)
|
||||
delayed_write('\n blocks', 1.5)
|
||||
delayed_write(' with', .2)
|
||||
delayed_write(' me', .2)
|
||||
delayed_write('\nas does', 1)
|
||||
delayed_write('\n the reactor', .6)
|
||||
delayed_write('\nkeep that', 1)
|
||||
delayed_write('\n factor', .6)
|
||||
delayed_write('\nin', 1)
|
||||
delayed_write(' mind', .4)
|
||||
delayed_write('\n\n', 2)
|
||||
|
||||
def end_chain(_):
|
||||
print "The end of the callback chain."
|
||||
from twisted.internet import reactor
|
||||
reactor.stop()
|
||||
|
||||
d = Deferred()
|
||||
|
||||
d.addCallback(start_chain)
|
||||
d.addCallback(blocking_poem)
|
||||
d.addCallback(end_chain)
|
||||
|
||||
def fire():
|
||||
print 'Firing deferred.'
|
||||
d.callback(True)
|
||||
print 'Firing finished.'
|
||||
|
||||
from twisted.internet import reactor
|
||||
|
||||
reactor.callWhenRunning(fire)
|
||||
|
||||
print 'Starting reactor.'
|
||||
reactor.run()
|
||||
print 'Done.'
|
@ -0,0 +1,12 @@
|
||||
from twisted.internet.defer import Deferred
|
||||
|
||||
def callback(res):
|
||||
raise Exception('oops')
|
||||
|
||||
d = Deferred()
|
||||
|
||||
d.addCallback(callback)
|
||||
|
||||
d.callback('Here is your result.')
|
||||
|
||||
print "Finished"
|
@ -0,0 +1,444 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import optparse, sys
|
||||
|
||||
from twisted.internet import defer
|
||||
from twisted.python.failure import Failure
|
||||
|
||||
__doc__ = """\
|
||||
usage: %prog
|
||||
A Deferred simulator. Use this to see how a particular
|
||||
set of callbacks and errbacks will fire in a deferred.\
|
||||
"""
|
||||
|
||||
class BadInput(Exception): pass
|
||||
|
||||
|
||||
def parse_args():
|
||||
parser = optparse.OptionParser(usage=__doc__)
|
||||
|
||||
help = "draw all three chains in one column"
|
||||
parser.add_option('--narrow', action='store_true', help=help)
|
||||
|
||||
options, args = parser.parse_args()
|
||||
|
||||
if args:
|
||||
parser.error('No arguments supported.')
|
||||
|
||||
return options
|
||||
|
||||
|
||||
class Screen(object):
|
||||
"""An ascii screen."""
|
||||
|
||||
def __init__(self):
|
||||
self.pixels = {} # (x, y) -> char
|
||||
|
||||
def draw_char(self, x, y, char):
|
||||
self.pixels[x,y] = char
|
||||
|
||||
def draw_horiz_line(self, x, y, width):
|
||||
for i in range(width):
|
||||
self.draw_char(x + i, y, '-')
|
||||
|
||||
def draw_vert_line(self, x, y, height, end_arrow=False):
|
||||
for i in range(height):
|
||||
self.draw_char(x, y + i, '|')
|
||||
if end_arrow:
|
||||
self.draw_char(x - 1, y + height - 1, '\\')
|
||||
self.draw_char(x + 1, y + height - 1, '/')
|
||||
|
||||
def draw_text(self, x, y, text):
|
||||
for i, char in enumerate(text):
|
||||
self.draw_char(x + i, y, char)
|
||||
|
||||
def clear(self):
|
||||
self.pixels.clear()
|
||||
|
||||
def __str__(self):
|
||||
width = max([p[0] + 1 for p in self.pixels] + [0])
|
||||
height = max([p[1] + 1 for p in self.pixels] + [0])
|
||||
|
||||
s = ''
|
||||
|
||||
for y in range(height):
|
||||
for x in range(width):
|
||||
s += self.pixels.get((x,y), ' ')
|
||||
s += '\n'
|
||||
|
||||
return s
|
||||
|
||||
|
||||
class Callback(object):
|
||||
"""
|
||||
A widget representing a single callback or errback.
|
||||
|
||||
Each callback widget has one of three styles:
|
||||
|
||||
return - a callback that returns a given value
|
||||
fail - a callback that raises an Exception(value)
|
||||
passthru - a callback that returns its argument unchanged
|
||||
|
||||
The widget is also a callable that behaves according
|
||||
to the widget's style.
|
||||
"""
|
||||
|
||||
height = 5
|
||||
|
||||
def __init__(self, style, value=None):
|
||||
self.style = style
|
||||
self.value = value
|
||||
self.min_width = len('0123456*') + len('return ') + 3
|
||||
|
||||
def __call__(self, res):
|
||||
if self.style == 'return':
|
||||
return self.value
|
||||
if self.style == 'fail':
|
||||
return Failure(Exception(self.value))
|
||||
return res
|
||||
|
||||
@property
|
||||
def caption(self):
|
||||
if self.style == 'passthru':
|
||||
return 'passthru'
|
||||
return self.style + ' ' + self.value
|
||||
|
||||
def format_value(self, res):
|
||||
if isinstance(res, Failure):
|
||||
return res.value.args[0] + '*'
|
||||
return res
|
||||
|
||||
def draw_passive(self, screen, x, y, width):
|
||||
self.draw_box(screen, x, y, width)
|
||||
self.draw_text(screen, x, y + 2, width, self.caption)
|
||||
|
||||
def draw_active(self, screen, x, y, width, res):
|
||||
self.draw_box(screen, x, y, width)
|
||||
self.draw_text(screen, x, y + 1, width, self.format_value(res))
|
||||
self.draw_text(screen, x, y + 3, width, self.format_value(self(res)))
|
||||
|
||||
def draw_box(self, screen, x, y, width):
|
||||
screen.draw_horiz_line(x, y, width)
|
||||
screen.draw_horiz_line(x, y + 4, width)
|
||||
screen.draw_vert_line(x, y + 1, 3)
|
||||
screen.draw_vert_line(x + width - 1, y + 1, 3)
|
||||
|
||||
def draw_text(self, screen, x, y, width, text):
|
||||
screen.draw_text(x + 1, y, text.center(width - 2))
|
||||
|
||||
|
||||
class Deferred(object):
|
||||
"""
|
||||
An widget for a deferred.
|
||||
|
||||
It is initialize with a non-empty list of Callback pairs,
|
||||
representing a callback chain in a Twisted Deferred.
|
||||
"""
|
||||
|
||||
def __init__(self, pairs):
|
||||
assert pairs
|
||||
self.pairs = pairs
|
||||
self.callback_width = max([p[0].min_width for p in self.pairs] + [0])
|
||||
self.callback_width = max([p[1].min_width for p in self.pairs]
|
||||
+ [self.callback_width])
|
||||
self.width = self.callback_width * 2 + 2
|
||||
self.height = Callback.height * len(self.pairs)
|
||||
self.height += 3 * len(self.pairs[1:])
|
||||
|
||||
def draw(self, screen, x, y):
|
||||
"""
|
||||
Draw a representation of the callback/errback chain
|
||||
on the given screen at the given coordinates.
|
||||
"""
|
||||
for callback, errback in self.pairs:
|
||||
callback.draw_passive(screen, x, y, self.callback_width)
|
||||
errback.draw_passive(screen, x + self.callback_width + 2,
|
||||
y, self.callback_width)
|
||||
y += Callback.height + 3
|
||||
|
||||
|
||||
class FiredDeferred(object):
|
||||
"""
|
||||
A widget for a fired deferred.
|
||||
|
||||
It is initialized with a Deferred widget (not a real deferred)
|
||||
and the method name ('callback' or 'errback') to draw the firing
|
||||
sequence for.
|
||||
"""
|
||||
|
||||
callback_y_offset = 4
|
||||
|
||||
def __init__(self, deferred, method):
|
||||
self.deferred = deferred
|
||||
self.method = method
|
||||
self.height = deferred.height + 8
|
||||
self.width = deferred.width
|
||||
|
||||
def draw(self, screen, x, y, result='initial'):
|
||||
d = self.make_drawing_deferred(screen, x, y)
|
||||
|
||||
if self.method == 'callback':
|
||||
d.callback(result)
|
||||
else:
|
||||
d.errback(Exception(result))
|
||||
|
||||
def make_drawing_deferred(self, screen, x, y):
|
||||
"""
|
||||
Return a new deferred that, when fired, will draw its
|
||||
firing sequence onto the given screen at the given coordinates.
|
||||
"""
|
||||
|
||||
callback_width = self.deferred.callback_width
|
||||
|
||||
callback_mid_x = x - 1 + callback_width / 2
|
||||
|
||||
errback_left_x = x + callback_width + 2
|
||||
errback_mid_x = errback_left_x - 1 + callback_width / 2
|
||||
|
||||
class DrawState(object):
|
||||
last_x = None
|
||||
last_y = None
|
||||
|
||||
state = DrawState()
|
||||
|
||||
def draw_connection(x):
|
||||
if state.last_x == x:
|
||||
screen.draw_vert_line(x - 1 + callback_width / 2,
|
||||
state.last_y - 3, 3, True)
|
||||
return
|
||||
|
||||
if state.last_x < x:
|
||||
screen.draw_vert_line(callback_mid_x, state.last_y - 3, 2)
|
||||
screen.draw_vert_line(errback_mid_x,
|
||||
state.last_y - 2, 2, True)
|
||||
else:
|
||||
screen.draw_vert_line(errback_mid_x, state.last_y - 3, 2)
|
||||
screen.draw_vert_line(callback_mid_x,
|
||||
state.last_y - 2, 2, True)
|
||||
|
||||
screen.draw_horiz_line(callback_mid_x + 1,
|
||||
state.last_y - 2,
|
||||
errback_mid_x - callback_mid_x - 1)
|
||||
|
||||
def wrap_callback(cb, x):
|
||||
def callback(res):
|
||||
cb.draw_active(screen, x, state.last_y, callback_width, res)
|
||||
draw_connection(x)
|
||||
state.last_x = x
|
||||
state.last_y += cb.height + 3
|
||||
return cb(res)
|
||||
return callback
|
||||
|
||||
def draw_value(res, y):
|
||||
if isinstance(res, Failure):
|
||||
text = res.value.args[0] + '*'
|
||||
text = text.center(callback_width + 20)
|
||||
screen.draw_text(errback_left_x - 10, y, text)
|
||||
else:
|
||||
screen.draw_text(x, y, res.center(callback_width))
|
||||
|
||||
def draw_start(res):
|
||||
draw_value(res, y)
|
||||
if isinstance(res, Failure):
|
||||
state.last_x = errback_left_x
|
||||
else:
|
||||
state.last_x = x
|
||||
state.last_y = y + 4
|
||||
return res
|
||||
|
||||
def draw_end(res):
|
||||
draw_value(res, state.last_y)
|
||||
if isinstance(res, Failure):
|
||||
draw_connection(errback_left_x)
|
||||
else:
|
||||
draw_connection(x)
|
||||
|
||||
d = defer.Deferred()
|
||||
|
||||
d.addBoth(draw_start)
|
||||
|
||||
for pair in self.deferred.pairs:
|
||||
callback = wrap_callback(pair[0], x)
|
||||
errback = wrap_callback(pair[1], errback_left_x)
|
||||
d.addCallbacks(callback, errback)
|
||||
|
||||
d.addBoth(draw_end)
|
||||
|
||||
return d
|
||||
|
||||
|
||||
def get_next_pair():
|
||||
"""Get the next callback/errback pair from the user."""
|
||||
|
||||
def get_cb():
|
||||
if not parts:
|
||||
raise BadInput('missing command')
|
||||
|
||||
cmd = parts.pop(0).lower()
|
||||
|
||||
for command in ('return', 'fail', 'passthru'):
|
||||
if command.startswith(cmd):
|
||||
cmd = command
|
||||
break
|
||||
else:
|
||||
raise BadInput('bad command: %s' % cmd)
|
||||
|
||||
if cmd in ('return', 'fail'):
|
||||
if not parts:
|
||||
raise BadInput('missing argument')
|
||||
|
||||
result = parts.pop(0)
|
||||
|
||||
if len(result) > 6:
|
||||
raise BadInput('result more than 6 chars long', result)
|
||||
|
||||
return Callback(cmd, result)
|
||||
else:
|
||||
return Callback(cmd)
|
||||
|
||||
try:
|
||||
line = raw_input()
|
||||
except EOFError:
|
||||
sys.exit()
|
||||
|
||||
if not line:
|
||||
return None
|
||||
|
||||
parts = line.strip().split()
|
||||
|
||||
callback, errback = get_cb(), get_cb()
|
||||
|
||||
if parts:
|
||||
raise BadInput('extra arguments')
|
||||
|
||||
return callback, errback
|
||||
|
||||
|
||||
def get_pairs():
|
||||
"""
|
||||
Get the list of callback/errback pairs from the user.
|
||||
They are returned as Callback widgets.
|
||||
"""
|
||||
|
||||
print """\
|
||||
Enter a list of callback/errback pairs in the form:
|
||||
|
||||
CALLBACK ERRBACK
|
||||
|
||||
Where CALLBACK and ERRBACK are one of:
|
||||
|
||||
return VALUE
|
||||
fail VALUE
|
||||
passthru
|
||||
|
||||
And where VALUE is a string of only letters and numbers (no spaces),
|
||||
no more than 6 characters long.
|
||||
|
||||
Each pair should be on a single line and you can abbreviate
|
||||
return/fail/passthru as r/f/p.
|
||||
|
||||
Examples:
|
||||
|
||||
r good f bad # callback returns 'good'
|
||||
# and errback raises Exception('bad')
|
||||
|
||||
f googly p # callback raises Exception('googly')
|
||||
# and errback passes its failure along
|
||||
|
||||
Enter a blank line when you are done, and a diagram of the deferred
|
||||
will be printed next to the firing patterns for both the callback()
|
||||
and errback() methods. In the diagram, a value followed by '*' is
|
||||
really an Exception wrapped in a Failure, i.e:
|
||||
|
||||
value* == Failure(Exception(value))
|
||||
|
||||
You will want to make your terminal as wide as possible.
|
||||
"""
|
||||
|
||||
pairs = []
|
||||
|
||||
while True:
|
||||
try:
|
||||
pair = get_next_pair()
|
||||
except BadInput, e:
|
||||
print 'ERROR:', e
|
||||
continue
|
||||
|
||||
if pair is None:
|
||||
if not pairs:
|
||||
print 'You must enter at least one pair.'
|
||||
continue
|
||||
else:
|
||||
break
|
||||
|
||||
pairs.append(pair)
|
||||
|
||||
return pairs
|
||||
|
||||
|
||||
def draw_single_column(d, callback, errback):
|
||||
screen = Screen()
|
||||
|
||||
screen.draw_text(0, 1, 'Deferred'.center(d.width))
|
||||
screen.draw_text(0, 2, '--------'.center(d.width))
|
||||
|
||||
d.draw(screen, 0, 4)
|
||||
|
||||
print screen
|
||||
|
||||
screen.clear()
|
||||
|
||||
screen.draw_text(0, 2, 'd.callback(initial)'.center(d.width))
|
||||
screen.draw_text(0, 3, '-------------------'.center(d.width))
|
||||
|
||||
callback.draw(screen, 0, 5)
|
||||
|
||||
print screen
|
||||
|
||||
screen.clear()
|
||||
|
||||
screen.draw_text(0, 2, 'd.errback(initial*)'.center(d.width))
|
||||
screen.draw_text(0, 3, '-------------------'.center(d.width))
|
||||
|
||||
errback.draw(screen, 0, 5)
|
||||
|
||||
print screen
|
||||
|
||||
|
||||
def draw_multi_column(d, callback, errback):
|
||||
screen = Screen()
|
||||
|
||||
screen.draw_text(0, 0, 'Deferred'.center(d.width))
|
||||
screen.draw_text(0, 1, '--------'.center(d.width))
|
||||
|
||||
screen.draw_text(d.width + 6, 0, 'd.callback(initial)'.center(d.width))
|
||||
screen.draw_text(d.width + 6, 1, '-------------------'.center(d.width))
|
||||
|
||||
screen.draw_text(2 * (d.width + 6), 0, 'd.errback(initial*)'.center(d.width))
|
||||
screen.draw_text(2 * (d.width + 6), 1, '-------------------'.center(d.width))
|
||||
|
||||
d.draw(screen, 0, callback.callback_y_offset + 3)
|
||||
callback.draw(screen, d.width + 6, 3)
|
||||
errback.draw(screen, 2 * (d.width + 6), 3)
|
||||
|
||||
screen.draw_vert_line(d.width + 3, 3, callback.height)
|
||||
screen.draw_vert_line(d.width + 3 + d.width + 6, 3, callback.height)
|
||||
|
||||
print screen
|
||||
|
||||
|
||||
def main():
|
||||
options = parse_args()
|
||||
|
||||
d = Deferred(get_pairs())
|
||||
callback = FiredDeferred(d, 'callback')
|
||||
errback = FiredDeferred(d, 'errback')
|
||||
|
||||
if options.narrow:
|
||||
draw_single_column(d, callback, errback)
|
||||
else:
|
||||
draw_multi_column(d, callback, errback)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Reference in New Issue
Block a user