Ejemplo n.º 1
0
def aio_sleep(seconds: float = 0) -> t.Awaitable:
    """Return sleep coroutine."""
    if trio and current_async_library() == 'trio':
        return trio.sleep(seconds)

    if curio and current_async_library() == 'curio':
        return curio.sleep(seconds)

    return asyncio.sleep(seconds)
Ejemplo n.º 2
0
def aio_event():
    """Create async event."""
    if trio and current_async_library() == 'trio':
        return trio.Event()

    if curio and current_async_library() == 'curio':
        return curio.Event()

    return asyncio.Event()
Ejemplo n.º 3
0
async def sleep(duration: float) -> None:
    if current_async_library() == 'trio':
        import trio
        await trio.sleep(duration)
    elif current_async_library() == 'asyncio':
        import asyncio
        await asyncio.sleep(duration)
    else:
        raise Exception("Invariant")
Ejemplo n.º 4
0
 async def agen(label):
     assert sniffio.current_async_library() == label
     try:
         yield 1
     finally:
         library = sniffio.current_async_library()
         try:
             await sys.modules[library].sleep(0)
         except trio.Cancelled:
             pass
         record.add((label, library))
Ejemplo n.º 5
0
def is_async_context() -> bool:
    """Returns ``True`` if currently in an async context, otherwise ``False``"""
    try:
        import sniffio
    except ImportError as e:
        raise ImportError(
            f"is_async_context / @awaitable unavailable - 'sniffio' not installed. Exc: {type(e)} {str(e)} "
        )
    try:
        # Detect if we're in async context
        sniffio.current_async_library()
        return True
    except sniffio.AsyncLibraryNotFoundError:
        return False
Ejemplo n.º 6
0
 def load(self):
     super().load()
     try:
         sniffio.current_async_library()
     except sniffio.AsyncLibraryNotFoundError:
         # In a synchronous context, we wrap asynchronous models
         # such that we can evaluate `.predict`
         # Otherwise, they will have to be awaited
         _model_dependencies = {}
         for model_name, m in self.model_dependencies.items():
             if isinstance(m, AsyncModel):
                 _model_dependencies[model_name] = WrappedAsyncModel(m)
             else:
                 _model_dependencies[model_name] = m
         self.model_dependencies = ModelDependenciesMapping(_model_dependencies)
Ejemplo n.º 7
0
    def _wrapper(*args, **kwargs):
        coro = m(*args, **kwargs)
        try:
            sniffio.current_async_library()
        except sniffio.AsyncLibraryNotFoundError:
            pass
        else:
            return coro

        result = None
        try:
            while True:
                result = coro.send(result)
        except StopIteration as si:
            return si.value
Ejemplo n.º 8
0
 def backend(self) -> ConcurrencyBackend:
     if not hasattr(self, "_backend_implementation"):
         backend = sniffio.current_async_library()
         if backend not in ("asyncio", "trio"):
             raise RuntimeError(f"Unsupported concurrency backend {backend!r}")
         self._backend_implementation = lookup_backend(backend)
     return self._backend_implementation
Ejemplo n.º 9
0
def normalize_backend(name: str = "auto", *, async_mode: bool) -> str:
    if name == "auto":
        if not async_mode:
            backend = "sync"
        else:
            import sniffio

            async_library = sniffio.current_async_library()
            assert async_library == "asyncio"
            backend = async_library
    else:  # pragma: no cover
        backend = name

    loaders_by_name = _get_backend_loaders()
    assert backend in loaders_by_name, "Unknown backend specifier: {backend!r}"
    loader = loaders_by_name[backend]

    if async_mode and not loader.is_async:  # pragma: no cover
        raise ValueError(
            f"Backend {loader.name!r} needs to be run in sync mode")

    if not async_mode and loader.is_async:  # pragma: no cover
        raise ValueError(
            f"Backend {loader.name!r} needs to be run in async mode")

    return backend
Ejemplo n.º 10
0
def _get_asynclib():
    asynclib_name = sniffio.current_async_library()
    modulename = 'anyio._backends._' + asynclib_name
    try:
        return sys.modules[modulename]
    except KeyError:
        return import_module(modulename)
