Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clean code #3

Merged
merged 9 commits into from
Nov 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -79,5 +79,5 @@ exclude_lines = ["no cov", "if __name__ == .__main__.:", "if TYPE_CHECKING:"]
profile = "black"

[[tool.mypy.overrides]]
module = ["pluggy.*"]
module = ["pluggy.*", "apluggy.*"]
ignore_missing_imports = true
275 changes: 0 additions & 275 deletions src/apluggy/_wrap.py

This file was deleted.

3 changes: 3 additions & 0 deletions src/apluggy/_wrap/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
__all__ = ["PluginManager"]

from .manager import PluginManager
19 changes: 19 additions & 0 deletions src/apluggy/_wrap/ahook.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import asyncio
from collections.abc import Callable
from typing import Any, Coroutine

from pluggy import HookCaller
from pluggy import PluginManager as PluginManager_


class AHook:
def __init__(self, pm: PluginManager_) -> None:
self.pm = pm

def __getattr__(self, name: str) -> Callable[..., Coroutine[Any, Any, list]]:
async def call(*args: Any, **kwargs: Any) -> list:
hook: HookCaller = getattr(self.pm.hook, name)
coros: list[asyncio.Future] = hook(*args, **kwargs)
return await asyncio.gather(*coros)

return call
53 changes: 53 additions & 0 deletions src/apluggy/_wrap/awith.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import contextlib
from collections.abc import AsyncIterator, Callable
from typing import Any, AsyncContextManager

from pluggy import HookCaller
from pluggy import PluginManager as PluginManager_


class AWith:
def __init__(self, pm: PluginManager_) -> None:
self.pm = pm

def __getattr__(self, name: str) -> Callable[..., AsyncContextManager]:
hook: HookCaller = getattr(self.pm.hook, name)
call = _Call(hook)
return call


def _Call(
hook: Callable[..., list[AsyncContextManager]]
) -> Callable[..., AsyncContextManager]:
@contextlib.asynccontextmanager
async def call(*args: Any, **kwargs: Any) -> AsyncIterator[list]:
ctxs = hook(*args, **kwargs)
async with contextlib.AsyncExitStack() as stack:
yields = [await stack.enter_async_context(ctx) for ctx in ctxs]

# TODO: Consider entering the contexts asynchronously as in the
# following commented out code.

# yields = await asyncio.gather(
# *[stack.enter_async_context(ctx) for ctx in ctxs]
# )

yield yields

# TODO: The following commented out code is an attempt to support
# `asend()` through the `gen` attribute. It only works for
# simple cases. It doesn't work with starlette.lifespan().
# When starlette is shutting down, an exception is raised
# `RuntimeError: generator didn't stop after athrow()`.

# stop = False
# while not stop:
# sent = yield yields
# try:
# yields = await asyncio.gather(
# *[ctx.gen.asend(sent) for ctx in ctxs]
# )
# except StopAsyncIteration:
# stop = True

return call
Loading
Loading