cpython icon indicating copy to clipboard operation
cpython copied to clipboard

gh-47146: Soft-deprecate structmember.h, expose its contents via Python.h

Open encukou opened this issue 3 years ago • 2 comments

The structmember.h header is deprecated, though it continues to be available and there are no plans to remove it. There are no deprecation warnings. Old code can stay unchanged (unless the extra include and non-namespaced macros bother you greatly). Specifically, no uses in CPython are updated -- that would just be unnecessary churn.

The header's contents are now available just by including Python.h, with a PY_ prefix added if it was missing:

  • PyMemberDef, PyMember_GetOne, PyMember_SetOne
  • Type macros like PY_T_INT, PY_T_DOUBLE, etc. (previously T_INT, T_DOUBLE, etc.)
  • The flags PY_READONLY (previously READONLY) and PY_AUDIT_READ (name unchanged)

Several items are not exposed from Python.h:

  • T_OBJECT (use PY_T_OBJECT_EX)
  • T_NONE (previously undocumented, and pretty quirky)
  • The macro WRITE_RESTRICTED which does nothing.
  • The macros RESTRICTED and READ_RESTRICTED, equivalents of PY_AUDIT_READ.
  • In some configurations, <stddef.h> is not included from Python.h. It should be included manually when using offsetof().

The PY_T_*, PY_READONLY and PY_AUDIT_READ macros are added to the stable API manifest. This is just a clerical change, really -- Stable ABI extensions in the wild use structmember.h, and PyMemberDef & Py_tp_members are already listed.

There is discussion on the issue to rename T_PYSSIZET to PY_T_SSIZE or similar. I chose not to do that -- users will probably copy/paste that with any spelling, and not renaming it makes migration docs simpler.

Co-Authored-By: Alexander Belopolsky [email protected] Co-Authored-By: Matthias Braun [email protected]

  • Issue: gh-47146

encukou avatar Nov 02 '22 16:11 encukou

Today I noticed the style guide says macros should have the Py_ prefix, not PY_. A minor point, but since this is renaming a bunch of macros, I'll switch to the preferred form.

encukou avatar Nov 07 '22 12:11 encukou

The PY_T_*, PY_READONLY and PY_AUDIT_READ macros are added to the stable API manifest. This is just a clerical change, really -- Stable ABI extensions in the wild use structmember.h, and PyMemberDef & Py_tp_members are already listed.

And by the same token, PyMember_GetOne and PyMember_SetOne should be added too.

encukou avatar Nov 08 '22 19:11 encukou

And here are tests. I'd appreciate a review, if anyone can spare the time.

encukou avatar Nov 16 '22 12:11 encukou

:robot: New build scheduled with the buildbot fleet by @encukou for commit e44b7cae62c4d7b28022b225160957c69181a458 :robot:

If you want to schedule another build, you need to add the ":hammer: test-with-buildbots" label again.

bedevere-bot avatar Nov 16 '22 12:11 bedevere-bot

Thank you! I did the changes, and will merge once everything is green.

encukou avatar Nov 21 '22 17:11 encukou

Nice work!

vstinner avatar Nov 22 '22 07:11 vstinner

Isn't it strange that the only public constant for object has an _EX suffix? Why not rename Py_T_OBJECT_EX to Py_T_OBJECT?

serhiy-storchaka avatar Jul 25 '23 13:07 serhiy-storchaka

I agree that _Py_T_OBJECT is surprising: returning None if an attribute doesn't exist, so it's not possible to know if the attribute value is None or if the attribute doesn't exist.

Py_T_OBJECT_EX behavior of raising an AttributeError if the attribute value is NULL doesn't better. I agree with @serhiy-storchaka, it should just be Py_T_OBJECT.

By the way, how was _Py_T_NONE used in the past? It's documented as:

Deprecated. Value is always None.

vstinner avatar Jul 25 '23 17:07 vstinner

Both _Py_T_OBJECT and Py_T_OBJECT_EX correspond to behavior of attributes of instances of Python classes. Just the latter is the default behavior, and the former is for the case when an instance attribute shadows the class attribute set to None. See an example in #107253.

T_NONE was introduced in 50e9fb9e2d6b4b12524116ab775ac6543e4a5332. I have not found a single case of its use.

serhiy-storchaka avatar Jul 25 '23 18:07 serhiy-storchaka

T_NONE was introduced in 50e9fb9. I have not found a single case of its use.

Maybe it's not worth it to add _Py_NONE in this case. I don't know.

vstinner avatar Jul 25 '23 18:07 vstinner

Isn't it strange that the only public constant for object has an _EX suffix? Why not rename Py_T_OBJECT_EX to Py_T_OBJECT?

T_OBJECT is still public API, it's just discouraged. (Probably not properly “soft-deprecated” in the new sense though?) Since all the others add Py_, I thought it would be confusing to also drop the suffix in this case.

encukou avatar Aug 02 '23 14:08 encukou