Le mar. 23 juin 2020 à 15:56, Petr Viktorin <encu...@gmail.com> a écrit :
> > Adding or removing members of C structures is causing multiple backward
> > compatibility issues.
> >
> > Adding a new member breaks the stable ABI (PEP 384), especially for
> > types declared statically (e.g. ``static PyTypeObject MyType =
> > {...};``).
>
> PyTypeObject is explicitly not part of the stable ABI, see PEP 384:
> https://www.python.org/dev/peps/pep-0384/#structures
> I don't know why Py_TPFLAGS_HAVE_FINALIZE was added, but it wasn't for
> the PEP 384 stable ABI.

Maybe Antoine Pitrou knows the rationale why Py_TPFLAGS_HAVE_FINALIZE
flag was added. Removing the flag was discussed at:

* https://bugs.python.org/issue32388
* https://mail.python.org/pipermail/python-dev/2017-December/151328.html


> > Summary
> > -------
> >
> > * (**Completed**) Reorganize the C API header files: create
> > ``Include/cpython/`` and
> >    ``Include/internal/`` subdirectories.
> > * (**Completed**) Move private functions exposing implementation
> > details to the internal
> >    C API.
> > * (**Completed**) Convert macros to static inline functions.
> > * (**Completed**) Add new functions ``Py_SET_TYPE()``, ``Py_SET_REFCNT()`` 
> > and
> >    ``Py_SET_SIZE()``. The ``Py_TYPE()``, ``Py_REFCNT()`` and
> >    ``Py_SIZE()`` macros become functions which cannot be used as l-value.
> > * (**Completed**) New C API functions must not return borrowed
> >    references.
> > * (**In Progress**) Provide ``pythoncapi_compat.h`` header file.
> > * (**In Progress**) Make structures opaque, add getter and setter
> >    functions.
> > * (**Not Started**) Deprecate ``PySequence_Fast_ITEMS()``.
> > * (**Not Started**) Convert ``PyTuple_GET_ITEM()`` and
> >    ``PyList_GET_ITEM()`` macros to static inline functions.
>
> What does **Completed** mean? All work in that category is done, and any
> new changes in the category will require a new PEP (or a change to this
> PEP)?

The purpose of the PEP is to show an overview of the work already done
towards the same goal. Changes were scattered in multiple issues and
so I don't think that it was easy to follow it.

The PEP cannot be exhaustive, hiding implementation details is a
work-in-progress.

Usually, once a PEP is approved, it should not be modified.

I don't think that minor incompatible changes should require a new whole PEP.

The purpose of the PEP is to define an overall process for past and
future changes in this area, and also announces  our willingness for
this (hide implementation details).

If tomorrow, an incompatible C API change becomes very controversial,
maybe another PEP will be justified.

So far, incompatible C API changes were done with no PEP. I decided to
write a PEP for the Py_TYPE() change: disallow to use it as an
l-value, that's one of the "most" incompatible changes since I started
to work on this.


> It seems that this PEP is largely asking for forgiveness, so trying to
> find better ways to solve the problems would be a waste of time at this
> point.

Most completed changes were already discussed during physical
meetings, like Pycons and Core dev sprints. From what I recall,
everybody (involved in the discussion) agreed on the solution.

But there is always room for enhancements! The purpose of the PEP is
also to make the work already done more visible, so it's easier to
reason about the overall picture.

Feel free to propose your ideas, it's exactly the role of a discussion on a PEP!


> > Make structures opaque
> > ----------------------
> >
> > All structures of the C API should become opaque: C extensions must
> > use getter or setter functions to get or set structure members. For
> > example, ``tuple->ob_item[0]`` must be replaced with
> > ``PyTuple_GET_ITEM(tuple, 0)``.
>
> All structures?
> I don't think we can make PyModuleDef opaque, for example.
> PEP 384 lists more structures, some of which I don't think should be
> opaque: https://www.python.org/dev/peps/pep-0384/#structures

Oh, no, PyModuleDef is fine. I would like to make the following
structures opaque:

* PyInterpreterState
* PyThreadState
* PyGC_Head
* PyTypeObject
* PyObject and PyVarObject
* PyTypeObject
* All types which inherit from PyObject or PyVarObject

But I'm not sure about the exact list. Let's start with this list :-)


> > Process to reduce the number of broken C extensions
> > ===================================================
> >
> > Process to reduce the number of broken C extensions when introducing C
> > API incompatible changes listed in this PEP:
> >
> > * Estimate how many popular C extensions are affected by the
> >    incompatible change.
> > * Coordinate with maintainers of broken C extensions to prepare their
> >    code for the future incompatible change.
> > * Introduce the incompatible changes in Python. The documentation must
> >    explain how to port existing code. It is recommended to merge such
> >    changes at the beginning of a development cycle to have more time for
> >    tests.
> > * Changes which are the most likely to break a large number of C
> >    extensions should be announced on the capi-sig mailing list to notify
> >    C extensions maintainers to prepare their project for the next Python.
> > * If the change breaks too many projects, reverting the change should be
> >    discussed, taking in account the number of broken packages, their
> >    importance in the Python community, and the importance of the change.
>
> What is "popular"? What is "too many"? Who decides?

The process is underspecified on purpose. I don't know that it's
possible to define strict limits.

For me the important part is discussing incompatible changes and
trying to reach a consensus.


> > Future incompatible changes can be announced by deprecating a function
> > in the documentation and by annotating the function with
> > ``Py_DEPRECATED()``.
>
> How long should functions be deprecated before being removed?

In the whole PEP 620, there is a single function which is deprecated:
PySequence_Fast_ITEMS().

Note: It seems like Brett and Benjamin wants to require to have a
deprecation for 2 releases before being able to remove a function:
https://discuss.python.org/t/pep-387-backwards-compatibilty-policy/4421

The PEP doesn't plan PySequence_Fast_ITEMS() removal, but I guess that
it should follow PEP 387. If it's deprecated in 3.10, its removal will
happen in Python 3.12.


> > But making a structure opaque and preventing the
> > usage of a macro as l-value cannot be deprecated with
> > ``Py_DEPRECATED()``.
>
> So, how should things like this be deprecated? And for how long?

These changes don't go through any deprecation process. When you build
a C extension affected by these incompatible changes, you get a
compilation error.


> > The important part is coordination and finding a balance between CPython
> > evolutions and backward compatibility. For example, breaking a random,
> > old, obscure and unmaintained C extension on PyPI is less severe than
> > breaking numpy.
>
> How will this balance be found?

By discussing the change.


> > If a change is reverted, we move back to the coordination step to better
> > prepare the change. Once more C extensions are ready, the incompatible
> > change can be reconsidered.
>
> When in the process should it be reverted?

Whenever you want. If there are too many complaints about an
incompatible change during the beta phase and we decide to revert the
change, the important part is to revert before the 3.x.0 final
release.

If the complaints only come after the final release, it's usually too
late and it's better to learn how to live with this change.

Do you think that these aspects should be clearly specified in the PEP?

Victor
-- 
Night gathers, and now my watch begins. It shall not end until my death.
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/U2LZUCAHSEP6ZEQ6F72IGI64HOHK6VN2/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to