Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions Doc/library/asyncio-api-index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -203,11 +203,6 @@ Exceptions
:class: full-width-table


* - :exc:`asyncio.TimeoutError`
- Raised on timeout by functions like :func:`wait_for`.
Keep in mind that ``asyncio.TimeoutError`` is **unrelated**
to the built-in :exc:`TimeoutError` exception.

* - :exc:`asyncio.CancelledError`
- Raised when a Task is cancelled. See also :meth:`Task.cancel`.

Expand Down
9 changes: 5 additions & 4 deletions Doc/library/asyncio-exceptions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@ Exceptions

.. exception:: TimeoutError

The operation has exceeded the given deadline.
A deprecated alias of :exc:`TimeoutError`,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you can to deprecated it, you need to add the ".. deprecated::" markup. For now, I suggest to keep it. There is no need to remove the alias.

In Python 3.10, we kept the IOError alias, even if it's no longer used.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The text was copyed from @tiran PR about replacing a custom socket.timeout exception with an alias to TimeoutError: https://github.com/python/cpython/pull/23413/files#diff-e9e93d6b76a8a1cf0825d557b12e7ce3e67081cad650063eee520b81fd651943R286

I can change it to something else if you insist.

raised when the operation has exceeded the given deadline.

.. important::
This exception is different from the builtin :exc:`TimeoutError`
exception.
.. versionchanged:: 3.10

This class was made an alias of :exc:`TimeoutError`.


.. exception:: CancelledError
Expand Down
12 changes: 6 additions & 6 deletions Doc/library/asyncio-task.rst
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,7 @@ Timeouts
completes.

If a timeout occurs, it cancels the task and raises
:exc:`asyncio.TimeoutError`.
:exc:`TimeoutError`.

To avoid the task :meth:`cancellation <Task.cancel>`,
wrap it in :func:`shield`.
Expand All @@ -482,7 +482,7 @@ Timeouts
# Wait for at most 1 second
try:
await asyncio.wait_for(eternity(), timeout=1.0)
except asyncio.TimeoutError:
except TimeoutError:
print('timeout!')

asyncio.run(main())
Expand All @@ -494,7 +494,7 @@ Timeouts
.. versionchanged:: 3.7
When *aw* is cancelled due to a timeout, ``wait_for`` waits
for *aw* to be cancelled. Previously, it raised
:exc:`asyncio.TimeoutError` immediately.
:exc:`TimeoutError` immediately.


Waiting Primitives
Expand All @@ -518,7 +518,7 @@ Waiting Primitives
*timeout* (a float or int), if specified, can be used to control
the maximum number of seconds to wait before returning.

Note that this function does not raise :exc:`asyncio.TimeoutError`.
Note that this function does not raise :exc:`TimeoutError`.
Futures or Tasks that aren't done when the timeout occurs are simply
returned in the second set.

Expand Down Expand Up @@ -597,7 +597,7 @@ Waiting Primitives
Each coroutine returned can be awaited to get the earliest next
result from the iterable of the remaining awaitables.

Raises :exc:`asyncio.TimeoutError` if the timeout occurs before
Raises :exc:`TimeoutError` if the timeout occurs before
all Futures are done.

.. deprecated-removed:: 3.8 3.10
Expand Down Expand Up @@ -697,7 +697,7 @@ Scheduling From Other Threads

try:
result = future.result(timeout)
except asyncio.TimeoutError:
except TimeoutError:
print('The coroutine took too long, cancelling the task...')
future.cancel()
except Exception as exc:
Expand Down
16 changes: 11 additions & 5 deletions Doc/library/concurrent.futures.rst
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ Executor Objects
* *func* is executed asynchronously and several calls to
*func* may be made concurrently.

The returned iterator raises a :exc:`concurrent.futures.TimeoutError`
The returned iterator raises a :exc:`TimeoutError`
if :meth:`~iterator.__next__` is called and the result isn't available
after *timeout* seconds from the original call to :meth:`Executor.map`.
*timeout* can be an int or a float. If *timeout* is not specified or
Expand Down Expand Up @@ -343,7 +343,7 @@ The :class:`Future` class encapsulates the asynchronous execution of a callable.
Return the value returned by the call. If the call hasn't yet completed
then this method will wait up to *timeout* seconds. If the call hasn't
completed in *timeout* seconds, then a
:exc:`concurrent.futures.TimeoutError` will be raised. *timeout* can be
:exc:`TimeoutError` will be raised. *timeout* can be
an int or float. If *timeout* is not specified or ``None``, there is no
limit to the wait time.

