pythonpython-3.xpython-c-api

How to check if an object in Python is a PyCapsule?


I have a C Extension that receives and accepts PyCapsule objects.

In my python wrapper, how can I check if a python object is of the PyCapsule type object?

>>> # My C extension
>>> foo = Foo()
>>> capsule = foo.to_capsule()  # returns a PyCapsule object from the C extension
>>> capsule
<capsule object "foo" at 0xf707df08>
>>> type(capsule)
<class 'PyCapsule'>
isinstance(capsule, PyCapsule)
NameError: name 'PyCapsule' is not defined

What I'm trying to do is write a function like:

def push_capsule(capsule):
    # check that the `capsule` is of type PyCapsule
    # c_extension.push_capsule(capsule)

Solution

  • It's a bit of a mess but you can get it from ctypes:

    def get_capsule_type():
        class PyTypeObject(ctypes.Structure):
            pass  # don't need to define the full structure
        capsuletype = PyTypeObject.in_dll(ctypes.pythonapi, "PyCapsule_Type")
        capsuletypepointer = ctypes.pointer(capsuletype)
        return ctypes.py_object.from_address(ctypes.addressof(capsuletypepointer)).value
    

    Creating a py_object from an address looks to require an address which contains a PyObject*, rather than the PyObject* itself, hence the extra layer of indirection.