Skip to content

Commit 807a7e6

Browse files
committed
Adapt and clarify tests and docs around explicitly annotated receiver parameters
1 parent ceb0671 commit 807a7e6

10 files changed

Lines changed: 109 additions & 104 deletions

File tree

conformance/results/mypy/protocols_generic.toml

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,25 +16,21 @@ protocols_generic.py:56: error: Incompatible types in assignment (expression has
1616
protocols_generic.py:66: error: Incompatible types in assignment (expression has type "Sender[int]", variable has type "Sender[float]") [assignment]
1717
protocols_generic.py:74: error: Incompatible types in assignment (expression has type "AttrProto[int]", variable has type "AttrProto[float]") [assignment]
1818
protocols_generic.py:75: error: Incompatible types in assignment (expression has type "AttrProto[float]", variable has type "AttrProto[int]") [assignment]
19-
protocols_generic.py:145: error: Incompatible types in assignment (expression has type "ConcreteHasProperty2", variable has type "HasPropertyProto") [assignment]
20-
protocols_generic.py:145: note: Following member(s) of "ConcreteHasProperty2" have conflicts:
21-
protocols_generic.py:145: note: Expected:
22-
protocols_generic.py:145: note: def [T] m(self, item: T, callback: Callable[[T], str]) -> str
23-
protocols_generic.py:145: note: Got:
24-
protocols_generic.py:145: note: def m(self, item: int, callback: Callable[[int], str]) -> str
25-
protocols_generic.py:146: error: Incompatible types in assignment (expression has type "ConcreteHasProperty3", variable has type "HasPropertyProto") [assignment]
26-
protocols_generic.py:146: note: Following member(s) of "ConcreteHasProperty3" have conflicts:
27-
protocols_generic.py:146: note: f: expected "ConcreteHasProperty3", got "int"
28-
protocols_generic.py:146: note: Expected:
29-
protocols_generic.py:146: note: def [T] m(self, item: T, callback: Callable[[T], str]) -> str
30-
protocols_generic.py:146: note: Got:
31-
protocols_generic.py:146: note: def m(self, item: int, callback: Callable[[int], str]) -> str
32-
protocols_generic.py:147: error: Incompatible types in assignment (expression has type "ConcreteHasProperty4", variable has type "HasPropertyProto") [assignment]
33-
protocols_generic.py:147: note: Following member(s) of "ConcreteHasProperty4" have conflicts:
34-
protocols_generic.py:147: note: Expected:
35-
protocols_generic.py:147: note: def [T] m(self, item: T, callback: Callable[[T], str]) -> str
36-
protocols_generic.py:147: note: Got:
37-
protocols_generic.py:147: note: def m(self, item: str, callback: Callable[[int], str]) -> str
19+
protocols_generic.py:120: error: Incompatible types in assignment (expression has type "InvalidParentProperty", variable has type "HasParentProperty") [assignment]
20+
protocols_generic.py:120: note: Following member(s) of "InvalidParentProperty" have conflicts:
21+
protocols_generic.py:120: note: parent: expected "InvalidParentProperty", got "int"
22+
protocols_generic.py:140: error: Incompatible types in assignment (expression has type "InvalidHasMethod", variable has type "HasMethod") [assignment]
23+
protocols_generic.py:140: note: Following member(s) of "InvalidHasMethod" have conflicts:
24+
protocols_generic.py:140: note: Expected:
25+
protocols_generic.py:140: note: def [T] m(self, item: T, callback: Callable[[T], str]) -> str
26+
protocols_generic.py:140: note: Got:
27+
protocols_generic.py:140: note: def m(self, item: int, callback: Callable[[int], str]) -> str
28+
protocols_generic.py:166: error: Incompatible types in assignment (expression has type "InvalidGreaterThan", variable has type "HasGreaterThan") [assignment]
29+
protocols_generic.py:166: note: Following member(s) of "InvalidGreaterThan" have conflicts:
30+
protocols_generic.py:166: note: Expected:
31+
protocols_generic.py:166: note: def __gt__(self, InvalidGreaterThan, /) -> bool
32+
protocols_generic.py:166: note: Got:
33+
protocols_generic.py:166: note: def __gt__(self, int, /) -> bool
3834
"""
3935
conformance_automated = "Pass"
4036
errors_diff = """

conformance/results/pycroscope/protocols_generic.toml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Treats global object as a literal.
44
"""
55
conformance_automated = "Fail"
66
errors_diff = """
7-
Line 96: Unexpected errors ['./protocols_generic.py:96:12: Literal[<protocols_generic.ConcreteHasParent object at 0x...>] is not equivalent to protocols_generic.ConcreteHasParent']
7+
Line 98: Unexpected errors ['./protocols_generic.py:98:12: Literal[<protocols_generic.ConcreteHasParent object at 0x...>] is not equivalent to protocols_generic.ConcreteHasParent']
88
"""
99
output = """
1010
./protocols_generic.py:40:0: Incompatible assignment: expected protocols_generic.Proto1[int, str], got protocols_generic.Concrete1 [incompatible_assignment]
@@ -13,8 +13,8 @@ output = """
1313
./protocols_generic.py:66:4: Incompatible assignment: expected protocols_generic.Sender[float | int], got protocols_generic.Sender[int] [incompatible_assignment]
1414
./protocols_generic.py:74:4: Incompatible assignment: expected protocols_generic.AttrProto[float | int], got protocols_generic.AttrProto[int] [incompatible_assignment]
1515
./protocols_generic.py:75:4: Incompatible assignment: expected protocols_generic.AttrProto[int], got protocols_generic.AttrProto[float | int] [incompatible_assignment]
16-
./protocols_generic.py:96:12: Literal[<protocols_generic.ConcreteHasParent object at 0x...>] is not equivalent to protocols_generic.ConcreteHasParent
17-
./protocols_generic.py:145:0: Incompatible assignment: expected protocols_generic.HasPropertyProto, got protocols_generic.ConcreteHasProperty2 [incompatible_assignment]
18-
./protocols_generic.py:146:0: Incompatible assignment: expected protocols_generic.HasPropertyProto, got protocols_generic.ConcreteHasProperty3 [incompatible_assignment]
19-
./protocols_generic.py:147:0: Incompatible assignment: expected protocols_generic.HasPropertyProto, got protocols_generic.ConcreteHasProperty4 [incompatible_assignment]
16+
./protocols_generic.py:98:12: Literal[<protocols_generic.ConcreteHasParent object at 0x...>] is not equivalent to protocols_generic.ConcreteHasParent
17+
./protocols_generic.py:120:0: Incompatible assignment: expected protocols_generic.HasParentProperty, got protocols_generic.InvalidParentProperty [incompatible_assignment]
18+
./protocols_generic.py:140:0: Incompatible assignment: expected protocols_generic.HasMethod, got protocols_generic.InvalidHasMethod [incompatible_assignment]
19+
./protocols_generic.py:166:0: Incompatible assignment: expected protocols_generic.HasGreaterThan, got protocols_generic.InvalidGreaterThan [incompatible_assignment]
2020
"""

conformance/results/pyrefly/protocols_generic.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ ERROR protocols_generic.py:56:20-29: `Box[float]` is not assignable to `Box[int]
99
ERROR protocols_generic.py:66:25-35: `Sender[int]` is not assignable to `Sender[float]` [bad-assignment]
1010
ERROR protocols_generic.py:74:28-36: `AttrProto[int]` is not assignable to `AttrProto[float]` [bad-assignment]
1111
ERROR protocols_generic.py:75:26-36: `AttrProto[float]` is not assignable to `AttrProto[int]` [bad-assignment]
12-
ERROR protocols_generic.py:145:25-47: `ConcreteHasProperty2` is not assignable to `HasPropertyProto` [bad-assignment]
13-
ERROR protocols_generic.py:146:25-47: `ConcreteHasProperty3` is not assignable to `HasPropertyProto` [bad-assignment]
14-
ERROR protocols_generic.py:147:25-47: `ConcreteHasProperty4` is not assignable to `HasPropertyProto` [bad-assignment]
12+
ERROR protocols_generic.py:120:26-49: `InvalidParentProperty` is not assignable to `HasParentProperty` [bad-assignment]
13+
ERROR protocols_generic.py:140:18-36: `InvalidHasMethod` is not assignable to `HasMethod` [bad-assignment]
14+
ERROR protocols_generic.py:166:23-43: `InvalidGreaterThan` is not assignable to `HasGreaterThan` [bad-assignment]
1515
"""

conformance/results/pyright/protocols_generic.toml

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,32 +25,27 @@ protocols_generic.py:74:28 - error: Type "AttrProto[int]" is not assignable to d
2525
protocols_generic.py:75:26 - error: Type "AttrProto[float]" is not assignable to declared type "AttrProto[int]"
2626
  "AttrProto[float]" is not assignable to "AttrProto[int]"
2727
    Type parameter "T@AttrProto" is invariant, but "float" is not the same as "int" (reportAssignmentType)
28-
protocols_generic.py:145:25 - error: Type "ConcreteHasProperty2" is not assignable to declared type "HasPropertyProto"
29-
  "ConcreteHasProperty2" is incompatible with protocol "HasPropertyProto"
28+
protocols_generic.py:120:26 - error: Type "InvalidParentProperty" is not assignable to declared type "HasParentProperty"
29+
  "InvalidParentProperty" is incompatible with protocol "HasParentProperty"
30+
    "parent" is an incompatible type
31+
      Type "() -> int" is not assignable to type "() -> InvalidParentProperty"
32+
        "HasParentProperty" is not assignable to "InvalidParentProperty"
33+
        Function return type "int" is incompatible with type "InvalidParentProperty"
34+
          "int" is not assignable to "InvalidParentProperty" (reportAssignmentType)
35+
protocols_generic.py:140:18 - error: Type "InvalidHasMethod" is not assignable to declared type "HasMethod"
36+
  "InvalidHasMethod" is incompatible with protocol "HasMethod"
3037
    "m" is an incompatible type
3138
      Type "(item: int, callback: (int) -> str) -> str" is not assignable to type "(item: T@m, callback: (T@m) -> str) -> str"
3239
        Parameter 1: type "T@m" is incompatible with type "int"
3340
          "object*" is not assignable to "int"
3441
        Parameter 2: type "(T@m) -> str" is incompatible with type "(int) -> str"
3542
          Type "(T@m) -> str" is not assignable to type "(int) -> str" (reportAssignmentType)
36-
protocols_generic.py:146:25 - error: Type "ConcreteHasProperty3" is not assignable to declared type "HasPropertyProto"
37-
  "ConcreteHasProperty3" is incompatible with protocol "HasPropertyProto"
38-
    "f" is an incompatible type
39-
      Type "() -> int" is not assignable to type "() -> HasPropertyProto"
40-
        Function return type "int" is incompatible with type "HasPropertyProto"
41-
          "int" is incompatible with protocol "HasPropertyProto"
42-
    "m" is an incompatible type
43-
      Type "(item: int, callback: (int) -> str) -> str" is not assignable to type "(item: T@m, callback: (T@m) -> str) -> str"
44-
        Parameter 1: type "T@m" is incompatible with type "int"
45-
... (reportAssignmentType)
46-
protocols_generic.py:147:25 - error: Type "ConcreteHasProperty4" is not assignable to declared type "HasPropertyProto"
47-
  "ConcreteHasProperty4" is incompatible with protocol "HasPropertyProto"
48-
    "m" is an incompatible type
49-
      Type "(item: str, callback: (int) -> str) -> str" is not assignable to type "(item: T@m, callback: (T@m) -> str) -> str"
50-
        Parameter 1: type "T@m" is incompatible with type "str"
51-
          "object*" is not assignable to "str"
52-
        Parameter 2: type "(T@m) -> str" is incompatible with type "(int) -> str"
53-
          Type "(T@m) -> str" is not assignable to type "(int) -> str" (reportAssignmentType)
43+
protocols_generic.py:166:23 - error: Type "InvalidGreaterThan" is not assignable to declared type "HasGreaterThan"
44+
  "InvalidGreaterThan" is incompatible with protocol "HasGreaterThan"
45+
    "__gt__" is an incompatible type
46+
      Type "(other: int) -> bool" is not assignable to type "(other: InvalidGreaterThan) -> bool"
47+
        Parameter 1: type "InvalidGreaterThan" is incompatible with type "int"
48+
          "InvalidGreaterThan" is not assignable to "int" (reportAssignmentType)
5449
"""
5550
conformance_automated = "Pass"
5651
errors_diff = """

conformance/results/results.html

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
conformance_automated = "Fail"
22
conformant = "Partial"
33
notes = """
4-
Only partially supports `@property` protocol members.
4+
Does not reject incompatible non-generic implementations of generic protocol methods.
55
"""
66
errors_diff = """
7-
Line 144: Unexpected errors ['protocols_generic.py:144:25: error[invalid-assignment] Object of type `ConcreteHasProperty1` is not assignable to `HasPropertyProto`']
7+
Line 140: Expected 1 errors
88
"""
99
output = """
1010
protocols_generic.py:40:24: error[invalid-assignment] Object of type `Concrete1` is not assignable to `Proto1[int, str]`
@@ -13,8 +13,6 @@ protocols_generic.py:56:20: error[invalid-assignment] Object of type `Box[float]
1313
protocols_generic.py:66:25: error[invalid-assignment] Object of type `Sender[int]` is not assignable to `Sender[float]`
1414
protocols_generic.py:74:28: error[invalid-assignment] Object of type `AttrProto[int]` is not assignable to `AttrProto[float]`
1515
protocols_generic.py:75:26: error[invalid-assignment] Object of type `AttrProto[float]` is not assignable to `AttrProto[int]`
16-
protocols_generic.py:144:25: error[invalid-assignment] Object of type `ConcreteHasProperty1` is not assignable to `HasPropertyProto`
17-
protocols_generic.py:145:25: error[invalid-assignment] Object of type `ConcreteHasProperty2` is not assignable to `HasPropertyProto`
18-
protocols_generic.py:146:25: error[invalid-assignment] Object of type `ConcreteHasProperty3` is not assignable to `HasPropertyProto`
19-
protocols_generic.py:147:25: error[invalid-assignment] Object of type `ConcreteHasProperty4` is not assignable to `HasPropertyProto`
16+
protocols_generic.py:120:26: error[invalid-assignment] Object of type `InvalidParentProperty` is not assignable to `HasParentProperty`
17+
protocols_generic.py:166:23: error[invalid-assignment] Object of type `InvalidGreaterThan` is not assignable to `HasGreaterThan`
2018
"""

conformance/results/zuban/protocols_generic.toml

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,19 @@ protocols_generic.py:56: error: Incompatible types in assignment (expression has
1717
protocols_generic.py:66: error: Incompatible types in assignment (expression has type "Sender[int]", variable has type "Sender[float]") [assignment]
1818
protocols_generic.py:74: error: Incompatible types in assignment (expression has type "AttrProto[int]", variable has type "AttrProto[float]") [assignment]
1919
protocols_generic.py:75: error: Incompatible types in assignment (expression has type "AttrProto[float]", variable has type "AttrProto[int]") [assignment]
20-
protocols_generic.py:145: error: Incompatible types in assignment (expression has type "ConcreteHasProperty2", variable has type "HasPropertyProto") [assignment]
21-
protocols_generic.py:145: note: Following member(s) of "ConcreteHasProperty2" have conflicts:
22-
protocols_generic.py:145: note: Expected:
23-
protocols_generic.py:145: note: def [T] m(self, item: T, callback: Callable[[T], str]) -> str
24-
protocols_generic.py:145: note: Got:
25-
protocols_generic.py:145: note: def m(self, item: int, callback: Callable[[int], str]) -> str
26-
protocols_generic.py:146: error: Incompatible types in assignment (expression has type "ConcreteHasProperty3", variable has type "HasPropertyProto") [assignment]
27-
protocols_generic.py:146: note: Following member(s) of "ConcreteHasProperty3" have conflicts:
28-
protocols_generic.py:146: note: f: expected "ConcreteHasProperty3", got "int"
29-
protocols_generic.py:146: note: Expected:
30-
protocols_generic.py:146: note: def [T] m(self, item: T, callback: Callable[[T], str]) -> str
31-
protocols_generic.py:146: note: Got:
32-
protocols_generic.py:146: note: def m(self, item: int, callback: Callable[[int], str]) -> str
33-
protocols_generic.py:147: error: Incompatible types in assignment (expression has type "ConcreteHasProperty4", variable has type "HasPropertyProto") [assignment]
34-
protocols_generic.py:147: note: Following member(s) of "ConcreteHasProperty4" have conflicts:
35-
protocols_generic.py:147: note: Expected:
36-
protocols_generic.py:147: note: def [T] m(self, item: T, callback: Callable[[T], str]) -> str
37-
protocols_generic.py:147: note: Got:
38-
protocols_generic.py:147: note: def m(self, item: str, callback: Callable[[int], str]) -> str
20+
protocols_generic.py:120: error: Incompatible types in assignment (expression has type "InvalidParentProperty", variable has type "HasParentProperty") [assignment]
21+
protocols_generic.py:120: note: Following member(s) of "InvalidParentProperty" have conflicts:
22+
protocols_generic.py:120: note: parent: expected "InvalidParentProperty", got "int"
23+
protocols_generic.py:140: error: Incompatible types in assignment (expression has type "InvalidHasMethod", variable has type "HasMethod") [assignment]
24+
protocols_generic.py:140: note: Following member(s) of "InvalidHasMethod" have conflicts:
25+
protocols_generic.py:140: note: Expected:
26+
protocols_generic.py:140: note: def [T] m(self, item: T, callback: Callable[[T], str]) -> str
27+
protocols_generic.py:140: note: Got:
28+
protocols_generic.py:140: note: def m(self, item: int, callback: Callable[[int], str]) -> str
29+
protocols_generic.py:166: error: Incompatible types in assignment (expression has type "InvalidGreaterThan", variable has type "HasGreaterThan") [assignment]
30+
protocols_generic.py:166: note: Following member(s) of "InvalidGreaterThan" have conflicts:
31+
protocols_generic.py:166: note: Expected:
32+
protocols_generic.py:166: note: def [Self: InvalidGreaterThan] __gt__(self, other: Self) -> bool
33+
protocols_generic.py:166: note: Got:
34+
protocols_generic.py:166: note: def __gt__(self, other: int) -> bool
3935
"""

conformance/tests/protocols_generic.py

Lines changed: 48 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,10 @@ def func3(attr_int: AttrProto[int], attr_float: AttrProto[float]):
7575
v2: AttrProto[int] = attr_float # E
7676

7777

78+
T_bounded = TypeVar("T_bounded", bound="HasParent")
79+
7880
class HasParent(Protocol):
79-
def get_parent(self: T) -> T:
81+
def get_parent(self: T_bounded) -> T_bounded:
8082
...
8183

8284

@@ -96,52 +98,69 @@ def get_parent(self) -> Self:
9698
assert_type(parent, ConcreteHasParent)
9799

98100

99-
class HasPropertyProto(Protocol):
101+
class HasParentProperty(Protocol):
100102
@property
101-
def f(self: T) -> T:
102-
...
103-
104-
def m(self, item: T, callback: Callable[[T], str]) -> str:
103+
def parent(self) -> Self:
105104
...
106105

107106

108-
class ConcreteHasProperty1:
107+
class ConcreteParentProperty:
109108
@property
110-
def f(self: T) -> T:
109+
def parent(self) -> Self:
111110
return self
112111

112+
113+
class InvalidParentProperty:
114+
@property
115+
def parent(self) -> int:
116+
return 0
117+
118+
119+
hp1: HasParentProperty = ConcreteParentProperty() # OK
120+
hp2: HasParentProperty = InvalidParentProperty() # E
121+
122+
123+
124+
class HasMethod(Protocol):
113125
def m(self, item: T, callback: Callable[[T], str]) -> str:
114-
return ""
126+
...
115127

116128

117-
class ConcreteHasProperty2:
118-
@property
119-
def f(self) -> Self:
120-
return self
129+
class ConcreteHasMethod:
130+
def m(self, item: T, callback: Callable[[T], str]) -> str:
131+
return ""
121132

133+
134+
class InvalidHasMethod:
122135
def m(self, item: int, callback: Callable[[int], str]) -> str:
123136
return ""
124137

125138

126-
class ConcreteHasProperty3:
127-
@property
128-
def f(self) -> int:
129-
return 0
139+
hm1: HasMethod = ConcreteHasMethod() # OK
140+
hm2: HasMethod = InvalidHasMethod() # E
130141

131-
def m(self, item: int, callback: Callable[[int], str]) -> str:
132-
return ""
133142

134143

135-
class ConcreteHasProperty4:
136-
@property
137-
def f(self) -> Self:
138-
return self
144+
class HasGreaterThan(Protocol):
145+
def __gt__(self, other: Self) -> bool:
146+
...
139147

140-
def m(self, item: str, callback: Callable[[int], str]) -> str:
141-
return ""
148+
149+
class ConcreteGreaterThan1:
150+
def __gt__(self, other: Self) -> bool:
151+
return False
152+
153+
154+
class ConcreteGreaterThan2:
155+
def __gt__(self, other: "ConcreteGreaterThan2") -> bool:
156+
return False
157+
158+
159+
class InvalidGreaterThan:
160+
def __gt__(self, other: int) -> bool:
161+
return False
142162

143163

144-
hp1: HasPropertyProto = ConcreteHasProperty1() # OK
145-
hp2: HasPropertyProto = ConcreteHasProperty2() # E
146-
hp3: HasPropertyProto = ConcreteHasProperty3() # E
147-
hp4: HasPropertyProto = ConcreteHasProperty4() # E
164+
hg1: HasGreaterThan = ConcreteGreaterThan1() # OK
165+
hg2: HasGreaterThan = ConcreteGreaterThan2() # OK
166+
hg3: HasGreaterThan = InvalidGreaterThan() # E

docs/guides/writing_stubs.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -652,7 +652,7 @@ referencing a type variable.
652652

653653
Yes::
654654

655-
_T = TypeVar("_T")
655+
_T = TypeVar("_T", bound="Foo")
656656

657657
class Foo:
658658
def bar(self) -> None: ...

0 commit comments

Comments
 (0)