Skip to content

Commit 6ac23fd

Browse files
authored
Merge branch 'main' into dis_labels
2 parents c363ee8 + 7680da4 commit 6ac23fd

Some content is hidden

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

54 files changed

+812
-557
lines changed

.github/workflows/build.yml

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,9 @@ jobs:
120120

121121
check_generated_files:
122122
name: 'Check if generated files are up to date'
123-
runs-on: ubuntu-latest
123+
# Don't use ubuntu-latest but a specific version to make the job
124+
# reproducible: to get the same tools versions (autoconf, aclocal, ...)
125+
runs-on: ubuntu-22.04
124126
timeout-minutes: 60
125127
needs: check_source
126128
if: needs.check_source.outputs.run_tests == 'true'
@@ -143,15 +145,16 @@ jobs:
143145
- name: Check Autoconf and aclocal versions
144146
run: |
145147
grep "Generated by GNU Autoconf 2.71" configure
146-
grep "aclocal 1.16.4" aclocal.m4
148+
grep "aclocal 1.16.5" aclocal.m4
147149
grep -q "runstatedir" configure
148150
grep -q "PKG_PROG_PKG_CONFIG" aclocal.m4
149151
- name: Configure CPython
150152
run: |
151153
# Build Python with the libpython dynamic library
152154
./configure --config-cache --with-pydebug --enable-shared
153-
- name: Regenerate autoconf files with container image
154-
run: make regen-configure
155+
- name: Regenerate autoconf files
156+
# Same command used by Tools/build/regen-configure.sh ($AUTORECONF)
157+
run: autoreconf -ivf -Werror
155158
- name: Build CPython
156159
run: |
157160
make -j4 regen-all

.github/workflows/posix-deps-apt.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
#!/bin/sh
22
apt-get update
33

4+
# autoconf-archive is needed by autoreconf (check_generated_files job)
45
apt-get -yq install \
56
build-essential \
67
pkg-config \
8+
autoconf-archive \
79
ccache \
810
gdb \
911
lcov \

Doc/howto/isolating-extensions.rst

Lines changed: 97 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -339,12 +339,44 @@ That is, heap types should:
339339
- Define a traverse function using ``Py_tp_traverse``, which
340340
visits the type (e.g. using :c:expr:`Py_VISIT(Py_TYPE(self))`).
341341

342-
Please refer to the :ref:`the documentation <type-structs>` of
342+
Please refer to the the documentation of
343343
:c:macro:`Py_TPFLAGS_HAVE_GC` and :c:member:`~PyTypeObject.tp_traverse`
344344
for additional considerations.
345345

346-
If your traverse function delegates to the ``tp_traverse`` of its base class
347-
(or another type), ensure that ``Py_TYPE(self)`` is visited only once.
346+
The API for defining heap types grew organically, leaving it
347+
somewhat awkward to use in its current state.
348+
The following sections will guide you through common issues.
349+
350+
351+
``tp_traverse`` in Python 3.8 and lower
352+
.......................................
353+
354+
The requirement to visit the type from ``tp_traverse`` was added in Python 3.9.
355+
If you support Python 3.8 and lower, the traverse function must *not*
356+
visit the type, so it must be more complicated::
357+
358+
static int my_traverse(PyObject *self, visitproc visit, void *arg)
359+
{
360+
if (Py_Version >= 0x03090000) {
361+
Py_VISIT(Py_TYPE(self));
362+
}
363+
return 0;
364+
}
365+
366+
Unfortunately, :c:data:`Py_Version` was only added in Python 3.11.
367+
As a replacement, use:
368+
369+
* :c:macro:`PY_VERSION_HEX`, if not using the stable ABI, or
370+
* :py:data:`sys.version_info` (via :c:func:`PySys_GetObject` and
371+
:c:func:`PyArg_ParseTuple`).
372+
373+
374+
Delegating ``tp_traverse``
375+
..........................
376+
377+
If your traverse function delegates to the :c:member:`~PyTypeObject.tp_traverse`
378+
of its base class (or another type), ensure that ``Py_TYPE(self)`` is visited
379+
only once.
348380
Note that only heap type are expected to visit the type in ``tp_traverse``.
349381

350382
For example, if your traverse function includes::
@@ -356,11 +388,70 @@ For example, if your traverse function includes::
356388
if (base->tp_flags & Py_TPFLAGS_HEAPTYPE) {
357389
// a heap type's tp_traverse already visited Py_TYPE(self)
358390
} else {
359-
Py_VISIT(Py_TYPE(self));
391+
if (Py_Version >= 0x03090000) {
392+
Py_VISIT(Py_TYPE(self));
393+
}
360394
}
361395

