isgenerator(...) - anywhere to be found?

Stefan Rank list-ener at strank.info
Tue Jan 22 16:29:32 CET 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