Skip to content

Commit 37c41f8

Browse files
Merge branch 'main' into interp-call-expansion
2 parents 2682157 + dafd141 commit 37c41f8

File tree

154 files changed

+4222
-1424
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

154 files changed

+4222
-1424
lines changed

.devcontainer/devcontainer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"image": "ghcr.io/python/devcontainer:2024.09.25.11038928730",
2+
"image": "ghcr.io/python/devcontainer:2025.05.25.15232270922",
33
"onCreateCommand": [
44
// Install common tooling.
55
"dnf",

Doc/c-api/init_config.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2111,7 +2111,7 @@ initialization::
21112111
21122112
/* Specify sys.path explicitly */
21132113
/* If you want to modify the default set of paths, finish
2114-
initialization first and then use PySys_GetObject("path") */
2114+
initialization first and then use PySys_GetAttrString("path") */
21152115
config.module_search_paths_set = 1;
21162116
status = PyWideStringList_Append(&config.module_search_paths,
21172117
L"/path/to/stdlib");

Doc/c-api/intro.rst

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -838,3 +838,41 @@ after every statement run by the interpreter.)
838838

839839
Please refer to :file:`Misc/SpecialBuilds.txt` in the Python source distribution
840840
for more detailed information.
841+
842+
843+
.. _c-api-tools:
844+
845+
Recommended third party tools
846+
=============================
847+
848+
The following third party tools offer both simpler and more sophisticated
849+
approaches to creating C, C++ and Rust extensions for Python:
850+
851+
* `Cython <https://cython.org/>`_
852+
* `cffi <https://cffi.readthedocs.io>`_
853+
* `HPy <https://hpyproject.org/>`_
854+
* `nanobind <https://github.com/wjakob/nanobind>`_ (C++)
855+
* `Numba <https://numba.pydata.org/>`_
856+
* `pybind11 <https://pybind11.readthedocs.io/>`_ (C++)
857+
* `PyO3 <https://pyo3.rs/>`_ (Rust)
858+
* `SWIG <https://www.swig.org>`_
859+
860+
Using tools such as these can help avoid writing code that is tightly bound to
861+
a particular version of CPython, avoid reference counting errors, and focus
862+
more on your own code than on using the CPython API. In general, new versions
863+
of Python can be supported by updating the tool, and your code will often use
864+
newer and more efficient APIs automatically. Some tools also support compiling
865+
for other implementations of Python from a single set of sources.
866+
867+
These projects are not supported by the same people who maintain Python, and
868+
issues need to be raised with the projects directly. Remember to check that the
869+
project is still maintained and supported, as the list above may become
870+
outdated.
871+
872+
.. seealso::
873+
874+
`Python Packaging User Guide: Binary Extensions <https://packaging.python.org/guides/packaging-binary-extensions/>`_
875+
The Python Packaging User Guide not only covers several available
876+
tools that simplify the creation of binary extensions, but also
877+
discusses the various reasons why creating an extension module may be
878+
desirable in the first place.

Doc/c-api/sys.rst

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,10 +258,57 @@ These are utility functions that make functionality from the :mod:`sys` module
258258
accessible to C code. They all work with the current interpreter thread's
259259
:mod:`sys` module's dict, which is contained in the internal thread state structure.
260260
261+
.. c:function:: PyObject *PySys_GetAttr(PyObject *name)
262+
263+
Get the attribute *name* of the :mod:`sys` module.
264+
Return a :term:`strong reference`.
265+
Raise :exc:`RuntimeError` and return ``NULL`` if it does not exist or
266+
if the :mod:`sys` module cannot be found.
267+
268+
If the non-existing object should not be treated as a failure, you can use
269+
:c:func:`PySys_GetOptionalAttr` instead.
270+
271+
.. versionadded:: next
272+
273+
.. c:function:: PyObject *PySys_GetAttrString(const char *name)
274+
275+
This is the same as :c:func:`PySys_GetAttr`, but *name* is
276+
specified as a :c:expr:`const char*` UTF-8 encoded bytes string,
277+
rather than a :c:expr:`PyObject*`.
278+
279+
If the non-existing object should not be treated as a failure, you can use
280+
:c:func:`PySys_GetOptionalAttrString` instead.
281+
282+
.. versionadded:: next
283+
284+
.. c:function:: int PySys_GetOptionalAttr(PyObject *name, PyObject **result)
285+
286+
Variant of :c:func:`PySys_GetAttr` which doesn't raise
287+
exception if the object does not exist.
288+
289+
* Set *\*result* to a new :term:`strong reference` to the object and
290+
return ``1`` if the object exists.
291+
* Set *\*result* to ``NULL`` and return ``0`` without setting an exception
292+
if the object does not exist.
293+
* Set an exception, set *\*result* to ``NULL``, and return ``-1``,
294+
if an error occurred.
295+
296+
.. versionadded:: next
297+
298+
.. c:function:: int PySys_GetOptionalAttrString(const char *name, PyObject **result)
299+
300+
This is the same as :c:func:`PySys_GetOptionalAttr`, but *name* is
301+
specified as a :c:expr:`const char*` UTF-8 encoded bytes string,
302+
rather than a :c:expr:`PyObject*`.
303+
304+
.. versionadded:: next
305+
261306
.. c:function:: PyObject *PySys_GetObject(const char *name)
262307
263-
Return the object *name* from the :mod:`sys` module or ``NULL`` if it does
264-
not exist, without setting an exception.
308+
Similar to :c:func:`PySys_GetAttrString`, but return a :term:`borrowed
309+
reference` and return ``NULL`` *without* setting exception on failure.
310+
311+
Preserves exception that was set before the call.
265312
266313
.. c:function:: int PySys_SetObject(const char *name, PyObject *v)
267314