362-
It is not necessary to handle the type's reference count in ``tp_new``
363-
and ``tp_clear``.
396+
It is not necessary to handle the type's reference count in
397+
:c:member:`~PyTypeObject.tp_new` and :c:member:`~PyTypeObject.tp_clear`.
398+
399+
400+
Defining ``tp_dealloc``
401+
.......................
402+
403+
If your type has a custom :c:member:`~PyTypeObject.tp_dealloc` function,
404+
it needs to:
405+
406+
- call :c:func:`PyObject_GC_UnTrack` before any fields are invalidated, and
407+
- decrement the reference count of the type.
408+
409+
To keep the type valid while ``tp_free`` is called, the type's refcount needs
410+
to be decremented *after* the instance is deallocated. For example::
411+
412+
static void my_dealloc(PyObject *self)
413+
{
414+
PyObject_GC_UnTrack(self);
415+
...
416+
PyTypeObject *type = Py_TYPE(self);
417+
type->tp_free(self);
418+
Py_DECREF(type);
419+
}
420+
421+
The default ``tp_dealloc`` function does this, so
422+
if your type does *not* override
423+
``tp_dealloc`` you don't need to add it.
424+
425+
426+
Not overriding ``tp_free``
427+
..........................
428+
429+
The :c:member:`~PyTypeObject.tp_free` slot of a heap type must be set to
430+
:c:func:`PyObject_GC_Del`.
431+
This is the default; do not override it.
432+
433+
434+
Avoiding ``PyObject_New``
435+
.........................
436+
437+
GC-tracked objects need to be allocated using GC-aware functions.
438+
439+
If you use use :c:func:`PyObject_New` or :c:func:`PyObject_NewVar`:
440+
441+
- Get and call type's :c:member:`~PyTypeObject.tp_alloc` slot, if possible.
442+
That is, replace ``TYPE *o = PyObject_New(TYPE, typeobj)`` with::
443+
444+
TYPE *o = typeobj->tp_alloc(typeobj, 0);
445+
446+
Replace ``o = PyObject_NewVar(TYPE, typeobj, size)`` with the same,
447+
but use size instead of the 0.
448+
449+
- If the above is not possible (e.g. inside a custom ``tp_alloc``),
450+
call :c:func:`PyObject_GC_New` or :c:func:`PyObject_GC_NewVar`::
451+
452+
TYPE *o = PyObject_GC_New(TYPE, typeobj);
453+
454+
TYPE *o = PyObject_GC_NewVar(TYPE, typeobj, size);
364455

365456

366457
Module State Access from Classes

Doc/library/subprocess.rst

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -791,9 +791,10 @@ Instances of the :class:`Popen` class have the following methods:
791791

792792
.. note::
793793

794-
The function is implemented using a busy loop (non-blocking call and
795-
short sleeps). Use the :mod:`asyncio` module for an asynchronous wait:
796-
see :class:`asyncio.create_subprocess_exec`.
794+
When the ``timeout`` parameter is not ``None``, then (on POSIX) the
795+
function is implemented using a busy loop (non-blocking call and short
796+
sleeps). Use the :mod:`asyncio` module for an asynchronous wait: see
797+
:class:`asyncio.create_subprocess_exec`.
797798

798799
.. versionchanged:: 3.3
799800
*timeout* was added.

Doc/using/configure.rst

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,21 @@ files. Commands to regenerate all generated files::
7474
The ``Makefile.pre.in`` file documents generated files, their inputs, and tools used
7575
to regenerate them. Search for ``regen-*`` make targets.
7676

77-
The ``make regen-configure`` command runs `tiran/cpython_autoconf
78-
<https://github.com/tiran/cpython_autoconf>`_ container for reproducible build;
79-
see container ``entry.sh`` script. The container is optional, the following
80-
command can be run locally, the generated files depend on autoconf and aclocal
81-
versions::
77+
configure script
78+
----------------
79+
80+
The ``make regen-configure`` command regenerates the ``aclocal.m4`` file and
81+
the ``configure`` script using the ``Tools/build/regen-configure.sh`` shell
82+
script which uses an Ubuntu container to get the same tools versions and have a
83+
reproducible output.
84+
85+
The container is optional, the following command can be run locally::
8286

8387
autoreconf -ivf -Werror
8488

89+
The generated files can change depending on the exact ``autoconf-archive``,
90+
``aclocal`` and ``pkg-config`` versions.
91+
8592

8693
.. _configure-options:
8794

Include/cpython/abstract.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,28 @@
22
# error "this header file must not be included directly"
33
#endif
44

5+
/* === Object Protocol ================================================== */
6+
7+
/* Like PyObject_CallMethod(), but expect a _Py_Identifier*
8+
as the method name. */
9+
PyAPI_FUNC(PyObject*) _PyObject_CallMethodId(
10+
PyObject *obj,
11+
_Py_Identifier *name,
12+
const char *format, ...);
13+
14+
/* Convert keyword arguments from the FASTCALL (stack: C array, kwnames: tuple)
15+
format to a Python dictionary ("kwargs" dict).
16+
17+
The type of kwnames keys is not checked. The final function getting
18+
arguments is responsible to check if all keys are strings, for example using
19+
PyArg_ParseTupleAndKeywords() or PyArg_ValidateKeywordArguments().
20+
21+
Duplicate keys are merged using the last value. If duplicate keys must raise
22+
an exception, the caller is responsible to implement an explicit keys on
23+
kwnames. */
24+
PyAPI_FUNC(PyObject*) _PyStack_AsDict(PyObject *const *values, PyObject *kwnames);
25+
26+
527
/* === Vectorcall protocol (PEP 590) ============================= */
628