Ejemplo n.º 11
0
 def __init__(self, obj, async_backend):
     # set to None now so we can know if we need to free it later
     # This should be at the top of __init__ so that __del__ doesn't raise
     # an unexpected AttributeError if something funky happens
     self.aio = None
     # this is not a public interface, let's make some assertions
     assert isinstance(obj, (pynng.Socket, pynng.Context))
     # we need to choose the correct nng lib functions based on the type of
     # object we've been passed; but really, all the logic is identical
     if isinstance(obj, pynng.Socket):
         self._nng_obj = obj.socket
         self._lib_arecv = lib.nng_recv_aio
         self._lib_asend = lib.nng_send_aio
     else:
         self._nng_obj = obj.context
         self._lib_arecv = lib.nng_ctx_recv
         self._lib_asend = lib.nng_ctx_send
     self.obj = obj
     if async_backend is None:
         async_backend = sniffio.current_async_library()
     if async_backend not in self._aio_helper_map:
         raise ValueError(
             'The async backend {} is not currently supported.'
             .format(async_backend)
         )
     self.awaitable, self.cb_arg = self._aio_helper_map[async_backend](self)
     aio_p = ffi.new('nng_aio **')
     _aio_map[id(self.cb_arg)] = self.cb_arg
     idarg = id(self.cb_arg)
     as_void = ffi.cast('void *', idarg)
     lib.nng_aio_alloc(aio_p, lib._async_complete, as_void)
     self.aio = aio_p[0]
Ejemplo n.º 12
0
def sniff() -> str:
    """Attempt to determine the in-use asynchronous I/O library by using
    the ``sniffio`` module if it is available.

    Returns the name of the library, or raises AsyncLibraryNotFoundError
    if the library cannot be determined.
    """
    # pylint: disable=import-outside-toplevel
    try:
        if _no_sniffio:
            raise ImportError
        import sniffio

        try:
            return sniffio.current_async_library()
        except sniffio.AsyncLibraryNotFoundError:
            raise AsyncLibraryNotFoundError("sniffio cannot determine " +
                                            "async library")
    except ImportError:
        import asyncio

        try:
            asyncio.get_running_loop()
            return "asyncio"
        except RuntimeError:
            raise AsyncLibraryNotFoundError("no async library detected")
Ejemplo n.º 13
0
def assertPassed(passed: float) -> Generator[None, None, None]:
    """
    A context manager that checks the code executed in its context has taken the exact given amount of time
    on the event loop.
    Naturally, exact timing can only work on a test event loop using simulated time.
    """

    try:
        from sniffio import current_async_library
    except ImportError:
        library = 'asyncio'
    else:
        library = current_async_library()

    if library == 'trio':
        import trio
        time = trio.current_time
    elif library == 'asyncio':
        time = asyncio.get_event_loop().time
    else:
        raise RuntimeError(f"Unsupported library {library!r}")

    begin = time()
    yield
    end = time()
    assert end - begin == passed
Ejemplo n.º 14
0
async def ensure_portal() -> None:
    """Ensure that the current async task is able to use :func:`greenback.await_`.

    If the current task has called :func:`ensure_portal` previously, calling
    it again is a no-op. Otherwise, :func:`ensure_portal` interposes a
    "coroutine shim" provided by `greenback` in between the event
    loop and the coroutine being used to run the task. For example,
    when running under Trio, `trio.lowlevel.Task.coro` is replaced with
    a wrapper around the coroutine it previously referred to. (The
    same thing happens under asyncio, but asyncio doesn't expose the
    coroutine field publicly, so some additional trickery is required
    in that case.)

    After installation of the coroutine shim, each task step passes
    through `greenback` on its way into and out of your code. At
    some performance cost, this effectively provides a **portal** that
    allows later calls to :func:`greenback.await_` in the same task to
    access an async environment, even if the function that calls
    :func:`await_` is a synchronous function.

    This function is a cancellation point and a schedule point (a checkpoint,
    in Trio terms) even if the calling task already had a portal set up.
    """

    this_task = current_task()
    if this_task not in task_has_portal:
        bestow_portal(this_task)

    # Execute a checkpoint so that we're now running inside the shim coroutine.
    # This is necessary in case the caller immediately invokes greenback.await_()
    # without any further checkpoints.
    library = sniffio.current_async_library()
    await sys.modules[library].sleep(0)
