Skip to content

Commit

Permalink
🔖 version 0.13.0
Browse files Browse the repository at this point in the history
  • Loading branch information
RF-Tar-Railt committed Dec 8, 2024
1 parent 4c47f4c commit ec0752a
Show file tree
Hide file tree
Showing 20 changed files with 193 additions and 151 deletions.
8 changes: 4 additions & 4 deletions arclet/letoderea/__init__.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
from .auxiliary import Interface as Interface
from .auxiliary import AuxType as AuxType
from .auxiliary import BaseAuxiliary as BaseAuxiliary
from .auxiliary import Cleanup as Cleanup
from .auxiliary import Complete as Complete
from .auxiliary import Interface as Interface
from .auxiliary import JudgeAuxiliary as JudgeAuxiliary
from .auxiliary import Prepare as Prepare
from .auxiliary import Scope as Scope
from .auxiliary import SupplyAuxiliary as SupplyAuxiliary
from .auxiliary import auxilia as auxilia
from .breakpoint import StepOut as StepOut
from .subscriber import Depend as Depend
from .subscriber import Depends as Depends
from .core import es as es
from .decorate import allow_event as allow_event
from .decorate import bind as bind
Expand All @@ -29,9 +27,11 @@
from .publisher import ExternalPublisher as ExternalPublisher
from .publisher import ProviderFactory as ProviderFactory
from .publisher import Publisher as Publisher
from .publisher import global_providers as global_providers
from .publisher import global_auxiliaries as global_auxiliaries
from .publisher import global_providers as global_providers
from .ref import deref as deref
from .subscriber import Depend as Depend
from .subscriber import Depends as Depends
from .subscriber import Subscriber as Subscriber
from .typing import Contexts as Contexts
from .typing import Force as Force
23 changes: 14 additions & 9 deletions arclet/letoderea/auxiliary.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
from abc import ABCMeta, abstractmethod
from dataclasses import dataclass
from enum import Enum
from typing import Any, Callable, ClassVar, Final, Literal, Optional, overload, TypeVar, Generic, Union
from typing import Any, Callable, ClassVar, Final, Generic, Literal, Optional, TypeVar, Union, overload

from tarina import run_always_await

from .exceptions import UndefinedRequirement, JudgementError, UnexpectedArgument
from .provider import Provider, ProviderFactory, Param
from .exceptions import JudgementError, ParsingStop, PropagationCancelled, UndefinedRequirement, UnexpectedArgument
from .provider import Param, Provider, ProviderFactory
from .typing import Contexts

