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):
  @staticmethod
  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)

--
logo
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.