PyObject_TypeCheck requires argument to have ob_type

Create issue
Issue #2819 resolved
Hrvoje Nikšić created an issue

PyPy defines PyObject_TypeCheck as:

#define PyObject_TypeCheck(ob, tp) \
    ((ob)->ob_type == (tp) || PyType_IsSubtype((ob)->ob_type, (tp)))

whereas CPython defines it as:

#define PyObject_TypeCheck(ob, tp) \
    (Py_TYPE(ob) == (tp) || PyType_IsSubtype(Py_TYPE(ob), (tp)))

The difference is that Py_TYPE explicitly casts its argument to PyObject *. This means that CPython's PyObject_TypeCheck works for objects without an ob_type member. These can appear in two cases:

  • for types that embed an existing Python type so they can inherit from it, and can't use PyObject_HEAD because they inherit from something other than base object - for example, a type that inherits from list or dict must embed PyListObject or PyDictObject and will not have an obj_type.
  • for C++ wrappers for PyObject * that define a cast to PyObject *.

The issue can be worked around with an explicit cast to PyObject * before the call to PyObject_TypeCheck, but the fix in the PyPy header seems trivial. (Also, there is no reason not to use Py_TYPE instead of explicit ob_type dereference.)

Comments (2)

  1. Log in to comment