T = TypeVar("T")
Expand All @@ -21,6 +21,14 @@ def __init__(self, ctx: Contexts, providers: list[Union[Provider, ProviderFactor
self.providers = providers
self.executed: set[str] = set()

@staticmethod
def stop():
raise ParsingStop

@staticmethod
def block():
raise PropagationCancelled

def clear(self):
self.ctx.clear()

Expand All @@ -44,16 +52,13 @@ def error(self) -> Optional[Exception]:
return self.ctx.get("$error")

@overload
def query(self, typ: type[Q], name: str) -> Q:
...
def query(self, typ: type[Q], name: str) -> Q: ...

@overload
def query(self, typ: type[Q], name: str, *, force_return: Literal[True]) -> Optional[Q]:
...
def query(self, typ: type[Q], name: str, *, force_return: Literal[True]) -> Optional[Q]: ...

@overload
def query(self, typ: type[Q], name: str, default: D) -> Union[Q, D]:
...
def query(self, typ: type[Q], name: str, default: D) -> Union[Q, D]: ...

def query(self, typ: type, name: str, default: Any = None, force_return: bool = False):
if name in self.ctx:
Expand Down
23 changes: 9 additions & 14 deletions arclet/letoderea/breakpoint.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
import asyncio
from asyncio import Future
from typing import Callable, Generic, Optional, TypeVar, Union, overload
from collections.abc import Awaitable
from typing import Callable, Generic, Optional, TypeVar, Union, overload

from .auxiliary import AuxType, BaseAuxiliary, auxilia
from .core import es
from .event import BaseEvent, get_auxiliaries, get_providers
from .exceptions import PropagationCancelled
from .handler import generate_contexts
from .provider import Provider
from .publisher import Publisher, global_providers
from .publisher import global_auxiliaries, global_providers
from .subscriber import Subscriber
from .typing import TCallable, TTarget


R = TypeVar("R")
R1 = TypeVar("R1")
D = TypeVar("D")
Expand All @@ -30,6 +29,7 @@ def new_target(event_t: type[BaseEvent], condition: "StepOut", fut: Future):
],
priority=condition.priority,
auxiliaries=[
*global_auxiliaries,
*condition.auxiliaries,
*get_auxiliaries(event_t),
],
Expand Down Expand Up @@ -124,24 +124,19 @@ async def wait(
default: Union[R, D, None] = None,
) -> Union[R, D, None]:
fut = asyncio.get_running_loop().create_future()
publisher = Publisher("__breakpoint__publisher__", *self.target)
subscribers = []

for et in self.target:
callable_target = new_target(et, self, fut) # type: ignore
publisher.register(
priority=self.priority,
auxiliaries=[
auxilia("step_out", AuxType.judge, prepare=lambda interface: isinstance(interface.event, et))
],
)(callable_target)

aux = auxilia("step_out", AuxType.judge, prepare=lambda interface: isinstance(interface.event, et))
subscribers.append(es.on(et, callable_target, priority=self.priority, auxiliaries=[aux]))
try:
es.register(publisher)
return await asyncio.wait_for(fut, timeout) if timeout else await fut
except asyncio.TimeoutError:
return default
finally:
if not fut.done():
fut.cancel()
publisher.subscribers.clear()
es.publishers.pop(publisher.id, None)
for sub in subscribers:
sub.dispose()
subscribers.clear()
137 changes: 84 additions & 53 deletions arclet/letoderea/core.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
from __future__ import annotations

import asyncio
from typing import Any, Callable, TypeVar, overload, Awaitable
from collections.abc import Sequence, Mapping
from weakref import finalize
from collections.abc import Mapping, Sequence
from itertools import chain
from typing import Any, Awaitable, Callable, TypeVar, overload
from weakref import finalize

from .event import BaseEvent
from .auxiliary import BaseAuxiliary
from .context import publisher_ctx
from .event import BaseEvent
from .handler import dispatch
from .provider import Provider, ProviderFactory
from .publisher import BackendPublisher, ExternalPublisher, Publisher, Publishable
from .publisher import BackendPublisher, ExternalPublisher, Publishable, Publisher
from .subscriber import Subscriber
from .typing import Result, Resultable, Contexts
from .typing import Contexts, Result, Resultable

T = TypeVar("T")

Expand Down Expand Up @@ -79,17 +79,31 @@ def publish(self, event: Any, publisher: str | Publisher | None = None):
"""发布事件"""
loop = asyncio.get_running_loop()
if isinstance(publisher, str) and (pub := self.publishers.get(publisher)):
task = loop.create_task(dispatch(pub.subscribers.values(), event, external_gather=self.external_gathers.get(event.__class__, None)))
task = loop.create_task(
dispatch(
pub.subscribers.values(), event, external_gather=self.external_gathers.get(event.__class__, None)
)
)
self._ref_tasks.add(task)
task.add_done_callback(self._ref_tasks.discard)
return task
if isinstance(publisher, Publisher):
task = loop.create_task(dispatch(publisher.subscribers.values(), event, external_gather=self.external_gathers.get(event.__class__, None)))
task = loop.create_task(
dispatch(
publisher.subscribers.values(),
event,
external_gather=self.external_gathers.get(event.__class__, None),
)
)
self._ref_tasks.add(task)
task.add_done_callback(self._ref_tasks.discard)
return task
if hasattr(event, "__publisher__") and (pub := self.publishers.get(event.__publisher__)):
task = loop.create_task(dispatch(pub.subscribers.values(), event, external_gather=self.external_gathers.get(event.__class__, None)))
task = loop.create_task(
dispatch(
pub.subscribers.values(), event, external_gather=self.external_gathers.get(event.__class__, None)
)
)
self._ref_tasks.add(task)
task.add_done_callback(self._ref_tasks.discard)
return task
Expand All @@ -107,28 +121,49 @@ def publish(self, event: Any, publisher: str | Publisher | None = None):
return task

@overload
def post(self, event: Resultable[T], publisher: str | Publisher | None = None) -> asyncio.Task[Result[T] | None]:
...
def post(
self, event: Resultable[T], publisher: str | Publisher | None = None
) -> asyncio.Task[Result[T] | None]: ...

@overload
def post(self, event: Any, publisher: str | Publisher | None = None) -> asyncio.Task[Result[Any] | None]:
...
def post(self, event: Any, publisher: str | Publisher | None = None) -> asyncio.Task[Result[Any] | None]: ...

def post(self, event: Any, publisher: str | Publisher | None = None):
"""发布事件并返回第一个响应结果"""
loop = asyncio.get_running_loop()
if isinstance(publisher, str) and (pub := self.publishers.get(publisher)):
task = loop.create_task(dispatch(pub.subscribers.values(), event, return_result=True, external_gather=self.external_gathers.get(event.__class__, None)))
task = loop.create_task(
dispatch(
pub.subscribers.values(),
event,
return_result=True,
external_gather=self.external_gathers.get(event.__class__, None),
)
)
self._ref_tasks.add(task)
task.add_done_callback(self._ref_tasks.discard)
return task
if isinstance(publisher, Publisher):
task = loop.create_task(dispatch(publisher.subscribers.values(), event, return_result=True, external_gather=self.external_gathers.get(event.__class__, None)))
task = loop.create_task(
dispatch(
publisher.subscribers.values(),
event,
return_result=True,
external_gather=self.external_gathers.get(event.__class__, None),
)
)
self._ref_tasks.add(task)
task.add_done_callback(self._ref_tasks.discard)
return task
if hasattr(event, "__publisher__") and (pub := self.publishers.get(event.__publisher__)):
task = loop.create_task(dispatch(pub.subscribers.values(), event, return_result=True, external_gather=self.external_gathers.get(event.__class__, None)))
task = loop.create_task(
dispatch(
pub.subscribers.values(),
event,
return_result=True,
external_gather=self.external_gathers.get(event.__class__, None),
)
)
self._ref_tasks.add(task)
task.add_done_callback(self._ref_tasks.discard)
return task
Expand All @@ -154,11 +189,10 @@ def on(
*,
priority: int = 16,
auxiliaries: list[BaseAuxiliary] | None = None,
providers: Sequence[
Provider[Any] | type[Provider[Any]] | ProviderFactory | type[ProviderFactory]
] | None = None,
) -> Subscriber:
...
providers: (
Sequence[Provider[Any] | type[Provider[Any]] | ProviderFactory | type[ProviderFactory]] | None
) = None,
) -> Subscriber: ...

@overload
def on(
Expand All @@ -167,40 +201,40 @@ def on(
*,
priority: int = 16,
auxiliaries: list[BaseAuxiliary] | None = None,
providers: Sequence[
Provider[Any] | type[Provider[Any]] | ProviderFactory | type[ProviderFactory]
] | None = None,
) -> Callable[[Callable[..., Any]], Subscriber]:
...
providers: (
Sequence[Provider[Any] | type[Provider[Any]] | ProviderFactory | type[ProviderFactory]] | None
) = None,
) -> Callable[[Callable[..., Any]], Subscriber]: ...

@overload
def on(
self,
*,
priority: int = 16,
auxiliaries: list[BaseAuxiliary] | None = None,
providers: Sequence[
Provider[Any] | type[Provider[Any]] | ProviderFactory | type[ProviderFactory]
] | None = None,
) -> Callable[[Callable[..., Any]], Subscriber]:
...
providers: (
Sequence[Provider[Any] | type[Provider[Any]] | ProviderFactory | type[ProviderFactory]] | None
) = None,
) -> Callable[[Callable[..., Any]], Subscriber]: ...

