Skip to content

Commit abca71c

Browse files
Merge branch '3.14' into backport-ff2577f-3.14
2 parents 8a9d395 + 06f9c8c commit abca71c

25 files changed

+171
-48
lines changed

Android/testbed/app/build.gradle.kts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,12 @@ android {
9292
}
9393
throw GradleException("Failed to find API level in $androidEnvFile")
9494
}
95-
targetSdk = 35
95+
96+
// This controls the API level of the maxVersion managed emulator, which is used
97+
// by CI and cibuildwheel. 34 takes up too much disk space (#142289), 35 has
98+
// issues connecting to the internet (#142387), and 36 and later are not
99+
// available as aosp_atd images yet.
100+
targetSdk = 33
96101

97102
versionCode = 1
98103
versionName = "1.0"

Doc/c-api/module.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,9 @@ or code that creates modules dynamically.
675675
``PyModuleDef`` (such as when using :ref:`multi-phase-initialization`,
676676
``PyModule_Create``, or ``PyModule_FromDefAndSpec``).
677677
678+
Return ``0`` on success.
679+
Return ``-1`` with an exception set on error.
680+
678681
.. versionadded:: 3.5
679682
680683
.. c:function:: int PyUnstable_Module_SetGIL(PyObject *module, void *gil)

Doc/faq/programming.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1226,13 +1226,13 @@ This converts the list into a set, thereby removing duplicates, and then back
12261226
into a list.
12271227

12281228

1229-
How do you remove multiple items from a list
1230-
--------------------------------------------
1229+
How do you remove multiple items from a list?
1230+
---------------------------------------------
12311231

12321232
As with removing duplicates, explicitly iterating in reverse with a
12331233
delete condition is one possibility. However, it is easier and faster
12341234
to use slice replacement with an implicit or explicit forward iteration.
1235-
Here are three variations.::
1235+
Here are three variations::
12361236

12371237
mylist[:] = filter(keep_function, mylist)
12381238
mylist[:] = (x for x in mylist if keep_condition)

Doc/library/contextvars.rst

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,32 @@ Context Variables
7777
to restore the variable to its previous value via the
7878
:meth:`ContextVar.reset` method.
7979

80+
For convenience, the token object can be used as a context manager
81+
to avoid calling :meth:`ContextVar.reset` manually::
82+
83+
var = ContextVar('var', default='default value')
84+
85+
with var.set('new value'):
86+
assert var.get() == 'new value'
87+
88+
assert var.get() == 'default value'
89+
90+
It is a shorthand for::
91+
92+
var = ContextVar('var', default='default value')
93+
94+
token = var.set('new value')
95+
try:
96+
assert var.get() == 'new value'
97+
finally:
98+
var.reset(token)
99+
100+
assert var.get() == 'default value'
101+
102+
.. versionadded:: 3.14
103+
104+
Added support for using tokens as context managers.
105+
80106
.. method:: reset(token)
81107

82108
Reset the context variable to the value it had before the
@@ -93,24 +119,18 @@ Context Variables
93119
# After the reset call the var has no value again, so
94120
# var.get() would raise a LookupError.
95121

122+
The same *token* cannot be used twice.
123+
96124

97125
.. class:: Token
98126

99127
*Token* objects are returned by the :meth:`ContextVar.set` method.
100128
They can be passed to the :meth:`ContextVar.reset` method to revert
101129
the value of the variable to what it was before the corresponding
102-
*set*.
103-
104-
The token supports :ref:`context manager protocol <context-managers>`
105-
to restore the corresponding context variable value at the exit from
106-
:keyword:`with` block::
107-
108-
var = ContextVar('var', default='default value')
109-
110-
with var.set('new value'):
111-
assert var.get() == 'new value'
130+
*set*. A single token cannot reset a context variable more than once.
112131

113-
assert var.get() == 'default value'
132+
Tokens support the :ref:`context manager protocol <context-managers>`
133+
to automatically reset context variables. See :meth:`ContextVar.set`.
114134

115135
.. versionadded:: 3.14
116136

Doc/library/os.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3880,7 +3880,7 @@ features:
38803880
import os
38813881

38823882
# semaphore with start value '1'
3883-
fd = os.eventfd(1, os.EFD_SEMAPHORE | os.EFC_CLOEXEC)
3883+
fd = os.eventfd(1, os.EFD_SEMAPHORE | os.EFD_CLOEXEC)
38843884
try:
38853885
# acquire semaphore
38863886
v = os.eventfd_read(fd)

Doc/library/pickle.rst

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -56,19 +56,6 @@ files.
5656

5757
The :mod:`pickle` module differs from :mod:`marshal` in several significant ways:
5858

59-
* The :mod:`pickle` module keeps track of the objects it has already serialized,
60-
so that later references to the same object won't be serialized again.
61-
:mod:`marshal` doesn't do this.
62-
63-
This has implications both for recursive objects and object sharing. Recursive
64-
objects are objects that contain references to themselves. These are not
65-
handled by marshal, and in fact, attempting to marshal recursive objects will
66-
crash your Python interpreter. Object sharing happens when there are multiple
67-
references to the same object in different places in the object hierarchy being
68-
serialized. :mod:`pickle` stores such objects only once, and ensures that all
69-
other references point to the master copy. Shared objects remain shared, which
70-
can be very important for mutable objects.
71-
7259
* :mod:`marshal` cannot be used to serialize user-defined classes and their
7360
instances. :mod:`pickle` can save and restore class instances transparently,
7461
however the class definition must be importable and live in the same module as

