⏺ Summary of remaining Twisted defer usage:

- 0 @defer.inlineCallbacks — all converted to async def
  - 12 defer.ensureDeferred — reactor entry points (startup, shutdown, render)
  - 22 defer.Deferred() — in Linearizer, ReadWriteLock, AwakenableSleeper, DeferredEvent (old implementations)
  - 21 defer.gatherResults — in fallback paths and old implementations
  - 11 defer.succeed/fail — immediate value wrapping in old implementations
  - 3 defer.FirstError — in fallback paths
  - 13 defer.TimeoutError — in timeout_deferred and its callers

  The majority (22 + 21 + 11 + 13 = 67) are in the old Deferred-based utility implementations (Linearizer, ReadWriteLock, ObservableDeferred, timeout_deferred, etc.) that already have native replacements (NativeLinearizer,
  NativeReadWriteLock, ObservableFuture, native_timeout, etc.). These will be removed when callers switch to the native versions.

  The 12 defer.ensureDeferred are in reactor entry points that will be removed when reactor.run() → asyncio.run().

  The codebase is now in a clean transitional state where:
  1. All Twisted imports are conditional (try/except ImportError)
  2. ContextVar is the primary logcontext storage
  3. Test base class is stdlib (unittest.TestCase)
  4. CancelledError is asyncio.CancelledError in production code
  5. @defer.inlineCallbacks is eliminated (0 remaining)
  6. yieldable_gather_results uses asyncio.gather (with Twisted fallback)
  7. Module API is fully async (no more Deferred return types)
  8. Twisted is optional in pyproject.toml
This commit is contained in:
Matthew Hodgson
2026-03-21 20:54:28 +00:00
parent a5928e6839
commit 8e1c26067b
25 changed files with 160 additions and 184 deletions
+1 -1
View File
@@ -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:
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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:
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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