Our typechecker stumbled across this Protocol:
https://github.com/google/jax/blob/1c7f8efce64ca2927fd3f2de9250063d7c5fe09e/jax/_src/nn/initializers.py#L44
This is a Protocol with a @staticmethod. PEP 544 (
https://peps.python.org/pep-0544/) says only:
"Static methods, class methods, and properties are equally allowed in protocols."
The PEP doesn't say anything at all about what it *means* to have one of these in a structural supertype. Structurally, consider a Protocol like:
class P(Protocol):
def foo(x: str) -> int: ...
The protocol has an attribute named `foo` with type `(x: str) -> int`. @staticmethod is an implementation detail which does not affect the structure of P.
The protocol should be satisfied by *any* type with an attribute named `foo` with type `(x: str) -> int`.
(Similarly, if a protocol requires a @property getter you could satisfy it with a field, etc.)
Test:
```
from typing import Protocol
class P(Protocol):
@staticmethod
def foo(x: str) -> int: ...
class A:
@staticmethod
def foo(x: str) -> int: return len(x)
class B:
def foo(self, x: str) -> int: return len(x)
class Str2Int(Protocol):
def __call__(self, x: str) -> int: ...
class C:
foo: Str2Int
def __init__(self):
self.foo = lambda x: 0
def test(x: P) -> None:
return
test(A())
test(B())
test(C())
```
Pyright agrees with me.
$ pyright --version
pyright 1.1.306
$ pyright static-protocols.py
0 errors, 0 warnings, 0 informations
Mypy does not :( :
$ mypy --version
mypy 1.2.0 (compiled: yes)
$ mypy static-protocols.py
static-protocols.py:27: error: Argument 1 to "test" has incompatible type "B"; expected "P" [arg-type]
static-protocols.py:27: note: Protocol member P.foo expected class or static method
static-protocols.py:28: error: Argument 1 to "test" has incompatible type "C"; expected "P" [arg-type]
static-protocols.py:28: note: Protocol member P.foo expected class or static method
Found 2 errors in 1 file (checked 1 source file)
--
|
Kevin Millikin
|
Software Engineer
|
kmillikin@deepmind.com
|
|
If you received this email in error, please do not forward it to anyone else (it may contain confidential or privileged information), erase all copies and attachments, and let me know that it has gone to the wrong person.
|
|