Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PEP 544: failing example #3312

Closed
BALOGHBence opened this issue Aug 28, 2023 · 5 comments
Closed

PEP 544: failing example #3312

BALOGHBence opened this issue Aug 28, 2023 · 5 comments

Comments

@BALOGHBence
Copy link

Documentation

The following example fails on Python 3.8.10 for several reasons.

class PColor(Protocol):
    @abstractmethod
    def draw(self) -> str:
        ...
    def complex_method(self) -> int:
        # some complex code here

class NiceColor(PColor):
    def draw(self) -> str:
        return "deep blue"

class BadColor(PColor):
    def draw(self) -> str:
        return super().draw()  # Error, no default implementation

class ImplicitColor:   # Note no 'PColor' base here
    def draw(self) -> str:
        return "probably gray"
    def complex_method(self) -> int:
        # class needs to implement this
        
nice: NiceColor
another: ImplicitColor

def represent(c: PColor) -> None:
    print(c.draw(), c.complex_method())

represent(nice) # OK
represent(another) # Also OK

The first reason why this fails is a syntax error (actually two), namely the methods complex_method are missing the ellipses. If these are corrected, the example still throws a NameError, since 'nice' and 'another' are actually not defined.

The corrected example:

class PColor(Protocol):
    @abstractmethod
    def draw(self) -> str:
        ...
    def complex_method(self) -> int:
        # some complex code here
        ...

class NiceColor(PColor):
    def draw(self) -> str:
        return "deep blue"

class BadColor(PColor):
    def draw(self) -> str:
        return super().draw()  # Error, no default implementation

class ImplicitColor:   # Note no 'PColor' base here
    def draw(self) -> str:
        return "probably gray"
    def complex_method(self) -> int:
        # class needs to implement this
        ...
        
nice: NiceColor = NiceColor()
another: ImplicitColor = ImplicitColor()

def represent(c: PColor) -> None:
    print(c.draw(), c.complex_method())

represent(nice) # OK
represent(another) # Also OK
@AA-Turner AA-Turner transferred this issue from python/cpython Aug 28, 2023
@AA-Turner
Copy link
Member

cc: @ilevkivskyi @JukkaL @ambv

@hugovk hugovk changed the title failing example in PEP 544 PEP 544: failing example Sep 27, 2023
@1chooo 1chooo mentioned this issue May 15, 2024
4 tasks
@Loclhost
Copy link

Another fails

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

I think the comments in the last lines need to be swapped

@sobolevn
Copy link
Member

@Loclhost please, create a new PR with the fix :)

@ilevkivskyi
Copy link
Member

ilevkivskyi commented Mar 18, 2025

@Loclhost
Just to save you time: it is correct in the PEP (you are not the first one, and not even twentieth one, to try to "fix" this "typo"). Please just read example carefully again.

@AA-Turner AA-Turner closed this as not planned Won't fix, can't repro, duplicate, stale Mar 18, 2025
@JelleZijlstra
Copy link
Member

(Hint to understand why this is correct: If you want to call C.meth (not C().meth), what is the signature it accepts?)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants
@JelleZijlstra @sobolevn @AA-Turner @ilevkivskyi @BALOGHBence @Loclhost and others