Skip to content

Commit 7549a92

Browse files
authored
Merge pull request #510 from python/main
Sync Fork from Upstream Repo
2 parents b3cd50d + 1d08d85 commit 7549a92

27 files changed

Lines changed: 213 additions & 203 deletions

Doc/library/atexit.rst

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,12 @@ internal error is detected, or when :func:`os._exit` is called.
4848

4949
.. function:: unregister(func)
5050

51-
Remove *func* from the list of functions to be run at interpreter
52-
shutdown. After calling :func:`unregister`, *func* is guaranteed not to be
53-
called when the interpreter shuts down, even if it was registered more than
54-
once. :func:`unregister` silently does nothing if *func* was not previously
55-
registered.
51+
Remove *func* from the list of functions to be run at interpreter shutdown.
52+
:func:`unregister` silently does nothing if *func* was not previously
53+
registered. If *func* has been registered more than once, every occurrence
54+
of that function in the :mod:`atexit` call stack will be removed. Equality
55+
comparisons (``==``) are used internally during unregistration, so function
56+
references do not need to have matching identities.
5657

5758

5859
.. seealso::

Doc/library/contextlib.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,10 @@ Functions and classes provided:
515515
These context managers may suppress exceptions just as they normally
516516
would if used directly as part of a :keyword:`with` statement.
517517

518+
... versionchanged:: 3.11
519+
Raises :exc:`TypeError` instead of :exc:`AttributeError` if *cm*
520+
is not a context manager.
521+
518522
.. method:: push(exit)
519523

520524
Adds a context manager's :meth:`__exit__` method to the callback stack.
@@ -585,6 +589,10 @@ Functions and classes provided:
585589
Similar to :meth:`enter_context` but expects an asynchronous context
586590
manager.
587591

592+
... versionchanged:: 3.11
593+
Raises :exc:`TypeError` instead of :exc:`AttributeError` if *cm*
594+
is not an asynchronous context manager.
595+
588596
.. method:: push_async_exit(exit)
589597

590598
Similar to :meth:`push` but expects either an asynchronous context manager

Doc/library/graphlib.rst

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -154,9 +154,10 @@
154154

155155
.. method:: static_order()
156156

157-
Returns an iterable of nodes in a topological order. Using this method
158-
does not require to call :meth:`TopologicalSorter.prepare` or
159-
:meth:`TopologicalSorter.done`. This method is equivalent to::
157+
Returns an iterator object which will iterate over nodes in a topological
158+
order. When using this method, :meth:`~TopologicalSorter.prepare` and
159+
:meth:`~TopologicalSorter.done` should not be called. This method is
160+
equivalent to::
160161

161162
def static_order(self):
162163
self.prepare()
@@ -206,4 +207,4 @@ The :mod:`graphlib` module defines the following exception classes:
206207
The detected cycle can be accessed via the second element in the :attr:`~CycleError.args`
207208
attribute of the exception instance and consists in a list of nodes, such that each node is,
208209
in the graph, an immediate predecessor of the next node in the list. In the reported list,
209-
the first and the last node will be the same, to make it clear that it is cyclic.
210+
the first and the last node will be the same, to make it clear that it is cyclic.

Doc/tutorial/controlflow.rst

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -110,14 +110,14 @@ The given end point is never part of the generated sequence; ``range(10)`` gener
110110
is possible to let the range start at another number, or to specify a different
111111
increment (even negative; sometimes this is called the 'step')::
112112

113-
range(5, 10)
114-
5, 6, 7, 8, 9
113+
>>> list(range(5, 10))
114+
[5, 6, 7, 8, 9]
115115

116-
range(0, 10, 3)
117-
0, 3, 6, 9
116+
>>> list(range(0, 10, 3))
117+
[0, 3, 6, 9]
118118

119-
range(-10, -100, -30)
120-
-10, -40, -70
119+
>>> list(range(-10, -100, -30))
120+
[-10, -40, -70]
121121

122122
To iterate over the indices of a sequence, you can combine :func:`range` and
123123
:func:`len` as follows::
@@ -137,7 +137,7 @@ function, see :ref:`tut-loopidioms`.
137137

138138
A strange thing happens if you just print a range::
139139

140-
>>> print(range(10))
140+
>>> range(10)
141141
range(0, 10)
142142

143143
In many ways the object returned by :func:`range` behaves as if it is a list,
@@ -155,13 +155,7 @@ that takes an iterable is :func:`sum`::
155155
6
156156

157157
Later we will see more functions that return iterables and take iterables as
158-
arguments. Lastly, maybe you are curious about how to get a list from a range.
159-
Here is the solution::
160-
161-
>>> list(range(4))
162-
[0, 1, 2, 3]
163-
164-
In chapter :ref:`tut-structures`, we will discuss in more detail about
158+
arguments. In chapter :ref:`tut-structures`, we will discuss in more detail about
165159
:func:`list`.
166160

167161
.. _tut-break:

