diff --git a/conformance/results/mypy/dataclasses_hash.toml b/conformance/results/mypy/dataclasses_hash.toml index 7af6dcbd..08809153 100644 --- a/conformance/results/mypy/dataclasses_hash.toml +++ b/conformance/results/mypy/dataclasses_hash.toml @@ -1,11 +1,19 @@ -conformant = "Partial" +conformant = "Unsupported" notes = """ +Does not synthesize `__hash__ = None` as a class attribute for unhashable dataclasses. +Does not report when an unhashable dataclass has `__hash__` called directly on an instance. Does not report when dataclass is not compatible with Hashable protocol. """ output = """ +dataclasses_hash.py:14: error: Expression is of type "Callable[[object], int]", not "None" [assert-type] +dataclasses_hash.py:36: error: Expression is of type "Callable[[object], int]", not "None" [assert-type] """ conformance_automated = "Fail" errors_diff = """ -Line 15: Expected 1 errors -Line 32: Expected 1 errors +Line 17: Expected 1 errors +Line 18: Expected 1 errors +Line 39: Expected 1 errors +Line 40: Expected 1 errors +Line 14: Unexpected errors ['dataclasses_hash.py:14: error: Expression is of type "Callable[[object], int]", not "None" [assert-type]'] +Line 36: Unexpected errors ['dataclasses_hash.py:36: error: Expression is of type "Callable[[object], int]", not "None" [assert-type]'] """ diff --git a/conformance/results/pyrefly/dataclasses_hash.toml b/conformance/results/pyrefly/dataclasses_hash.toml index 2d674772..4c89ed9c 100644 --- a/conformance/results/pyrefly/dataclasses_hash.toml +++ b/conformance/results/pyrefly/dataclasses_hash.toml @@ -3,6 +3,8 @@ conformance_automated = "Pass" errors_diff = """ """ output = """ -ERROR dataclasses_hash.py:15:16-22: `DC1` is not assignable to `Hashable` [bad-assignment] -ERROR dataclasses_hash.py:32:16-22: `DC3` is not assignable to `Hashable` [bad-assignment] +ERROR dataclasses_hash.py:17:1-16: Expected a callable, got `None` [not-callable] +ERROR dataclasses_hash.py:18:16-22: `DC1` is not assignable to `Hashable` [bad-assignment] +ERROR dataclasses_hash.py:39:1-16: Expected a callable, got `None` [not-callable] +ERROR dataclasses_hash.py:40:16-22: `DC3` is not assignable to `Hashable` [bad-assignment] """ diff --git a/conformance/results/pyright/dataclasses_hash.toml b/conformance/results/pyright/dataclasses_hash.toml index bd6c15f8..7e05cf57 100644 --- a/conformance/results/pyright/dataclasses_hash.toml +++ b/conformance/results/pyright/dataclasses_hash.toml @@ -1,10 +1,12 @@ conformant = "Pass" output = """ -dataclasses_hash.py:15:16 - error: Type "DC1" is not assignable to declared type "Hashable" +dataclasses_hash.py:17:1 - error: Object of type "None" cannot be called (reportOptionalCall) +dataclasses_hash.py:18:16 - error: Type "DC1" is not assignable to declared type "Hashable"   "DC1" is incompatible with protocol "Hashable"     "__hash__" is an incompatible type       Type "None" is not assignable to type "() -> int" (reportAssignmentType) -dataclasses_hash.py:32:16 - error: Type "DC3" is not assignable to declared type "Hashable" +dataclasses_hash.py:39:1 - error: Object of type "None" cannot be called (reportOptionalCall) +dataclasses_hash.py:40:16 - error: Type "DC3" is not assignable to declared type "Hashable"   "DC3" is incompatible with protocol "Hashable"     "__hash__" is an incompatible type       Type "None" is not assignable to type "() -> int" (reportAssignmentType) diff --git a/conformance/results/results.html b/conformance/results/results.html index a99606a6..058d7e55 100644 --- a/conformance/results/results.html +++ b/conformance/results/results.html @@ -737,9 +737,9 @@

Python Type System Conformance Test Results

Pass      dataclasses_hash -
Partial

Does not report when dataclass is not compatible with Hashable protocol.

-Pass +
Unsupported

Does not synthesize `__hash__ = None` as a class attribute for unhashable dataclasses.

Does not report when an unhashable dataclass has `__hash__` called directly on an instance.

Does not report when dataclass is not compatible with Hashable protocol.

Pass +
Partial

Does not synthesize a `__hash__ = None` class attribute for unhashable dataclasses.

Pass      dataclasses_inheritance diff --git a/conformance/results/zuban/dataclasses_hash.toml b/conformance/results/zuban/dataclasses_hash.toml index 210b7f0b..52f7a8fa 100644 --- a/conformance/results/zuban/dataclasses_hash.toml +++ b/conformance/results/zuban/dataclasses_hash.toml @@ -1,7 +1,17 @@ -conformance_automated = "Pass" +conformance_automated = "Fail" +conformant = "Partial" +notes = """ +Does not synthesize a `__hash__ = None` class attribute for unhashable dataclasses. +""" errors_diff = """ +Line 14: Unexpected errors ['dataclasses_hash.py:14: error: Expression is of type "Callable[[object], int]", not "None" [misc]'] +Line 36: Unexpected errors ['dataclasses_hash.py:36: error: Expression is of type "Callable[[object], int]", not "None" [misc]'] """ output = """ -dataclasses_hash.py:15: error: Incompatible types in assignment (expression has type "DC1", variable has type "Hashable") [assignment] -dataclasses_hash.py:32: error: Incompatible types in assignment (expression has type "DC3", variable has type "Hashable") [assignment] +dataclasses_hash.py:14: error: Expression is of type "Callable[[object], int]", not "None" [misc] +dataclasses_hash.py:17: error: "DC1" has no attribute "__hash__" [attr-defined] +dataclasses_hash.py:18: error: Incompatible types in assignment (expression has type "DC1", variable has type "Hashable") [assignment] +dataclasses_hash.py:36: error: Expression is of type "Callable[[object], int]", not "None" [misc] +dataclasses_hash.py:39: error: "DC3" has no attribute "__hash__" [attr-defined] +dataclasses_hash.py:40: error: Incompatible types in assignment (expression has type "DC3", variable has type "Hashable") [assignment] """ diff --git a/conformance/tests/dataclasses_hash.py b/conformance/tests/dataclasses_hash.py index 7a5e6884..f2d441d6 100644 --- a/conformance/tests/dataclasses_hash.py +++ b/conformance/tests/dataclasses_hash.py @@ -3,7 +3,7 @@ """ from dataclasses import dataclass -from typing import Hashable +from typing import Callable, Hashable, assert_type @dataclass @@ -11,7 +11,10 @@ class DC1: a: int -# This should generate an error because DC1 isn't hashable. +assert_type(DC1.__hash__, None) + +# These should generate errors because DC1 isn't hashable. +DC1(0).__hash__() # E v1: Hashable = DC1(0) # E @@ -20,7 +23,9 @@ class DC2: a: int -v2: Hashable = DC2(0) +dc2_hash: Callable[..., int] = DC2.__hash__ # OK +DC2(0).__hash__() # OK +v2: Hashable = DC2(0) # OK @dataclass(eq=True) @@ -28,7 +33,10 @@ class DC3: a: int -# This should generate an error because DC3 isn't hashable. +assert_type(DC3.__hash__, None) + +# These should generate errors because DC3 isn't hashable. +DC3(0).__hash__() # E v3: Hashable = DC3(0) # E @@ -37,7 +45,9 @@ class DC4: a: int -v4: Hashable = DC4(0) +dc4_hash: Callable[..., int] = DC4.__hash__ # OK +DC4(0).__hash__() # OK +v4: Hashable = DC4(0) # OK @dataclass(eq=True, unsafe_hash=True) @@ -45,7 +55,9 @@ class DC5: a: int -v5: Hashable = DC5(0) +dc5_hash: Callable[..., int] = DC5.__hash__ # OK +DC5(0).__hash__() # OK +v5: Hashable = DC5(0) # OK @dataclass(eq=True) @@ -56,7 +68,9 @@ def __hash__(self) -> int: return 0 -v6: Hashable = DC6(0) +dc6_hash: Callable[..., int] = DC6.__hash__ # OK +DC6(0).__hash__() # OK +v6: Hashable = DC6(0) # OK @dataclass(frozen=True) @@ -67,4 +81,6 @@ def __eq__(self, other) -> bool: return self.a == other.a -v7: Hashable = DC7(0) +dc7_hash: Callable[..., int] = DC7.__hash__ # OK +DC7(0).__hash__() # OK +v7: Hashable = DC7(0) # OK