Пример #1
0
 def __repr__(self):
     typenames = ', '.join(qualified_name(cls) for cls in self.types)
     value_repr = ('factory=%s' % callable_name(self.value_or_factory) if self.is_factory
                   else 'value=%r' % self.value_or_factory)
     return ('{self.__class__.__name__}({value_repr}, types=[{typenames}], name={self.name!r}, '
             'context_attr={self.context_attr!r})'.format(
                 self=self, value_repr=value_repr, typenames=typenames))
Пример #2
0
    async def wrapper(*args, **kwargs) -> None:
        async def teardown_callback(exception: Optional[Exception]):
            try:
                await generator.asend(exception)
            except StopAsyncIteration:
                pass
            finally:
                await generator.aclose()

        try:
            ctx = next(arg for arg in args[:2] if isinstance(arg, Context))
        except StopIteration:
            raise RuntimeError('the first positional argument to {}() has to be a Context '
                               'instance'.format(callable_name(func))) from None

        generator = func(*args, **kwargs)
        try:
            await generator.asend(None)
        except StopAsyncIteration:
            pass
        except BaseException:
            await generator.aclose()
            raise
        else:
            ctx.add_teardown_callback(teardown_callback, True)
Пример #3
0
def context_teardown(func: Callable):
    """
    Wrap an async generator function to execute the rest of the function at context teardown.

    This function returns an async function, which, when called, starts the wrapped async
    generator. The wrapped async function is run until the first ``yield`` statement
    (``await async_generator.yield_()`` on Python 3.5). When the context is being torn down, the
    exception that ended the context, if any, is sent to the generator.

    For example::

        class SomeComponent(Component):
            @context_teardown
            async def start(self, ctx: Context):
                service = SomeService()
                ctx.add_resource(service)
                exception = yield
                service.stop()

    :param func: an async generator function
    :return: an async function

    """
    @wraps(func)
    async def wrapper(*args, **kwargs) -> None:
        async def teardown_callback(exception: Optional[Exception]):
            try:
                await generator.asend(exception)
            except StopAsyncIteration:
                pass
            finally:
                await generator.aclose()

        try:
            ctx = next(arg for arg in args[:2] if isinstance(arg, Context))
        except StopIteration:
            raise RuntimeError(
                'the first positional argument to {}() has to be a Context '
                'instance'.format(callable_name(func))) from None

        generator = func(*args, **kwargs)
        try:
            await generator.asend(None)
        except StopAsyncIteration:
            raise RuntimeError('{} did not do "await yield_()"'.format(
                callable_name(func))) from None
        except BaseException:
            await generator.aclose()
            raise
        else:
            ctx.add_teardown_callback(teardown_callback, True)

    if iscoroutinefunction(func):
        func = async_generator(func)
    elif not isasyncgenfunction(func):
        raise TypeError('{} must be an async generator function'.format(
            callable_name(func)))

    return wrapper
Пример #4
0
 def __repr__(self):
     typenames = ', '.join(qualified_name(cls) for cls in self.types)
     value_repr = ('factory=%s' % callable_name(self.value_or_factory) if
                   self.is_factory else 'value=%r' % self.value_or_factory)
     return (
         '{self.__class__.__name__}({value_repr}, types=[{typenames}], name={self.name!r}, '
         'context_attr={self.context_attr!r})'.format(self=self,
                                                      value_repr=value_repr,
                                                      typenames=typenames))
Пример #5
0
        def inner_wrapper(*args, **kwargs):
            try:
                ctx = next(arg for arg in args[:2] if isinstance(arg, Context))
            except StopIteration:
                raise RuntimeError('the first positional argument to {}() has to be a Context '
                                   'instance'.format(callable_name(func))) from None

            executor = ctx.require_resource(Executor, resource_name)
            return asyncio_extras.call_in_executor(func, *args, executor=executor, **kwargs)
Пример #6
0
def context_teardown(func: Callable):
    """
    Wrap an async generator function to execute the rest of the function at context teardown.

    This function returns an async function, which, when called, starts the wrapped async
    generator. The wrapped async function is run until the first ``yield`` statement
    (``await async_generator.yield_()`` on Python 3.5). When the context is being torn down, the
    exception that ended the context, if any, is sent to the generator.

    For example::

        class SomeComponent(Component):
            @context_teardown
            async def start(self, ctx: Context):
                service = SomeService()
                ctx.add_resource(service)
                exception = yield
                service.stop()

    :param func: an async generator function
    :return: an async function

    """
    @wraps(func)
    async def wrapper(*args, **kwargs) -> None:
        async def teardown_callback(exception: Optional[Exception]):
            try:
                await generator.asend(exception)
            except StopAsyncIteration:
                pass
            finally:
                await generator.aclose()

        try:
            ctx = next(arg for arg in args[:2] if isinstance(arg, Context))
        except StopIteration:
            raise RuntimeError('the first positional argument to {}() has to be a Context '
                               'instance'.format(callable_name(func))) from None

        generator = func(*args, **kwargs)
        try:
            await generator.asend(None)
        except StopAsyncIteration:
            pass
        except BaseException:
            await generator.aclose()
            raise
        else:
            ctx.add_teardown_callback(teardown_callback, True)

    if iscoroutinefunction(func):
        func = async_generator(func)
    elif not isasyncgenfunction(func):
        raise TypeError('{} must be an async generator function'.format(callable_name(func)))

    return wrapper
Пример #7
0
        def inner_wrapper(*args, **kwargs):
            try:
                ctx = next(arg for arg in args[:2] if isinstance(arg, Context))
            except StopIteration:
                raise RuntimeError(
                    'the first positional argument to {}() has to be a Context '
                    'instance'.format(callable_name(func))) from None

            executor = ctx.require_resource(Executor, resource_name)
            return asyncio_extras.call_in_executor(func,
                                                   *args,
                                                   executor=executor,
                                                   **kwargs)
Пример #8
0
def test_callable_name(inputval, expected):
    assert callable_name(inputval) == expected
Пример #9
0
def test_callable_name(inputval, expected):
    assert callable_name(inputval) == expected