[pypy-issue] Issue #2819: PyObject_TypeCheck requires argument to have ob_type (pypy/pypy)

Hrvoje Nikšić issues-reply at bitbucket.org
Thu May 3 11:08:22 EDT 2018

New issue 2819: PyObject_TypeCheck requires argument to have ob_type

Hrvoje Nikšić:

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

More information about the pypy-issue mailing list