Skip to content

Commit f389e39

Browse files
author
remimd
committed
refacto
1 parent 060d901 commit f389e39

9 files changed

Lines changed: 56 additions & 39 deletions

File tree

documentation/integrations.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,14 +63,14 @@ async def lifespan(_: FastAPI) -> AsyncIterator[None]:
6363

6464
app = FastAPI(lifespan=lifespan)
6565

66-
request_slot = reserve_scoped_slot(Request, InjectionScope.REQUEST)
66+
request_slot_key = reserve_scoped_slot(Request, InjectionScope.REQUEST)
6767

6868
@app.middleware("http")
6969
async def define_request_scope_middleware(
7070
request: Request,
7171
handler: Callable[[Request], Awaitable[Response]],
7272
) -> Response:
7373
async with adefine_scope(InjectionScope.REQUEST) as scope:
74-
scope.set_slot(request_slot, request)
74+
scope.set_slot(request_slot_key, request)
7575
return await handler(request)
7676
```

documentation/scoped-dependencies.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,10 @@ from injection import define_scope, reserve_scoped_slot
110110

111111
class Request: ...
112112

113-
request_slot = reserve_scoped_slot(Request, scope_name="request")
113+
request_slot_key = reserve_scoped_slot(Request, scope_name="request")
114114

115115
def process_request(request: Request) -> None:
116116
with define_scope("request") as scope:
117-
scope.set_slot(request_slot, request)
117+
scope.set_slot(request_slot_key, request)
118118
# ...
119119
```

injection/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from ._core.module import Mode, Module, Priority, mod
44
from ._core.scope import ScopeFacade as Scope
55
from ._core.scope import ScopeKind, adefine_scope, define_scope
6-
from ._core.slots import Slot
6+
from ._core.slots import SlotKey
77

88
__all__ = (
99
"Injectable",
@@ -13,7 +13,7 @@
1313
"Priority",
1414
"Scope",
1515
"ScopeKind",
16-
"Slot",
16+
"SlotKey",
1717
"adefine_scope",
1818
"afind_instance",
1919
"aget_instance",

injection/__init__.pyi

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,13 @@ singleton = __MODULE.singleton
3333
@asynccontextmanager
3434
def adefine_scope(
3535
name: str,
36+
/,
3637
kind: ScopeKind | ScopeKindStr = ...,
3738
) -> AsyncIterator[Scope]: ...
3839
@contextmanager
3940
def define_scope(
4041
name: str,
42+
/,
4143
kind: ScopeKind | ScopeKindStr = ...,
4244
) -> Iterator[Scope]: ...
4345
def mod(name: str = ..., /) -> Module:
@@ -59,11 +61,14 @@ class ScopeKind(Enum):
5961
CONTEXTUAL = ...
6062
SHARED = ...
6163

62-
class Scope:
63-
def set_slot[T](self, slot: Slot[T], value: T) -> Self: ...
64-
def slot_map(self, values: Mapping[Slot[Any], Any]) -> Self: ...
64+
@runtime_checkable
65+
class Scope(Protocol):
66+
@abstractmethod
67+
def set_slot[T](self, key: SlotKey[T], value: T) -> Self: ...
68+
@abstractmethod
69+
def slot_map(self, mapping: Mapping[SlotKey[Any], Any], /) -> Self: ...
6570

66-
class Slot[T]: ...
71+
class SlotKey[T]: ...
6772

6873
class LazyInstance[T]:
6974
def __init__(
@@ -197,7 +202,7 @@ class Module:
197202
scope_name: str,
198203
*,
199204
mode: Mode | ModeStr = ...,
200-
) -> Slot[T]: ...
205+
) -> SlotKey[T]: ...
201206
def make_injected_function[**P, T](
202207
self,
203208
wrapped: Callable[P, T],

injection/_core/injectables.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
in_scope_cache,
2424
remove_scoped_values,
2525
)
26-
from injection._core.slots import Slot
26+
from injection._core.slots import SlotKey
2727
from injection.exceptions import EmptySlotError, InjectionError
2828

2929

@@ -197,11 +197,11 @@ def unlock(self) -> None:
197197
class ScopedSlotInjectable[T](Injectable[T]):
198198
cls: type[T]
199199
scope_name: str
200-
slot: Slot[T] = field(default_factory=Slot)
200+
key: SlotKey[T] = field(default_factory=SlotKey)
201201

202202
@property
203203
def is_locked(self) -> bool:
204-
return in_scope_cache(self.slot, self.scope_name)
204+
return in_scope_cache(self.key, self.scope_name)
205205

206206
async def aget_instance(self) -> T:
207207
return self.get_instance()
@@ -211,14 +211,14 @@ def get_instance(self) -> T:
211211
scope = get_scope(scope_name)
212212

213213
try:
214-
return scope.cache[self.slot]
214+
return scope.cache[self.key]
215215
except KeyError as exc:
216216
raise EmptySlotError(
217217
f"The slot for `{self.cls}` isn't set in the current `{scope_name}` scope."
218218
) from exc
219219

220220
def unlock(self) -> None:
221-
remove_scoped_values(self.slot, self.scope_name)
221+
remove_scoped_values(self.key, self.scope_name)
222222

223223

224224
@dataclass(repr=False, eq=False, frozen=True, slots=True)