def on(
self,
events: type | tuple[type, ...] | None = None,
func: Callable[..., Any] | None = None,
priority: int = 16,
auxiliaries: list[BaseAuxiliary] | None = None,
providers: Sequence[
Provider[Any] | type[Provider[Any]] | ProviderFactory | type[ProviderFactory]
] | None = None,
providers: (
Sequence[Provider[Any] | type[Provider[Any]] | ProviderFactory | type[ProviderFactory]] | None
) = None,
):
if not (pub := publisher_ctx.get()):
if not events:
pub = self._backend_publisher
else:
events = events if isinstance(events, tuple) else (events,)
if len(events) == 1 and (hasattr(e := events[0], "__publisher__") and e.__publisher__ in self.publishers):
if len(events) == 1 and (
hasattr(e := events[0], "__publisher__") and e.__publisher__ in self.publishers
):
pub = self.publishers[e.__publisher__]
else:
pub = Publisher(f"global::{sorted(events, key=lambda e: id(e))}", *events)
Expand All @@ -221,11 +255,10 @@ def use(
*,
priority: int = 16,
auxiliaries: list[BaseAuxiliary] | None = None,
providers: Sequence[
Provider[Any] | type[Provider[Any]] | ProviderFactory | type[ProviderFactory]
] | None = None,
) -> Subscriber:
...
providers: (
Sequence[Provider[Any] | type[Provider[Any]] | ProviderFactory | type[ProviderFactory]] | None
) = None,
) -> Subscriber: ...

@overload
def use(
Expand All @@ -234,33 +267,31 @@ def use(
*,
priority: int = 16,
auxiliaries: list[BaseAuxiliary] | None = None,
providers: Sequence[
Provider[Any] | type[Provider[Any]] | ProviderFactory | type[ProviderFactory]
] | None = None,
) -> Callable[[Callable[..., Any]], Subscriber]:
...
providers: (
Sequence[Provider[Any] | type[Provider[Any]] | ProviderFactory | type[ProviderFactory]] | None
) = None,
) -> Callable[[Callable[..., Any]], Subscriber]: ...

@overload
def use(
self,
*,
priority: int = 16,
auxiliaries: list[BaseAuxiliary] | None = None,
providers: Sequence[
Provider[Any] | type[Provider[Any]] | ProviderFactory | type[ProviderFactory]
] | None = None,
) -> Callable[[Callable[..., Any]], Subscriber]:
...
providers: (
Sequence[Provider[Any] | type[Provider[Any]] | ProviderFactory | type[ProviderFactory]] | None
) = None,
) -> Callable[[Callable[..., Any]], Subscriber]: ...

def use(
self,
pub: str | Publisher | None = None,
func: Callable[..., Any] | None = None,
priority: int = 16,
auxiliaries: list[BaseAuxiliary] | None = None,
providers: Sequence[
Provider[Any] | type[Provider[Any]] | ProviderFactory | type[ProviderFactory]
] | None = None,
providers: (
Sequence[Provider[Any] | type[Provider[Any]] | ProviderFactory | type[ProviderFactory]] | None
) = None,
):
if not pub:
publisher = publisher_ctx.get() or self._backend_publisher
Expand Down
Loading

0 comments on commit ec0752a

Please sign in to comment.