Skip to content

Commit

Permalink
Add defer to default exports and use double-quotes for docstirngs
Browse files Browse the repository at this point in the history
  • Loading branch information
achimnol committed Feb 25, 2020
1 parent 0beeff6 commit 3b22bfa
Show file tree
Hide file tree
Showing 8 changed files with 52 additions and 45 deletions.
2 changes: 1 addition & 1 deletion src/aiotools/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.9.0
0.9.1
7 changes: 5 additions & 2 deletions src/aiotools/__init__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# Import submodules only when installed properly
from . import (
context,
defer as _defer,
func,
iter,
iter as _iter,
timer,
server,
)
Expand All @@ -16,14 +17,16 @@

__all__ = (
*context.__all__,
*_defer.__all__,
*func.__all__,
*iter.__all__,
*_iter.__all__,
*timer.__all__,
*server.__all__,
'__version__',
)

from .context import * # noqa
from .defer import * # noqa
from .func import * # noqa
from .iter import * # noqa
from .timer import * # noqa
Expand Down
32 changes: 16 additions & 16 deletions src/aiotools/context.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
'''
"""
Provides an implementation of asynchronous context manager and its applications.
.. note::
The async context managers in this module are transparent aliases to
``contextlib.asynccontextmanager`` of the standard library in Python 3.7
and later.
'''
"""

import abc
import contextlib
Expand Down Expand Up @@ -34,9 +34,9 @@
__all__ += ['AsyncContextDecorator', 'actxdecorator']

class AbstractAsyncContextManager(abc.ABC): # type: ignore
'''
"""
The base abstract interface for asynchronous context manager.
'''
"""

async def __aenter__(self):
return self # pragma: no cover
Expand All @@ -54,9 +54,9 @@ def __subclasshook__(cls, C):
return NotImplemented

class AsyncContextDecorator:
'''
"""
Make an asynchronous context manager be used as a decorator function.
'''
"""

def _recreate_cm(self):
return self
Expand All @@ -72,9 +72,9 @@ async def inner(*args, **kwargs):

class AsyncContextManager(AsyncContextDecorator, # type: ignore
AbstractAsyncContextManager):
'''
"""
Converts an async-generator function into asynchronous context manager.
'''
"""

def __init__(self, func: Callable[..., Any], args, kwargs):
if not inspect.isasyncgenfunction(func):
Expand Down Expand Up @@ -150,7 +150,7 @@ def helper(*args, **kwargs):


class aclosing:
'''
"""
An analogy to :func:`contextlib.closing` for async generators.
The motivation has been proposed by:
Expand All @@ -159,7 +159,7 @@ class aclosing:
* https://vorpus.org/blog/some-thoughts-on-asynchronous-api-design-\
in-a-post-asyncawait-world/#cleanup-in-generators-and-async-generators
* https://www.python.org/dev/peps/pep-0533/
'''
"""

def __init__(self, thing):
self.thing = thing
Expand All @@ -172,7 +172,7 @@ async def __aexit__(self, *args):


class AsyncContextGroup:
'''
"""
Merges a group of context managers into a single context manager.
Internally it uses :func:`asyncio.gather()` to execute them with overlapping,
to reduce the execution time via asynchrony.
Expand Down Expand Up @@ -208,7 +208,7 @@ class AsyncContextGroup:
managers one by one using the :meth:`~.add`
method.
'''
"""

