Skip to content

Commit 59672cf

Browse files
committed
Merge remote-tracking branch 'upstream/main' into feat/binary_shift_optimization
2 parents c24ad0a + 360fedc commit 59672cf

23 files changed

+176
-54
lines changed

‎Doc/library/io.rst‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ explicitly when opening text files. If you want to use UTF-8, pass
131131
``encoding="utf-8"``. To use the current locale encoding,
132132
``encoding="locale"`` is supported in Python 3.10.
133133

134-
When you need to run existing code on Windows that attempts to opens
134+
When you need to run existing code on Windows that attempts to open
135135
UTF-8 files using the default locale encoding, you can enable the UTF-8
136136
mode. See :ref:`UTF-8 mode on Windows <win-utf8-mode>`.
137137

‎Doc/library/typing.rst‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -625,7 +625,7 @@ These can be used as types in annotations using ``[]``, each having a unique syn
625625

626626
Union type; ``Union[X, Y]`` is equivalent to ``X | Y`` and means either X or Y.
627627

628-
To define a union, use e.g. ``Union[int, str]`` or the shorthand ``int | str``. Details:
628+
To define a union, use e.g. ``Union[int, str]`` or the shorthand ``int | str``. Using that shorthand is recommended. Details:
629629

630630
* The arguments must be types and there must be at least one.
631631

‎Doc/library/unittest.mock.rst‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1516,7 +1516,7 @@ attribute in a class) that does not exist will fail with :exc:`AttributeError`::
15161516
>>> test()
15171517
Traceback (most recent call last):
15181518
...
1519-
AttributeError: <module 'sys' (built-in)> does not have the attribute 'non_existing'
1519+
AttributeError: <module 'sys' (built-in)> does not have the attribute 'non_existing_attribute'
15201520

15211521
but adding ``create=True`` in the call to :func:`patch` will make the previous example
15221522
work as expected::

‎Doc/whatsnew/3.10.rst‎

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1437,7 +1437,7 @@ and to match the behavior of static type checkers specified in the PEP.
14371437
14381438
1. ``Literal`` now de-duplicates parameters.
14391439
2. Equality comparisons between ``Literal`` objects are now order independent.
1440-
3. ``Literal`` comparisons now respects types. For example,
1440+
3. ``Literal`` comparisons now respect types. For example,
14411441
``Literal[0] == Literal[False]`` previously evaluated to ``True``. It is
14421442
now ``False``. To support this change, the internally used type cache now
14431443
supports differentiating types.
@@ -1647,13 +1647,12 @@ Deprecated
16471647
:meth:`importlib.machinery.FrozenImporter.find_module`,
16481648
:meth:`importlib.machinery.WindowsRegistryFinder.find_module`,
16491649
:meth:`importlib.machinery.PathFinder.find_module`,
1650-
:meth:`importlib.abc.MetaPathFinder.find_module`),
1650+
:meth:`importlib.abc.MetaPathFinder.find_module` ),
16511651
:meth:`importlib.abc.PathEntryFinder.find_module` (
1652-
:meth:`importlib.machinery.FileFinder.find_module`,
1653-
), and
1652+
:meth:`importlib.machinery.FileFinder.find_module` ), and
16541653
:meth:`importlib.abc.PathEntryFinder.find_loader` (
1655-
:meth:`importlib.machinery.FileFinder.find_loader`
1656-
) now raise :exc:`DeprecationWarning` and are slated for removal in
1654+
:meth:`importlib.machinery.FileFinder.find_loader` )
1655+
now raise :exc:`DeprecationWarning` and are slated for removal in
16571656
Python 3.12 (previously they were documented as deprecated in Python 3.4).
16581657
(Contributed by Brett Cannon in :issue:`42135`.)
16591658
@@ -1694,7 +1693,7 @@ Deprecated
16941693
* :func:`asyncio.get_event_loop` now emits a deprecation warning if there is
16951694
no running event loop. In the future it will be an alias of
16961695
:func:`~asyncio.get_running_loop`.
1697-
:mod:`asyncio` functions which implicitly create a :class:`~asyncio.Future`
1696+
:mod:`asyncio` functions which implicitly create :class:`~asyncio.Future`
16981697
or :class:`~asyncio.Task` objects now emit
16991698
a deprecation warning if there is no running event loop and no explicit
17001699
*loop* argument is passed: :func:`~asyncio.ensure_future`,
@@ -1834,7 +1833,7 @@ Removed
18341833
running in different threads.
18351834
18361835
Note that the low-level API will still accept ``loop``.
1837-
See `Changes in the Python API`_ for examples of how to replace existing code.
1836+
See :ref:`changes-python-api` for examples of how to replace existing code.
18381837
18391838
(Contributed by Yurii Karabas, Andrew Svetlov, Yury Selivanov and Kyle Stanley
18401839
in :issue:`42392`.)
@@ -1858,6 +1857,7 @@ Changes in the Python syntax
18581857
following keyword.
18591858
(Contributed by Serhiy Storchaka in :issue:`43833`).
18601859
1860+
.. _changes-python-api:
18611861
18621862
Changes in the Python API
18631863
-------------------------
@@ -1979,7 +1979,7 @@ Build Changes
19791979
(Contributed by Victor Stinner in :issue:`36020`.)
19801980
19811981
* :mod:`sqlite3` requires SQLite 3.7.15 or higher. (Contributed by Sergey Fedoseev
1982-
and Erlend E. Aasland :issue:`40744` and :issue:`40810`.)
1982+
and Erlend E. Aasland in :issue:`40744` and :issue:`40810`.)
19831983
19841984
* The :mod:`atexit` module must now always be built as a built-in module.
19851985
(Contributed by Victor Stinner in :issue:`42639`.)

