Most reliable/pythonic way to tell if an instance comes from a class implemented in C/etc?

Carl Banks pavlovevidence at gmail.com
Mon May 24 18:30:37 EDT 2010


[Following up to Terry Reedy's post since I don't see the original]

On May 24, 11:30 am, Terry Reedy <tjre... at udel.edu> wrote:
> On 5/24/2010 12:56 PM, Nathan Rice wrote:
>
> > I'm trying to do some fairly deep introspection and instrumentation of
> > instances and classes at runtime, and in order for everything to be
> > properly behaved I need to have radically different behavior in the
> > event that the thing passed to me is a wrapped class/instance.  Is there
> > a really good way, given an instance of a class, to determine if it is
> > wrapped or native?  Currently I check to see if it has __slots__ then
> > try to setattr a dummy variable but I imagine there is probably a
> > cleaner way.


There is no foolproof way, but the simplest and most reliable way is
to check the __flags__ attribute to see if it's a heap type, which all
Python new-style classes are and almost all C-defined types aren't:

cls.__flags__ & 512     # Py_TPFLAGS_HEAPTYPE


However, in Python 2.x, old-style classes aren't types and so don't
have a __flags__ attribute, so to cover that case you should check if
it's a classobj.

isinstance(cls,types.ClassType)


So a complete function would look something like this:

def is_probably_python_class(cls):
    return isinstance(cls,types.ClassType) \
        or (isinstance(cls,type) and cls.__flags__ & 512)


It's not foolproof for a couple reasons: it's possible to define heap
types in C, and it's possible to define a metatype that does things
differently, but I would suppose these cases are rare.

Incidentally, depending on  your use case, you might find it helpful
also to know whether a type is a base type (meaning that it can be
subclassed).  You can check that with cls.__flags__ & 1024.  A
complete list of flags is in the include file object.h.  Note that, in
order to be subclassable, a type defined in C has to behave like a
Python class to a certain extent.  Thus you can assume a little bit
more about it.


Carl Banks



More information about the Python-list mailing list