Ejemplo n.º 15
0
def sniff():
    """Attempt to determine the in-use asynchronous I/O library by using
    the ``sniffio`` module if it is available.

    Returns the name of the library, or raises AsyncLibraryNotFoundError
    if the library cannot be determined.
    """
    try:
        if _no_sniffio:
            raise ImportError
        import sniffio
        try:
            return sniffio.current_async_library()
        except sniffio.AsyncLibraryNotFoundError:
            raise AsyncLibraryNotFoundError('sniffio cannot determine ' +
                                            'async library')
    except ImportError:
        import asyncio
        try:
            asyncio.get_running_loop()
            return 'asyncio'
        except RuntimeError:
            raise AsyncLibraryNotFoundError('no async library detected')
        except AttributeError:  # pragma: no cover
            # we have to check current_task on 3.6
            if not asyncio.Task.current_task():
                raise AsyncLibraryNotFoundError('no async library detected')
            return 'asyncio'
Ejemplo n.º 16
0
def normalize_backend(backend, async_mode):
    if backend is None:
        if not async_mode:
            backend = Backend(name="sync")
        else:
            import sniffio

            backend = Backend(name=sniffio.current_async_library())
    elif not isinstance(backend, Backend):
        backend = Backend(name=backend)

    loaders_by_name = backend_directory()
    if backend.name not in loaders_by_name:
        raise ValueError("unknown backend specifier {}".format(backend.name))

    loader = loaders_by_name[backend.name]

    if async_mode and not loader.is_async:
        raise ValueError("{} backend needs to be run in sync mode".format(
            loader.name))

    if not async_mode and loader.is_async:
        raise ValueError("{} backend needs to be run in async mode".format(
            loader.name))

    return backend
Ejemplo n.º 17
0
async def persist_delayed(timeout):
    if current_async_library() == 'trio':
        await trio.sleep(timeout)
    else:
        await asyncio.sleep(timeout)
    #print('PERSIST', state)
    state._appstate_shelve['state'] = state.as_dict()
    state._appstate_shelve.sync()
Ejemplo n.º 18
0
async def run_concurrently(*coroutines):
    if sniffio.current_async_library() == "trio":
        async with trio.open_nursery() as nursery:
            for coroutine in coroutines:
                nursery.start_soon(coroutine)
    else:
        coros = (coroutine() for coroutine in coroutines)
        await asyncio.gather(*coros)
Ejemplo n.º 19
0
 async def __aenter__(self):
     assert self.parent.did_it == 0
     self.parent.did_it = 1
     if sys.version_info >= (3, 7):
         assert sniffio.current_async_library() == "asyncio"
     await asyncio.sleep(0.01, loop=self.loop)
     self.parent.did_it = 2
     return self
Ejemplo n.º 20
0
def create_event() -> "Event":
    if sniffio.current_async_library() == "trio":
        import trio

        return trio.Event()
    else:
        import asyncio

        return asyncio.Event()
Ejemplo n.º 21
0
def get_cipher(stream):
    if sniffio.current_async_library() == "trio":
        return (
            stream.stream.cipher()
            if isinstance(stream.stream, trio.SSLStream)
            else None
        )
    else:
        return stream.stream_writer.get_extra_info("cipher", default=None)
Ejemplo n.º 22
0
def get_asynclib(asynclib_name: Optional[str] = None) -> Any:
    if asynclib_name is None:
        asynclib_name = sniffio.current_async_library()

    modulename = 'anyio._backends._' + asynclib_name
    try:
        return sys.modules[modulename]
    except KeyError:
        return import_module(modulename)
Ejemplo n.º 23
0
 async def iter_trio(self):
     if sys.version_info >= (3, 7):
         assert sniffio.current_async_library() == "trio"
     await trio.sleep(0.01)
     yield 1
     await trio.sleep(0.01)
     yield 2
     await trio.sleep(0.01)
     self.flag |= 1
