diff --git a/synapse/_scripts/synapse_port_db.py b/synapse/_scripts/synapse_port_db.py index ed767b5ec3..2a1110a8ff 100755 --- a/synapse/_scripts/synapse_port_db.py +++ b/synapse/_scripts/synapse_port_db.py @@ -1580,11 +1580,10 @@ def main() -> None: hs=hs, ) - @defer.inlineCallbacks - def run() -> Generator["defer.Deferred[Any]", Any, None]: - yield defer.ensureDeferred(porter.run()) + async def run() -> None: + await porter.run() - hs.get_clock().call_when_running(run) + hs.get_clock().call_when_running(lambda: defer.ensureDeferred(run())) reactor.run() diff --git a/synapse/events/presence_router.py b/synapse/events/presence_router.py index 2a50c23e47..d8e0d97354 100644 --- a/synapse/events/presence_router.py +++ b/synapse/events/presence_router.py @@ -30,10 +30,7 @@ from typing import ( from typing_extensions import ParamSpec -try: - from twisted.internet.defer import CancelledError -except ImportError: - pass +from asyncio import CancelledError from synapse.api.presence import UserPresenceState from synapse.util.async_helpers import delay_cancellation, maybe_awaitable diff --git a/synapse/handlers/auth.py b/synapse/handlers/auth.py index c0fc45ba1c..8f5df65e4e 100644 --- a/synapse/handlers/auth.py +++ b/synapse/handlers/auth.py @@ -20,6 +20,7 @@ # [This file includes modifications made by New Vector Limited] # # +from asyncio import CancelledError import logging import time import unicodedata diff --git a/synapse/handlers/profile.py b/synapse/handlers/profile.py index 37a4aa51b9..2ed6d4c0df 100644 --- a/synapse/handlers/profile.py +++ b/synapse/handlers/profile.py @@ -23,10 +23,7 @@ import random from bisect import bisect_right from typing import TYPE_CHECKING -try: - from twisted.internet.defer import CancelledError -except ImportError: - pass +from asyncio import CancelledError from synapse.api.constants import ProfileFields from synapse.api.errors import ( AuthError, diff --git a/synapse/http/federation/matrix_federation_agent.py b/synapse/http/federation/matrix_federation_agent.py index b34784e6ae..598ae92cc6 100644 --- a/synapse/http/federation/matrix_federation_agent.py +++ b/synapse/http/federation/matrix_federation_agent.py @@ -173,14 +173,13 @@ class MatrixFederationAgent: self._well_known_resolver = _well_known_resolver - @defer.inlineCallbacks - def request( + async def request( self, method: bytes, uri: bytes, headers: Headers | None = None, bodyProducer: Optional[IBodyProducer] = None, - ) -> Generator[defer.Deferred, Any, IResponse]: + ) -> IResponse: """ Args: method: HTTP method: GET/POST/etc @@ -193,10 +192,7 @@ class MatrixFederationAgent: a file for a file upload). Or None if the request is to have no body. Returns: - A deferred which fires when the header of the response has been received - (regardless of the response status code). Fails if there is any problem - which prevents that response from being received (including problems that - prevent the request from being sent). + The response (once headers are received). """ # We use urlparse as that will set `port` to None if there is no # explicit port. @@ -216,8 +212,8 @@ class MatrixFederationAgent: and not _is_ip_literal(parsed_uri.hostname) and not parsed_uri.port ): - well_known_result = yield defer.ensureDeferred( - self._well_known_resolver.get_well_known(parsed_uri.hostname) + well_known_result = await self._well_known_resolver.get_well_known( + parsed_uri.hostname ) delegated_server = well_known_result.delegated_server @@ -249,7 +245,7 @@ class MatrixFederationAgent: if not request_headers.hasHeader(b"user-agent"): request_headers.addRawHeader(b"user-agent", self.user_agent) - res = yield make_deferred_yieldable( + res = await make_deferred_yieldable( self._agent.request(method, uri, request_headers, bodyProducer) ) diff --git a/synapse/http/federation/well_known_resolver.py b/synapse/http/federation/well_known_resolver.py index 33acf4963e..dcc3e7fd4b 100644 --- a/synapse/http/federation/well_known_resolver.py +++ b/synapse/http/federation/well_known_resolver.py @@ -43,10 +43,7 @@ from synapse.util.clock import Clock from synapse.util.duration import Duration from synapse.util.json import json_decoder from synapse.util.metrics import Measure -try: - from twisted.internet.defer import CancelledError -except ImportError: - pass +from asyncio import CancelledError # period to cache .well-known results for by default WELL_KNOWN_DEFAULT_CACHE_PERIOD = 24 * 3600 diff --git a/synapse/http/server.py b/synapse/http/server.py index 31b7266240..a3baacfa48 100644 --- a/synapse/http/server.py +++ b/synapse/http/server.py @@ -45,15 +45,17 @@ import jinja2 from canonicaljson import encode_canonical_json from zope.interface import implementer -import asyncio as _asyncio +from asyncio import CancelledError -from twisted.internet import defer, interfaces, reactor -from twisted.internet.defer import CancelledError -from twisted.python import failure - -# Tuple of CancelledError types for f.check() during transition -_CancelledErrors = (CancelledError, _asyncio.CancelledError) -from twisted.web import resource +try: + from twisted.internet import defer, interfaces, reactor + from twisted.internet.defer import CancelledError as TwistedCancelledError + from twisted.python import failure + from twisted.web import resource + # Catch both CancelledError types during transition + _CancelledErrors = (CancelledError, TwistedCancelledError) +except ImportError: + _CancelledErrors = (CancelledError,) # type: ignore[assignment] from synapse.types import ISynapseThreadlessReactor diff --git a/synapse/logging/_remote.py b/synapse/logging/_remote.py index 4a57ebe54b..0ac1f584b4 100644 --- a/synapse/logging/_remote.py +++ b/synapse/logging/_remote.py @@ -19,6 +19,7 @@ # # +from asyncio import CancelledError import logging import sys import traceback diff --git a/synapse/module_api/__init__.py b/synapse/module_api/__init__.py index 0ebd609b4c..09d7939114 100644 --- a/synapse/module_api/__init__.py +++ b/synapse/module_api/__init__.py @@ -827,7 +827,7 @@ class ModuleApi: """ return [attr.asdict(t) for t in await self._store.user_get_threepids(user_id)] - def check_user_exists(self, user_id: str) -> "defer.Deferred[str | None]": + async def check_user_exists(self, user_id: str) -> str | None: """Check if user exists. Added in Synapse v0.25.0. @@ -839,15 +839,14 @@ class ModuleApi: Canonical (case-corrected) user_id, or None if the user is not registered. """ - return defer.ensureDeferred(self._auth_handler.check_user_exists(user_id)) + return await self._auth_handler.check_user_exists(user_id) - @defer.inlineCallbacks - def register( + async def register( self, localpart: str, displayname: str | None = None, emails: list[str] | None = None, - ) -> Generator["defer.Deferred[Any]", Any, tuple[str, str]]: + ) -> tuple[str, str]: """Registers a new user with given localpart and optional displayname, emails. Also returns an access token for the new user. @@ -869,17 +868,17 @@ class ModuleApi: logger.warning( "Using deprecated ModuleApi.register which creates a dummy user device." ) - user_id = yield self.register_user(localpart, displayname, emails or []) - _, access_token, _, _ = yield self.register_device(user_id) + user_id = await self.register_user(localpart, displayname, emails or []) + _, access_token, _, _ = await self.register_device(user_id) return user_id, access_token - def register_user( + async def register_user( self, localpart: str, displayname: str | None = None, emails: list[str] | None = None, admin: bool = False, - ) -> "defer.Deferred[str]": + ) -> str: """Registers a new user with given localpart and optional displayname, emails. Added in Synapse v1.2.0. @@ -898,21 +897,19 @@ class ModuleApi: Returns: user_id """ - return defer.ensureDeferred( - self._hs.get_registration_handler().register_user( - localpart=localpart, - default_display_name=displayname, - bind_emails=emails or [], - admin=admin, - ) + return await self._hs.get_registration_handler().register_user( + localpart=localpart, + default_display_name=displayname, + bind_emails=emails or [], + admin=admin, ) - def register_device( + async def register_device( self, user_id: str, device_id: str | None = None, initial_display_name: str | None = None, - ) -> "defer.Deferred[tuple[str, str, int | None, str | None]]": + ) -> tuple[str, str, int | None, str | None]: """Register a device for a user and generate an access token. Added in Synapse v1.2.0. @@ -927,17 +924,15 @@ class ModuleApi: Returns: Tuple of device ID, access token, access token expiration time and refresh token """ - return defer.ensureDeferred( - self._hs.get_registration_handler().register_device( - user_id=user_id, - device_id=device_id, - initial_display_name=initial_display_name, - ) + return await self._hs.get_registration_handler().register_device( + user_id=user_id, + device_id=device_id, + initial_display_name=initial_display_name, ) - def record_user_external_id( + async def record_user_external_id( self, auth_provider_id: str, remote_user_id: str, registered_user_id: str - ) -> defer.Deferred: + ) -> None: """Record a mapping between an external user id from a single sign-on provider and a mxid. @@ -952,10 +947,8 @@ class ModuleApi: external_id: id on that system user_id: complete mxid that it is mapped to """ - return defer.ensureDeferred( - self._store.record_user_external_id( - auth_provider_id, remote_user_id, registered_user_id - ) + await self._store.record_user_external_id( + auth_provider_id, remote_user_id, registered_user_id ) async def create_login_token( @@ -988,10 +981,9 @@ class ModuleApi: auth_provider_session_id, ) - @defer.inlineCallbacks - def invalidate_access_token( + async def invalidate_access_token( self, access_token: str - ) -> Generator["defer.Deferred[Any]", Any, None]: + ) -> None: """Invalidate an access token for a user Added in Synapse v0.25.0. @@ -999,37 +991,27 @@ class ModuleApi: Args: access_token: access token - Returns: - twisted.internet.defer.Deferred - resolves once the access token - has been removed. - Raises: synapse.api.errors.AuthError: the access token is invalid """ # see if the access token corresponds to a device - user_info = yield defer.ensureDeferred( - self._auth.get_user_by_access_token(access_token) - ) + user_info = await self._auth.get_user_by_access_token(access_token) device_id = user_info.get("device_id") user_id = user_info["user"].to_string() if device_id: # delete the device, which will also delete its access tokens - yield defer.ensureDeferred( - self._device_handler.delete_devices(user_id, [device_id]) - ) + await self._device_handler.delete_devices(user_id, [device_id]) else: # no associated device. Just delete the access token. - yield defer.ensureDeferred( - self._auth_handler.delete_access_token(access_token) - ) + await self._auth_handler.delete_access_token(access_token) - def run_db_interaction( + async def run_db_interaction( self, desc: str, func: Callable[Concatenate[LoggingTransaction, P], T], *args: P.args, **kwargs: P.kwargs, - ) -> "defer.Deferred[T]": + ) -> T: """Run a function with a database connection Added in Synapse v0.25.0. @@ -1045,9 +1027,7 @@ class ModuleApi: Result of func """ # type-ignore: See https://github.com/python/mypy/issues/8862 - return defer.ensureDeferred( - self._store.db_pool.runInteraction(desc, func, *args, **kwargs) # type: ignore[arg-type] - ) + return await self._store.db_pool.runInteraction(desc, func, *args, **kwargs) # type: ignore[arg-type] def register_cached_function(self, cached_func: CachedFunction) -> None: """Register a cached function that should be invalidated across workers. @@ -1117,15 +1097,11 @@ class ModuleApi: new_user=new_user, ) - @defer.inlineCallbacks - def get_state_events_in_room( + async def get_state_events_in_room( self, room_id: str, types: Iterable[tuple[str, str | None]] - ) -> Generator[defer.Deferred, Any, Iterable[EventBase]]: + ) -> Iterable[EventBase]: """Gets current state events for the given room. - (This is exposed for compatibility with the old SpamCheckerApi. We should - probably deprecate it and replace it with an async method in a subclass.) - Added in Synapse v1.22.0. Args: @@ -1136,12 +1112,10 @@ class ModuleApi: Returns: The filtered state events in the room. """ - state_ids = yield defer.ensureDeferred( - self._storage_controllers.state.get_current_state_ids( - room_id=room_id, state_filter=StateFilter.from_types(types) - ) + state_ids = await self._storage_controllers.state.get_current_state_ids( + room_id=room_id, state_filter=StateFilter.from_types(types) ) - state = yield defer.ensureDeferred(self._store.get_events(state_ids.values())) + state = await self._store.get_events(state_ids.values()) return state.values() async def update_room_membership( diff --git a/synapse/module_api/callbacks/third_party_event_rules_callbacks.py b/synapse/module_api/callbacks/third_party_event_rules_callbacks.py index 24f2efbdee..035eb34640 100644 --- a/synapse/module_api/callbacks/third_party_event_rules_callbacks.py +++ b/synapse/module_api/callbacks/third_party_event_rules_callbacks.py @@ -21,10 +21,7 @@ import logging from typing import TYPE_CHECKING, Any, Awaitable, Callable -try: - from twisted.internet.defer import CancelledError -except ImportError: - pass +from asyncio import CancelledError from synapse.api.errors import ModuleFailedException, SynapseError from synapse.events import EventBase from synapse.events.snapshot import UnpersistedEventContextBase diff --git a/synapse/notifier.py b/synapse/notifier.py index 817c07efca..8453d09c38 100644 --- a/synapse/notifier.py +++ b/synapse/notifier.py @@ -67,10 +67,7 @@ from synapse.util.async_helpers import ( from synapse.util.duration import Duration from synapse.util.stringutils import shortstr from synapse.visibility import filter_and_transform_events_for_client -try: - from twisted.internet.defer import CancelledError -except ImportError: - pass +from asyncio import CancelledError if TYPE_CHECKING: from synapse.server import HomeServer diff --git a/synapse/types/__init__.py b/synapse/types/__init__.py index 05b7e51676..09c71dfab0 100644 --- a/synapse/types/__init__.py +++ b/synapse/types/__init__.py @@ -21,6 +21,7 @@ # import abc import asyncio +from asyncio import CancelledError import logging import re import string diff --git a/synapse/util/async_helpers.py b/synapse/util/async_helpers.py index 22d0edc350..80e1d5a944 100644 --- a/synapse/util/async_helpers.py +++ b/synapse/util/async_helpers.py @@ -24,6 +24,7 @@ import asyncio import collections import inspect import itertools +from asyncio import CancelledError import logging from collections import OrderedDict from contextlib import asynccontextmanager @@ -47,12 +48,19 @@ from typing import ( import attr from typing_extensions import Concatenate, ParamSpec, Unpack +from asyncio import CancelledError + try: from twisted.internet import defer - from twisted.internet.defer import CancelledError + from twisted.internet.defer import CancelledError as TwistedCancelledError from twisted.python.failure import Failure + + # Tuple for catching both CancelledError types during transition + AnyCancelledError = (CancelledError, TwistedCancelledError) except ImportError: - pass + defer = None # type: ignore[assignment] + Failure = BaseException # type: ignore[misc,assignment] + AnyCancelledError = (CancelledError,) # type: ignore[assignment] from synapse.logging.context import ( PreserveLoggingContext, @@ -317,7 +325,7 @@ async def yieldable_gather_results( """Executes the function with each argument concurrently. Args: - func: Function to execute that returns a Deferred + func: Function to execute that returns an awaitable iter: An iterable that yields items that get passed as the first argument to the function *args: Arguments to be passed to each call to func @@ -326,28 +334,31 @@ async def yieldable_gather_results( Returns A list containing the results of the function """ + async def _run(item: T) -> R: + return await func(item, *args, **kwargs) + try: - return await make_deferred_yieldable( - defer.gatherResults( - [run_in_background(func, item, *args, **kwargs) for item in iter], - consumeErrors=True, - ) + asyncio.get_running_loop() + results = await asyncio.gather( + *[_run(item) for item in iter], + return_exceptions=True, ) - except defer.FirstError as dfe: - # unwrap the error from defer.gatherResults. - - # The raised exception's traceback only includes func() etc if - # the 'await' happens before the exception is thrown - ie if the failure - # happens *asynchronously* - otherwise Twisted throws away the traceback as it - # could be large. - # - # We could maybe reconstruct a fake traceback from Failure.frames. Or maybe - # we could throw Twisted into the fires of Mordor. - - # suppress exception chaining, because the FirstError doesn't tell us anything - # very interesting. - assert isinstance(dfe.subFailure.value, BaseException) - raise dfe.subFailure.value from None + for r in results: + if isinstance(r, BaseException): + raise r + return results # type: ignore[return-value] + except RuntimeError: + # No asyncio loop — use Twisted fallback + try: + return await make_deferred_yieldable( + defer.gatherResults( + [run_in_background(func, item, *args, **kwargs) for item in iter], + consumeErrors=True, + ) + ) + except defer.FirstError as dfe: + assert isinstance(dfe.subFailure.value, BaseException) + raise dfe.subFailure.value from None async def yieldable_gather_results_delaying_cancellation( @@ -362,7 +373,7 @@ async def yieldable_gather_results_delaying_cancellation( See `yieldable_gather_results`. Args: - func: Function to execute that returns a Deferred + func: Function to execute that returns an awaitable iter: An iterable that yields items that get passed as the first argument to the function *args: Arguments to be passed to each call to func @@ -371,18 +382,22 @@ async def yieldable_gather_results_delaying_cancellation( Returns A list containing the results of the function """ - try: - return await make_deferred_yieldable( - delay_cancellation( - defer.gatherResults( - [run_in_background(func, item, *args, **kwargs) for item in iter], - consumeErrors=True, - ) - ) + # Use asyncio.shield to delay cancellation + async def _run(item: T) -> R: + return await func(item, *args, **kwargs) + + results = await asyncio.shield( + asyncio.gather( + *[_run(item) for item in iter], + return_exceptions=True, ) - except defer.FirstError as dfe: - assert isinstance(dfe.subFailure.value, BaseException) - raise dfe.subFailure.value from None + ) + + for r in results: + if isinstance(r, BaseException): + raise r + + return results # type: ignore[return-value] T1 = TypeVar("T1") @@ -536,7 +551,21 @@ async def gather_optional_coroutines( overload above. """ + # Use asyncio.gather if an event loop is running, otherwise fall back to + # Twisted's defer.gatherResults during transition try: + asyncio.get_running_loop() + tasks = [ + asyncio.ensure_future(coroutine) + for coroutine in coroutines + if coroutine is not None + ] + results = await asyncio.gather(*tasks, return_exceptions=True) + for r in results: + if isinstance(r, BaseException): + raise r + except RuntimeError: + # No asyncio loop — use Twisted results = await make_deferred_yieldable( defer.gatherResults( [ @@ -548,26 +577,11 @@ async def gather_optional_coroutines( ) ) - results_iter = iter(results) - return tuple( - next(results_iter) if coroutine is not None else None - for coroutine in coroutines - ) - except defer.FirstError as dfe: - # unwrap the error from defer.gatherResults. - - # The raised exception's traceback only includes func() etc if - # the 'await' happens before the exception is thrown - ie if the failure - # happens *asynchronously* - otherwise Twisted throws away the traceback as it - # could be large. - # - # We could maybe reconstruct a fake traceback from Failure.frames. Or maybe - # we could throw Twisted into the fires of Mordor. - - # suppress exception chaining, because the FirstError doesn't tell us anything - # very interesting. - assert isinstance(dfe.subFailure.value, BaseException) - raise dfe.subFailure.value from None + results_iter = iter(results) + return tuple( + next(results_iter) if coroutine is not None else None + for coroutine in coroutines + ) @attr.s(slots=True, auto_attribs=True) @@ -692,7 +706,7 @@ class Linearizer: # exit path, but that would slow down the uncontended case. try: await self._clock.sleep(Duration(seconds=0)) - except CancelledError: + except AnyCancelledError: self._release_lock(key, entry) raise diff --git a/synapse/util/background_queue.py b/synapse/util/background_queue.py index ef84a5f660..740798ae82 100644 --- a/synapse/util/background_queue.py +++ b/synapse/util/background_queue.py @@ -31,10 +31,7 @@ except ImportError: from synapse.util.async_helpers import DeferredEvent from synapse.util.duration import Duration -try: - from twisted.internet.defer import CancelledError -except ImportError: - pass +from asyncio import CancelledError if TYPE_CHECKING: from synapse.server import HomeServer diff --git a/synapse/util/caches/response_cache.py b/synapse/util/caches/response_cache.py index c6ac4249d9..74930bf3d9 100644 --- a/synapse/util/caches/response_cache.py +++ b/synapse/util/caches/response_cache.py @@ -51,10 +51,7 @@ from synapse.util.cancellation import cancellable, is_function_cancellable from synapse.util.clock import Clock from synapse.util.duration import Duration from synapse.util.wheel_timer import WheelTimer -try: - from twisted.internet.defer import CancelledError -except ImportError: - pass +from asyncio import CancelledError logger = logging.getLogger(__name__) diff --git a/synapse/util/task_scheduler.py b/synapse/util/task_scheduler.py index 7047d6cdeb..507f38aaa0 100644 --- a/synapse/util/task_scheduler.py +++ b/synapse/util/task_scheduler.py @@ -41,10 +41,7 @@ from synapse.metrics.background_process_metrics import ( from synapse.types import JsonMapping, ScheduledTask, TaskStatus from synapse.util.duration import Duration from synapse.util.stringutils import random_string -try: - from twisted.internet.defer import CancelledError -except ImportError: - pass +from asyncio import CancelledError if TYPE_CHECKING: from synapse.server import HomeServer diff --git a/tests/storage/databases/main/test_events_worker.py b/tests/storage/databases/main/test_events_worker.py index 0ade4b88d0..3e7ad52d1a 100644 --- a/tests/storage/databases/main/test_events_worker.py +++ b/tests/storage/databases/main/test_events_worker.py @@ -25,7 +25,7 @@ from unittest import mock try: from twisted.enterprise.adbapi import ConnectionPool - from twisted.internet.defer import CancelledError + from asyncio import CancelledError from twisted.internet.defer import Deferred, ensureDeferred except ImportError: pass diff --git a/tests/storage/test_database.py b/tests/storage/test_database.py index 2bf91f5124..08086e4209 100644 --- a/tests/storage/test_database.py +++ b/tests/storage/test_database.py @@ -26,7 +26,7 @@ import attr try: from twisted.internet import defer - from twisted.internet.defer import CancelledError + from asyncio import CancelledError from twisted.internet.defer import Deferred except ImportError: pass diff --git a/tests/storage/util/test_partial_state_events_tracker.py b/tests/storage/util/test_partial_state_events_tracker.py index 1e6cd8ebfb..ac50c1ed41 100644 --- a/tests/storage/util/test_partial_state_events_tracker.py +++ b/tests/storage/util/test_partial_state_events_tracker.py @@ -23,7 +23,7 @@ from typing import Collection from unittest import mock try: - from twisted.internet.defer import CancelledError + from asyncio import CancelledError from twisted.internet.defer import ensureDeferred except ImportError: pass diff --git a/tests/unittest.py b/tests/unittest.py index 77fb994fe9..33fb3291ba 100644 --- a/tests/unittest.py +++ b/tests/unittest.py @@ -393,10 +393,22 @@ class TestCase(_stdlib_unittest.TestCase): result = results[0] if not isinstance(result, Failure): self.fail(f"Deferred {d!r} succeeded with {result!r}, expected failure") - if expected_types and not result.check(*expected_types): - self.fail( - f"Expected {expected_types}, got {result.type}: {result.value}" - ) + if expected_types: + # During transition, check both asyncio and Twisted CancelledError + expanded_types = list(expected_types) + from asyncio import CancelledError as AsyncCE + try: + from twisted.internet.defer import CancelledError as TwistedCE + if AsyncCE in expanded_types and TwistedCE not in expanded_types: + expanded_types.append(TwistedCE) + elif TwistedCE in expanded_types and AsyncCE not in expanded_types: + expanded_types.append(AsyncCE) + except ImportError: + pass + if not result.check(*expanded_types): + self.fail( + f"Expected {expected_types}, got {result.type}: {result.value}" + ) return result def assertObjectHasAttributes(self, attrs: dict[str, object], obj: object) -> None: diff --git a/tests/util/caches/test_descriptors.py b/tests/util/caches/test_descriptors.py index 46ae43cbb5..15b766a2e2 100644 --- a/tests/util/caches/test_descriptors.py +++ b/tests/util/caches/test_descriptors.py @@ -31,7 +31,7 @@ from unittest import mock try: from twisted.internet import defer, reactor - from twisted.internet.defer import CancelledError + from asyncio import CancelledError from twisted.internet.defer import Deferred from twisted.internet.interfaces import IReactorTime except ImportError: diff --git a/tests/util/caches/test_response_cache.py b/tests/util/caches/test_response_cache.py index 79593e9412..f7be204936 100644 --- a/tests/util/caches/test_response_cache.py +++ b/tests/util/caches/test_response_cache.py @@ -36,7 +36,7 @@ from synapse.util.duration import Duration from tests.server import get_clock from tests.unittest import TestCase try: - from twisted.internet.defer import CancelledError + from asyncio import CancelledError except ImportError: pass diff --git a/tests/util/test_async_helpers.py b/tests/util/test_async_helpers.py index d16618946e..154a01ce90 100644 --- a/tests/util/test_async_helpers.py +++ b/tests/util/test_async_helpers.py @@ -25,7 +25,7 @@ from parameterized import parameterized_class try: from twisted.internet import defer - from twisted.internet.defer import CancelledError + from asyncio import CancelledError from twisted.internet.defer import Deferred, ensureDeferred from twisted.python.failure import Failure except ImportError: diff --git a/tests/util/test_linearizer.py b/tests/util/test_linearizer.py index e6181c6cb1..7c61373e7b 100644 --- a/tests/util/test_linearizer.py +++ b/tests/util/test_linearizer.py @@ -23,7 +23,7 @@ from typing import Hashable, Protocol try: from twisted.internet import defer - from twisted.internet.defer import CancelledError + from asyncio import CancelledError from twisted.internet.defer import Deferred except ImportError: pass diff --git a/tests/util/test_rwlock.py b/tests/util/test_rwlock.py index 3314a72cea..93e601e559 100644 --- a/tests/util/test_rwlock.py +++ b/tests/util/test_rwlock.py @@ -23,7 +23,7 @@ from typing import AsyncContextManager, Callable, Sequence try: from twisted.internet import defer - from twisted.internet.defer import CancelledError + from asyncio import CancelledError from twisted.internet.defer import Deferred except ImportError: pass