Skip to content

Commit ae39942

Browse files
authored
fix: Unexpected RecursionError
1 parent adcb7e2 commit ae39942

File tree

3 files changed

+230
-266
lines changed

3 files changed

+230
-266
lines changed

injection/_core/injectables.py

Lines changed: 5 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from abc import ABC, abstractmethod
2-
from collections.abc import Awaitable, Callable, Iterator, MutableMapping
3-
from contextlib import contextmanager, suppress
2+
from collections.abc import Awaitable, Callable, MutableMapping
3+
from contextlib import suppress
44
from dataclasses import dataclass, field
55
from functools import partial
66
from typing import (
@@ -53,13 +53,11 @@ def get_instance(self) -> T:
5353

5454

5555
class CacheLogic[T]:
56-
__slots__ = ("__is_instantiating", "__semaphore")
56+
__slots__ = ("__semaphore",)
5757

58-
__is_instantiating: bool
5958
__semaphore: AsyncContextManager[Any]
6059

6160
def __init__(self) -> None:
62-
self.__is_instantiating = False
6361
self.__semaphore = AsyncSemaphore(1)
6462

6563
async def aget_or_create[K](
@@ -68,14 +66,11 @@ async def aget_or_create[K](
6866
key: K,
6967
factory: Callable[..., Awaitable[T]],
7068
) -> T:
71-
self.__fail_if_instantiating()
7269
async with self.__semaphore:
7370
with suppress(KeyError):
7471
return cache[key]
7572

76-
with self.__instantiating():
77-
instance = await factory()
78-
73+
instance = await factory()
7974
cache[key] = instance
8075

8176
return instance
@@ -86,29 +81,13 @@ def get_or_create[K](
8681
key: K,
8782
factory: Callable[..., T],
8883
) -> T:
89-
self.__fail_if_instantiating()
9084
with suppress(KeyError):
9185
return cache[key]
9286

93-
with self.__instantiating():
94-
instance = factory()
95-
87+
instance = factory()
9688
cache[key] = instance
9789
return instance
9890

99-
def __fail_if_instantiating(self) -> None:
100-
if self.__is_instantiating:
101-
raise RecursionError("Recursive call detected during instantiation.")
102-
103-
@contextmanager
104-
def __instantiating(self) -> Iterator[None]:
105-
self.__is_instantiating = True
106-
107-
try:
108-
yield
109-
finally:
110-
self.__is_instantiating = False
111-
11291

11392
@dataclass(repr=False, eq=False, frozen=True, slots=True)
11493
class SingletonInjectable[T](Injectable[T]):

tests/test_singleton.py

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -183,18 +183,3 @@ class C(B): ...
183183

184184
a = get_instance(A)
185185
assert isinstance(a, C)
186-
187-
async def test_singleton_with_circular_dependency_raise_recursion_error(self):
188-
class A: ...
189-
190-
@singleton
191-
@dataclass
192-
class B:
193-
a: A
194-
195-
@singleton
196-
async def a_factory(_b: B) -> A:
197-
return A() # pragma: no cover
198-
199-
with pytest.raises(RecursionError):
200-
await aget_instance(A)

0 commit comments

Comments
 (0)