def __init__(self,
context_managers: Optional[Iterable[AbstractAsyncContextManager]] = None): # noqa
Expand All @@ -217,9 +217,9 @@ def __init__(self,
self._cm_exits: List[asyncio.Task] = []

def add(self, cm):
'''
"""
TODO: fill description
'''
"""
self._cm.append(cm)

async def __aenter__(self):
Expand All @@ -240,9 +240,9 @@ async def __aexit__(self, *exc_info):
return_exceptions=True)

def exit_states(self):
'''
"""
TODO: fill description
'''
"""
return self._cm_exits


Expand Down
4 changes: 4 additions & 0 deletions src/aiotools/defer.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ async def do():
Callable,
)

__all__ = (
'defer', 'adefer',
)


def defer(func):
"""
Expand Down
12 changes: 6 additions & 6 deletions src/aiotools/func.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,19 @@

from .compat import get_running_loop

__all__ = [
__all__ = (
'apartial',
'lru_cache',
]
)

_CacheEntry = collections.namedtuple('_CacheEntry', 'value expire_at')


def apartial(coro, *args, **kwargs):
'''
"""
Wraps a coroutine function with pre-defined arguments (including keyword
arguments). It is an asynchronous version of :func:`functools.partial`.
'''
"""

@functools.wraps(coro)
async def wrapped(*cargs, **ckwargs):
Expand All @@ -27,7 +27,7 @@ async def wrapped(*cargs, **ckwargs):
def lru_cache(maxsize: int = 128,
typed: bool = False,
expire_after: float = None):
'''
"""
A simple LRU cache just like :func:`functools.lru_cache`, but it works for
coroutines. This is not as heavily optimized as :func:`functools.lru_cache`
which uses an internal C implementation, as it targets async operations
Expand All @@ -51,7 +51,7 @@ def lru_cache(maxsize: int = 128,
expire_after: Re-calculate the value if the configured time has passed even
when the cache is hit. When re-calculation happens the
expiration timer is also reset.
'''
"""

if maxsize is not None and not isinstance(maxsize, int):
raise TypeError('Expected maxsize to be an integer or None')
Expand Down
4 changes: 2 additions & 2 deletions src/aiotools/iter.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@


async def aiter(obj, sentinel=_sentinel):
'''
"""
Analogous to the builtin :func:`iter()`.
'''
"""

if sentinel is _sentinel:
# Since we cannot directly return the return value of obj.__aiter__()
Expand Down
24 changes: 12 additions & 12 deletions src/aiotools/server.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
'''
"""
Based on :doc:`aiotools.context`, this module provides an automated lifecycle
management for multi-process servers with explicit initialization steps and
graceful shutdown steps.
Expand All @@ -21,7 +21,7 @@ async def myserver(loop, pidx, args):
await do_forced_shutdown()
aiotools.start_server(myserver, ...)
'''
"""

import asyncio
from contextlib import (
Expand Down Expand Up @@ -69,7 +69,7 @@ async def myserver(loop, pidx, args):


class InterruptedBySignal(BaseException):
'''
"""
A new :class:`BaseException` that represents interruption by an arbitrary UNIX
signal.
Expand All @@ -78,18 +78,18 @@ class InterruptedBySignal(BaseException):
bypassing except clauses catching the :class:`Exception` type only)
The first argument of this exception is the signal number received.
'''
"""
pass


class AsyncServerContextManager(AbstractAsyncContextManager):
'''
"""
A modified version of :func:`contextlib.asynccontextmanager`.
The implementation detail is mostly taken from the ``contextlib`` standard
library, with a minor change to inject ``self.yield_return`` into the wrapped
async generator.
'''
"""

yield_return: Optional[signal.Signals]

Expand Down Expand Up @@ -140,13 +140,13 @@ async def __aexit__(self, exc_type, exc_value, tb):

class ServerMainContextManager(AbstractContextManager,
ContextDecorator):
'''
"""
A modified version of :func:`contextlib.contextmanager`.
The implementation detail is mostly taken from the ``contextlib`` standard
library, with a minor change to inject ``self.yield_return`` into the wrapped
generator.
'''
"""

yield_return: Optional[signal.Signals]

Expand Down Expand Up @@ -211,7 +211,7 @@ def __call__(self, func):


def _main_ctxmgr(func):
'''
"""
A decorator wrapper for :class:`ServerMainContextManager`
Usage example:
Expand All @@ -228,7 +228,7 @@ def mymain():
do_forced_shutdown()
aiotools.start_server(..., main_ctxmgr=mymain, ...)
'''
"""
@functools.wraps(func)
def helper(*args, **kwargs):
return ServerMainContextManager(func, args, kwargs)
Expand Down Expand Up @@ -361,7 +361,7 @@ def start_server(
use_threading: bool = False,
start_method: Literal['spawn', 'fork', 'forkserver'] = None,
args: Iterable[Any] = tuple()):
'''
"""
Starts a multi-process server where each process has their own individual
asyncio event loop. Their lifecycles are automantically managed -- if the
main program receives one of the signals specified in ``stop_signals`` it
Expand Down Expand Up @@ -486,7 +486,7 @@ def start_server(
**start_method** argument can be set to change the subprocess spawning
implementation.
'''
"""

@_main_ctxmgr
def noop_main_ctxmgr():
Expand Down
12 changes: 6 additions & 6 deletions src/aiotools/timer.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'''
"""
Provides a simple implementation of timers run inside asyncio event loops.
'''
"""

import asyncio
import enum
Expand All @@ -12,18 +12,18 @@


class TimerDelayPolicy(enum.Enum):
'''
"""
An enumeration of supported policies for when the timer function takes
longer on each tick than the given timer interval.
'''
"""
DEFAULT = 0
CANCEL = 1


def create_timer(cb: Callable[[float], None], interval: float,
delay_policy: TimerDelayPolicy = TimerDelayPolicy.DEFAULT,
loop: Optional[asyncio.AbstractEventLoop] = None) -> asyncio.Task:
'''
"""
Schedule a timer with the given callable and the interval in seconds.
The interval value is also passed to the callable.
If the callable takes longer than the timer interval, all accumulated
Expand All @@ -34,7 +34,7 @@ def create_timer(cb: Callable[[float], None], interval: float,
Returns:
You can stop the timer by cancelling the returned task.
'''
"""
if loop is None:
loop = get_running_loop()

Expand Down

0 comments on commit 3b22bfa

Please sign in to comment.