Ejemplo n.º 24
0
 async def iter_asyncio(self, do_test=True):
     if do_test and sys.version_info >= (3, 7):
         assert sniffio.current_async_library() == "asyncio"
     await asyncio.sleep(0.01, loop=self.loop)
     yield 1
     await asyncio.sleep(0.01, loop=self.loop)
     yield 2
     await asyncio.sleep(0.01, loop=self.loop)
     self.flag |= 1
Ejemplo n.º 25
0
 def call(self, f, *a, **kw):
     if not inspect.iscoroutinefunction(f):
         return f(*a, **kw)
     
     if current_async_library() == 'trio':
         if not getattr(state, '_nursery'):
             raise Exception('Provide state._nursery for async task to run.')
         state._nursery.start_soon(f)
     else:
         return asyncio.create_task(f())
Ejemplo n.º 26
0
 async def run_asyncio_trio_iter(self, loop):
     sth = SomeThing(loop)
     n = 0
     if sys.version_info >= (3, 7):
         assert sniffio.current_async_library() == "asyncio"
     async for x in trio_as_aio(sth.iter_trio()):
         n += 1
         assert x == n
     assert n == 2
     assert sth.flag == 1
Ejemplo n.º 27
0
    async def _init_backend(self) -> None:
        if not (hasattr(self, "_backend")):
            backend = sniffio.current_async_library()
            if backend == "trio":
                from .trio import TrioBackend

                self._backend: AsyncNetworkBackend = TrioBackend()
            else:
                from .asyncio import AsyncIOBackend

                self._backend = AsyncIOBackend()
Ejemplo n.º 28
0
def _get_asynclib():
    try:
        asynclib_name = sniffio.current_async_library()
    except sniffio.AsyncLibraryNotFoundError as exc:
        raise RuntimeError('Not running in any supported asynchronous event loop') from exc

    modulename = 'anyio._backends.' + asynclib_name
    try:
        return sys.modules[modulename]
    except KeyError:
        return import_module(modulename)
Ejemplo n.º 29
0
def _detect_running_asynclib() -> Optional[str]:
    # This function can be removed once https://github.com/python-trio/sniffio/pull/5 has been
    # merged
    try:
        return sniffio.current_async_library()
    except sniffio.AsyncLibraryNotFoundError:
        if 'curio' in sys.modules:
            from curio.meta import curio_running
            if curio_running():
                return 'curio'

        return None
Ejemplo n.º 30
0
def current_task():
    # anyio's TaskInfo comparisons are invalid after their associated native
    # task object is GC'd https://github.com/agronholm/anyio/issues/324
    asynclib_name = sniffio.current_async_library()
    if asynclib_name == "trio":
        return trio.lowlevel.current_task()

    if asynclib_name == "asyncio":
        task = asyncio_current_task()
        if task is None:
            raise RuntimeError("must be called from a running task")  # pragma: no cover
        return task
    raise RuntimeError(f"unsupported asynclib={asynclib_name}")  # pragma: no cover
Ejemplo n.º 31
0
    async def _connect(self):
        if sniffio.current_async_library() == "asyncio":
            loop = asyncio.get_event_loop()
            self._sub_trans, self._sub_prot, = await loop.subprocess_exec(
                partial(AsyncioMockServerProtocol, server=self),
                "../wago-firmware/wago",
                "-d",
                "-D",
                "-p0",
                "-c",
                "../wago-firmware/wago.sample.csv",
                stdin=asyncio.subprocess.PIPE,
                stdout=asyncio.subprocess.PIPE,
                stderr=sys.stderr,
            )
            return self._sub_prot
        elif sniffio.current_async_library() == "trio":
            import trio
            import subprocess

            self._sub_prot = await trio.open_process(
                [
                    "../wago-firmware/wago",
                    "-d",
                    "-D",
                    "-p0",
                    "-c",
                    "../wago-firmware/wago.sample.csv",
                ],
                stdin=subprocess.PIPE,
                stdout=subprocess.PIPE,
                stderr=sys.stderr,
            )
            p = TrioMockServerProtocol(server=self)  # pylint: disable=abstract-class-instantiated
            await self.task_group.spawn(p._recv_loop)
            return p
        else:
            raise RuntimeError("Not supported")