Skip to content

Commit 81b5092

Browse files
generatedunixname1734921407115435meta-codesync[bot]
authored andcommitted
Import CPython 3.14.7+ stable branch (2026-08-18)
Summary: Imported python/cpython `3.14.7+` from upstream rev [`90a1f02`](https://www.github.com/python/cpython/commit/90a1f02b7da0c356d10a23f1faee7dc063f887ed) (committed 2026-08-18 13:09:24+00:00). # Commit Info - Base: (`3.14.7+`) - [`a59c5bb`](https://www.github.com/python/cpython/commit/a59c5bb023fd74a3c482fc29bd6cefc32c56b531) (commit date: 2026-08-17 13:28:28+00:00) - Imported: (`3.14.7+`) - [`90a1f02`](https://www.github.com/python/cpython/commit/90a1f02b7da0c356d10a23f1faee7dc063f887ed) (commit date: 2026-08-18 13:09:24+00:00) # Noteworthy file changes - Low-signal files (7 added) (NEWS.d, docs, .github) Complete list of added/removed files: https://www.internalfb.com/intern/everpaste/?color=0&handle=GCAJpAfO4BLr9vYHABzgI7gcqCtVbr0LAAAz Reviewed By: itamaro Differential Revision: D116612193 fbshipit-source-id: 0f4d8c178191af000112c071c4d7ecabed1d8e06
1 parent 820efd4 commit 81b5092

46 files changed

Lines changed: 742 additions & 112 deletions

Some content is hidden

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

Doc/library/urllib.request.rst

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -991,8 +991,14 @@ These methods are available on :class:`HTTPPasswordMgr` and
991991

992992
*uri* can be either a single URI, or a sequence of URIs. *realm*, *user* and
993993
*passwd* must be strings. This causes ``(user, passwd)`` to be used as
994-
authentication tokens when authentication for *realm* and a super-URI of any of
995-
the given URIs is given.
994+
authentication tokens when authentication for *realm* and a super-URI of any
995+
of the given URIs is given. If a URI includes a scheme, its credentials only
996+
match authentication URIs with the same scheme or no scheme. A URI without a
997+
scheme matches authentication URIs with any scheme.
998+
999+
.. versionchanged:: next
1000+
Authentication credentials for URIs with a scheme are now scoped by
1001+
that scheme.
9961002

9971003

9981004
.. method:: HTTPPasswordMgr.find_user_password(realm, authuri)

Lib/concurrent/interpreters/__init__.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,14 @@ def create():
6868

6969
def list_all():
7070
"""Return all existing interpreters."""
71-
return [Interpreter(id, _whence=whence)
72-
for id, whence in _interpreters.list_all(require_ready=True)]
71+
interps = []
72+
for id, whence in _interpreters.list_all(require_ready=True):
73+
try:
74+
interps.append(Interpreter(id, _whence=whence))
75+
except InterpreterNotFoundError:
76+
# It was destroyed after it was listed.
77+
pass
78+
return interps
7379

7480

7581
def get_current():

Lib/importlib/_bootstrap_external.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,10 @@ def _bless_my_loader(module_globals):
646646
loader = module_globals.get('__loader__', None)
647647
spec = module_globals.get('__spec__', missing)
648648

649+
# The __main__ module of a script or the REPL has __spec__ set to None.
650+
if spec is None and module_globals.get('__name__') == '__main__':
651+
return loader
652+
649653
if loader is None:
650654
if spec is missing:
651655
# If working with a module:

Lib/test/clinic.test.c

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5303,14 +5303,53 @@ Test_property_set(PyObject *self, PyObject *value, void *Py_UNUSED(context))
53035303
{
53045304
int return_value;
53055305

5306+
if (value == NULL) {
5307+
PyErr_Format(PyExc_AttributeError,
5308+
"attribute 'property' of '%.100s' objects cannot be deleted",
5309+
Py_TYPE(self)->tp_name);
5310+
return -1;
5311+
}
53065312
return_value = Test_property_set_impl((TestObj *)self, value);
53075313

53085314
return return_value;
53095315
}
53105316

53115317
static int
53125318
Test_property_set_impl(TestObj *self, PyObject *value)
5313-
/*[clinic end generated code: output=49f925ab2a33b637 input=3bc3f46a23c83a88]*/
5319+
/*[clinic end generated code: output=ec103a151cf51d25 input=3bc3f46a23c83a88]*/
5320+
5321+
/*[clinic input]
5322+
@setter
5323+
@deleter
5324+
Test.settable_and_deletable
5325+
[clinic start generated code]*/
5326+
5327+
#if !defined(Test_settable_and_deletable_DOCSTR)
5328+
# define Test_settable_and_deletable_DOCSTR NULL
5329+
#endif
5330+
#if defined(TEST_SETTABLE_AND_DELETABLE_GETSETDEF)
5331+
# undef TEST_SETTABLE_AND_DELETABLE_GETSETDEF
5332+
# define TEST_SETTABLE_AND_DELETABLE_GETSETDEF {"settable_and_deletable", (getter)Test_settable_and_deletable_get, (setter)Test_settable_and_deletable_set, Test_settable_and_deletable_DOCSTR},
5333+
#else
5334+
# define TEST_SETTABLE_AND_DELETABLE_GETSETDEF {"settable_and_deletable", NULL, (setter)Test_settable_and_deletable_set, NULL},
5335+
#endif
5336+
5337+
static int
5338+
Test_settable_and_deletable_set_impl(TestObj *self, PyObject *value);
5339+
5340+
static int
5341+
Test_settable_and_deletable_set(PyObject *self, PyObject *value, void *Py_UNUSED(context))
5342+
{
5343+
int return_value;
5344+
5345+
return_value = Test_settable_and_deletable_set_impl((TestObj *)self, value);
5346+
5347+
return return_value;
5348+
}
5349+
5350+
static int
5351+
Test_settable_and_deletable_set_impl(TestObj *self, PyObject *value)
5352+
/*[clinic end generated code: output=479986d499b2f56d input=f5647f3511b9daea]*/
53145353

53155354
/*[clinic input]
53165355
@setter
@@ -5335,14 +5374,20 @@ Test_setter_first_with_docstr_set(PyObject *self, PyObject *value, void *Py_UNUS
53355374
{
53365375
int return_value;
53375376

5377+
if (value == NULL) {
5378+
PyErr_Format(PyExc_AttributeError,
5379+
"attribute 'setter_first_with_docstr' of '%.100s' objects cannot be deleted",
5380+
Py_TYPE(self)->tp_name);
5381+
return -1;
5382+
}
53385383
return_value = Test_setter_first_with_docstr_set_impl((TestObj *)self, value);
53395384

53405385
return return_value;
53415386
}
53425387

53435388
static int
53445389
Test_setter_first_with_docstr_set_impl(TestObj *self, PyObject *value)
5345-
/*[clinic end generated code: output=5aaf44373c0af545 input=31a045ce11bbe961]*/
5390+
/*[clinic end generated code: output=eac8bafcaa50aa51 input=31a045ce11bbe961]*/
53465391

53475392
/*[clinic input]
53485393
@getter

Lib/test/libregrtest/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,7 @@ def run_tests_sequentially(self, runtests: RunTests) -> None:
446446

447447
def get_state(self) -> str:
448448
state = self.results.get_state(self.fail_env_changed)
449-
if self.first_state:
449+
if self.first_state and self.first_state != state:
450450
state = f'{self.first_state} then {state}'
451451
return state
452452

Lib/test/libregrtest/result.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@ class TestResult:
100100
# partial coverage in a worker run; not used by sequential in-process runs
101101
covered_lines: list[Location] | None = None
102102

103+
# short descriptions of how the test altered the execution environment
104+
env_changed_reasons: list[str] | None = None
105+
103106
def is_failed(self, fail_env_changed: bool) -> bool:
104107
if self.state == State.ENV_CHANGED:
105108
return fail_env_changed
@@ -175,9 +178,15 @@ def __str__(self) -> str:
175178
def has_meaningful_duration(self):
176179
return State.has_meaningful_duration(self.state)
177180

178-
def set_env_changed(self):
181+
def set_env_changed(self, *reasons):
179182
if self.state is None or self.state == State.PASSED:
180183
self.state = State.ENV_CHANGED
184+
if reasons:
185+
if self.env_changed_reasons is None:
186+
self.env_changed_reasons = []
187+
for reason in reasons:
188+
if reason not in self.env_changed_reasons:
189+
self.env_changed_reasons.append(reason)
181190

182191
def must_stop(self, fail_fast: bool, fail_env_changed: bool) -> bool:
183192
if State.must_stop(self.state):

Lib/test/libregrtest/results.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ def __init__(self) -> None:
3030
self.skipped: TestList = []
3131
self.resource_denied: TestList = []
3232
self.env_changed: TestList = []
33+
# test name => how the test altered the execution environment
34+
self.env_changed_reasons: dict[TestName, list[str]] = {}
3335
self.run_no_tests: TestList = []
3436
self.rerun: TestList = []
3537
self.rerun_results: list[TestResult] = []
@@ -107,6 +109,9 @@ def accumulate_result(self, result: TestResult, runtests: RunTests) -> None:
107109
self.good.append(test_name)
108110
case State.ENV_CHANGED:
109111
self.env_changed.append(test_name)
112+
if result.env_changed_reasons:
113+
self.env_changed_reasons[test_name] = \
114+
result.env_changed_reasons
110115
self.rerun_results.append(result)
111116
case State.SKIPPED:
112117
self.skipped.append(test_name)
@@ -254,7 +259,18 @@ def display_result(self, tests: TestTuple, quiet: bool, print_slowest: bool) ->
254259
print()
255260
count_text = count(len(tests_list), count_text)
256261
print(title_format.format(count_text))
257-
printlist(tests_list)
262+
if tests_list is self.env_changed:
263+
# List every test and every reason on a separate line.
264+
for test_name in sorted(tests_list):
265+
reasons = self.env_changed_reasons.get(test_name)
266+
if reasons:
267+
print(f" {test_name}:")
268+
for reason in reasons:
269+
print(f" {reason}")
270+
else:
271+
print(f" {test_name}")
272+
else:
273+
printlist(tests_list)
258274

259275
if self.good and not quiet:
260276
print()

Lib/test/libregrtest/run_workers.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,8 @@ def _runtest(self, test_name: TestName) -> MultiprocessResult:
386386
f'Warning -- {test_name} leaked temporary files '
387387
f'({len(tmp_files)}): {", ".join(sorted(tmp_files))}')
388388
stdout += msg
389-
result.set_env_changed()
389+
result.set_env_changed(
390+
f"leaked temporary files: {', '.join(sorted(tmp_files))}")
390391

391392
return MultiprocessResult(result, stdout)
392393

Lib/test/libregrtest/save_env.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ def __exit__(self, exc_type, exc_val, exc_tb):
347347
current = get()
348348
# Check for changes to the resource's value
349349
if current != original:
350-
support.environment_altered = True
350+
support.set_environment_altered(f"{name} was modified")
351351
restore(original)
352352
if not self.quiet and not self.pgo:
353353
print_warning(

Lib/test/libregrtest/single.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,8 @@ def test_func():
173173
remove_testfn(test_name, runtests.verbose)
174174

175175
if gc.garbage:
176-
support.environment_altered = True
176+
support.set_environment_altered(
177+
f"{len(gc.garbage)} uncollectable object(s)")
177178
print_warning(f"{test_name} created {len(gc.garbage)} "
178179
f"uncollectable object(s)")
179180

@@ -194,6 +195,7 @@ def _runtest_env_changed_exc(result: TestResult, runtests: RunTests,
194195
# Reset the environment_altered flag to detect if a test altered
195196
# the environment
196197
support.environment_altered = False
198+
support.environment_altered_reasons.clear()
197199

198200
pgo = runtests.pgo
199201
if pgo:
@@ -261,7 +263,7 @@ def _runtest_env_changed_exc(result: TestResult, runtests: RunTests,
261263
return
262264

263265
if support.environment_altered:
264-
result.set_env_changed()
266+
result.set_env_changed(*support.environment_altered_reasons)
265267
# Don't override the state if it was already set (REFLEAK or ENV_CHANGED)
266268
if result.state is None:
267269
result.state = State.PASSED

0 commit comments

Comments
 (0)