on 22.01.2008 16:09 Paul McGuire said the following:
> On Jan 22, 7:46 am, Stefan Rank <[EMAIL PROTECTED]> 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

-- 
http://mail.python.org/mailman/listinfo/python-list

Reply via email to