Expand All @@ -357,7 +357,7 @@ The :class:`Future` class encapsulates the asynchronous execution of a callable.
Return the exception raised by the call. If the call hasn't yet
completed then this method will wait up to *timeout* seconds. If the
call hasn't completed in *timeout* seconds, then a
:exc:`concurrent.futures.TimeoutError` will be raised. *timeout* can be
:exc:`TimeoutError` will be raised. *timeout* can be
an int or float. If *timeout* is not specified or ``None``, there is no
limit to the wait time.

Expand Down Expand Up @@ -473,7 +473,7 @@ Module Functions
they complete (finished or cancelled futures). Any futures given by *fs* that
are duplicated will be returned once. Any futures that completed before
:func:`as_completed` is called will be yielded first. The returned iterator
raises a :exc:`concurrent.futures.TimeoutError` if :meth:`~iterator.__next__`
raises a :exc:`TimeoutError` if :meth:`~iterator.__next__`
is called and the result isn't available after *timeout* seconds from the
original call to :func:`as_completed`. *timeout* can be an int or float. If
*timeout* is not specified or ``None``, there is no limit to the wait time.
Expand All @@ -497,7 +497,13 @@ Exception classes

.. exception:: TimeoutError

Raised when a future operation exceeds the given timeout.
A deprecated alias of :exc:`TimeoutError`,
raised when a future operation exceeds the given timeout.

.. versionchanged:: 3.10

This class was made an alias of :exc:`TimeoutError`.


.. exception:: BrokenExecutor

Expand Down
13 changes: 13 additions & 0 deletions Doc/whatsnew/3.10.rst
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,12 @@ New Modules
Improved Modules
================

asyncio
-------

The exception :exc:`asyncio.TimeoutError` is now an alias of :exc:`TimeoutError`.
(Contributed by Andrew Svetlov in :issue:`42413`.)

base64
------

Expand All @@ -179,6 +185,13 @@ codecs
Add a :func:`codecs.unregister` function to unregister a codec search function.
(Contributed by Hai Shi in :issue:`41842`.)

concurrent.futures
------------------

The exception :exc:`concurrent.futures.TimeoutError` is now
an alias of :exc:`TimeoutError`.
(Contributed by Andrew Svetlov in :issue:`42413`.)

contextlib
----------

Expand Down
3 changes: 1 addition & 2 deletions Lib/asyncio/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ class CancelledError(BaseException):
"""The Future or Task was cancelled."""


class TimeoutError(Exception):
"""The operation exceeded the given deadline."""
TimeoutError = TimeoutError # make local alias for the standard exception

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to move this one to asyncio/__init__.py?

Please mention "bpo-42413:" in the comment. Like:

# bpo-42413: asyncio.TimeoutError is now an alias to the builtin TimeoutError exception.
TimeoutError = TimeoutError

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can but it increases a chance of backward incompatibility.
People still can use from asyncio.exceptions import TimeoutError.
I dislike this style and strive to avoid it personally, but I recall a lot of third-party code that uses such imports.

The main reason is that IDE or another tool can insert obj.__class__.__module__ when applies 'autoimport' to the edited python file.
PyCharm, for example, changed this behavior to substitute the top-most name (perform a lookup in __init__.py for the package) about a year ago after I discussed the feature with PyCharm devs at US PyCon 2019.
I'm not sure what other tools do.
Ideally, we can add some trick with module-level __getattr__ to raise a warning about bad usage but I'm really not sure if we should do it this PR.



class InvalidStateError(Exception):
Expand Down
5 changes: 1 addition & 4 deletions Lib/concurrent/futures/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,7 @@ class CancelledError(Error):
"""The Future was cancelled."""
pass

class TimeoutError(Error):
"""The operation exceeded the given deadline."""
pass

TimeoutError = TimeoutError # make local alias for the standard exception

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same remark, can it be moved to __init__.py and mention the bpo in the comment?

class InvalidStateError(Error):
"""The operation is not allowed in this state."""
pass
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Replace ``concurrent.futures.TimeoutError`` and ``asyncio.TimeoutError``
with builtin :exc:`TimeoutError`, keep these names as deprecated aliases.