Lokasi ngalangkungan proxy:   [ UP ]  
[Ngawartoskeun bug]   [Panyetelan cookie]                
Skip to content

gh-146636: Add Free-threaded Stable ABI migration guide#148453

Open
clin1234 wants to merge 18 commits into
python:mainfrom
clin1234:patch-6
Open

gh-146636: Add Free-threaded Stable ABI migration guide#148453
clin1234 wants to merge 18 commits into
python:mainfrom
clin1234:patch-6

Conversation

@clin1234
Copy link
Copy Markdown
Contributor

@clin1234 clin1234 commented Apr 12, 2026

@bedevere-app bedevere-app Bot added awaiting review docs Documentation in the Doc dir skip news labels Apr 12, 2026
@github-project-automation github-project-automation Bot moved this to Todo in Docs PRs Apr 12, 2026
@bedevere-app bedevere-app Bot mentioned this pull request Apr 12, 2026
9 tasks
Copy link
Copy Markdown
Contributor

@da-woods da-woods left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a lot that isn't right here (or is mostly about freethreading generally rather than about the stable ABI).

Comment thread Doc/howto/freethreading-stable-abi.rst Outdated
Comment thread Doc/howto/freethreading-stable-abi.rst Outdated
Comment thread Doc/howto/freethreading-stable-abi.rst Outdated
Comment thread Doc/howto/freethreading-stable-abi.rst Outdated
Comment thread Doc/howto/freethreading-stable-abi.rst Outdated
Comment thread Doc/howto/freethreading-stable-abi.rst Outdated
Comment thread Doc/howto/freethreading-stable-abi.rst Outdated
Comment thread Doc/howto/freethreading-stable-abi.rst Outdated
Comment thread Doc/howto/freethreading-stable-abi.rst Outdated
:c:func:`PyDict_SetItem`, or explicitly using macros), it attempts to acquire
the underlying mutex.

Using Critical Sections
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The weakness right now is that I don't think they're part of the stable ABI (but hopefully will be)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you were referring to https://docs.python.org/3/c-api/dict.html#c.PyDict_SetItem, it's part of the Stable ABI: https://docs.python.org/3/c-api/dict.html#c.PyDict_SetItem

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No - I was referring to critical sections. Which I really hope are added before 3.15 comes out but I don't think currently are. Sorry if that was ambiguous.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now being proposed: #149225

Comment thread Doc/howto/freethreading-stable-abi.rst Outdated
@da-woods
Copy link
Copy Markdown
Contributor

