[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.python

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

Diez B. Roggisch

1/22/2008 1:21:00 PM

For a simple greenlet/tasklet/microthreading experiment I found myself in
the need to ask the question

isgenerator(v)

but didn't find any implementation in the usual suspects - builtins or
inspect.

I was able to help myself out with a simple (out of my head, hope its

def isgenerator(v):
def _g(): yield
return type(v) == type(_g())

But I wonder why there is no such method already available?

Diez
6 Answers

Stefan Rank

1/22/2008 1:46:00 PM

0

on 22.01.2008 14:20 Diez B. Roggisch said the following:
>
> def isgenerator(v):
> def _g(): yield
> return type(v) == type(_g())
>
> But I wonder why there is no such method already available?


This tests for generator objects, and you could also use::

return type(v) is types.GeneratorType

I think that this is pretty direct already.

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

Diez B. Roggisch

1/22/2008 2:17:00 PM

0

Stefan Rank wrote:

> on 22.01.2008 14:20 Diez B. Roggisch said the following:
>>
>> def isgenerator(v):
>> def _g(): yield
>> return type(v) == type(_g())
>>
>> But I wonder why there is no such method already available?
>
>
> This tests for generator objects, and you could also use::
>
> return type(v) is types.GeneratorType
>
> I think that this is pretty direct already.

Not as nice as it could be, but certainly way less hackish than my approach.
Thanks!

> 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)

Not sure if that's not a bit too much on the dark magic side.. but good to
know that it exists.

Diez

Christian Heimes

1/22/2008 3:07:00 PM

0

Stefan Rank wrote:
> on 22.01.2008 14:20 Diez B. Roggisch said the following:
>> def isgenerator(v):
>> def _g(): yield
>> return type(v) == type(_g())
>>
>> But I wonder why there is no such method already available?
>
>
> This tests for generator objects, and you could also use::
>
> return type(v) is types.GeneratorType
>
> I think that this is pretty direct already.
>
> 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)

Can you please write a function for the inspect module + docs + a small
unit tests and submit a patch? The inspect module is missing the
isgenerator function.

Christian

Paul McGuire

1/22/2008 3:09:00 PM

0

On Jan 22, 7:46 am, Stefan Rank <list-e...@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

-- Paul

Stefan Rank

1/22/2008 3:30:00 PM

0

on 22.01.2008 16:09 Paul McGuire said the following:
> On Jan 22, 7:46 am, Stefan Rank <list-e...@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

james.pye

1/22/2008 4:14:00 PM

0

On Jan 22, 6:20 am, "Diez B. Roggisch" <de...@nospam.web.de> wrote:
> For a simple greenlet/tasklet/microthreading experiment I found myself in
> the need to ask the question
>
> isgenerator(v)
>
> but didn't find any implementation in the usual suspects - builtins or
> inspect.

types.GeneratorType exists in newer Pythons, but I'd suggest just
checking for a send method. ;)
That way, you can use something that emulates the interface without
being forced to use a generator.

hasattr(ob, 'send')..