Doc/c-api/unicode.rst

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1726,10 +1726,6 @@ They all return ``NULL`` or ``-1`` if an exception occurs.
17261726
from user input, prefer calling :c:func:`PyUnicode_FromString` and
17271727
:c:func:`PyUnicode_InternInPlace` directly.
17281728
1729-
.. impl-detail::
1730-
1731-
Strings interned this way are made :term:`immortal`.
1732-
17331729
17341730
.. c:function:: unsigned int PyUnicode_CHECK_INTERNED(PyObject *str)
17351731
@@ -1806,9 +1802,24 @@ object.
18061802
18071803
See also :c:func:`PyUnicodeWriter_DecodeUTF8Stateful`.
18081804
1805+
.. c:function:: int PyUnicodeWriter_WriteASCII(PyUnicodeWriter *writer, const char *str, Py_ssize_t size)
1806+
1807+
Write the ASCII string *str* into *writer*.
1808+
1809+
*size* is the string length in bytes. If *size* is equal to ``-1``, call
1810+
``strlen(str)`` to get the string length.
1811+
1812+
*str* must only contain ASCII characters. The behavior is undefined if
1813+
*str* contains non-ASCII characters.
1814+
1815+
On success, return ``0``.
1816+
On error, set an exception, leave the writer unchanged, and return ``-1``.
1817+
1818+
.. versionadded:: next
1819+
18091820
.. c:function:: int PyUnicodeWriter_WriteWideChar(PyUnicodeWriter *writer, const wchar_t *str, Py_ssize_t size)
18101821
1811-
Writer the wide string *str* into *writer*.
1822+
Write the wide string *str* into *writer*.
18121823
18131824
*size* is a number of wide characters. If *size* is equal to ``-1``, call
18141825
``wcslen(str)`` to get the string length.

Doc/data/stable_abi.dat

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Doc/extending/extending.rst

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -204,17 +204,32 @@ value must be in a particular range or must satisfy other conditions,
204204
:c:data:`PyExc_ValueError` is appropriate.
205205

206206
You can also define a new exception that is unique to your module.
207-
For this, you can declare a static global object variable at the beginning
208-
of the file::
207+
The simplest way to do this is to declare a static global object variable at
208+
the beginning of the file::
209209

210-
static PyObject *SpamError;
210+
static PyObject *SpamError = NULL;
211211

212-
and initialize it with an exception object in the module's
212+
and initialize it by calling :c:func:`PyErr_NewException` in the module's
213213
:c:data:`Py_mod_exec` function (:c:func:`!spam_module_exec`)::
214214

