[Python-ideas] Structural type checking for PEP 484

Matthias Kramm kramm at google.com
Fri Sep 11 18:18:32 CEST 2015

On Thursday, September 10, 2015 at 11:38:48 PM UTC-7, Jukka Lehtosalo wrote:
> The proposal doesn't spell out the rules for subtyping, but we should 
> follow the ordinary rules for subtyping for functions, and return types 
> would behave covariantly. So the answer is yes.

Ok. Note that this introduces some weird corner cases when trying to decide 
whether a class implements a protocol.


class P(Protocol):
  def f() -> P

class A:
  def f() -> A

It would be both valid to say that A *does not* implement P (because the 
return value of f is incompatible with P) as it would be to say that A 
*does* implement it (because once it does, the return value of f becomes 
compatible with P).

For a more quirky example, consider

class A(Protocol):
    def f(self) -> B
    def g(self) -> str

class B(Protocol):
    def f(self) -> A
    def g(self) -> float

class C:
  def f(self) -> D: return self.x
  def g(self): return self.y

class D:
  def f(self) -> C: return self.x
  def g(self): return self.y

Short of introducing intersection types, the protocols A and B are 
incompatible (because the return types of g() are mutually exclusive). 
Hence, C and D can, respectively, conform to either A or B, but not both.
So the possible assignments are:
C -> A
D -> B
C -> B
D -> A
It seems undecidable which of the two is the right one.
(The structural type converter in pytype solves this by dropping the 
"mutually exclusive" constraint to the floor and making A and B both a C 
*and* a D, which you can do if all you want is a name for an anonymous 
structural type, But here you're using your structural types in type 
declarations, so that solution doesn't apply)


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20150911/59217811/attachment-0002.html>

More information about the Python-ideas mailing list