Skip to content

Commit 6d45a72

Browse files
authored
Merge branch 'main' into fix-issue-95371
2 parents a107c68 + 7c72c1f commit 6d45a72

File tree

18 files changed

+231
-104
lines changed

18 files changed

+231
-104
lines changed

Doc/library/calendar.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,14 @@ interpreted as prescribed by the ISO 8601 standard. Year 0 is 1 BC, year -1 is
138138

139139
:class:`TextCalendar` instances have the following methods:
140140

141+
.. method:: formatweek(theweek, w=0)
142+
143+
Return a single week in a string with no newline. If *w* is provided, it
144+
specifies the width of the date columns, which are centered. Depends
145+
on the first weekday as specified in the constructor or set by the
146+
:meth:`setfirstweekday` method.
147+
148+
141149
.. method:: formatmonth(theyear, themonth, w=0, l=0)
142150

143151
Return a month's calendar in a multi-line string. If *w* is provided, it

Doc/whatsnew/3.14.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -614,8 +614,8 @@ sys
614614
sys.monitoring
615615
--------------
616616

617-
Two new events are added: :monitoring-event:`BRANCH_LEFT` and
618-
:monitoring-event:`BRANCH_RIGHT`. The ``BRANCH`` event is deprecated.
617+
* Two new events are added: :monitoring-event:`BRANCH_LEFT` and
618+
:monitoring-event:`BRANCH_RIGHT`. The ``BRANCH`` event is deprecated.
619619

620620
tkinter
621621
-------

Include/internal/pycore_uop_metadata.h

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

Lib/copy.py

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,15 @@ def copy(x):
6767

6868
cls = type(x)
6969

70-
copier = _copy_dispatch.get(cls)
71-
if copier:
72-
return copier(x)
70+
if cls in _copy_atomic_types:
71+
return x
72+
if cls in _copy_builtin_containers:
73+
return cls.copy(x)
74+
7375

7476
if issubclass(cls, type):
7577
# treat it as a regular class:
76-
return _copy_immutable(x)
78+
return x
7779

7880
copier = getattr(cls, "__copy__", None)
7981
if copier is not None:
@@ -98,23 +100,12 @@ def copy(x):
98100
return _reconstruct(x, None, *rv)
99101

100102

101-
_copy_dispatch = d = {}
102-
103-
def _copy_immutable(x):
104-
return x
105-
for t in (types.NoneType, int, float, bool, complex, str, tuple,
103+
_copy_atomic_types = {types.NoneType, int, float, bool, complex, str, tuple,
106104
bytes, frozenset, type, range, slice, property,
107105
types.BuiltinFunctionType, types.EllipsisType,
108106
types.NotImplementedType, types.FunctionType, types.CodeType,
109-
weakref.ref, super):
110-
d[t] = _copy_immutable
111-
112-
d[list] = list.copy
113-
d[dict] = dict.copy
114-
d[set] = set.copy
115-
d[bytearray] = bytearray.copy
116-
117-
del d, t
107+
weakref.ref, super}
108+
_copy_builtin_containers = {list, dict, set, bytearray}
118109

119110
def deepcopy(x, memo=None, _nil=[]):
120111
"""Deep copy operation on arbitrary Python objects.

Lib/subprocess.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ def _text_encoding():
386386

387387
def call(*popenargs, timeout=None, **kwargs):
388388
"""Run command with arguments. Wait for command to complete or
389-
timeout, then return the returncode attribute.
389+
for timeout seconds, then return the returncode attribute.
390390
391391
The arguments are the same as for the Popen constructor. Example:
392392
@@ -523,8 +523,8 @@ def run(*popenargs,
523523
in the returncode attribute, and output & stderr attributes if those streams
524524
were captured.
525525
526-
If timeout is given, and the process takes too long, a TimeoutExpired
527-
exception will be raised.
526+
If timeout (seconds) is given and the process takes too long,
527+
a TimeoutExpired exception will be raised.
528528
529529
There is an optional argument "input", allowing you to
530530
pass bytes or a string to the subprocess's stdin. If you use this argument

Lib/test/test_pydoc/test_pydoc.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ class A(builtins.object)
7979
class B(builtins.object)
8080
| Methods defined here:
8181
|
82-
| __annotate__(...)
82+
| __annotate__(format, /)
8383
|
8484
| ----------------------------------------------------------------------
8585
| Data descriptors defined here:
@@ -180,7 +180,7 @@ class A(builtins.object)
180180
181181
class B(builtins.object)
182182
Methods defined here:
183-
__annotate__(...)
183+
__annotate__(format, /)
184184
----------------------------------------------------------------------
185185
Data descriptors defined here:
186186
__dict__

Lib/test/test_type_annotations.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import annotationlib
2+
import inspect
23
import textwrap
34
import types
45
import unittest
@@ -380,6 +381,11 @@ class X:
380381
annotate(None)
381382
self.assertEqual(annotate(annotationlib.Format.VALUE), {"x": int})
382383

384+
sig = inspect.signature(annotate)
385+
self.assertEqual(sig, inspect.Signature([
386+
inspect.Parameter("format", inspect.Parameter.POSITIONAL_ONLY)
387+
]))
388+
383389
def test_comprehension_in_annotation(self):
384390
# This crashed in an earlier version of the code
385391
ns = run_code("x: [y for y in range(10)]")
@@ -400,6 +406,7 @@ def f(x: int) -> int: pass
400406

401407
def test_name_clash_with_format(self):
402408
# this test would fail if __annotate__'s parameter was called "format"
409+
# during symbol table construction
403410
code = """
404411
class format: pass
405412
@@ -408,3 +415,45 @@ def f(x: format): pass
408415
ns = run_code(code)
409416
f = ns["f"]
410417
self.assertEqual(f.__annotations__, {"x": ns["format"]})
418+
419+
code = """
420+
class Outer:
421+
class format: pass
422+
423+
def meth(self, x: format): ...
424+
"""
425+
ns = run_code(code)
426+
self.assertEqual(ns["Outer"].meth.__annotations__, {"x": ns["Outer"].format})
427+
428+
code = """
429+
def f(format):
430+
def inner(x: format): pass
431+
return inner
432+
res = f("closure var")
433+
"""
434+
ns = run_code(code)
435+
self.assertEqual(ns["res"].__annotations__, {"x": "closure var"})
436+
437+
code = """
438+
def f(x: format):
439+
pass
440+
"""
441+
ns = run_code(code)
442+
# picks up the format() builtin
443+
self.assertEqual(ns["f"].__annotations__, {"x": format})
444+
445+
code = """
446+
def outer():
447+
def f(x: format):
448+
pass
449+
if False:
450+
class format: pass
451+
return f
452+
f = outer()
453+
"""
454+
ns = run_code(code)
455+
with self.assertRaisesRegex(
456+
NameError,
457+
"cannot access free variable 'format' where it is not associated with a value in enclosing scope",
458+
):
459+
ns["f"].__annotations__
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Set ``LIBS`` instead of ``LDFLAGS`` when checking if :mod:`sqlite3` library
2+
functions are available. This fixes the ordering of linked libraries during
3+
checks, which was incorrect when using a statically linked ``libsqlite3``.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Improve performance of :func:`copy.copy` by 30% via
2+
a fast path for atomic types and container types.

0 commit comments

Comments
 (0)