Doc/whatsnew/3.10.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ have been incorporated. Some of the most notable ones are as follows:
278278
279279
.. code-block:: python
280280
281-
>>> try
281+
>>> try:
282282
... x = 2
283283
... something = 3
284284
File "<stdin>", line 3
@@ -1084,7 +1084,7 @@ and will be incorrect in some rare cases, including some ``_``-s in
10841084
importlib.metadata
10851085
------------------
10861086
1087-
Feature parity with ``importlib_metadata`` 4.4
1087+
Feature parity with ``importlib_metadata`` 4.6
10881088
(`history <https://importlib-metadata.readthedocs.io/en/latest/history.html>`_).
10891089
10901090
:ref:`importlib.metadata entry points <entry-points>`

Doc/whatsnew/3.11.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,18 @@ New Features
7575
Other Language Changes
7676
======================
7777

78+
A :exc:`TypeError` is now raised instead of an :exc:`AttributeError` in
79+
:meth:`contextlib.ExitStack.enter_context` and
80+
:meth:`contextlib.AsyncExitStack.enter_async_context` for objects which do not
81+
support the :term:`context manager` or :term:`asynchronous context manager`
82+
protocols correspondingly.
83+
(Contributed by Serhiy Storchaka in :issue:`44471`.)
84+
85+
* A :exc:`TypeError` is now raised instead of an :exc:`AttributeError` in
86+
:keyword:`with` and :keyword:`async with` statements for objects which do not
87+
support the :term:`context manager` or :term:`asynchronous context manager`
88+
protocols correspondingly.
89+
(Contributed by Serhiy Storchaka in :issue:`12022`.)
7890

7991

8092
New Modules

Lib/abc.py

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,14 @@ def my_abstract_method(self, ...):
2828
class abstractclassmethod(classmethod):
2929
"""A decorator indicating abstract classmethods.
3030
31-
Deprecated, use 'classmethod' with 'abstractmethod' instead.
31+
Deprecated, use 'classmethod' with 'abstractmethod' instead:
32+
33+
class C(ABC):
34+
@classmethod
35+
@abstractmethod
36+
def my_abstract_classmethod(cls, ...):
37+
...
38+
3239
"""
3340

3441
__isabstractmethod__ = True
@@ -41,7 +48,14 @@ def __init__(self, callable):
4148
class abstractstaticmethod(staticmethod):
4249
"""A decorator indicating abstract staticmethods.
4350
44-
Deprecated, use 'staticmethod' with 'abstractmethod' instead.
51+
Deprecated, use 'staticmethod' with 'abstractmethod' instead:
52+
53+
class C(ABC):
54+
@staticmethod
55+
@abstractmethod
56+
def my_abstract_staticmethod(...):
57+
...
58+
4559
"""
4660

4761
__isabstractmethod__ = True
@@ -54,7 +68,14 @@ def __init__(self, callable):
5468
class abstractproperty(property):
5569
"""A decorator indicating abstract properties.
5670
57-
Deprecated, use 'property' with 'abstractmethod' instead.
71+
Deprecated, use 'property' with 'abstractmethod' instead:
72+
73+
class C(ABC):
74+
@property
75+
@abstractmethod
76+
def my_abstract_property(self):
77+
...
78+
5879
"""
5980

6081
__isabstractmethod__ = True

Lib/asyncio/trsock.py

Lines changed: 0 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import socket
2-
import warnings
32

43

54
class TransportSocket:
@@ -16,13 +15,6 @@ class TransportSocket:
1615
def __init__(self, sock: socket.socket):
1716
self._sock = sock
1817

19-
def _na(self, what):
20-
warnings.warn(
21-
f"Using {what} on sockets returned from get_extra_info('socket') "
22-
f"will be prohibited in asyncio 3.9. Please report your use case "
23-
f"to bugs.python.org.",
24-
DeprecationWarning, source=self)
25-
2618
@property
2719
def family(self):
2820
return self._sock.family
@@ -90,98 +82,6 @@ def getsockname(self):
9082
def getsockbyname(self):
9183
return self._sock.getsockbyname()
9284

