Skip to content

Commit d2f9b08

Browse files
authored
Add conformance tests for the 'match_args' parameter to dataclass. (#2056)
The spec lists 'match_args' as a dataclass parameter that static type checkers must honor, so it would be good to have tests for it.
1 parent d945fea commit d2f9b08

File tree

10 files changed

+99
-8
lines changed

10 files changed

+99
-8
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
conformant = "Pass"
2+
conformance_automated = "Pass"
3+
errors_diff = """
4+
"""
5+
output = """
6+
dataclasses_match_args.py:42: error: "type[DC4]" has no attribute "__match_args__" [attr-defined]
7+
"""

conformance/results/mypy/version.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
version = "mypy 1.17.1"
2-
test_duration = 2.96
2+
test_duration = 2.04
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
conformant = "Partial"
2+
notes = """
3+
Adds kw-only fields to __match_args__.
4+
"""
5+
conformance_automated = "Fail"
6+
errors_diff = """
7+
Line 18: Unexpected errors ["dataclasses_match_args.py:18:0 Assert type [70]: Expected `Tuple[typing_extensions.Literal['x']]` but got `Tuple[typing_extensions.Literal['x'], typing_extensions.Literal['*'], typing_extensions.Literal['y']]`."]
8+
"""
9+
output = """
10+
dataclasses_match_args.py:18:0 Assert type [70]: Expected `Tuple[typing_extensions.Literal['x']]` but got `Tuple[typing_extensions.Literal['x'], typing_extensions.Literal['*'], typing_extensions.Literal['y']]`.
11+
dataclasses_match_args.py:42:0 Undefined attribute [16]: `DC4` has no attribute `__match_args__`.
12+
"""

conformance/results/pyre/version.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
version = "pyre 0.9.25"
2-
test_duration = 5.93
2+
test_duration = 10.27
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
conformant = "Partial"
2+
notes = """
3+
Generates __match_args__ when match_args=False.
4+
"""
5+
conformance_automated = "Fail"
6+
errors_diff = """
7+
Line 42: Expected 1 errors
8+
"""
9+
output = """
10+
"""
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
version = "pyright 1.1.403"
2-
test_duration = 3.15
2+
test_duration = 1.83

conformance/results/results.html

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -159,16 +159,16 @@ <h3>Python Type System Conformance Test Results</h3>
159159
<div class="table_container"><table><tbody>
160160
<tr><th class="col1">&nbsp;</th>
161161
<th class='tc-header'><div class='tc-name'>mypy 1.17.1</div>
162-
<div class='tc-time'>3.0sec</div>
162+
<div class='tc-time'>2.0sec</div>
163163
</th>
164164
<th class='tc-header'><div class='tc-name'>pyright 1.1.403</div>
165-
<div class='tc-time'>3.1sec</div>
165+
<div class='tc-time'>1.8sec</div>
166166
</th>
167167
<th class='tc-header'><div class='tc-name'>pyre 0.9.25</div>
168-
<div class='tc-time'>5.9sec</div>
168+
<div class='tc-time'>10.3sec</div>
169169
</th>
170170
<th class='tc-header'><div class='tc-name'>zuban 0.0.19</div>
171-
<div class='tc-time'>0.15sec</div>
171+
<div class='tc-time'>0.35sec</div>
172172
</th>
173173
</tr>
174174
<tr><th class="column" colspan="5">
@@ -744,6 +744,12 @@ <h3>Python Type System Conformance Test Results</h3>
744744
<th class="column col2 partially-conformant"><div class="hover-text">Partial<span class="tooltip-text" id="bottom"><p>Rejects legitimate use of dataclass field with `kw_only=True`.</p></span></div></th>
745745
<th class="column col2 conformant">Pass</th>
746746
</tr>
747+
<tr><th class="column col1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dataclasses_match_args</th>
748+
<th class="column col2 conformant">Pass</th>
749+
<th class="column col2 partially-conformant"><div class="hover-text">Partial<span class="tooltip-text" id="bottom"><p>Generates __match_args__ when match_args=False.</p></span></div></th>
750+
<th class="column col2 partially-conformant"><div class="hover-text">Partial<span class="tooltip-text" id="bottom"><p>Adds kw-only fields to __match_args__.</p></span></div></th>
751+
<th class="column col2 conformant">Pass</th>
752+
</tr>
747753
<tr><th class="column col1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dataclasses_order</th>
748754
<th class="column col2 conformant">Pass</th>
749755
<th class="column col2 conformant">Pass</th>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
conformant = "Pass"
2+
conformance_automated = "Pass"
3+
errors_diff = """
4+
"""
5+
output = """
6+
dataclasses_match_args.py:42: error: "Type[DC4]" has no attribute "__match_args__"
7+
"""
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
version = "zuban 0.0.19"
2-
test_duration = 0.15
2+
test_duration = 0.35
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
"""
2+
Tests the match_args feature of dataclass added in Python 3.10.
3+
"""
4+
5+
# Specification: https://docs.python.org/3/library/dataclasses.html#module-contents
6+
7+
from dataclasses import dataclass, KW_ONLY
8+
from typing import assert_type, Literal
9+
10+
# If true, the __match_args__ tuple will be created from the list of non keyword-only parameters to the generated __init__() method
11+
12+
@dataclass(match_args=True)
13+
class DC1:
14+
x: int
15+
_: KW_ONLY
16+
y: str
17+
18+
assert_type(DC1.__match_args__, tuple[Literal['x']])
19+
20+
# The match_args default is True
21+
22+
@dataclass
23+
class DC2:
24+
x: int
25+
26+
assert_type(DC2.__match_args__, tuple[Literal['x']])
27+
28+
# __match_args__ is created even if __init__() is not generated
29+
30+
@dataclass(match_args=True, init=False)
31+
class DC3:
32+
x: int = 0
33+
34+
assert_type(DC3.__match_args__, tuple[Literal['x']])
35+
36+
# If false, or if __match_args__ is already defined in the class, then __match_args__ will not be generated.
37+
38+
@dataclass(match_args=False)
39+
class DC4:
40+
x: int
41+
42+
DC4.__match_args__ # E
43+
44+
@dataclass(match_args=True)
45+
class DC5:
46+
__match_args__ = ()
47+
x: int
48+
49+
assert_type(DC5.__match_args__, tuple[()])

0 commit comments

Comments
 (0)