I have been trying to use the Singleton pattern in Python with proper type hints.
Here is my attempt
from typing import Any, TypeVar, override
T = TypeVar('T', bound='SingletonBase')
class Singleton(type):
_instances: dict[type[T], T] = {} # type variable T has no meaning in this context
@override
def __call__(cls: type[T], *args: Any, **kwargs: dict[str, Any]) -> T:
if cls not in cls._instances: # Access to generic instance variable through class is ambiguous
instance = super().__call__(*args, **kwargs)
cls._instances[cls] = instance # Access to generic instance variable through class is ambiguous
return cls._instances[cls] # Expression of type T is incompatible with return type T@__call__
class SingletonBase(metaclass=Singleton):
pass
I get a lot of complaints from the type checker. (I have annotate my code with the complaints as comments)
I found this answer Type hinting for generic singleton?
But that only handles annotations for the return type. I would like to understand what’s going on here and learn how to implement the Singleton pattern with proper type hints.