Skip to content

Incorrect example of Protocol type check in documentation #2176

Closed as not planned

Description

@e1turin

On the page "Protocols — typing documentation" in section "type[] and class objects vs protocols" is given wrong example: instead of class instances are given class references. Even more, error and success cases are mismatched:

from typing import Any, Protocol

class ProtoA(Protocol):
    def meth(self, x: int) -> int: ...
class ProtoB(Protocol):
    def meth(self, obj: Any, x: int) -> int: ...

class C:
    def meth(self, x: int) -> int: ...

a: ProtoA = C  # Type check error, signatures don't match!
b: ProtoB = C  # OK

Should be this:

a: ProtoA = C()  # OK
b: ProtoB = C()  # Error

Activity

  1. changed the title [-]Bad example of Protocol implementation check in documentation[/-] [+]Incorrect example of Protocol type check in documentation[/+] on Feb 13, 2026
  2. e1turin commented on Feb 13, 2026

    @e1turin
    Author

    I suggest such a change: #2177

  3. JelleZijlstra commented on Feb 14, 2026

    @JelleZijlstra
    Member

    No, this is correct. Class objects can match protocols.

  4. carljm commented on Feb 14, 2026

    @carljm
    Member

    Arguably this example is incorrect as written, but for the subtler reason that the obj parameter in ProtoB.meth should be positional-only, otherwise its name should matter for assignability.

  5. e1turin commented on Feb 14, 2026

    @e1turin
    Author

    Well, now I understood what was going on. But are you really saying that this is correct behavior?:

    a: ProtoA = C  # Type check error, signatures don't match!
  6. carljm commented on Feb 14, 2026

    @carljm
    Member

    But are you really saying that this is correct behavior?:

    a: ProtoA = C # Type check error, signatures don't match!

    Yes. C.meth has the signature (self: C, x: int) -> int. ProtoA.meth has the signature (x: int) -> int. The former signature is not assignable to the latter.

    The protocol is interpreted as an instance type, so the method is bound; the self argument "disappears". But C.meth accessed off the class is an unbound method, so it still has its self argument. The idea of the example is that that self ends up mapping to the obj: Any argument in ProtoB.meth.

  7. e1turin commented on Feb 14, 2026

    @e1turin
    Author

    Oh, I see now. Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions