Skip to content

Commit 778de8e

Browse files
authored
Merge branch 'main' into pythongh-117657-seq-lock
2 parents a9907b8 + b6c62c7 commit 778de8e

File tree

69 files changed

+1552
-547
lines changed

Some content is hidden

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

69 files changed

+1552
-547
lines changed

Doc/c-api/exceptions.rst

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -221,13 +221,14 @@ For convenience, some of these functions will always return a
221221
222222
.. c:function:: PyObject* PyErr_SetFromWindowsErr(int ierr)
223223
224-
This is a convenience function to raise :exc:`WindowsError`. If called with
224+
This is a convenience function to raise :exc:`OSError`. If called with
225225
*ierr* of ``0``, the error code returned by a call to :c:func:`!GetLastError`
226226
is used instead. It calls the Win32 function :c:func:`!FormatMessage` to retrieve
227227
the Windows description of error code given by *ierr* or :c:func:`!GetLastError`,
228-
then it constructs a tuple object whose first item is the *ierr* value and whose
229-
second item is the corresponding error message (gotten from
230-
:c:func:`!FormatMessage`), and then calls ``PyErr_SetObject(PyExc_WindowsError,
228+
then it constructs a :exc:`OSError` object with the :attr:`~OSError.winerror`
229+
attribute set to the error code, the :attr:`~OSError.strerror` attribute
230+
set to the corresponding error message (gotten from
231+
:c:func:`!FormatMessage`), and then calls ``PyErr_SetObject(PyExc_OSError,
231232
object)``. This function always returns ``NULL``.
232233
233234
.. availability:: Windows.

Doc/c-api/init.rst

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ The following functions can be safely called before Python is initialized:
5959
:c:func:`Py_Initialize`: :c:func:`Py_EncodeLocale`, :c:func:`Py_GetPath`,
6060
:c:func:`Py_GetPrefix`, :c:func:`Py_GetExecPrefix`,
6161
:c:func:`Py_GetProgramFullPath`, :c:func:`Py_GetPythonHome`,
62-
and :c:func:`Py_GetProgramName`.
62+
:c:func:`Py_GetProgramName` and :c:func:`PyEval_InitThreads`.
6363

6464

6565
.. _global-conf-vars:
@@ -326,6 +326,7 @@ Initializing and finalizing the interpreter
326326
.. c:function:: void Py_Initialize()
327327
328328
.. index::
329+
single: PyEval_InitThreads()
329330
single: modules (in module sys)
330331
single: path (in module sys)
331332
pair: module; builtins
@@ -841,6 +842,33 @@ code, or when embedding the Python interpreter:
841842
This thread's interpreter state.
842843
843844
845+
.. c:function:: void PyEval_InitThreads()
846+
847+
.. index::
848+
single: PyEval_AcquireThread()
849+
single: PyEval_ReleaseThread()
850+
single: PyEval_SaveThread()
851+
single: PyEval_RestoreThread()
852+
853+
Deprecated function which does nothing.
854+
855+
In Python 3.6 and older, this function created the GIL if it didn't exist.
856+
857+
.. versionchanged:: 3.9
858+
The function now does nothing.
859+
860+
.. versionchanged:: 3.7
861+
This function is now called by :c:func:`Py_Initialize()`, so you don't
862+
have to call it yourself anymore.
863+
864+
.. versionchanged:: 3.2
865+
This function cannot be called before :c:func:`Py_Initialize()` anymore.
866+
867+
.. deprecated:: 3.9
868+
869+
.. index:: pair: module; _thread
870+
871+
844872
.. c:function:: PyThreadState* PyEval_SaveThread()
845873
846874
Release the global interpreter lock (if it has been created) and reset the

Doc/data/stable_abi.dat

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

Doc/library/os.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2135,7 +2135,7 @@ features:
21352135

21362136
.. audit-event:: os.chmod path,mode,dir_fd os.chmod
21372137

2138-
.. versionadded:: 3.3
2138+
.. versionchanged:: 3.3
21392139
Added support for specifying *path* as an open file descriptor,
21402140
and the *dir_fd* and *follow_symlinks* arguments.
21412141

@@ -2166,7 +2166,7 @@ features:
21662166
The function is limited on WASI, see :ref:`wasm-availability` for more
21672167
information.
21682168

2169-
.. versionadded:: 3.3
2169+
.. versionchanged:: 3.3
21702170
Added support for specifying *path* as an open file descriptor,
21712171
and the *dir_fd* and *follow_symlinks* arguments.
21722172

@@ -2310,7 +2310,7 @@ features:
23102310
.. versionchanged:: 3.2
23112311
The *path* parameter became optional.
23122312

2313-
.. versionadded:: 3.3
2313+
.. versionchanged:: 3.3
23142314
Added support for specifying *path* as an open file descriptor.
23152315

23162316
.. versionchanged:: 3.6

Doc/tools/templates/layout.html

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,90 @@
4141
{{ "}" }}
4242
</style>
4343
{{ super() }}
44+
45+
<meta name="readthedocs-addons-api-version" content="1">
46+
<script type="text/javascript">
47+
function onSwitch(event) {
48+
const option = event.target.selectedIndex;
49+
const item = event.target.options[option];
50+
window.location.href = item.dataset.url;
51+
}
52+
53+
document.addEventListener("readthedocs-addons-data-ready", function(event) {
54+
const config = event.detail.data()
55+
56+
// Add some mocked hardcoded versions pointing to the official
57+
// documentation while migrating to Read the Docs.
58+
// These are only for testing purposes.
59+
// TODO: remove them when managing all the versions on Read the Docs,
60+
// since all the "active, built and not hidden" versions will be shown automatically.
61+
let versions = config.versions.active.concat([
62+
{
63+
slug: "dev (3.13)",
64+
urls: {
65+
documentation: "https://docs.python.org/3.13/",
66+
}
67+
},
68+
{
69+
slug: "3.12",
70+
urls: {
71+
documentation: "https://docs.python.org/3.12/",
72+
}
73+
},
74+
{
75+
slug: "3.11",
76+
urls: {
77+
documentation: "https://docs.python.org/3.11/",
78+
}
79+
},
80+
]);
81+
82+
const versionSelect = `
83+
<select id="version_select">
84+
${ versions.map(
85+
(version) => `
86+
<option
87+
value="${ version.slug }"
88+
${ config.versions.current.slug === version.slug ? 'selected="selected"' : '' }
89+
data-url="${ version.urls.documentation }">
90+
${ version.slug }
91+
</option>`
92+
).join("\n") }
93+
</select>
94+
`;
95+
96+
// Prepend the current language to the options on the selector
97+
let languages = config.projects.translations.concat(config.projects.current);
98+
languages = languages.sort((a, b) => a.language.name.localeCompare(b.language.name));
99+
100+
const languageSelect = `
101+
<select id="language_select">
102+
${ languages.map(
103+
(translation) => `
104+
<option
105+
value="${ translation.slug }"
106+
${ config.projects.current.slug === translation.slug ? 'selected="selected"' : '' }
107+
data-url="${ translation.urls.documentation }">
108+
${ translation.language.name }
109+
</option>`
110+
).join("\n") }
111+
</select>
112+
`;
113+
114+
// Query all the placeholders because there are different ones for Desktop/Mobile
115+
const versionPlaceholders = document.querySelectorAll(".version_switcher_placeholder");
116+
for (placeholder of versionPlaceholders) {
117+
placeholder.innerHTML = versionSelect;
118+
let selectElement = placeholder.querySelector("select");
119+
selectElement.addEventListener("change", onSwitch);
120+
}
121+
122+
const languagePlaceholders = document.querySelectorAll(".language_switcher_placeholder");
123+
for (placeholder of languagePlaceholders) {
124+
placeholder.innerHTML = languageSelect;
125+
let selectElement = placeholder.querySelector("select");
126+
selectElement.addEventListener("change", onSwitch);
127+
}
128+
});
129+
</script>
44130
{% endblock %}

Doc/whatsnew/3.13.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2027,9 +2027,9 @@ Removed
20272027
added in Python 3.8 and the old macros were deprecated in Python 3.11.
20282028
(Contributed by Irit Katriel in :gh:`105111`.)
20292029

2030-
* Remove ``PyEval_InitThreads()`` and ``PyEval_ThreadsInitialized()``
2031-
functions, deprecated in Python 3.9. Since Python 3.7, ``Py_Initialize()``
2032-
always creates the GIL: calling ``PyEval_InitThreads()`` did nothing and
2030+
* Remove ``PyEval_ThreadsInitialized()``
2031+
function, deprecated in Python 3.9. Since Python 3.7, ``Py_Initialize()``
2032+
always creates the GIL: calling ``PyEval_InitThreads()`` does nothing and
20332033
``PyEval_ThreadsInitialized()`` always returned non-zero.
20342034
(Contributed by Victor Stinner in :gh:`105182`.)
20352035

Include/ceval.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ PyAPI_FUNC(PyObject *) PyEval_EvalFrameEx(PyFrameObject *f, int exc);
107107
PyAPI_FUNC(PyThreadState *) PyEval_SaveThread(void);
108108
PyAPI_FUNC(void) PyEval_RestoreThread(PyThreadState *);
109109

110+
Py_DEPRECATED(3.9) PyAPI_FUNC(void) PyEval_InitThreads(void);
111+
110112
PyAPI_FUNC(void) PyEval_AcquireThread(PyThreadState *tstate);
111113
PyAPI_FUNC(void) PyEval_ReleaseThread(PyThreadState *tstate);
112114

Include/cpython/object.h

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -448,8 +448,8 @@ without deallocating anything (and so unbounded call-stack depth is avoided).
448448
When the call stack finishes unwinding again, code generated by the END macro
449449
notices this, and calls another routine to deallocate all the objects that
450450
may have been added to the list of deferred deallocations. In effect, a
451-
chain of N deallocations is broken into (N-1)/(_PyTrash_UNWIND_LEVEL-1) pieces,
452-
with the call stack never exceeding a depth of _PyTrash_UNWIND_LEVEL.
451+
chain of N deallocations is broken into (N-1)/(Py_TRASHCAN_HEADROOM-1) pieces,
452+
with the call stack never exceeding a depth of Py_TRASHCAN_HEADROOM.
453453
454454
Since the tp_dealloc of a subclass typically calls the tp_dealloc of the base
455455
class, we need to ensure that the trashcan is only triggered on the tp_dealloc
@@ -461,30 +461,33 @@ passed as second argument to Py_TRASHCAN_BEGIN().
461461
/* Python 3.9 private API, invoked by the macros below. */
462462
PyAPI_FUNC(int) _PyTrash_begin(PyThreadState *tstate, PyObject *op);
463463
PyAPI_FUNC(void) _PyTrash_end(PyThreadState *tstate);
464+
465+
PyAPI_FUNC(void) _PyTrash_thread_deposit_object(PyThreadState *tstate, PyObject *op);
466+
PyAPI_FUNC(void) _PyTrash_thread_destroy_chain(PyThreadState *tstate);
467+
468+
464469
/* Python 3.10 private API, invoked by the Py_TRASHCAN_BEGIN(). */
465-
PyAPI_FUNC(int) _PyTrash_cond(PyObject *op, destructor dealloc);
466470

467-
#define Py_TRASHCAN_BEGIN_CONDITION(op, cond) \
468-
do { \
469-
PyThreadState *_tstate = NULL; \
470-
/* If "cond" is false, then _tstate remains NULL and the deallocator \
471-
* is run normally without involving the trashcan */ \
472-
if (cond) { \
473-
_tstate = PyThreadState_GetUnchecked(); \
474-
if (_PyTrash_begin(_tstate, _PyObject_CAST(op))) { \
475-
break; \
476-
} \
477-
}
478-
/* The body of the deallocator is here. */
479-
#define Py_TRASHCAN_END \
480-
if (_tstate) { \
481-
_PyTrash_end(_tstate); \
482-
} \
483-
} while (0);
471+
/* To avoid raising recursion errors during dealloc trigger trashcan before we reach
472+
* recursion limit. To avoid trashing, we don't attempt to empty the trashcan until
473+
* we have headroom above the trigger limit */
474+
#define Py_TRASHCAN_HEADROOM 50
484475

485476
#define Py_TRASHCAN_BEGIN(op, dealloc) \
486-
Py_TRASHCAN_BEGIN_CONDITION((op), \
487-
_PyTrash_cond(_PyObject_CAST(op), (destructor)(dealloc)))
477+
do { \
478+
PyThreadState *tstate = PyThreadState_Get(); \
479+
if (tstate->c_recursion_remaining <= Py_TRASHCAN_HEADROOM && Py_TYPE(op)->tp_dealloc == (destructor)dealloc) { \
480+
_PyTrash_thread_deposit_object(tstate, (PyObject *)op); \
481+
break; \
482+
} \
483+
tstate->c_recursion_remaining--;
484+
/* The body of the deallocator is here. */
485+
#define Py_TRASHCAN_END \
486+
tstate->c_recursion_remaining++; \
487+
if (tstate->delete_later && tstate->c_recursion_remaining > (Py_TRASHCAN_HEADROOM*2)) { \
488+
_PyTrash_thread_destroy_chain(tstate); \
489+
} \
490+
} while (0);
488491

489492

490493
PyAPI_FUNC(void *) PyObject_GetItemData(PyObject *obj);

Include/cpython/pystate.h

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,6 @@ typedef struct _stack_chunk {
5656
PyObject * data[1]; /* Variable sized */
5757
} _PyStackChunk;
5858

59-
struct _py_trashcan {
60-
int delete_nesting;
61-
PyObject *delete_later;
62-
};
63-
6459
struct _ts {
6560
/* See Python/ceval.c for comments explaining most fields */
6661

@@ -152,7 +147,7 @@ struct _ts {
152147
*/
153148
unsigned long native_thread_id;
154149

155-
struct _py_trashcan trash;
150+
PyObject *delete_later;
156151

157152
/* Tagged pointer to top-most critical section, or zero if there is no
158153
* active critical section. Critical sections are only used in

Include/internal/pycore_global_objects_fini_generated.h

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

Include/internal/pycore_global_strings.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,7 @@ struct _Py_global_strings {
353353
STRUCT_FOR_ID(co_stacksize)
354354
STRUCT_FOR_ID(co_varnames)
355355
STRUCT_FOR_ID(code)
356+
STRUCT_FOR_ID(col_offset)
356357
STRUCT_FOR_ID(command)
357358
STRUCT_FOR_ID(comment_factory)
358359
STRUCT_FOR_ID(compile_mode)
@@ -402,6 +403,7 @@ struct _Py_global_strings {
402403
STRUCT_FOR_ID(encode)
403404
STRUCT_FOR_ID(encoding)
404405
STRUCT_FOR_ID(end)
406+
STRUCT_FOR_ID(end_col_offset)
405407
STRUCT_FOR_ID(end_lineno)
406408
STRUCT_FOR_ID(end_offset)
407409
STRUCT_FOR_ID(endpos)
@@ -522,6 +524,7 @@ struct _Py_global_strings {
522524
STRUCT_FOR_ID(kw1)
523525
STRUCT_FOR_ID(kw2)
524526
STRUCT_FOR_ID(kwdefaults)
527+
STRUCT_FOR_ID(label)
525528
STRUCT_FOR_ID(lambda)
526529
STRUCT_FOR_ID(last)
527530
STRUCT_FOR_ID(last_exc)
@@ -585,6 +588,7 @@ struct _Py_global_strings {
585588
STRUCT_FOR_ID(namespaces)
586589
STRUCT_FOR_ID(narg)
587590
STRUCT_FOR_ID(ndigits)
591+
STRUCT_FOR_ID(nested)
588592
STRUCT_FOR_ID(new_file_name)
589593
STRUCT_FOR_ID(new_limit)
590594
STRUCT_FOR_ID(newline)

0 commit comments

Comments
 (0)