From 4991939e51f3652a4f4eacd7761c07f770bd38d8 Mon Sep 17 00:00:00 2001 From: Rebecca Chen Date: Mon, 21 Jul 2025 14:36:33 -0700 Subject: [PATCH] Add conformance tests for the 'match_args' parameter to dataclass. 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. --- .../results/mypy/dataclasses_match_args.toml | 7 +++ conformance/results/mypy/version.toml | 2 +- .../results/pyre/dataclasses_match_args.toml | 12 +++++ .../pyright/dataclasses_match_args.toml | 10 ++++ conformance/results/pyright/version.toml | 2 +- conformance/results/results.html | 9 +++- conformance/tests/dataclasses_match_args.py | 49 +++++++++++++++++++ 7 files changed, 87 insertions(+), 4 deletions(-) create mode 100644 conformance/results/mypy/dataclasses_match_args.toml create mode 100644 conformance/results/pyre/dataclasses_match_args.toml create mode 100644 conformance/results/pyright/dataclasses_match_args.toml create mode 100644 conformance/tests/dataclasses_match_args.py diff --git a/conformance/results/mypy/dataclasses_match_args.toml b/conformance/results/mypy/dataclasses_match_args.toml new file mode 100644 index 00000000..1309854f --- /dev/null +++ b/conformance/results/mypy/dataclasses_match_args.toml @@ -0,0 +1,7 @@ +conformant = "Pass" +conformance_automated = "Pass" +errors_diff = """ +""" +output = """ +dataclasses_match_args.py:42: error: "type[DC4]" has no attribute "__match_args__" [attr-defined] +""" diff --git a/conformance/results/mypy/version.toml b/conformance/results/mypy/version.toml index a9b73efe..91c238fc 100644 --- a/conformance/results/mypy/version.toml +++ b/conformance/results/mypy/version.toml @@ -1,2 +1,2 @@ version = "mypy 1.17.0" -test_duration = 2.7 +test_duration = 2.8 diff --git a/conformance/results/pyre/dataclasses_match_args.toml b/conformance/results/pyre/dataclasses_match_args.toml new file mode 100644 index 00000000..d7bd7961 --- /dev/null +++ b/conformance/results/pyre/dataclasses_match_args.toml @@ -0,0 +1,12 @@ +conformant = "Partial" +notes = """ +Adds kw-only fields to __match_args__. +""" +conformance_automated = "Fail" +errors_diff = """ +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']]`."] +""" +output = """ +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']]`. +dataclasses_match_args.py:42:0 Undefined attribute [16]: `DC4` has no attribute `__match_args__`. +""" diff --git a/conformance/results/pyright/dataclasses_match_args.toml b/conformance/results/pyright/dataclasses_match_args.toml new file mode 100644 index 00000000..e85cc6da --- /dev/null +++ b/conformance/results/pyright/dataclasses_match_args.toml @@ -0,0 +1,10 @@ +conformant = "Partial" +notes = """ +Generates __match_args__ when match_args=False. +""" +conformance_automated = "Fail" +errors_diff = """ +Line 42: Expected 1 errors +""" +output = """ +""" diff --git a/conformance/results/pyright/version.toml b/conformance/results/pyright/version.toml index a5b181d8..89d7a4ab 100644 --- a/conformance/results/pyright/version.toml +++ b/conformance/results/pyright/version.toml @@ -1,2 +1,2 @@ version = "pyright 1.1.403" -test_duration = 5.6 +test_duration = 5.7 diff --git a/conformance/results/results.html b/conformance/results/results.html index 7b4f244c..bc857fc9 100644 --- a/conformance/results/results.html +++ b/conformance/results/results.html @@ -159,10 +159,10 @@

Python Type System Conformance Test Results

+ + + + + diff --git a/conformance/tests/dataclasses_match_args.py b/conformance/tests/dataclasses_match_args.py new file mode 100644 index 00000000..6593fa20 --- /dev/null +++ b/conformance/tests/dataclasses_match_args.py @@ -0,0 +1,49 @@ +""" +Tests the match_args feature of dataclass added in Python 3.10. +""" + +# Specification: https://docs.python.org/3/library/dataclasses.html#module-contents + +from dataclasses import dataclass, KW_ONLY +from typing import assert_type, Literal + +# If true, the __match_args__ tuple will be created from the list of non keyword-only parameters to the generated __init__() method + +@dataclass(match_args=True) +class DC1: + x: int + _: KW_ONLY + y: str + +assert_type(DC1.__match_args__, tuple[Literal['x']]) + +# The match_args default is True + +@dataclass +class DC2: + x: int + +assert_type(DC2.__match_args__, tuple[Literal['x']]) + +# __match_args__ is created even if __init__() is not generated + +@dataclass(match_args=True, init=False) +class DC3: + x: int = 0 + +assert_type(DC3.__match_args__, tuple[Literal['x']]) + +# If false, or if __match_args__ is already defined in the class, then __match_args__ will not be generated. + +@dataclass(match_args=False) +class DC4: + x: int + +DC4.__match_args__ # E + +@dataclass(match_args=True) +class DC5: + __match_args__ = () + x: int + +assert_type(DC5.__match_args__, tuple[()])
 
mypy 1.17.0
-
2.7sec
+
2.8sec
pyright 1.1.403
-
5.6sec
+
5.7sec
pyre 0.9.25
3.9sec
@@ -652,6 +652,11 @@

Python Type System Conformance Test Results

Pass
Partial

Rejects legitimate use of dataclass field with `kw_only=True`.

     dataclasses_match_argsPass
Partial

Generates __match_args__ when match_args=False.

Partial

Adds kw-only fields to __match_args__.

     dataclasses_order Pass Pass