From 4df38ba73331680f4668d36f424aae6c1ff8464e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jelmer=20Vernoo=C4=B3?= Date: Sat, 19 Nov 2022 14:45:21 +0000 Subject: [PATCH] Add typing hints for twistedsupport. --- testtools/twistedsupport/_deferred.py | 14 ++++++++++---- testtools/twistedsupport/_spinner.py | 11 +++++++---- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/testtools/twistedsupport/_deferred.py b/testtools/twistedsupport/_deferred.py index 71cea9d1..ffeb2d97 100644 --- a/testtools/twistedsupport/_deferred.py +++ b/testtools/twistedsupport/_deferred.py @@ -2,8 +2,14 @@ """Utilities for Deferreds.""" +from typing import List, TYPE_CHECKING + from functools import partial +if TYPE_CHECKING: + from twisted.python.failure import Failure + from twisted.internet.defer import Deferred + from testtools.content import TracebackContent @@ -29,8 +35,8 @@ def extract_result(deferred): code). In those cases, it is better to add callbacks and errbacks as needed. """ - failures = [] - successes = [] + failures: List["Failure"] = [] + successes: List["Deferred"] = [] deferred.addCallbacks(successes.append, failures.append) if len(failures) == 1: failures[0].raiseException() @@ -76,8 +82,8 @@ def on_deferred_result(deferred, on_success, on_failure, on_no_result): :return: Whatever is returned by the triggered callback. :rtype: ``T`` """ - successes = [] - failures = [] + successes: List["Deferred"] = [] + failures: List["Failure"] = [] def capture(value, values): values.append(value) diff --git a/testtools/twistedsupport/_spinner.py b/testtools/twistedsupport/_spinner.py index e01c48c1..a7bb648a 100644 --- a/testtools/twistedsupport/_spinner.py +++ b/testtools/twistedsupport/_spinner.py @@ -18,6 +18,7 @@ from fixtures import Fixture import signal +from typing import Union from ._deferreddebug import DebugTwisted @@ -74,7 +75,7 @@ def trap_unhandled_errors(function, *args, **kwargs): # an instance doesn't work with Python 3 and viceversa overriding __del__ # via inheritance doesn't work with Python 2. So we handle the two cases # differently. TODO: perhaps there's a way to have a single code path? - class DebugInfo(real_DebugInfo): + class DebugInfo(real_DebugInfo): # type: ignore _runRealDel = True @@ -86,11 +87,11 @@ def __del__(self): if self._runRealDel: real_DebugInfo.__del__(self) - defer.DebugInfo = DebugInfo + defer.DebugInfo = DebugInfo # type: ignore try: result = function(*args, **kwargs) finally: - defer.DebugInfo = real_DebugInfo + defer.DebugInfo = real_DebugInfo # type: ignore errors = [] for info in debug_infos: if info.failResult is not None: @@ -153,6 +154,8 @@ class Spinner: # the ideal, and it actually works for many cases. _OBLIGATORY_REACTOR_ITERATIONS = 0 + _failure: Union[Failure, object] + def __init__(self, reactor, debug=False): """Construct a Spinner. @@ -175,7 +178,7 @@ def _cancel_timeout(self): def _get_result(self): if self._failure is not self._UNSET: - self._failure.raiseException() + self._failure.raiseException() # type: ignore if self._success is not self._UNSET: return self._success raise NoResultError()