- Notifications
You must be signed in to change notification settings - Fork263
Description
The problem I'm having is that thetype
doesn't supportParamSpec
, so I can't use that to enforceargs
andkwargs
, in the same way as asCallable
. I'm not 100% sure whether this is correct, but isn't everytype
aCallable
, so in a sense thattype
is a subtype ofCallable
, so there should be a way to representtype
in the same way as aCallable
to obey Liskov?
For example, I'm trying to write an overload such that passing in atype
will returnExpectType
, while a generalCallable
returnsExpectCallable
:
fromcollections.abcimportCallableimporttyping_extensionsastP=t.ParamSpec("P")T_co=t.TypeVar("T_co",covariant=True)classExpectCallable(t.Generic[P,T_co]): ...classExpectType(ExpectCallable[P,T_co]): ...@t.overloaddefexpect(v:type[T_co],/,*args:P.args,**kwargs:P.kwargs)->ExpectType[P,T_co]: ...@t.overloaddefexpect(v:Callable[P,T_co],/,*args:P.args,**kwargs:P.kwargs)->ExpectCallable[P,T_co]: ...defexpect(v:type[T_co]|Callable[P,T_co],/,*args:P.args,**kwargs:P.kwargs)->ExpectType[P,T_co]|ExpectCallable[P,T_co]:returnExpectType()ifisinstance(v,type)elseExpectCallable()classA:def__init__(self,inp:str,/)->None: ...deffn(inp:str,/)->None: ...t.assert_type(expect(A),ExpectType[[],A])# Shouldn't be allowedt.assert_type(expect(fn,"inp"),ExpectCallable[[str],None])
As you can see thatt.assert_type(expect(A), ExpectType[[], A])
passes with no errors, even thoughA
is suppose to take in astr
argument. I'm expectingexpect(A)
to require astr
argument, similar to howexpect(fn, "inp")
requires the second parameter"inp"
.
Note that I haven't used*args
and**kwargs
in the example for simplicity, but they are meant to be used inside of theExpect
classes.
Maybe the simplest way is to add a new classTypeCallable
that allows forTypeCallable[P, T]
instead of modifyingtype
, so the above example is achievable:
@t.overloaddefexpect(v:TypeCallable[P,T_co],/,*args:P.args,**kwargs:P.kwargs)->ExpectType[P,T_co]: ...@t.overloaddefexpect(v:Callable[P,T_co],/,*args:P.args,**kwargs:P.kwargs)->ExpectCallable[P,T_co]: ...defexpect(v:TypeCallable[P,T_co]|Callable[P,T_co],/,*args:P.args,**kwargs:P.kwargs)->ExpectType[P,T_co]|ExpectCallable[P,T_co]:returnExpectType()ifisinstance(v,type)elseExpectCallable()
Note that I think#1966 might also solve the above problem.