Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit a6c3e07

Browse filesBrowse files
authored
Remove __eq__ and __ne__ overrides for dataclasses and attrs (#8642)
Fixes #8638.
1 parent f4bf900 commit a6c3e07
Copy full SHA for a6c3e07

File tree

Expand file treeCollapse file tree

7 files changed

+15
-112
lines changed
Filter options
Expand file treeCollapse file tree

7 files changed

+15
-112
lines changed

‎mypy/plugins/attrs.py

Copy file name to clipboardExpand all lines: mypy/plugins/attrs.py
+5-18Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -176,10 +176,10 @@ def deserialize(cls, info: TypeInfo, data: JsonDict) -> 'Attribute':
176176
)
177177

178178

179-
def _determine_eq_order(ctx: 'mypy.plugin.ClassDefContext') -> Tuple[bool, bool]:
179+
def _determine_eq_order(ctx: 'mypy.plugin.ClassDefContext') -> bool:
180180
"""
181181
Validate the combination of *cmp*, *eq*, and *order*. Derive the effective
182-
values of eq and order.
182+
value of order.
183183
"""
184184
cmp = _get_decorator_optional_bool_argument(ctx, 'cmp')
185185
eq = _get_decorator_optional_bool_argument(ctx, 'eq')
@@ -190,7 +190,7 @@ def _determine_eq_order(ctx: 'mypy.plugin.ClassDefContext') -> Tuple[bool, bool]
190190

191191
# cmp takes precedence due to bw-compatibility.
192192
if cmp is not None:
193-
return cmp, cmp
193+
return cmp
194194

195195
# If left None, equality is on and ordering mirrors equality.
196196
if eq is None:
@@ -202,7 +202,7 @@ def _determine_eq_order(ctx: 'mypy.plugin.ClassDefContext') -> Tuple[bool, bool]
202202
if eq is False and order is True:
203203
ctx.api.fail("eq must be True if order is True", ctx.reason)
204204

205-
return eq, order
205+
return order
206206

207207

