Skip to content

Commit 0cf3fdb

Browse files
authored
Merge branch 'main' into gh-158316-bytearray-decode
2 parents aab9071 + ab01d18 commit 0cf3fdb

69 files changed

Lines changed: 2515 additions & 1324 deletions

File tree

Some content is hidden

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

‎.github/workflows/reusable-san.yml‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,14 @@ jobs:
9090
--openssl="${OPENSSL_VER}"
9191
--system=Linux
9292
--tsan
93+
# gh-157958: -O2 instead of the pydebug default -Og to avoid a clang 21
94+
# compile-time blowup on some interpreter files.
95+
# (https://github.com/llvm/llvm-project/issues/179695)
9396
- name: Configure CPython
9497
run: >-
9598
./configure
9699
--config-cache
100+
OPT="-O2 -g"
97101
${{
98102
inputs.sanitizer == 'TSan'
99103
&& '--with-thread-sanitizer'

‎Doc/c-api/unicode.rst‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,10 @@ APIs:
425425
the UCS1 range, it will be transformed into UCS1
426426
(:c:macro:`PyUnicode_1BYTE_KIND`).
427427
428+
All characters must be in range [U+0000; U+10ffff]. If *kind* is
429+
:c:macro:`PyUnicode_4BYTE_KIND` and the string contains invalid characters,
430+
the behavior is undefined.
431+
428432
.. versionadded:: 3.3
429433
430434
@@ -1896,10 +1900,13 @@ object.
18961900
18971901
.. c:function:: int PyUnicodeWriter_WriteUCS4(PyUnicodeWriter *writer, const Py_UCS4 *str, Py_ssize_t size)
18981902
1899-
Writer the UCS4 string *str* into *writer*.
1903+
Write the UCS4 string *str* into *writer*.
19001904
19011905
*size* is a number of UCS4 characters.
19021906
1907+
All characters must be in range [U+0000; U+10ffff]. If the string contains
1908+
invalid characters, the behavior is undefined.
1909+
19031910
On success, return ``0``.
19041911
On error, set an exception, leave the writer unchanged, and return ``-1``.
19051912

‎Doc/library/asyncio-eventloop.rst‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,10 @@ Opening network connections
581581
.. versionchanged:: 3.12
582582
*all_errors* was added.
583583

584+
.. versionchanged:: next
585+
Raises a ``ValueError`` if ``ssl.check_hostname`` is ``True``
586+
and ``server_hostname`` is not supplied.
587+
584588
.. seealso::
585589

586590
The :func:`open_connection` function is a high-level alternative

‎Doc/library/asyncio-stream.rst‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,10 @@ StreamWriter
425425
.. versionchanged:: 3.12
426426
Added the *ssl_shutdown_timeout* parameter.
427427

428+
.. versionchanged:: next
429+
Raises a ``ValueError`` if ``sslcontext.check_hostname`` is ``True``
430+
and ``server_hostname`` is not supplied.
431+
428432

429433
.. method:: is_closing()
430434

‎Doc/library/ssl.rst‎

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1859,6 +1859,12 @@ to speed up repeated connections from the same clients.
18591859
:class:`SSLContext` representing a certificate chain that matches the server
18601860
name.
18611861

1862+
If the callback assigns a new context to :attr:`SSLSocket.context`, any
1863+
further ClientHello message on the same connection (for example after a
1864+
TLS 1.3 HelloRetryRequest) is dispatched to the new context's
1865+
*sni_callback*, if it has one; the original callback is not called again
1866+
for that connection.
1867+
18621868
Due to the early negotiation phase of the TLS connection, only limited
18631869
methods and attributes are usable like
18641870
:meth:`SSLSocket.selected_alpn_protocol` and :attr:`SSLSocket.context`.
@@ -1883,6 +1889,11 @@ to speed up repeated connections from the same clients.
18831889

18841890
.. versionadded:: 3.7
18851891

1892+
.. versionchanged:: next
1893+
After the callback assigns a new :attr:`SSLSocket.context`, later
1894+
ClientHello messages on the connection are dispatched to the new
1895+
context's *sni_callback*.
1896+
18861897
.. method:: SSLContext.set_servername_callback(server_name_callback)
18871898

18881899
This is a legacy API retained for backwards compatibility. When possible,
@@ -2004,7 +2015,11 @@ to speed up repeated connections from the same clients.
20042015
outgoing BIO.
20052016

20062017
The *server_side*, *server_hostname* and *session* parameters have the
2007-
same meaning as in :meth:`SSLContext.wrap_socket`.
2018+
same meaning as in :meth:`SSLContext.wrap_socket`, and are validated in
2019+
the same way: in particular a :exc:`ValueError` is raised when
2020+
:attr:`~SSLContext.check_hostname` is enabled but no *server_hostname* is
2021+
given, since there would be no name to match the peer's certificate
2022+
against.
20082023

20092024
.. versionchanged:: 3.6
20102025
*session* argument was added.
@@ -2013,6 +2028,13 @@ to speed up repeated connections from the same clients.
20132028
The method returns an instance of :attr:`SSLContext.sslobject_class`
20142029
instead of hard-coded :class:`SSLObject`.
20152030

2031+
.. versionchanged:: next
2032+
The *server_side*, *server_hostname* and *session* parameters are now
2033+
validated as :meth:`SSLContext.wrap_socket` validates them. Previously
2034+
a context with :attr:`~SSLContext.check_hostname` enabled and no
2035+
*server_hostname* was accepted, and verified the certificate chain but
2036+
never the peer's identity.
2037+
20162038
.. attribute:: SSLContext.sslobject_class
20172039

20182040
The return type of :meth:`SSLContext.wrap_bio`, defaults to

‎Doc/pylock.toml‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -220,9 +220,9 @@ wheels = [{ url = "https://files.pythonhosted.org/packages/71/46/17f022dd3e953bf
220220

221221
[[packages]]
222222
name = "python-docs-theme"
223-
version = "2026.9"
224-
sdist = { url = "https://files.pythonhosted.org/packages/5a/5e/fee7dbfd6a5ebf27f4a91c8cdf204f35f0744fd1fbde7f50cd479d1d890c/python_docs_theme-2026.9.tar.gz", upload-time = 2026-09-19T08:41:45Z, size = 40572, hashes = { sha256 = "1a400cb5e6ac6c8b4788eb0a98067a8c35e8aea15e38941e90a7f764582702fc" } }
225-
wheels = [{ url = "https://files.pythonhosted.org/packages/68/e1/0d603158c9d9a59cd05dfa98a1682c2fffbc387f1e3a724794480f8acaab/python_docs_theme-2026.9-py3-none-any.whl", upload-time = 2026-09-19T08:41:43Z, size = 49214, hashes = { sha256 = "1a4bdc4f9c664c35a58714af0a98efee4ecb7c3bc4ee0752782c953164ac8fc3" } }]
223+
version = "2026.9.1"
224+
sdist = { url = "https://files.pythonhosted.org/packages/10/84/74b9dc8e57aad8e77e20e56b42db5ca101ef250272b178734c3e638e6c9c/python_docs_theme-2026.9.1.tar.gz", upload-time = 2026-09-30T16:17:50Z, size = 92406, hashes = { sha256 = "575743d4c38f39c8615c564269bb3eac5856c1e0191e5798168656cff828ec59" } }
225+
wheels = [{ url = "https://files.pythonhosted.org/packages/85/cd/1b313c9440012be2bca5aebac85f86990aa7deafb37a3cac816c21fd6c04/python_docs_theme-2026.9.1-py3-none-any.whl", upload-time = 2026-09-30T16:17:49Z, size = 99993, hashes = { sha256 = "3e4743ec90bdaf5d1144741b3b9c38cf9bf82c605d3c9a23ae178d9cea0f4429" } }]
226226

227227
[[packages]]
228228
name = "requests"
@@ -316,6 +316,6 @@ wheels = [{ url = "https://files.pythonhosted.org/packages/87/55/ab40a0d1378ee5c
316316

317317
[[packages]]
318318
name = "urllib3"
319-
version = "2.7.0"
320-
sdist = { url = "https://files.pythonhosted.org/packages/53/0c/06f8b233b8fd13b9e5ee11424ef85419ba0d8ba0b3138bf360be2ff56953/urllib3-2.7.0.tar.gz", upload-time = 2026-05-07T16:13:18Z, size = 433602, hashes = { sha256 = "231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c" } }
321-
wheels = [{ url = "https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl", upload-time = 2026-05-07T16:13:17Z, size = 131087, hashes = { sha256 = "9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897" } }]
319+
version = "2.8.0"
320+
sdist = { url = "https://files.pythonhosted.org/packages/e3/05/b17359e1cefb4f909b5e40b1b90a496d987258916dbbf88e842c729f510e/urllib3-2.8.0.tar.gz", upload-time = 2026-09-15T19:29:36Z, size = 458972, hashes = { sha256 = "63bf2ead4c879426ebf22ef2a781eeb4aa3b4ae798a0435506f8687fd5bb9b63" } }
321+
wheels = [{ url = "https://files.pythonhosted.org/packages/92/9d/c4e665119135114480843e7ab388fa94d8480650450e6f8e26b70d323a4c/urllib3-2.8.0-py3-none-any.whl", upload-time = 2026-09-15T19:29:34Z, size = 135717, hashes = { sha256 = "0cf3cae568d36aa9576b28dfb35f11328f1cb974ca7647d9475ebb86c75ac6e3" } }]

‎Include/internal/pycore_call.h‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ extern "C" {
1212
#include "pycore_pystate.h" // _PyThreadState_GET()
1313
#include "pycore_stats.h"
1414

15+
/* Flags that determine the C calling convention. */
16+
#define _Py_METH_CALL_FLAGS \
17+
(METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O | \
18+
METH_KEYWORDS | METH_METHOD)
19+
1520
/* Suggested size (number of positional arguments) for arrays of PyObject*
1621
allocated on a C stack to avoid allocating memory on the heap memory. Such
1722
array is used to pass positional arguments to call functions of the

‎Include/internal/pycore_dict.h‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ PyAPI_FUNC(int) _PyDict_DelItemIf(PyObject *mp, PyObject *key,
2323
int (*predicate)(PyObject *value, void *arg),
2424
void *arg);
2525

26+
// Atomically replace an existing value if it is expected (by identity).
27+
// Return 1 if replaced, 0 if absent or different, or -1 on error.
28+
extern int _PyDict_ReplaceItemIf(PyObject *dict, PyObject *key,
29+
PyObject *expected, PyObject *replacement);
30+
2631
// "KnownHash" variants
2732
// Export for '_asyncio' shared extension
2833
PyAPI_FUNC(int) _PyDict_SetItem_KnownHash(PyObject *mp, PyObject *key,
@@ -147,8 +152,8 @@ PyAPI_FUNC(Py_ssize_t) _PyDictKeys_StringLookup(PyDictKeysObject* dictkeys, PyOb
147152
*/
148153
PyAPI_FUNC(Py_ssize_t) _PyDictKeys_StringLookupAndVersion(PyDictKeysObject* dictkeys, PyObject *key, uint32_t *version);
149154
PyAPI_FUNC(Py_ssize_t) _PyDictKeys_StringLookupSplit(PyDictKeysObject* dictkeys, PyObject *key);
150-
PyAPI_FUNC(PyObject *)_PyDict_LoadGlobal(PyDictObject *, PyDictObject *, PyObject *);
151-
PyAPI_FUNC(void) _PyDict_LoadGlobalStackRef(PyDictObject *, PyDictObject *, PyObject *, _PyStackRef *);
155+
// Return the borrowed source dictionary, or NULL if absent or on error.
156+
PyAPI_FUNC(PyObject *) _PyDict_LoadGlobalStackRef(PyDictObject *, PyDictObject *, PyObject *, _PyStackRef *);
152157

153158
// Loads the __builtins__ object from the globals dict. Returns a new reference.
154159
extern PyObject *_PyDict_LoadBuiltinsFromGlobals(PyObject *globals);

‎Include/internal/pycore_getopt.h‎

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,21 @@
55
# error "this header requires Py_BUILD_CORE define"
66
#endif
77

8-
extern int _PyOS_opterr;
9-
extern Py_ssize_t _PyOS_optind;
10-
extern const wchar_t *_PyOS_optarg;
8+
struct _PyOS_GetOpt {
9+
int error; // generate error messages
10+
Py_ssize_t index; // index into argv array
11+
const wchar_t *arg; // optional argument
12+
const wchar_t *ptr;
13+
Py_ssize_t argc;
14+
wchar_t * const *argv;
15+
};
1116

12-
extern void _PyOS_ResetGetOpt(void);
17+
extern void _PyOS_GetOpt_Init(
18+
struct _PyOS_GetOpt *getopt,
19+
Py_ssize_t argc,
20+
wchar_t * const *argv);
1321

14-
typedef struct {
15-
const wchar_t *name;
16-
int has_arg;
17-
int val;
18-
} _PyOS_LongOption;
19-
20-
extern int _PyOS_GetOpt(Py_ssize_t argc, wchar_t * const *argv, int *longindex);
22+
extern int _PyOS_GetOpt(
23+
struct _PyOS_GetOpt *getopt);
2124

2225
#endif /* !Py_INTERNAL_PYGETOPT_H */

‎Include/internal/pycore_import.h‎

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,20 +32,16 @@ extern int _PyImport_FixupBuiltin(
3232
PyObject *modules
3333
);
3434

35-
extern PyObject * _PyImport_ResolveName(
36-
PyThreadState *tstate, PyObject *name, PyObject *globals, int level);
3735
extern PyObject * _PyImport_GetAbsName(
3836
PyThreadState *tstate, PyObject *name, PyObject *globals, int level);
3937
// Symbol is exported for the JIT on Windows builds.
4038
PyAPI_FUNC(PyObject *) _PyImport_LoadLazyImportTstate(
4139
PyThreadState *tstate, PyObject *lazy_import);
42-
typedef enum {
43-
_Py_LAZY_SUBMODULE_ERROR = -1,
44-
_Py_LAZY_SUBMODULE_NOT_FOUND = 0,
45-
_Py_LAZY_SUBMODULE_LOADED = 1,
46-
} _PyLazySubmoduleImportResult;
47-
extern _PyLazySubmoduleImportResult _PyImport_TryLoadLazySubmodule(
48-
PyObject *mod_name, PyObject *attr_name, PyObject **result);
40+
// Bind a pending child on module before removing its registration. Return a
41+
// new reference, NULL without an exception if absent, or NULL on error.
42+
// Set recheck_dict if a concurrent lookup may have already bound the child.
43+
extern PyObject * _PyImport_TryLoadLazySubmodule(
44+
PyObject *module, PyObject *attr_name, int *recheck_dict);
4945
extern PyObject * _PyImport_LazyImportModuleLevelObject(
5046
PyThreadState *tstate, PyObject *name, PyObject *builtins,
5147
PyObject *globals, PyObject *locals, PyObject *fromlist, int level);

0 commit comments

Comments
 (0)