I often use the following construct to generate singletons in my code:
class Thing:
pass
class ThingSingletonFactory:
_thing = None
def __new__(cls) -> Thing:
if cls._thing is None:
cls._thing = Thing()
return cls._thing
def get_thing() -> Thing:
return ThingSingletonFactory()
thing = get_thing()
same_thing = get_thing()
assert thing is same_thing
class ThingSingletonFactory
stores the only instance of Thing
, and returns it anytime a new ThingSingletonFactory()
is requested. Works great for API clients, logging.Logger, etc.
I'm adding mypy type checking to an existing project that uses this, and mypy does not like it, at all.
line 8: error: Incompatible return type for "__new__" (returns "Thing", but must return a subtype of "ThingSingletonFactory") [misc]
line 15: error: Incompatible return value type (got "ThingSingletonFactory", expected "Thing") [return-value]
I feel the type hints in the code are correct: __new__()
does return the type Thing, as does the func get_thing()
.
How can I provide mypy the hints required to make it happy? Or is this construct simply considered "bad" ?