215+
SpamError = PyErr_NewException("spam.error", NULL, NULL);
216+
217+
Since :c:data:`!SpamError` is a global variable, it will be overwitten every time
218+
the module is reinitialized, when the :c:data:`Py_mod_exec` function is called.
219+
220+
For now, let's avoid the issue: we will block repeated initialization by raising an
221+
:py:exc:`ImportError`::
222+
223+
static PyObject *SpamError = NULL;
224+
215225
static int
216226
spam_module_exec(PyObject *m)
217227
{
228+
if (SpamError != NULL) {
229+
PyErr_SetString(PyExc_ImportError,
230+
"cannot initialize spam module more than once");
231+
return -1;
232+
}
218233
SpamError = PyErr_NewException("spam.error", NULL, NULL);
219234
if (PyModule_AddObjectRef(m, "SpamError", SpamError) < 0) {
220235
return -1;
@@ -253,6 +268,11 @@ needed to ensure that it will not be discarded, causing :c:data:`!SpamError` to
253268
become a dangling pointer. Should it become a dangling pointer, C code which
254269
raises the exception could cause a core dump or other unintended side effects.
255270

271+
For now, the :c:func:`Py_DECREF` call to remove this reference is missing.
272+
Even when the Python interpreter shuts down, the global :c:data:`!SpamError`
273+
variable will not be garbage-collected. It will "leak".
274+
We did, however, ensure that this will happen at most once per process.
275+
256276
We discuss the use of :c:macro:`PyMODINIT_FUNC` as a function return type later in this
257277
sample.
258278

Doc/extending/index.rst

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,19 +26,9 @@ Recommended third party tools
2626
=============================
2727

2828
This guide only covers the basic tools for creating extensions provided
29-
as part of this version of CPython. Third party tools like
30-
`Cython <https://cython.org/>`_, `cffi <https://cffi.readthedocs.io>`_,
31-
`SWIG <https://www.swig.org>`_ and `Numba <https://numba.pydata.org/>`_
32-
offer both simpler and more sophisticated approaches to creating C and C++
33-
extensions for Python.
34-
35-
.. seealso::
36-
37-
`Python Packaging User Guide: Binary Extensions <https://packaging.python.org/guides/packaging-binary-extensions/>`_
38-
The Python Packaging User Guide not only covers several available
39-
tools that simplify the creation of binary extensions, but also
40-
discusses the various reasons why creating an extension module may be
41-
desirable in the first place.
29+
as part of this version of CPython. Some :ref:`third party tools
30+
<c-api-tools>` offer both simpler and more sophisticated approaches to creating
31+
C and C++ extensions for Python.
4232

4333

4434
Creating extensions without third party tools

Doc/faq/extending.rst

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -37,24 +37,9 @@ Writing C is hard; are there any alternatives?
3737
----------------------------------------------
3838

3939
There are a number of alternatives to writing your own C extensions, depending
40-
on what you're trying to do.
41-
42-
.. XXX make sure these all work
43-
44-
`Cython <https://cython.org>`_ and its relative `Pyrex
45-
<https://www.csse.canterbury.ac.nz/greg.ewing/python/Pyrex/>`_ are compilers
46-
that accept a slightly modified form of Python and generate the corresponding
47-
C code. Cython and Pyrex make it possible to write an extension without having
48-
to learn Python's C API.
49-
50-
If you need to interface to some C or C++ library for which no Python extension
51-
currently exists, you can try wrapping the library's data types and functions
52-
with a tool such as `SWIG <https://www.swig.org>`_. `SIP
53-
<https://github.com/Python-SIP/sip>`__, `CXX
54-
<https://cxx.sourceforge.net/>`_ `Boost
55-
<https://www.boost.org/libs/python/doc/index.html>`_, or `Weave
56-
<https://github.com/scipy/weave>`_ are also
57-
alternatives for wrapping C++ libraries.
40+
on what you're trying to do. :ref:`Recommended third party tools <c-api-tools>`
41+
offer both simpler and more sophisticated approaches to creating C and C++
42+
extensions for Python.
5843

5944

6045
How can I execute arbitrary Python statements from C?

Doc/howto/cporting.rst

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,11 @@ We recommend the following resources for porting extension modules to Python 3:
1414
module.
1515
* The `Porting guide`_ from the *py3c* project provides opinionated
1616
suggestions with supporting code.
17-
* The `Cython`_ and `CFFI`_ libraries offer abstractions over
18-
Python's C API.
17+
* :ref:`Recommended third party tools <c-api-tools>` offer abstractions over
18+
the Python's C API.
1919
Extensions generally need to be re-written to use one of them,
2020
but the library then handles differences between various Python
2121
versions and implementations.
2222

2323
.. _Migrating C extensions: http://python3porting.com/cextensions.html
2424
.. _Porting guide: https://py3c.readthedocs.io/en/latest/guide.html
25-
.. _Cython: https://cython.org/
26-
.. _CFFI: https://cffi.readthedocs.io/en/latest/

0 commit comments

Comments
 (0)