How do I type hint a static method as a class (static) attribute? #9317
-
I want to define an interface for defining methods associated with a class that corresponds to a Callable signature defined elsewhere. How can I get the following to work? Code sample in pyright playground from typing import Callable, Protocol
type FooFun = Callable[[int], int]
class MyInterface(Protocol):
function: FooFun
class MyConcrete(MyInterface):
@staticmethod
def function(my_int: int) -> int: # Base method is declared as an instance method but override is not
return my_int
class MySecondConcrete(MyInterface):
def function(self, my_int: int) -> int: # Positional parameter count mismatch; base method has 1, but override has 2
return my_int Of course, there is also the conventional option of just simply using regular static method function signatures ( |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 4 replies
-
If I understand you correctly, you want to define some protocol from typing import Protocol
class MyInterface(Protocol):
def function(self, my_int: int) -> int: ...
class MyConcrete:
@staticmethod
def function(my_int: int) -> int:
return my_int
class MySecondConcrete:
def function(self, my_int: int) -> int:
return my_int
x1: MyInterface = MyConcrete()
x2: MyInterface = MySecondConcrete() Note that in my formulation, the two concrete classes don't directly inherit from the protocol. This allows them to match the protocol without resulting in override violations. Override checks are necessarily more strict than protocol matching because a subclass might be used as either a class object or a class instance, and it needs to follow the LSP (Liskov Substitution Principle) in both cases. A protocol simply needs to work with class instances. I'll note that protocol matching rules are clearly defined in the typing spec. However, the typing spec doesn't currently define the rules for overrides. It's an area where additional work is needed. That said, I think pyright's override rules in this case are defensible and correct from a typing perspective. |
Beta Was this translation helpful? Give feedback.
As I mentioned above, overrides need to honor the LSP regardless of whether you access the attribute from the class object or from an instance of that class. This is required because
Child
is a subtype ofParent
andtype[Child]
is a subtype oftype[Parent]
.