729
// PyVectorcall_NARGS() is exported as a function for the stable ABI.
@@ -16,6 +38,16 @@ _PyVectorcall_NARGS(size_t n)
1638

1739
PyAPI_FUNC(vectorcallfunc) PyVectorcall_Function(PyObject *callable);
1840

41+
// Backwards compatibility aliases (PEP 590) for API that was provisional
42+
// in Python 3.8
43+
#define _PyObject_Vectorcall PyObject_Vectorcall
44+
#define _PyObject_VectorcallMethod PyObject_VectorcallMethod
45+
#define _PyObject_FastCallDict PyObject_VectorcallDict
46+
#define _PyVectorcall_Function PyVectorcall_Function
47+
#define _PyObject_CallOneArg PyObject_CallOneArg
48+
#define _PyObject_CallMethodNoArgs PyObject_CallMethodNoArgs
49+
#define _PyObject_CallMethodOneArg PyObject_CallMethodOneArg
50+
1951
/* Same as PyObject_Vectorcall except that keyword arguments are passed as
2052
dict, which may be NULL if there are no keyword arguments. */
2153
PyAPI_FUNC(PyObject *) PyObject_VectorcallDict(

Include/cpython/complexobject.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,16 @@ typedef struct {
77
double imag;
88
} Py_complex;
99

10+
// Operations on complex numbers.
11+
PyAPI_FUNC(Py_complex) _Py_c_sum(Py_complex, Py_complex);
12+
PyAPI_FUNC(Py_complex) _Py_c_diff(Py_complex, Py_complex);
13+
PyAPI_FUNC(Py_complex) _Py_c_neg(Py_complex);
14+
PyAPI_FUNC(Py_complex) _Py_c_prod(Py_complex, Py_complex);
15+
PyAPI_FUNC(Py_complex) _Py_c_quot(Py_complex, Py_complex);
16+
PyAPI_FUNC(Py_complex) _Py_c_pow(Py_complex, Py_complex);
17+
PyAPI_FUNC(double) _Py_c_abs(Py_complex);
18+
19+
1020
/* Complex object interface */
1121

1222
/*

Include/cpython/dictobject.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ typedef struct {
3232
PyDictValues *ma_values;
3333
} PyDictObject;
3434

35+
PyAPI_FUNC(PyObject *) _PyDict_GetItem_KnownHash(PyObject *mp, PyObject *key,
36+
Py_hash_t hash);
37+
PyAPI_FUNC(PyObject *) _PyDict_GetItemStringWithError(PyObject *, const char *);
3538
PyAPI_FUNC(PyObject *) PyDict_SetDefault(
3639
PyObject *mp, PyObject *key, PyObject *defaultobj);
3740

@@ -46,6 +49,8 @@ static inline Py_ssize_t PyDict_GET_SIZE(PyObject *op) {
4649

4750
PyAPI_FUNC(int) PyDict_ContainsString(PyObject *mp, const char *key);
4851

52+
PyAPI_FUNC(PyObject *) _PyDict_NewPresized(Py_ssize_t minused);
53+
4954
PyAPI_FUNC(int) PyDict_Pop(PyObject *dict, PyObject *key, PyObject **result);
5055
PyAPI_FUNC(int) PyDict_PopString(PyObject *dict, const char *key, PyObject **result);
5156
PyAPI_FUNC(PyObject *) _PyDict_Pop(PyObject *dict, PyObject *key, PyObject *default_value);

Include/cpython/longintrepr.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,16 @@ struct _longobject {
8989
_PyLongValue long_value;
9090
};
9191

92+
PyAPI_FUNC(PyLongObject*) _PyLong_New(Py_ssize_t);
93+
94+
// Return a copy of src.
95+
PyAPI_FUNC(PyObject*) _PyLong_Copy(PyLongObject *src);
96+
97+
PyAPI_FUNC(PyLongObject*) _PyLong_FromDigits(
98+
int negative,
99+
Py_ssize_t digit_count,
100+
digit *digits);
101+
92102

93103
/* Inline some internals for speed. These should be in pycore_long.h
94104
* if user code didn't need them inlined. */

Include/cpython/longobject.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ PyAPI_FUNC(PyObject*) PyLong_FromUnicodeObject(PyObject *u, int base);
77
PyAPI_FUNC(int) PyUnstable_Long_IsCompact(const PyLongObject* op);
88
PyAPI_FUNC(Py_ssize_t) PyUnstable_Long_CompactValue(const PyLongObject* op);
99

10+
// _PyLong_Sign. Return 0 if v is 0, -1 if v < 0, +1 if v > 0.
11+
// v must not be NULL, and must be a normalized long.
12+
// There are no error cases.
13+
PyAPI_FUNC(int) _PyLong_Sign(PyObject *v);
14+
1015
/* _PyLong_FromByteArray: View the n unsigned bytes as a binary integer in
1116
base 256, and return a Python int with the same numeric value.
1217
If n is 0, the integer is 0. Else:

0 commit comments

Comments
 (0)