Mikhail
Mikhail

Reputation: 9007

How to check if a python function is a Tornado generator

Given a function foobar how can I check that it's a generator that is expected by Tornado?

In [1]: from tornado import gen

In [2]: @gen.coroutine
   ...: def foobar():
   ...:     print 'boom'
   ...:

I wasn't able to find any properties, that could indicate that it's correctly decorated by a gen.coroutine

Upvotes: 4

Views: 406

Answers (2)

Ben Darnell
Ben Darnell

Reputation: 22154

There is no good way to detect this, and even if @coroutine were modified to set some attribute, this would fail in cases when multiple decorators are used (e.g. handlers may be decorated with both @authenticated and @coroutine, and the @authenticated decorator's wrapper will hide whatever @coroutine added)

Furthermore, many functions (including core Tornado methods like AsyncHTTPClient.fetch or most methods of IOStream) are not technically coroutines but they can be called as if they were. In most cases the most important question is not "is this a coroutine" but "does this return a Future". There is no way to determine this in Python without calling the function.

Upvotes: 4

wim
wim

Reputation: 363294

I could not find a satisfactory way to introspect it from the already existing decorator gen.coroutine.

I'm not sure if this is helpful for you, but if you have control over the specific decorator itself then you may have the option of simply tacking on an attribute to the function itself.

>>> def my_gen_coroutine(f):
...     f = gen.coroutine(f)
...     f.is_a_tornado_generator = True
...     return f
... 
>>> @my_gen_coroutine
... def foobar():
...     print 'boom'
...     
>>> foobar.is_a_tornado_generator
True
>>> foobar()
boom
<tornado.concurrent.Future at 0x1397d50>

Of course, you would use getattr(some_function, 'is_a_tornado_generator', False) when you don't know if the attribute is there or not.

Upvotes: 2

Related Questions