Skip to content

Commit a134b85

Browse files
committed
Fix ty type check
1 parent 62374d4 commit a134b85

2 files changed

Lines changed: 25 additions & 14 deletions

File tree

graphqler/utils/singleton.py

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,28 @@
1-
def singleton(myClass):
2-
instances = {}
1+
from typing import Any, Generic, TypeVar
32

4-
def getInstance(*args, **kwargs):
5-
if myClass not in instances:
6-
instances[myClass] = myClass(*args, **kwargs)
7-
return instances[myClass]
3+
_T = TypeVar("_T")
84

9-
# Expose the original class so callers can create fresh non-singleton instances
10-
# when needed (e.g. per-chain ObjectsBucket in the fuzzer):
11-
# fresh_bucket = ObjectsBucket.__wrapped__(api)
12-
setattr(getInstance, "__wrapped__", myClass)
135

14-
# Allow clearing the cached instance (useful for test isolation).
15-
setattr(getInstance, "reset", lambda: instances.pop(myClass, None))
6+
class _SingletonCallable(Generic[_T]):
7+
"""Callable wrapper returned by the @singleton decorator.
168
17-
return getInstance
9+
Exposes the original class as ``__wrapped__`` and provides a ``reset()``
10+
helper that clears the cached instance (useful for test isolation).
11+
"""
12+
13+
def __init__(self, cls: type[_T]) -> None:
14+
self.__wrapped__: type[_T] = cls
15+
self._instances: dict[type[_T], _T] = {}
16+
17+
def __call__(self, *args: Any, **kwargs: Any) -> _T:
18+
if self.__wrapped__ not in self._instances:
19+
self._instances[self.__wrapped__] = self.__wrapped__(*args, **kwargs)
20+
return self._instances[self.__wrapped__]
21+
22+
def reset(self) -> None:
23+
"""Clear the cached instance so the next call creates a fresh one."""
24+
self._instances.pop(self.__wrapped__, None)
25+
26+
27+
def singleton(myClass: type[_T]) -> _SingletonCallable[_T]:
28+
return _SingletonCallable(myClass)

tests/unit/utils/test_objects_bucket_connection.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def _build_bucket(connection_fields=None):
5353

5454
# Access the underlying class to bypass the singleton decorator for isolated testing.
5555
# ObjectsBucket.__wrapped__ is the original undecorated class set by the @singleton decorator.
56-
real_cls = ObjectsBucket.__wrapped__
56+
real_cls = ObjectsBucket.__wrapped__ # type: ignore
5757
bucket = real_cls.__new__(real_cls)
5858
bucket.api = api
5959
bucket.objects = {}

0 commit comments

Comments
 (0)