‎Lib/asyncio/base_events.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1285,8 +1285,8 @@ async def create_datagram_endpoint(self, protocol_factory,
12851285
addr_infos = {} # Using order preserving dict
12861286
for idx, addr in ((0, local_addr), (1, remote_addr)):
12871287
if addr is not None:
1288-
assert isinstance(addr, tuple) and len(addr) == 2, (
1289-
'2-tuple is expected')
1288+
if not (isinstance(addr, tuple) and len(addr) == 2):
1289+
raise TypeError('2-tuple is expected')
12901290

12911291
infos = await self._ensure_resolved(
12921292
addr, family=family, type=socket.SOCK_DGRAM,

‎Lib/functools.py‎

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -740,6 +740,7 @@ def _compose_mro(cls, types):
740740
# Remove entries which are already present in the __mro__ or unrelated.
741741
def is_related(typ):
742742
return (typ not in bases and hasattr(typ, '__mro__')
743+
and not isinstance(typ, GenericAlias)
743744
and issubclass(cls, typ))
744745
types = [n for n in types if is_related(n)]
745746
# Remove entries which are strict bases of other entries (they will end up
@@ -841,9 +842,13 @@ def _is_union_type(cls):
841842
from typing import get_origin, Union
842843
return get_origin(cls) in {Union, types.UnionType}
843844

844-
def _is_valid_union_type(cls):
845+
def _is_valid_dispatch_type(cls):
846+
if isinstance(cls, type) and not isinstance(cls, GenericAlias):
847+
return True
845848
from typing import get_args
846-
return _is_union_type(cls) and all(isinstance(arg, type) for arg in get_args(cls))
849+
return (_is_union_type(cls) and
850+
all(isinstance(arg, type) and not isinstance(arg, GenericAlias)
851+
for arg in get_args(cls)))
847852

848853
def register(cls, func=None):
849854
"""generic_func.register(cls, func) -> func
@@ -852,9 +857,15 @@ def register(cls, func=None):
852857
853858
"""
854859
nonlocal cache_token
855-
if func is None:
856-
if isinstance(cls, type) or _is_valid_union_type(cls):
860+
if _is_valid_dispatch_type(cls):
861+
if func is None:
857862
return lambda f: register(cls, f)
863+
else:
864+
if func is not None:
865+
raise TypeError(
866+
f"Invalid first argument to `register()`. "
867+
f"{cls!r} is not a class or union type."
868+
)
858869
ann = getattr(cls, '__annotations__', {})
859870
if not ann:
860871
raise TypeError(
@@ -867,7 +878,7 @@ def register(cls, func=None):
867878
# only import typing if annotation parsing is necessary
868879
from typing import get_type_hints
869880
argname, cls = next(iter(get_type_hints(func).items()))
870-
if not isinstance(cls, type) and not _is_valid_union_type(cls):
881+
if not _is_valid_dispatch_type(cls):
871882
if _is_union_type(cls):
872883
raise TypeError(
873884
f"Invalid annotation for {argname!r}. "

‎Lib/test/test_asyncio/test_base_events.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1603,11 +1603,11 @@ def test_create_datagram_endpoint_addr_error(self):
16031603
coro = self.loop.create_datagram_endpoint(
16041604
MyDatagramProto, local_addr='localhost')
16051605
self.assertRaises(
1606-
AssertionError, self.loop.run_until_complete, coro)
1606+
TypeError, self.loop.run_until_complete, coro)
16071607
coro = self.loop.create_datagram_endpoint(
16081608
MyDatagramProto, local_addr=('localhost', 1, 2, 3))
16091609
self.assertRaises(
1610-
AssertionError, self.loop.run_until_complete, coro)
1610+
TypeError, self.loop.run_until_complete, coro)
16111611

16121612
def test_create_datagram_endpoint_connect_err(self):
16131613
self.loop.sock_connect = mock.Mock()

‎Lib/test/test_asyncio/test_proactor_events.py‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ def test_loop_reading_data(self):
7777
self.loop._proactor.recv_into.assert_called_with(self.sock, called_buf)
7878
self.protocol.data_received.assert_called_with(bytearray(buf))
7979

80+
@unittest.skipIf(sys.flags.optimize, "Assertions are disabled in optimized mode")
8081
def test_loop_reading_no_data(self):
8182
res = self.loop.create_future()
8283
res.set_result(0)
@@ -869,6 +870,7 @@ def test_datagram_loop_reading_data(self):
869870
self.protocol.datagram_received.assert_called_with(b'data', ('127.0.0.1', 12068))
870871
close_transport(tr)
871872

873+
@unittest.skipIf(sys.flags.optimize, "Assertions are disabled in optimized mode")
872874
def test_datagram_loop_reading_no_data(self):
873875
res = self.loop.create_future()
874876
res.set_result((b'', ('127.0.0.1', 12068)))

‎Lib/test/test_asyncio/test_selector_events.py‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"""Tests for selector_events.py"""
22

3+
import sys
34
import selectors
45
import socket
56
import unittest
@@ -804,6 +805,7 @@ def test_write_ready_closing(self):
804805
self.sock.close.assert_called_with()
805806
self.protocol.connection_lost.assert_called_with(None)
806807

808+
@unittest.skipIf(sys.flags.optimize, "Assertions are disabled in optimized mode")
807809
def test_write_ready_no_data(self):
808810
transport = self.socket_transport()
809811
# This is an internal error.

‎Lib/test/test_functools.py‎

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2722,6 +2722,74 @@ def _(arg: int | float):
27222722
self.assertEqual(f(1), "types.UnionType")
27232723
self.assertEqual(f(1.0), "types.UnionType")
27242724

2725+
def test_register_genericalias(self):
2726+
@functools.singledispatch
2727+
def f(arg):
2728+
return "default"
2729+
2730+
with self.assertRaisesRegex(TypeError, "Invalid first argument to "):
2731+
f.register(list[int], lambda arg: "types.GenericAlias")
2732+
with self.assertRaisesRegex(TypeError, "Invalid first argument to "):
2733+
f.register(typing.List[int], lambda arg: "typing.GenericAlias")
2734+
with self.assertRaisesRegex(TypeError, "Invalid first argument to "):
2735+
f.register(list[int] | str, lambda arg: "types.UnionTypes(types.GenericAlias)")
2736+
with self.assertRaisesRegex(TypeError, "Invalid first argument to "):
2737+
f.register(typing.List[float] | bytes, lambda arg: "typing.Union[typing.GenericAlias]")
2738+
with self.assertRaisesRegex(TypeError, "Invalid first argument to "):
2739+
f.register(typing.Any, lambda arg: "typing.Any")
2740+
2741+
self.assertEqual(f([1]), "default")
2742+
self.assertEqual(f([1.0]), "default")
2743+
self.assertEqual(f(""), "default")
2744+
self.assertEqual(f(b""), "default")
2745+
2746+
def test_register_genericalias_decorator(self):
2747+
@functools.singledispatch
2748+
def f(arg):
2749+
return "default"
2750+
2751+
with self.assertRaisesRegex(TypeError, "Invalid first argument to "):
2752+
f.register(list[int])
2753+
with self.assertRaisesRegex(TypeError, "Invalid first argument to "):
2754+
f.register(typing.List[int])
2755+
with self.assertRaisesRegex(TypeError, "Invalid first argument to "):
2756+
f.register(list[int] | str)
2757+
with self.assertRaisesRegex(TypeError, "Invalid first argument to "):
2758+
f.register(typing.List[int] | str)
2759+
with self.assertRaisesRegex(TypeError, "Invalid first argument to "):
2760+
f.register(typing.Any)
2761+
2762+
def test_register_genericalias_annotation(self):
2763+
@functools.singledispatch
2764+
def f(arg):
2765+
return "default"
2766+
2767+
with self.assertRaisesRegex(TypeError, "Invalid annotation for 'arg'"):
2768+
@f.register
2769+
def _(arg: list[int]):
2770+
return "types.GenericAlias"
2771+
with self.assertRaisesRegex(TypeError, "Invalid annotation for 'arg'"):
2772+
@f.register
2773+
def _(arg: typing.List[float]):
2774+
return "typing.GenericAlias"
2775+
with self.assertRaisesRegex(TypeError, "Invalid annotation for 'arg'"):
2776+
@f.register
2777+
def _(arg: list[int] | str):
2778+
return "types.UnionType(types.GenericAlias)"
2779+
with self.assertRaisesRegex(TypeError, "Invalid annotation for 'arg'"):
2780+
@f.register
2781+
def _(arg: typing.List[float] | bytes):
2782+
return "typing.Union[typing.GenericAlias]"
2783+
with self.assertRaisesRegex(TypeError, "Invalid annotation for 'arg'"):
2784+
@f.register
2785+
def _(arg: typing.Any):
2786+
return "typing.Any"
2787+
2788+
self.assertEqual(f([1]), "default")
2789+
self.assertEqual(f([1.0]), "default")
2790+
self.assertEqual(f(""), "default")
2791+
self.assertEqual(f(b""), "default")
2792+
27252793

27262794
class CachedCostItem:
27272795
_cost = 1

0 commit comments

Comments
 (0)