Skip to content

Commit 8c69bfb

Browse files
Add decorator utility methods
1 parent 15e01d2 commit 8c69bfb

File tree

2 files changed

+102
-13
lines changed

2 files changed

+102
-13
lines changed

alluka/managed/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,14 @@
3232

3333
from __future__ import annotations
3434

35-
__all__: list[str] = ["ConfigFile", "Manager", "PluginConfig"]
35+
__all__: list[str] = ["ConfigFile", "Manager", "PluginConfig", "TypeConfig"]
3636

3737
import typing
3838

3939
from . import _index
4040
from ._config import ConfigFile as ConfigFile
4141
from ._config import PluginConfig as PluginConfig # noqa: TC002
42+
from ._config import TypeConfig as TypeConfig
4243
from ._manager import Manager as Manager
4344

4445
if typing.TYPE_CHECKING:

alluka/managed/_config.py

Lines changed: 100 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,15 @@
3737
from collections import abc as collections
3838

3939
if typing.TYPE_CHECKING:
40+
import typing_extensions
4041
from typing_extensions import Self
4142

43+
_P = typing_extensions.ParamSpec("_P")
4244
_CoroT = collections.Coroutine[typing.Any, typing.Any, "_T"]
4345

4446

4547
_T = typing.TypeVar("_T")
48+
_OtherT = typing.TypeVar("_OtherT")
4649
_DictKeyT = typing.Union[str, int, float, bool, None]
4750
_DictValueT = typing.Union[
4851
collections.Mapping[_DictKeyT, "_DictValueT"], collections.Sequence["_DictValueT"], _DictKeyT
@@ -56,7 +59,7 @@ class TypeConfig(typing.Generic[_T]):
5659
these.
5760
"""
5861

59-
__slots__ = ("_async_cleanup", "_async_create", "_cleanup", "_create", "_dep_type", "_dependencies", "_name")
62+
__slots__ = ("_async_cleanup", "_async_create", "_cleanup", "_create", "_dep_type", "_name")
6063

6164
@typing.overload
6265
def __init__(
@@ -69,7 +72,6 @@ def __init__(
6972
async_create: collections.Callable[..., _CoroT[_T]],
7073
cleanup: typing.Optional[collections.Callable[[_T], None]] = None,
7174
create: typing.Optional[collections.Callable[..., _T]] = None,
72-
dependencies: collections.Sequence[type[typing.Any]] = (),
7375
) -> None: ...
7476

7577
@typing.overload
@@ -83,7 +85,6 @@ def __init__(
8385
async_create: typing.Optional[collections.Callable[..., _CoroT[_T]]] = None,
8486
cleanup: typing.Optional[collections.Callable[[_T], None]] = None,
8587
create: collections.Callable[..., _T],
86-
dependencies: collections.Sequence[type[typing.Any]] = (),
8788
) -> None: ...
8889

8990
def __init__(
@@ -96,7 +97,6 @@ def __init__(
9697
async_create: typing.Optional[collections.Callable[..., _CoroT[_T]]] = None,
9798
cleanup: typing.Optional[collections.Callable[[_T], None]] = None,
9899
create: typing.Optional[collections.Callable[..., _T]] = None,
99-
dependencies: collections.Sequence[type[typing.Any]] = (),
100100
) -> None:
101101
"""Initialise a type config.
102102
@@ -119,8 +119,6 @@ def __init__(
119119
Callback used to use to destroy the dependency in a sync runtime.
120120
create
121121
Callback used to use to create the dependency in a sync runtime.
122-
dependencies
123-
Sequence of type dependencies that are required to create this dependency.
124122
125123
Raises
126124
------
@@ -135,9 +133,56 @@ def __init__(
135133
self._cleanup = cleanup
136134
self._create = create
137135
self._dep_type = dep_type
138-
self._dependencies = dependencies
139136
self._name = name
140137

138+
@classmethod
139+
def from_create(
140+
cls, dep_type: type[_OtherT], name: str, /
141+
) -> collections.Callable[[collections.Callable[..., _OtherT]], TypeConfig[_OtherT]]:
142+
"""Initialise a type config by decorating a sync create callback.
143+
144+
Parameters
145+
----------
146+
dep_type
147+
Type of the dep this should be registered for.
148+
name
149+
Name used to identify this type dependency in configuration files.
150+
151+
Returns
152+
-------
153+
TypeConfig
154+
The created type config.
155+
"""
156+
157+
def decorator(callback: collections.Callable[..., _OtherT], /) -> TypeConfig[_OtherT]:
158+
return cls(dep_type, name, create=callback)
159+
160+
return decorator
161+
162+
@classmethod
163+
def from_async_create(
164+
cls, dep_type: type[_OtherT], name: str, /
165+
) -> collections.Callable[[collections.Callable[..., _CoroT[_OtherT]]], TypeConfig[_OtherT]]:
166+
"""Initialise a type config by decorating an async create callback.
167+
168+
Parameters
169+
----------
170+
dep_type
171+
Type of the dep this should be registered for.
172+
name
173+
Name used to identify this type dependency in configuration files.
174+
175+
Returns
176+
-------
177+
TypeConfig
178+
The created type config.
179+
"""
180+
181+
def decorator(callback: collections.Callable[..., _CoroT[_OtherT]], /) -> TypeConfig[_OtherT]:
182+
return cls(dep_type, name, async_create=callback)
183+
184+
return decorator
185+
141186
@property
142187
def async_cleanup(self) -> typing.Optional[collections.Callable[[_T], _CoroT[None]]]:
143188
"""Callback used to use to cleanup the dependency in an async runtime."""
@@ -163,16 +208,59 @@ def dep_type(self) -> type[_T]:
163208
"""The type created values should be registered as a type dependency for."""
164209
return self._dep_type
165210

166-
@property
167-
def dependencies(self) -> collections.Sequence[type[typing.Any]]:
168-
"""Sequence of type dependencies that are required to create this dependency."""
169-
return self._dependencies
170-
171211
@property
172212
def name(self) -> str:
173213
"""Name used to identify this type dependency in configuration files."""
174214
return self._name
175215

216+
def with_create(self, callback: collections.Callable[_P, _T], /) -> collections.Callable[_P, _T]:
217+
"""Set the synchronous create callback through a decorator call.
218+
219+
Parameters
220+
----------
221+
callback
222+
The callback to set as the synchronous create callback.
223+
"""
224+
self._create = callback
225+
return callback
226+
227+
def with_async_create(
228+
self, callback: collections.Callable[_P, _CoroT[_T]], /
229+
) -> collections.Callable[_P, _CoroT[_T]]:
230+
"""Set the asynchronous create callback through a decorator call.
231+
232+
Parameters
233+
----------
234+
callback
235+
The callback to set as the asynchronous create callback.
236+
"""
237+
self._async_create = callback
238+
return callback
239+
240+
def with_cleanup(self, callback: collections.Callable[[_T], None], /) -> collections.Callable[[_T], None]:
241+
"""Set the synchronous cleanup callback through a decorator call.
242+
243+
Parameters
244+
----------
245+
callback
246+
The callback to set as the asynchronous cleanup callback.
247+
"""
248+
self._cleanup = callback
249+
return callback
250+
251+
def with_async_cleanup(
252+
self, callback: collections.Callable[[_T], _CoroT[None]], /
253+
) -> collections.Callable[[_T], _CoroT[None]]:
254+
"""Set the asynchronous cleanup callback through a decorator call.
255+
256+
Parameters
257+
----------
258+
callback
259+
The callback to set as the synchronous cleanup callback.
260+
"""
261+
self._async_cleanup = callback
262+
return callback
263+
176264

177265
class PluginConfig(abc.ABC):
178266
"""Base class used for configuring plugins loaded via Alluka's manager.

0 commit comments

Comments
 (0)