93-
def accept(self):
94-
self._na('accept() method')
95-
return self._sock.accept()
96-
97-
def connect(self, *args, **kwargs):
98-
self._na('connect() method')
99-
return self._sock.connect(*args, **kwargs)
100-
101-
def connect_ex(self, *args, **kwargs):
102-
self._na('connect_ex() method')
103-
return self._sock.connect_ex(*args, **kwargs)
104-
105-
def bind(self, *args, **kwargs):
106-
self._na('bind() method')
107-
return self._sock.bind(*args, **kwargs)
108-
109-
def ioctl(self, *args, **kwargs):
110-
self._na('ioctl() method')
111-
return self._sock.ioctl(*args, **kwargs)
112-
113-
def listen(self, *args, **kwargs):
114-
self._na('listen() method')
115-
return self._sock.listen(*args, **kwargs)
116-
117-
def makefile(self):
118-
self._na('makefile() method')
119-
return self._sock.makefile()
120-
121-
def sendfile(self, *args, **kwargs):
122-
self._na('sendfile() method')
123-
return self._sock.sendfile(*args, **kwargs)
124-
125-
def close(self):
126-
self._na('close() method')
127-
return self._sock.close()
128-
129-
def detach(self):
130-
self._na('detach() method')
131-
return self._sock.detach()
132-
133-
def sendmsg_afalg(self, *args, **kwargs):
134-
self._na('sendmsg_afalg() method')
135-
return self._sock.sendmsg_afalg(*args, **kwargs)
136-
137-
def sendmsg(self, *args, **kwargs):
138-
self._na('sendmsg() method')
139-
return self._sock.sendmsg(*args, **kwargs)
140-
141-
def sendto(self, *args, **kwargs):
142-
self._na('sendto() method')
143-
return self._sock.sendto(*args, **kwargs)
144-
145-
def send(self, *args, **kwargs):
146-
self._na('send() method')
147-
return self._sock.send(*args, **kwargs)
148-
149-
def sendall(self, *args, **kwargs):
150-
self._na('sendall() method')
151-
return self._sock.sendall(*args, **kwargs)
152-
153-
def set_inheritable(self, *args, **kwargs):
154-
self._na('set_inheritable() method')
155-
return self._sock.set_inheritable(*args, **kwargs)
156-
157-
def share(self, process_id):
158-
self._na('share() method')
159-
return self._sock.share(process_id)
160-
161-
def recv_into(self, *args, **kwargs):
162-
self._na('recv_into() method')
163-
return self._sock.recv_into(*args, **kwargs)
164-
165-
def recvfrom_into(self, *args, **kwargs):
166-
self._na('recvfrom_into() method')
167-
return self._sock.recvfrom_into(*args, **kwargs)
168-
169-
def recvmsg_into(self, *args, **kwargs):
170-
self._na('recvmsg_into() method')
171-
return self._sock.recvmsg_into(*args, **kwargs)
172-
173-
def recvmsg(self, *args, **kwargs):
174-
self._na('recvmsg() method')
175-
return self._sock.recvmsg(*args, **kwargs)
176-
177-
def recvfrom(self, *args, **kwargs):
178-
self._na('recvfrom() method')
179-
return self._sock.recvfrom(*args, **kwargs)
180-
181-
def recv(self, *args, **kwargs):
182-
self._na('recv() method')
183-
return self._sock.recv(*args, **kwargs)
184-
18585
def settimeout(self, value):
18686
if value == 0:
18787
return
@@ -196,11 +96,3 @@ def setblocking(self, flag):
19696
return
19797
raise ValueError(
19898
'setblocking(): transport sockets cannot be blocking')
199-
200-
def __enter__(self):
201-
self._na('context manager protocol')
202-
return self._sock.__enter__()
203-
204-
def __exit__(self, *err):
205-
self._na('context manager protocol')
206-
return self._sock.__exit__(*err)

Lib/contextlib.py

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -473,9 +473,14 @@ def enter_context(self, cm):
473473
"""
474474
# We look up the special methods on the type to match the with
475475
# statement.
476-
_cm_type = type(cm)
477-
_exit = _cm_type.__exit__
478-
result = _cm_type.__enter__(cm)
476+
cls = type(cm)
477+
try:
478+
_enter = cls.__enter__
479+
_exit = cls.__exit__
480+
except AttributeError:
481+
raise TypeError(f"'{cls.__module__}.{cls.__qualname__}' object does "
482+
f"not support the context manager protocol") from None
483+
result = _enter(cm)
479484
self._push_cm_exit(cm, _exit)
480485
return result
481486

@@ -600,9 +605,15 @@ async def enter_async_context(self, cm):
600605
If successful, also pushes its __aexit__ method as a callback and
601606
returns the result of the __aenter__ method.
602607
"""
603-
_cm_type = type(cm)
604-
_exit = _cm_type.__aexit__
605-
result = await _cm_type.__aenter__(cm)
608+
cls = type(cm)
609+
try:
610+
_enter = cls.__aenter__
611+
_exit = cls.__aexit__
612+
except AttributeError:
613+
raise TypeError(f"'{cls.__module__}.{cls.__qualname__}' object does "
614+
f"not support the asynchronous context manager protocol"
615+
) from None
616+
result = await _enter(cm)
606617
self._push_async_cm_exit(cm, _exit)
607618
return result
608619

Lib/importlib/metadata/__init__.py

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -362,14 +362,6 @@ def _parse_groups(text):
362362
)
363363

364364

365-
def flake8_bypass(func):
366-
# defer inspect import as performance optimization.
367-
import inspect
368-
369-
is_flake8 = any('flake8' in str(frame.filename) for frame in inspect.stack()[:5])
370-
return func if not is_flake8 else lambda: None
371-
372-
373365
class Deprecated:
374366
"""
375367
Compatibility add-in for mapping to indicate that
@@ -405,7 +397,7 @@ def __getitem__(self, name):
405397
return super().__getitem__(name)
406398

407399
def get(self, name, default=None):
408-
flake8_bypass(self._warn)()
400+
self._warn()
409401
return super().get(name, default)
410402

411403
def __iter__(self):

0 commit comments

Comments
 (0)