Fix typechecking with twisted trunk (#16121)
This commit is contained in:
parent
0538e3e2db
commit
e691243e19
|
@ -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:
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Attempt to fix the twisted trunk job.
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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]]
|
||||||
|
|
|
@ -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!")
|
||||||
|
|
Loading…
Reference in New Issue