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