AnkurVj
AnkurVj

Reputation: 8198

How to write a method decorated with @defer.inlineCallbacks that may or may not yield?

My method is of the following form:

@defer.inlineCallbacks
def myAsyncMethod():
    if someCondition:
        yield anotherAsyncMethod()

The problem is that if someCondition is not True then no yield happens and this essentially becomes a synchronous function. The decorator then causes this to be an error.

Right now, I am just doing yield 1 at the end of it. is that the right thing to do here? I could of course do:

d = Deferred()
d.callback(0)
yield d

But I don't see how that is any different

Edit: What I meant here is that if I try to do yield myAsyncMethod() then it would generate an exception. I dont want to have to handle the exception. One way to avoid it is to just yield something at the end of myAsyncMethod(), but is there another no-hacky way of doing this. What is the common practice here?

Upvotes: 2

Views: 971

Answers (1)

Jean-Paul Calderone
Jean-Paul Calderone

Reputation: 48335

The premise is incorrect. Consider:

>>> def foo():
...     if False:
...             yield
... 
>>> foo()
<generator object foo at 0x7f579cc4ccd0>
>>> 

Here, the yield statement is never evaluated. This doesn't stop foo from returning a generator, though.

This means that you can decorate such a function with inlineCallbacks without any problem.

>>> @inlineCallbacks
... def foo():
...     if False:
...             yield
... 
>>> foo()
<Deferred at 0x7f08328e3ef0  current result: None>
>>> 

Since the generator has no elements, what you get back is a Deferred that already has None as a result, as you can see here.

Further, this means you can call such a function and yield it from another inlineCallbacks-decorated function without problems:

>>> @inlineCallbacks
... def bar():
...     print "Foo result is:", (yield foo())
... 
>>> bar()
Foo result is: None
<Deferred at 0x7f08328e3ef0  current result: None>
>>> 

Here you see that bar executed, yielded the result of calling foo, printed out the result of that Deferred, and then completed with its own Deferred (which also already has a None result).

Upvotes: 2

Related Questions