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))
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)
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
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))
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)
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
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)
def test_callable_name(inputval, expected): assert callable_name(inputval) == expected