I think the way most people will want to proceed is:

  1. Switch to PEP 793 module initialization (https://peps.python.org/pep-0793/). This will hopefully be a fairly trivial change for most people.
  2. Switch to using opaque objects and accessing all their type data through PyObject_GetTypeData. This will be a painful change for most people (and especially if they're starting from static types).
  3. Follow the general free-threading C API advice in https://docs.python.org/3/howto/free-threading-extensions.html#container-thread-safety (e.g. avoid borrowed reference, use critical sections once they become available). My personal opinion is that it isn't worth duplicating the advice.
  4. Decide if they want to mark their extension as thread-safe.

But steps 1 and 2 are the main ones and are almost not covered here.

Comment thread Doc/howto/freethreading-stable-abi.rst
@clin1234
Copy link
Copy Markdown
Contributor Author

clin1234 commented Apr 12, 2026

Based on WIP PR: #148013

@picnixz
Copy link
Copy Markdown
Member

picnixz commented Apr 12, 2026

I don't understand why we are having this PR when the reference documentation is not merged. Can we revisit this later? I would have expected the PEP's author to write this.

@picnixz picnixz marked this pull request as draft April 12, 2026 17:03
@clin1234 clin1234 marked this pull request as ready for review April 12, 2026 17:44
@picnixz
Copy link
Copy Markdown
Member

picnixz commented Apr 13, 2026

I left it as a draft because I do not think it is time for it to be reviewed. Please wait for the PEP author first.

@encukou
Copy link
Copy Markdown
Member

encukou commented Apr 13, 2026

Please don't repeat text from free-threading HOWTO. This document should be about migrating from that to the stable ABI; anything that's relevant to free-threading in general should be explained there (and possibly linked from the new document).

Also don't repeat information from the reference docs. A migration guide should link to the docs, and perhaps point out how/why the new thing is different.

And please see here on how-to guides in general: https://diataxis.fr/how-to-guides/

@read-the-docs-community
Copy link
Copy Markdown

read-the-docs-community Bot commented May 2, 2026

@clin1234 clin1234 requested a review from da-woods May 7, 2026 19:31
@clin1234 clin1234 marked this pull request as draft May 7, 2026 19:31
@clin1234 clin1234 marked this pull request as ready for review May 17, 2026 09:33
clin1234 added 5 commits May 17, 2026 05:33
This document provides detailed instructions on how to use the Free Threading Stable ABI in CPython, including guidelines for module initialization, API usage, and thread safety considerations.
Clarified access restrictions on PyObject members and recommended functions for type and reference count manipulation.
clin1234 and others added 9 commits May 17, 2026 05:33
Clarified that direct access to PyObject members is prohibited.
Co-authored-by: da-woods <dw-git@d-woods.co.uk>
Updated documentation to clarify the identification of free-threaded limited API builds in C, including changes to macros and initialization methods.
Updated the documentation to clarify the use of the stable ABI and GIL management in Python extensions, including changes to member access and initialization methods.
Removed sections on API guidelines, critical sections, and thread safety from the documentation.
Comment thread Doc/howto/freethreading-stable-abi.rst Outdated
Comment on lines +17 to +18
The CPython C API exposes the :c:macro:`!Py_LIMITED_API` macro: in the free-threaded stable ABI
build it's defined to ``1``, and in the regular build it's not defined.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't right.

Comment thread Doc/howto/freethreading-stable-abi.rst Outdated
Comment on lines +28 to +32
- define both :c:macro:`!Py_LIMITED_API` and :c:macro:`!Py_TARGET_ABI3T`, or
- define only :c:macro:`!Py_LIMITED_API` and:

- on Windows, define :c:macro:`!Py_GIL_DISABLED`;
- on other systems, use the headers of free-threaded build of Python.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the idiomatic way is probably just to define Py_TARGET_ABI3T with the version hex that you want to target.

The other ways (involving defining Py_LIMITED_API and maybe using the free-threading headers) are a bit opaque so it's probably better not to recommend them.

Comment thread Doc/howto/freethreading-stable-abi.rst Outdated
Comment on lines +37 to +38
Accessing any member of ``PyObject`` directly is now prohibited, like the non-GIL
stable ABI. For instance, prefer ``Py_TYPE()`` and ``Py_SET_TYPE()`` over ``ob_type``,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

like the non-GIL stable ABI

I think this is the wrong way around and it's "the GIL stable ABI".

I think also that accessing the members is recommended against in the GIL stable ABI and actually impossible in the freethreading stable ABI.

the GIL disabled; otherwise importing the extension will raise a warning and
enable the GIL at runtime.

Multi-phase and single-phase initialization is supported to indicate that an extension module
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think single-phase initialization is supported

PySlot_END
};

Furthermore, using ``PyABIInfo_VAR`` and ``Py_mod_abi`` is recommended so that an
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

required I think

Comment thread Doc/howto/freethreading-stable-abi.rst Outdated

.. _critical-sections:

Replacements:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At least in the C and C++ world the macros are available and encouraged. So I'm not sure "replacements" makes sense.

Comment on lines +119 to +124
|:c:macro:`Py_BEGIN_CRITICAL_SECTION_MUTEX` |``PyCriticalSection_BeginMutex`` |
|:c:macro:`Py_END_CRITICAL_SECTION` |``PyCriticalSection_End`` |
+-------------------------------------------+---------------------------------------+
|:c:macro:`Py_BEGIN_CRITICAL_SECTION2_MUTEX`|``PyCriticalSection2_BeginMutex`` |
|:c:macro:`Py_END_CRITICAL_SECTION2` |``PyCriticalSection2_End`` |
+-------------------------------------------+---------------------------------------+
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think the mutex versions are exposed at all

``Py_REFCNT``, ``Py_IncRef()`` and ``Py_DecRef()`` over ``ob_refcnt``, etc.

Similarly, members of ``PyVarObject`` are not visible. If you need any object of such type
to be passed as a ``PyObject`` parameter to any API function, cast it directly as ``PyObject``.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The big consequence here is not that you can't access the members. It's that you can't define structures like

struct S {
    PyObject_HEAD
    // your struct goes here
};

and thus have to omit the PyObject_HEAD and set the object size to -size to indicate opaqueness.

You also can't use PyVarObject at all easily right now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

4 participants