--- /dev/null
+.. change::
+ :tags: bug, asyncio
+ :tickets: 6592
+
+ Added ``asyncio.exceptions.TimeoutError``,
+ ``asyncio.exceptions.CancelledError`` as so-called "exit exceptions", a
+ class of exceptions that include things like ``GreenletExit`` and
+ ``KeyboardInterrupt``, which are considered to be events that warrant
+ considering a DBAPI connection to be in an unusable state where it should
+ be recycled.
):
exc_info = sys.exc_info()
- is_exit_exception = not isinstance(e, Exception)
+ is_exit_exception = util.is_exit_exception(e)
if not self._is_disconnect:
self._is_disconnect = (
phase transactions may be used.
"""
-
try:
self._do_commit()
finally:
from .concurrency import await_fallback
from .concurrency import await_only
from .concurrency import greenlet_spawn
+from .concurrency import is_exit_exception
from .deprecations import deprecated
from .deprecations import deprecated_20
from .deprecations import deprecated_20_cls
from .langhelpers import memoized_property
from .. import exc
-
if compat.py37:
try:
from contextvars import copy_context as _copy_context
_copy_context = None
+def is_exit_exception(e):
+ return not isinstance(e, Exception) or isinstance(
+ e, (asyncio.TimeoutError, asyncio.CancelledError)
+ )
+
+
# implementation based on snaury gist at
# https://gist.github.com/snaury/202bf4f22c41ca34e56297bae5f33fef
# Issue for context: https://github.com/python-greenlet/greenlet/issues/173
from ._concurrency_py3k import await_only
from ._concurrency_py3k import await_fallback
from ._concurrency_py3k import greenlet_spawn
+ from ._concurrency_py3k import is_exit_exception
from ._concurrency_py3k import AsyncAdaptedLock
from ._concurrency_py3k import _util_async_run # noqa F401
from ._concurrency_py3k import (
"the greenlet library is required to use this function."
)
+ def is_exit_exception(e): # noqa F811
+ return not isinstance(e, Exception)
+
def await_only(thing): # noqa F811
_not_implemented()