isgenerator(...) - anywhere to be found?
Stefan Rank
list-ener at strank.info
Tue Jan 22 10:29:32 EST 2008
on 22.01.2008 16:09 Paul McGuire said the following:
> On Jan 22, 7:46 am, Stefan Rank <list-e... at strank.info> wrote:
>> I also need to test for generator functions from time to time for which
>> I use::
>>
>> def _isaGeneratorFunction(func):
>> '''Check the bitmask of `func` for the magic generator flag.'''
>> return bool(func.func_code.co_flags & CO_GENERATOR)
>>
>> cheers,
>> stefan
>
> Might want to catch AttributeError in this routine - not all func
> arguments will have a func_code attribute. See below:
>
> class Z(object):
> def __call__(*args):
> for i in range(3):
> yield 1
>
> for i in Z()():
> print i
> # prints 1 three times
>
> import types
> print type(Z()()) == types.GeneratorType
> # prints 'True'
>
> print Z()().func_code
> # raises AttributeError, doesn't have a func_code attribute
You are right about that for generator *objects*.
But _isaGeneratorFunction tests for generator *functions* (the ones you
call in order to get a generator object) and those must have a func_code.
So in your example::
>>> from compiler.consts import CO_GENERATOR
>>> Z().__call__.func_code.co_flags & CO_GENERATOR
32
>>> Z.__call__.func_code.co_flags & CO_GENERATOR
32
You have to use __call__ directly, you can't use the code-object-flag
test on the callable class instance Z(), but I think that's just as well
since this kind of test should not be necessary at all, except in rare
code parts (such as Diez' microthreading experiments).
cheers,
stefan
More information about the Python-list
mailing list