injection/_core/module.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@
7070
SimpleScopedInjectable,
7171
SingletonInjectable,
7272
)
73-
from injection._core.slots import Slot
73+
from injection._core.slots import SlotKey
7474
from injection.exceptions import (
7575
ModuleError,
7676
ModuleLockError,
@@ -492,11 +492,8 @@ def decorator(
492492

493493
def should_be_injectable[T](self, wrapped: type[T] | None = None, /) -> Any:
494494
def decorator(wp: type[T]) -> type[T]:
495-
updater = Updater(
496-
classes=(wp,),
497-
injectable=ShouldBeInjectable(wp),
498-
mode=Mode.FALLBACK,
499-
)
495+
injectable = ShouldBeInjectable(wp)
496+
updater = Updater.with_basics(wp, injectable, Mode.FALLBACK)
500497
self.update(updater)
501498
return wp
502499

@@ -548,11 +545,11 @@ def reserve_scoped_slot[T](
548545
scope_name: str,
549546
*,
550547
mode: Mode | ModeStr = Mode.get_default(),
551-
) -> Slot[T]:
548+
) -> SlotKey[T]:
552549
injectable = ScopedSlotInjectable(cls, scope_name)
553550
updater = Updater.with_basics(cls, injectable, mode)
554551
self.update(updater)
555-
return injectable.slot
552+
return injectable.key
556553

557554
def inject[**P, T](
558555
self,

injection/_core/scope.py

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
)
2424

2525
from injection._core.common.key import new_short_key
26-
from injection._core.slots import Slot
26+
from injection._core.slots import SlotKey
2727
from injection.exceptions import (
2828
InjectionError,
2929
ScopeAlreadyDefinedError,
@@ -127,6 +127,7 @@ def get_scope(self) -> Scope | None:
127127
@asynccontextmanager
128128
async def adefine_scope(
129129
name: str,
130+
/,
130131
kind: ScopeKind | ScopeKindStr = ScopeKind.get_default(),
131132
) -> AsyncIterator[ScopeFacade]:
132133
async with AsyncScope() as scope:
@@ -137,6 +138,7 @@ async def adefine_scope(
137138
@contextmanager
138139
def define_scope(
139140
name: str,
141+
/,
140142
kind: ScopeKind | ScopeKindStr = ScopeKind.get_default(),
141143
) -> Iterator[ScopeFacade]:
142144
with SyncScope() as scope:
@@ -208,7 +210,7 @@ def _bind_scope(
208210
)
209211

210212
with states[name].bind(scope):
211-
yield ScopeFacade(scope)
213+
yield _UserScope(scope)
212214

213215

214216
@runtime_checkable
@@ -286,19 +288,32 @@ def enter[T](self, context_manager: ContextManager[T]) -> T:
286288
return self.delegate.enter_context(context_manager)
287289

288290

291+
@runtime_checkable
292+
class ScopeFacade(Protocol):
293+
__slots__ = ()
294+
295+
@abstractmethod
296+
def set_slot[T](self, key: SlotKey[T], value: T) -> Self:
297+
raise NotImplementedError
298+
299+
@abstractmethod
300+
def slot_map(self, mapping: Mapping[SlotKey[Any], Any], /) -> Self:
301+
raise NotImplementedError
302+
303+
289304
@dataclass(repr=False, frozen=True, slots=True)
290-
class ScopeFacade:
305+
class _UserScope(ScopeFacade):
291306
scope: Scope
292307

293-
def set_slot[T](self, slot: Slot[T], value: T) -> Self:
294-
return self.slot_map({slot: value})
308+
def set_slot[T](self, key: SlotKey[T], value: T) -> Self:
309+
return self.slot_map({key: value})
295310

296-
def slot_map(self, values: Mapping[Slot[Any], Any]) -> Self:
311+
def slot_map(self, mapping: Mapping[SlotKey[Any], Any], /) -> Self:
297312
cache = self.scope.cache
298313

299-
for slot in values:
300-
if slot in cache:
314+
for slot_key in mapping:
315+
if slot_key in cache:
301316
raise InjectionError("Slot already set.")
302317

303-
cache.update(values)
318+
cache.update(mapping)
304319
return self

injection/_core/slots.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
class Slot[T]:
1+
class SlotKey[T]:
22
__slots__ = ()

tests/core/test_module.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -215,11 +215,11 @@ def test_set_constant_with_success_with_type_alias(self, module):
215215

216216
def test_reserve_scoped_slot_with_success(self, module):
217217
scope_name = "test"
218-
slot = module.reserve_scoped_slot(SomeClass, scope_name)
218+
slot_key = module.reserve_scoped_slot(SomeClass, scope_name)
219219

220220
with define_scope(scope_name) as scope:
221221
instance = SomeClass()
222-
scope.set_slot(slot, instance)
222+
scope.set_slot(slot_key, instance)
223223

224224
assert module.get_instance(SomeClass) is instance
225225

@@ -238,16 +238,16 @@ def test_reserve_scoped_slot_with_several_definitions_raise_injection_error(
238238
module,
239239
):
240240
scope_name = "test"
241-
slot = module.reserve_scoped_slot(SomeClass, scope_name)
241+
slot_key = module.reserve_scoped_slot(SomeClass, scope_name)
242242

243243
with define_scope(scope_name) as scope:
244244
instance1 = SomeClass()
245-
scope.set_slot(slot, instance1)
245+
scope.set_slot(slot_key, instance1)
246246

247247
instance2 = SomeClass()
248248

249249
with pytest.raises(InjectionError):
250-
scope.set_slot(slot, instance2)
250+
scope.set_slot(slot_key, instance2)
251251

252252
"""
253253
init_modules

0 commit comments

Comments
 (0)