Description
_Py_T_OBJECT
is considered legacy PyMemberDef type. The difference between _Py_T_OBJECT
and Py_T_OBJECT_EX
is that the former returns None
if read NULL
, while the latter raises AttrributeError. _Py_T_OBJECT
manifests itself in two effects:
- The default value of the attribute is
None
, even if it was not initialized in the constructor. It is a desirable behavior in some cases. - After deleting an attribute its value is still
None
. You cannot truly delete it.
A Py_T_OBJECT_EX
member behaves like a normal attribute in Python object, while a _Py_T_OBJECT
member behaves like in the case when the corresponding class attribute was set to None
:
class A:
attr = None
x = A()
assert x.attr is None
x.attr = 5
assert x.attr == 5
del x.attr
assert x.attr is None
What if replace _Py_T_OBJECT
with Py_T_OBJECT_EX
? It turns out that you can replace it in 105 sites but 31 sites should keep _Py_T_OBJECT
to make existing tests pass. This is not a very reliable result because the tests may not cover all cases. On the other hand, some tests are too picky and check the attributes of a newly created uninitialized object, even if they are normally initialized.
In any case, we can take these results and replace _Py_T_OBJECT
with Py_T_OBJECT_EX
on case by case basis.