Make the utility reusable.

This commit is contained in:
Itamar Turner-Trauring 2022-04-15 09:32:15 -04:00
parent 58bd381202
commit 186aa9abc4
3 changed files with 48 additions and 32 deletions

View File

@ -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)

View File

@ -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

View File

@ -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