From 186aa9abc4715ef42f7d7d1c7ecd95884bdeab45 Mon Sep 17 00:00:00 2001 From: Itamar Turner-Trauring Date: Fri, 15 Apr 2022 09:32:15 -0400 Subject: [PATCH] Make the utility reusable. --- src/allmydata/test/test_deferredutil.py | 28 +++++++++++++++++++ src/allmydata/test/test_storage_https.py | 17 +----------- src/allmydata/util/deferredutil.py | 35 +++++++++++++----------- 3 files changed, 48 insertions(+), 32 deletions(-) diff --git a/src/allmydata/test/test_deferredutil.py b/src/allmydata/test/test_deferredutil.py index 2a155089f..a37dfdd6f 100644 --- a/src/allmydata/test/test_deferredutil.py +++ b/src/allmydata/test/test_deferredutil.py @@ -129,3 +129,31 @@ class UntilTests(unittest.TestCase): self.assertEqual([1], counter) r1.callback(None) self.assertEqual([2], counter) + + +class AsyncToDeferred(unittest.TestCase): + """Tests for ``deferredutil.async_to_deferred.``""" + + def test_async_to_deferred_success(self): + """ + Normal results from a ``@async_to_deferred``-wrapped function get + turned into a ``Deferred`` with that value. + """ + @deferredutil.async_to_deferred + async def f(x, y): + return x + y + + result = f(1, y=2) + self.assertEqual(self.successResultOf(result), 3) + + def test_async_to_deferred_exception(self): + """ + Exceptions from a ``@async_to_deferred``-wrapped function get + turned into a ``Deferred`` with that value. + """ + @deferredutil.async_to_deferred + async def f(x, y): + return x/y + + result = f(1, 0) + self.assertIsInstance(self.failureResultOf(result).value, ZeroDivisionError) diff --git a/src/allmydata/test/test_storage_https.py b/src/allmydata/test/test_storage_https.py index 73c99725a..3b41e8308 100644 --- a/src/allmydata/test/test_storage_https.py +++ b/src/allmydata/test/test_storage_https.py @@ -6,14 +6,12 @@ server authentication logic, which may one day apply outside of HTTP Storage Protocol. """ -from functools import wraps from contextlib import asynccontextmanager from cryptography import x509 from twisted.internet.endpoints import serverFromString from twisted.internet import reactor -from twisted.internet.defer import Deferred from twisted.internet.task import deferLater from twisted.web.server import Site from twisted.web.static import Data @@ -31,6 +29,7 @@ from .certs import ( from ..storage.http_common import get_spki_hash from ..storage.http_client import _StorageClientHTTPSPolicy from ..storage.http_server import _TLSEndpointWrapper +from ..util.deferredutil import async_to_deferred class HTTPSNurlTests(SyncTestCase): @@ -73,20 +72,6 @@ ox5zO3LrQmQw11OaIAs2/kviKAoKTFFxeyYcpS5RuKNDZfHQCXlLwt9bySxG self.assertEqual(get_spki_hash(certificate), expected_hash) -def async_to_deferred(f): - """ - Wrap an async function to return a Deferred instead. - - Maybe solution to https://tahoe-lafs.org/trac/tahoe-lafs/ticket/3886 - """ - - @wraps(f) - def not_async(*args, **kwargs): - return Deferred.fromCoroutine(f(*args, **kwargs)) - - return not_async - - class PinningHTTPSValidation(AsyncTestCase): """ Test client-side validation logic of HTTPS certificates that uses diff --git a/src/allmydata/util/deferredutil.py b/src/allmydata/util/deferredutil.py index ed2a11ee4..782663e8b 100644 --- a/src/allmydata/util/deferredutil.py +++ b/src/allmydata/util/deferredutil.py @@ -4,24 +4,13 @@ Utilities for working with Twisted Deferreds. Ported to Python 3. """ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function -from __future__ import unicode_literals - -from future.utils import PY2 -if PY2: - from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401 - import time +from functools import wraps -try: - from typing import ( - Callable, - Any, - ) -except ImportError: - pass +from typing import ( + Callable, + Any, +) from foolscap.api import eventually from eliot.twisted import ( @@ -231,3 +220,17 @@ def until( yield action() if condition(): break + + +def async_to_deferred(f): + """ + Wrap an async function to return a Deferred instead. + + Maybe solution to https://tahoe-lafs.org/trac/tahoe-lafs/ticket/3886 + """ + + @wraps(f) + def not_async(*args, **kwargs): + return defer.Deferred.fromCoroutine(f(*args, **kwargs)) + + return not_async