Doc/reference/datamodel.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,7 @@ Special read-only attributes
546546
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
547547

548548
.. index::
549+
single: __builtins__ (function attribute)
549550
single: __closure__ (function attribute)
550551
single: __globals__ (function attribute)
551552
pair: global; namespace
@@ -556,6 +557,12 @@ Special read-only attributes
556557
* - Attribute
557558
- Meaning
558559

560+
* - .. attribute:: function.__builtins__
561+
- A reference to the :class:`dictionary <dict>` that holds the function's
562+
builtins namespace.
563+
564+
.. versionadded:: 3.10
565+
559566
* - .. attribute:: function.__globals__
560567
- A reference to the :class:`dictionary <dict>` that holds the function's
561568
:ref:`global variables <naming>` -- the global namespace of the module

Lib/email/generator.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
NLCRE = re.compile(r'\r\n|\r|\n')
2323
fcre = re.compile(r'^From ', re.MULTILINE)
2424
NEWLINE_WITHOUT_FWSP = re.compile(r'\r\n[^ \t]|\r[^ \n\t]|\n[^ \t]')
25+
NEWLINE_WITHOUT_FWSP_BYTES = re.compile(br'\r\n[^ \t]|\r[^ \n\t]|\n[^ \t]')
2526

2627

2728
class Generator:
@@ -429,7 +430,16 @@ def _write_headers(self, msg):
429430
# This is almost the same as the string version, except for handling
430431
# strings with 8bit bytes.
431432
for h, v in msg.raw_items():
432-
self._fp.write(self.policy.fold_binary(h, v))
433+
folded = self.policy.fold_binary(h, v)
434+
if self.policy.verify_generated_headers:
435+
linesep = self.policy.linesep.encode()
436+
if not folded.endswith(linesep):
437+
raise HeaderWriteError(
438+
f'folded header does not end with {linesep!r}: {folded!r}')
439+
if NEWLINE_WITHOUT_FWSP_BYTES.search(folded.removesuffix(linesep)):
440+
raise HeaderWriteError(
441+
f'folded header contains newline: {folded!r}')
442+
self._fp.write(folded)
433443
# A blank line always separates headers from body
434444
self.write(self._NL)
435445

Lib/test/test_ast/test_ast.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1419,6 +1419,13 @@ def test_replace_reject_unknown_instance_fields(self):
14191419
self.assertIs(node.ctx, context)
14201420
self.assertRaises(AttributeError, getattr, node, 'unknown')
14211421

1422+
def test_replace_non_str_kwarg(self):
1423+
node = ast.Name(id="x")
1424+
errmsg = "got an unexpected keyword argument <object object"
1425+
with self.assertRaisesRegex(TypeError, errmsg):
1426+
node.__replace__(**{object(): "y"})
1427+
1428+
14221429
class ASTHelpers_Test(unittest.TestCase):
14231430
maxDiff = None
14241431

@@ -3281,6 +3288,27 @@ class _AllFieldTypes(ast.AST):
32813288
self.assertIs(obj.a, None)
32823289
self.assertEqual(obj.b, [])
32833290

3291+
def test_non_str_kwarg(self):
3292+
warn_msg = "got an unexpected keyword argument <object object"
3293+
with (
3294+
self.assertRaises(TypeError),
3295+
self.assertWarnsRegex(DeprecationWarning, warn_msg),
3296+
):
3297+
ast.Name(**{object(): 'y'})
3298+
3299+
class FakeStr:
3300+
def __init__(self, value):
3301+
self.value = value
3302+
3303+
def __hash__(self):
3304+
return hash(self.value)
3305+
3306+
def __eq__(self, other):
3307+
return isinstance(other, str) and self.value == other
3308+
3309+
with self.assertRaisesRegex(TypeError, "got multiple values for argument"):
3310+
ast.Name("x", **{FakeStr('id'): 'y'})
3311+
32843312

32853313
@support.cpython_only
32863314
class ModuleStateTests(unittest.TestCase):

Lib/test/test_ctypes/test_pointers.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,16 @@ class Cls(Structure):
403403
self.assertEqual(len(ws_typ), 0, ws_typ)
404404
self.assertEqual(len(ws_ptr), 0, ws_ptr)
405405

406+
def test_pointer_proto_missing_argtypes_error(self):
407+
class BadType(ctypes._Pointer):
408+
# _type_ is intentionally missing
409+
pass
410+
411+
func = ctypes.pythonapi.Py_GetVersion
412+
func.argtypes = (BadType,)
413+
414+
with self.assertRaises(ctypes.ArgumentError):
415+
func(object())
406416

407417
class PointerTypeCacheTestCase(unittest.TestCase):
408418
# dummy tests to check warnings and base behavior

0 commit comments

Comments
 (0)