Fix typechecking with twisted trunk (#16121)

This commit is contained in:
David Robertson 2023-08-24 15:53:07 +01:00 committed by GitHub
parent 0538e3e2db
commit e691243e19
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 36 additions and 36 deletions

View File

@ -54,8 +54,8 @@ jobs:
poetry remove twisted poetry remove twisted
poetry add --extras tls git+https://github.com/twisted/twisted.git#${{ inputs.twisted_ref || 'trunk' }} poetry add --extras tls git+https://github.com/twisted/twisted.git#${{ inputs.twisted_ref || 'trunk' }}
poetry install --no-interaction --extras "all test" poetry install --no-interaction --extras "all test"
- name: Remove warn_unused_ignores from mypy config - name: Remove unhelpful options from mypy config
run: sed '/warn_unused_ignores = True/d' -i mypy.ini run: sed -e '/warn_unused_ignores = True/d' -e '/warn_redundant_casts = True/d' -i mypy.ini
- run: poetry run mypy - run: poetry run mypy
trial: trial:

1
changelog.d/16121.misc Normal file
View File

@ -0,0 +1 @@
Attempt to fix the twisted trunk job.

View File

@ -1474,10 +1474,10 @@ class EventCreationHandler:
# We now persist the event (and update the cache in parallel, since we # We now persist the event (and update the cache in parallel, since we
# don't want to block on it). # don't want to block on it).
event, context = events_and_context[0] #
result, _ = await make_deferred_yieldable( # Note: mypy gets confused if we inline dl and check with twisted#11770.
gather_results( # Some kind of bug in mypy's deduction?
( deferreds = (
run_in_background( run_in_background(
self._persist_events, self._persist_events,
requester=requester, requester=requester,
@ -1488,9 +1488,9 @@ class EventCreationHandler:
run_in_background( run_in_background(
self.cache_joined_hosts_for_events, events_and_context self.cache_joined_hosts_for_events, events_and_context
).addErrback(log_failure, "cache_joined_hosts_for_event failed"), ).addErrback(log_failure, "cache_joined_hosts_for_event failed"),
),
consumeErrors=True,
) )
result, _ = await make_deferred_yieldable(
gather_results(deferreds, consumeErrors=True)
).addErrback(unwrapFirstError) ).addErrback(unwrapFirstError)
return result return result

View File

@ -809,23 +809,24 @@ def run_in_background( # type: ignore[misc]
# `res` may be a coroutine, `Deferred`, some other kind of awaitable, or a plain # `res` may be a coroutine, `Deferred`, some other kind of awaitable, or a plain
# value. Convert it to a `Deferred`. # value. Convert it to a `Deferred`.
d: "defer.Deferred[R]"
if isinstance(res, typing.Coroutine): if isinstance(res, typing.Coroutine):
# Wrap the coroutine in a `Deferred`. # Wrap the coroutine in a `Deferred`.
res = defer.ensureDeferred(res) d = defer.ensureDeferred(res)
elif isinstance(res, defer.Deferred): elif isinstance(res, defer.Deferred):
pass d = res
elif isinstance(res, Awaitable): elif isinstance(res, Awaitable):
# `res` is probably some kind of completed awaitable, such as a `DoneAwaitable` # `res` is probably some kind of completed awaitable, such as a `DoneAwaitable`
# or `Future` from `make_awaitable`. # or `Future` from `make_awaitable`.
res = defer.ensureDeferred(_unwrap_awaitable(res)) d = defer.ensureDeferred(_unwrap_awaitable(res))
else: else:
# `res` is a plain value. Wrap it in a `Deferred`. # `res` is a plain value. Wrap it in a `Deferred`.
res = defer.succeed(res) d = defer.succeed(res)
if res.called and not res.paused: if d.called and not d.paused:
# The function should have maintained the logcontext, so we can # The function should have maintained the logcontext, so we can
# optimise out the messing about # optimise out the messing about
return res return d
# The function may have reset the context before returning, so # The function may have reset the context before returning, so
# we need to restore it now. # we need to restore it now.
@ -843,8 +844,8 @@ def run_in_background( # type: ignore[misc]
# which is supposed to have a single entry and exit point. But # which is supposed to have a single entry and exit point. But
# by spawning off another deferred, we are effectively # by spawning off another deferred, we are effectively
# adding a new exit point.) # adding a new exit point.)
res.addBoth(_set_context_cb, ctx) d.addBoth(_set_context_cb, ctx)
return res return d
T = TypeVar("T") T = TypeVar("T")
@ -877,7 +878,7 @@ def make_deferred_yieldable(deferred: "defer.Deferred[T]") -> "defer.Deferred[T]
ResultT = TypeVar("ResultT") ResultT = TypeVar("ResultT")
def _set_context_cb(result: ResultT, context: LoggingContext) -> ResultT: def _set_context_cb(result: ResultT, context: LoggingContextOrSentinel) -> ResultT:
"""A callback function which just sets the logging context""" """A callback function which just sets the logging context"""
set_current_context(context) set_current_context(context)
return result return result

View File

@ -470,7 +470,7 @@ class CacheMultipleEntries(CacheEntry[KT, VT]):
def deferred(self, key: KT) -> "defer.Deferred[VT]": def deferred(self, key: KT) -> "defer.Deferred[VT]":
if not self._deferred: if not self._deferred:
self._deferred = ObservableDeferred(defer.Deferred(), consumeErrors=True) self._deferred = ObservableDeferred(defer.Deferred(), consumeErrors=True)
return self._deferred.observe().addCallback(lambda res: res.get(key)) return self._deferred.observe().addCallback(lambda res: res[key])
def add_invalidation_callback( def add_invalidation_callback(
self, key: KT, callback: Optional[Callable[[], None]] self, key: KT, callback: Optional[Callable[[], None]]

View File

@ -60,11 +60,9 @@ class ObservableDeferredTest(TestCase):
observer1.addBoth(check_called_first) observer1.addBoth(check_called_first)
# store the results # store the results
results: List[Optional[ObservableDeferred[int]]] = [None, None] results: List[Optional[int]] = [None, None]
def check_val( def check_val(res: int, idx: int) -> int:
res: ObservableDeferred[int], idx: int
) -> ObservableDeferred[int]:
results[idx] = res results[idx] = res
return res return res
@ -93,14 +91,14 @@ class ObservableDeferredTest(TestCase):
observer1.addBoth(check_called_first) observer1.addBoth(check_called_first)
# store the results # store the results
results: List[Optional[ObservableDeferred[str]]] = [None, None] results: List[Optional[Failure]] = [None, None]
def check_val(res: ObservableDeferred[str], idx: int) -> None: def check_failure(res: Failure, idx: int) -> None:
results[idx] = res results[idx] = res
return None return None
observer1.addErrback(check_val, 0) observer1.addErrback(check_failure, 0)
observer2.addErrback(check_val, 1) observer2.addErrback(check_failure, 1)
try: try:
raise Exception("gah!") raise Exception("gah!")