208208
def _get_decorator_optional_bool_argument(
@@ -248,7 +248,7 @@ def attr_class_maker_callback(ctx: 'mypy.plugin.ClassDefContext',
248248

249249
init = _get_decorator_bool_argument(ctx, 'init', True)
250250
frozen = _get_frozen(ctx)
251-
eq, order = _determine_eq_order(ctx)
251+
order = _determine_eq_order(ctx)
252252

253253
auto_attribs = _get_decorator_bool_argument(ctx, 'auto_attribs', auto_attribs_default)
254254
kw_only = _get_decorator_bool_argument(ctx, 'kw_only', False)
@@ -287,8 +287,6 @@ def attr_class_maker_callback(ctx: 'mypy.plugin.ClassDefContext',
287287
adder = MethodAdder(ctx)
288288
if init:
289289
_add_init(ctx, attributes, adder)
290-
if eq:
291-
_add_eq(ctx, adder)
292290
if order:
293291
_add_order(ctx, adder)
294292
if frozen:
@@ -587,17 +585,6 @@ def _parse_assignments(
587585
return lvalues, rvalues
588586

589587

590-
def _add_eq(ctx: 'mypy.plugin.ClassDefContext', adder: 'MethodAdder') -> None:
591-
"""Generate __eq__ and __ne__ for this class."""
592-
# For __ne__ and __eq__ the type is:
593-
# def __ne__(self, other: object) -> bool
594-
bool_type = ctx.api.named_type('__builtins__.bool')
595-
object_type = ctx.api.named_type('__builtins__.object')
596-
args = [Argument(Var('other', object_type), object_type, None, ARG_POS)]
597-
for method in ['__ne__', '__eq__']:
598-
adder.add_method(method, args, bool_type)
599-
600-
601588
def _add_order(ctx: 'mypy.plugin.ClassDefContext', adder: 'MethodAdder') -> None:
602589
"""Generate all the ordering methods for this class."""
603590
bool_type = ctx.api.named_type('__builtins__.bool')

‎mypy/plugins/dataclasses.py

Copy file name to clipboardExpand all lines: mypy/plugins/dataclasses.py
-21Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -123,27 +123,6 @@ def transform(self) -> None:
123123
[], obj_type)
124124
info.names[SELF_TVAR_NAME] = SymbolTableNode(MDEF, self_tvar_expr)
125125

126-
# Add an eq method, but only if the class doesn't already have one.
127-
if decorator_arguments['eq'] and info.get('__eq__') is None:
128-
for method_name in ['__eq__', '__ne__']:
129-
# The TVar is used to enforce that "other" must have
130-
# the same type as self (covariant). Note the
131-
# "self_type" parameter to add_method.
132-
obj_type = ctx.api.named_type('__builtins__.object')
133-
cmp_tvar_def = TypeVarDef(SELF_TVAR_NAME, info.fullname + '.' + SELF_TVAR_NAME,
134-
-1, [], obj_type)
135-
cmp_other_type = TypeVarType(cmp_tvar_def)
136-
cmp_return_type = ctx.api.named_type('__builtins__.bool')
137-
138-
add_method(
139-
ctx,
140-
method_name,
141-
args=[Argument(Var('other', cmp_other_type), cmp_other_type, None, ARG_POS)],
142-
return_type=cmp_return_type,
143-
self_type=cmp_other_type,
144-
tvar_def=cmp_tvar_def,
145-
)
146-
147126
# Add <, >, <=, >=, but only if the class has an eq method.
148127
if decorator_arguments['order']:
149128
if not decorator_arguments['eq']:

‎test-data/unit/check-attr.test

Copy file name to clipboardExpand all lines: test-data/unit/check-attr.test
-13Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,6 @@ from attr import attrib, attrs
185185
class A:
186186
a: int
187187
reveal_type(A) # N: Revealed type is 'def (a: builtins.int) -> __main__.A'
188-
reveal_type(A.__eq__) # N: Revealed type is 'def (self: __main__.A, other: builtins.object) -> builtins.bool'
189-
reveal_type(A.__ne__) # N: Revealed type is 'def (self: __main__.A, other: builtins.object) -> builtins.bool'
190188
reveal_type(A.__lt__) # N: Revealed type is 'def [_AT] (self: _AT`-1, other: _AT`-1) -> builtins.bool'
191189
reveal_type(A.__le__) # N: Revealed type is 'def [_AT] (self: _AT`-1, other: _AT`-1) -> builtins.bool'
192190
reveal_type(A.__gt__) # N: Revealed type is 'def [_AT] (self: _AT`-1, other: _AT`-1) -> builtins.bool'
@@ -251,8 +249,6 @@ from attr import attrib, attrs
251249
class A:
252250
a: int
253251
reveal_type(A) # N: Revealed type is 'def (a: builtins.int) -> __main__.A'
254-
reveal_type(A.__eq__) # N: Revealed type is 'def (self: __main__.A, other: builtins.object) -> builtins.bool'
255-
reveal_type(A.__ne__) # N: Revealed type is 'def (self: __main__.A, other: builtins.object) -> builtins.bool'
256252

257253
A(1) < A(2) # E: Unsupported left operand type for < ("A")
258254
A(1) <= A(2) # E: Unsupported left operand type for <= ("A")
@@ -771,15 +767,6 @@ B() <= 1 # E: Unsupported operand types for <= ("B" and "int")
771767
C() <= 1 # E: Unsupported operand types for <= ("C" and "int")
772768
D() <= 1 # E: Unsupported operand types for <= ("D" and "int")
773769

774-
A() == A()
775-
B() == A()
776-
C() == A()
777-
D() == A()
778-
779-
A() == int
780-
B() == int
781-
C() == int
782-
D() == int
783770
[builtins fixtures/list.pyi]
784771

785772
[case testAttrsComplexSuperclass]

‎test-data/unit/check-dataclasses.test

Copy file name to clipboardExpand all lines: test-data/unit/check-dataclasses.test
-42Lines changed: 0 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -377,48 +377,6 @@ Application.COUNTER = 1
377377

378378
[builtins fixtures/list.pyi]
379379

380-
[case testDataclassEquality]
381-
# flags: --python-version 3.6
382-
from dataclasses import dataclass
383-
384-
@dataclass
385-
class Application:
386-
name: str
387-
rating: int
388-
389-
app1 = Application("example-1", 5)
390-
app2 = Application("example-2", 5)
391-
app1 == app2
392-
app1 != app2
393-
app1 == None # E: Unsupported operand types for == ("Application" and "None")
394-
395-
[builtins fixtures/list.pyi]
396-
397-
[case testDataclassCustomEquality]
398-
# flags: --python-version 3.6
399-
from dataclasses import dataclass
400-
401-
@dataclass
402-
class Application:
403-
name: str
404-
rating: int
405-
406-
def __eq__(self, other: 'Application') -> bool:
407-
...
408-
409-
app1 = Application("example-1", 5)
410-
app2 = Application("example-2", 5)
411-
app1 == app2
412-
app1 != app2 # E: Unsupported left operand type for != ("Application")
413-
app1 == None # E: Unsupported operand types for == ("Application" and "None")
414-
415-
class SpecializedApplication(Application):
416-
...
417-
418-
app1 == SpecializedApplication("example-3", 5)
419-
420-
[builtins fixtures/list.pyi]
421-
422380
[case testDataclassOrdering]
423381
# flags: --python-version 3.6
424382
from dataclasses import dataclass

‎test-data/unit/check-incremental.test

Copy file name to clipboardExpand all lines: test-data/unit/check-incremental.test
+10-14Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3016,8 +3016,6 @@ main:15: error: Unsupported left operand type for >= ("NoCmp")
30163016
[case testAttrsIncrementalDunder]
30173017
from a import A
30183018
reveal_type(A) # N: Revealed type is 'def (a: builtins.int) -> a.A'
3019-
reveal_type(A.__eq__) # N: Revealed type is 'def (self: a.A, other: builtins.object) -> builtins.bool'
3020-
reveal_type(A.__ne__) # N: Revealed type is 'def (self: a.A, other: builtins.object) -> builtins.bool'
30213019
reveal_type(A.__lt__) # N: Revealed type is 'def [_AT] (self: _AT`-1, other: _AT`-1) -> builtins.bool'
30223020
reveal_type(A.__le__) # N: Revealed type is 'def [_AT] (self: _AT`-1, other: _AT`-1) -> builtins.bool'
30233021
reveal_type(A.__gt__) # N: Revealed type is 'def [_AT] (self: _AT`-1, other: _AT`-1) -> builtins.bool'
@@ -3055,20 +3053,18 @@ class A:
30553053
[stale]
30563054
[out2]
30573055
main:2: note: Revealed type is 'def (a: builtins.int) -> a.A'
3058-
main:3: note: Revealed type is 'def (self: a.A, other: builtins.object) -> builtins.bool'
3059-
main:4: note: Revealed type is 'def (self: a.A, other: builtins.object) -> builtins.bool'
3056+
main:3: note: Revealed type is 'def [_AT] (self: _AT`-1, other: _AT`-1) -> builtins.bool'
3057+
main:4: note: Revealed type is 'def [_AT] (self: _AT`-1, other: _AT`-1) -> builtins.bool'
30603058
main:5: note: Revealed type is 'def [_AT] (self: _AT`-1, other: _AT`-1) -> builtins.bool'
30613059
main:6: note: Revealed type is 'def [_AT] (self: _AT`-1, other: _AT`-1) -> builtins.bool'
3062-
main:7: note: Revealed type is 'def [_AT] (self: _AT`-1, other: _AT`-1) -> builtins.bool'
3063-
main:8: note: Revealed type is 'def [_AT] (self: _AT`-1, other: _AT`-1) -> builtins.bool'
3064-
main:17: error: Unsupported operand types for < ("A" and "int")
3065-
main:18: error: Unsupported operand types for <= ("A" and "int")
3066-
main:19: error: Unsupported operand types for > ("A" and "int")
3067-
main:20: error: Unsupported operand types for >= ("A" and "int")
3068-
main:24: error: Unsupported operand types for > ("A" and "int")
3069-
main:25: error: Unsupported operand types for >= ("A" and "int")
3070-
main:26: error: Unsupported operand types for < ("A" and "int")
3071-
main:27: error: Unsupported operand types for <= ("A" and "int")
3060+
main:15: error: Unsupported operand types for < ("A" and "int")
3061+
main:16: error: Unsupported operand types for <= ("A" and "int")
3062+
main:17: error: Unsupported operand types for > ("A" and "int")
3063+
main:18: error: Unsupported operand types for >= ("A" and "int")
3064+
main:22: error: Unsupported operand types for > ("A" and "int")
3065+
main:23: error: Unsupported operand types for >= ("A" and "int")
3066+
main:24: error: Unsupported operand types for < ("A" and "int")
3067+
main:25: error: Unsupported operand types for <= ("A" and "int")
30723068

30733069
[case testAttrsIncrementalSubclassModified]
30743070
from b import B

‎test-data/unit/deps.test

Copy file name to clipboardExpand all lines: test-data/unit/deps.test
-2Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1435,9 +1435,7 @@ class B(A):
14351435
[out]
14361436
<m.A.(abstract)> -> <m.B.__init__>, m
14371437
<m.A._DT> -> <m.B._DT>
1438-
<m.A.__eq__> -> <m.B.__eq__>
14391438
<m.A.__init__> -> <m.B.__init__>, m.B.__init__
1440-
<m.A.__ne__> -> <m.B.__ne__>
14411439
<m.A.__new__> -> <m.B.__new__>
14421440
<m.A.x> -> <m.B.x>
14431441
<m.A.y> -> <m.B.y>

‎test-data/unit/stubgen.test

Copy file name to clipboardExpand all lines: test-data/unit/stubgen.test
-2Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2162,8 +2162,6 @@ from typing import Any
21622162
class C:
21632163
x: Any = ...
21642164
def __init__(self, x: Any) -> None: ...
2165-
def __ne__(self, other: Any) -> Any: ...
2166-
def __eq__(self, other: Any) -> Any: ...
21672165
def __lt__(self, other: Any) -> Any: ...
21682166
def __le__(self, other: Any) -> Any: ...
21692167
def __gt__(self, other: Any) -> Any: ...

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.