Say i have a function, that makes an instance of incoming class.
def instantiate[T](class_: type[T], a: int, b: str) -> T:
return class_(a, b)
I want type checker to be able to say if a class is fit for this function or not, i. e. if its __init__
signature supports such instatiation.
I thought of using Protocol
class FitForInstantiate(Protocol):
__init__: Callable[[int, str], None]
and then saying that class T
must comply to it.
def instantiate[T: FitForInstantiate](class_: type[T], a: int, b: str) -> T:
return class_(a, b)
Then for classes
class A:
def __init__(self, a: int, b: str):
self.a = a
self.b = b
class B:
def __init__(self, a: int, b: int):
self.a = a
self.b = b
typechecker pyright will accept A
as an argument for instantiate
, but will print an error for B
. But if i then expand A
‘s signature:
class A:
def __init__(self, a: int, b: str, c: list | None = None):
self.a = a
self.b = b
self.c = c or []
it will no longer comply to a protocol. And even though it is still good for instatiate
, pyright will print an error for it too.
Is there a way to use Python typing such that all classes with fitting __init__
signatures will be considered correct type?
3
This is possible when you change the signature of instatiate
def instantiate(class_: typing.Callable[[int,str], T], a: int, b: str) -> T:
return class_(a, b)
(Maybe rename ‘class_’ to ‘constructor’ or so)
Now use with
ainst = instantiate( A, 1, 'xyz' )
binst = instantiate( B, 1, 'xyz' ) # this will trigger a type checker warning
The disadvantage is that you do not tell the type checker that ‘class_’ is a class variable itself. So if you want to use class-like aspects of the ‘class_’ variable in instantiate
the type checker would not allow. After the object is constructed it could be mitigated as is possible to obtain the class variable via type
. But I dont see a way to get the class object before the instance is created.
The advantage is that you can use this to match the parameter types as well. Either as total (with ParamSpec) or individually with type variables.
1