diff --git a/conformance/results/mypy/namedtuples_define_class.toml b/conformance/results/mypy/namedtuples_define_class.toml index adf590b4..575c5c0c 100644 --- a/conformance/results/mypy/namedtuples_define_class.toml +++ b/conformance/results/mypy/namedtuples_define_class.toml @@ -11,11 +11,19 @@ namedtuples_define_class.py:46: error: Argument 2 to "Point" has incompatible ty namedtuples_define_class.py:47: error: Argument "units" to "Point" has incompatible type "int"; expected "str" [arg-type] namedtuples_define_class.py:48: error: Too many arguments for "Point" [call-arg] namedtuples_define_class.py:49: error: Unexpected keyword argument "other" for "Point" [call-arg] -namedtuples_define_class.py:59: error: Non-default NamedTuple fields cannot follow default fields [misc] -namedtuples_define_class.py:98: error: Argument 2 to "Property" has incompatible type "float"; expected "str" [arg-type] -namedtuples_define_class.py:105: error: NamedTuple should be a single base [misc] +namedtuples_define_class.py:59: error: Invalid statement in NamedTuple definition; expected "field_name: field_type [= default]" [misc] +namedtuples_define_class.py:65: error: Missing positional argument "units" in call to "Point2" [call-arg] +namedtuples_define_class.py:67: error: Too many values to unpack (2 expected, 3 provided) [misc] +namedtuples_define_class.py:76: error: NamedTuple field name cannot start with an underscore: _y [misc] +namedtuples_define_class.py:86: error: Non-default NamedTuple fields cannot follow default fields [misc] +namedtuples_define_class.py:125: error: Argument 2 to "Property" has incompatible type "float"; expected "str" [arg-type] +namedtuples_define_class.py:132: error: NamedTuple should be a single base [misc] """ conformance_automated = "Fail" errors_diff = """ -Line 79: Expected 1 errors +Line 69: Expected 1 errors +Line 106: Expected 1 errors +Line 59: Unexpected errors ['namedtuples_define_class.py:59: error: Invalid statement in NamedTuple definition; expected "field_name: field_type [= default]" [misc]'] +Line 65: Unexpected errors ['namedtuples_define_class.py:65: error: Missing positional argument "units" in call to "Point2" [call-arg]'] +Line 67: Unexpected errors ['namedtuples_define_class.py:67: error: Too many values to unpack (2 expected, 3 provided) [misc]'] """ diff --git a/conformance/results/mypy/namedtuples_define_functional.toml b/conformance/results/mypy/namedtuples_define_functional.toml index 151e6588..19158d3d 100644 --- a/conformance/results/mypy/namedtuples_define_functional.toml +++ b/conformance/results/mypy/namedtuples_define_functional.toml @@ -11,8 +11,15 @@ namedtuples_define_functional.py:43: error: Argument "x" to "Point6" has incompa namedtuples_define_functional.py:52: error: "namedtuple()" has duplicate field name "a" [misc] namedtuples_define_functional.py:53: error: "namedtuple()" field name "def" is a keyword [misc] namedtuples_define_functional.py:54: error: "namedtuple()" field name "def" is a keyword [misc] -namedtuples_define_functional.py:66: error: Missing positional argument "a" in call to "NT5" [call-arg] +namedtuples_define_functional.py:55: error: "namedtuple()" field name "_d" starts with an underscore [misc] +namedtuples_define_functional.py:66: error: Name "NT5" already defined on line 57 [no-redef] +namedtuples_define_functional.py:67: error: Missing positional argument "_1" in call to "NT5" [call-arg] +namedtuples_define_functional.py:68: error: Too many arguments for "NT5" [call-arg] +namedtuples_define_functional.py:69: error: Missing positional arguments "abc", "_1" in call to "NT5" [call-arg] """ -conformance_automated = "Pass" +conformance_automated = "Fail" errors_diff = """ +Line 66: Unexpected errors ['namedtuples_define_functional.py:66: error: Name "NT5" already defined on line 57 [no-redef]'] +Line 67: Unexpected errors ['namedtuples_define_functional.py:67: error: Missing positional argument "_1" in call to "NT5" [call-arg]'] +Line 68: Unexpected errors ['namedtuples_define_functional.py:68: error: Too many arguments for "NT5" [call-arg]'] """ diff --git a/conformance/results/mypy/version.toml b/conformance/results/mypy/version.toml index 6bd36c63..869e8bf2 100644 --- a/conformance/results/mypy/version.toml +++ b/conformance/results/mypy/version.toml @@ -1,2 +1,2 @@ version = "mypy 1.15.0" -test_duration = 2.1 +test_duration = 2.0 diff --git a/conformance/results/pyre/namedtuples_define_class.toml b/conformance/results/pyre/namedtuples_define_class.toml index 3ce86df7..d60d70ca 100644 --- a/conformance/results/pyre/namedtuples_define_class.toml +++ b/conformance/results/pyre/namedtuples_define_class.toml @@ -16,11 +16,15 @@ namedtuples_define_class.py:46:14 Incompatible parameter type [6]: In call `Poin namedtuples_define_class.py:47:17 Incompatible parameter type [6]: In call `Point.__init__`, for argument `units`, expected `str` but got `int`. namedtuples_define_class.py:48:5 Too many arguments [19]: Call `Point.__init__` expects 3 positional arguments, 4 were provided. namedtuples_define_class.py:49:6 Unexpected keyword [28]: Unexpected keyword argument `other` to call `Point.__init__`. -namedtuples_define_class.py:59:4 Missing named tuple default [74]: Named tuple field without default value may not be preceded by a field with default value. -namedtuples_define_class.py:79:4 Invalid assignment [41]: Cannot reassign final attribute `x`. -namedtuples_define_class.py:98:18 Incompatible parameter type [6]: In call `Property.__init__`, for 2nd positional argument, expected `str` but got `float`. -namedtuples_define_class.py:105:23 Invalid inheritance [39]: If NamedTuple is included as a base class, the class may not extend anything else besides Generic. +namedtuples_define_class.py:67:0 Unable to unpack [23]: Unable to unpack 3 values, 2 were expected. +namedtuples_define_class.py:86:4 Missing named tuple default [74]: Named tuple field without default value may not be preceded by a field with default value. +namedtuples_define_class.py:106:4 Invalid assignment [41]: Cannot reassign final attribute `x`. +namedtuples_define_class.py:125:18 Incompatible parameter type [6]: In call `Property.__init__`, for 2nd positional argument, expected `str` but got `float`. +namedtuples_define_class.py:132:23 Invalid inheritance [39]: If NamedTuple is included as a base class, the class may not extend anything else besides Generic. """ -conformance_automated = "Pass" +conformance_automated = "Fail" errors_diff = """ +Line 69: Expected 1 errors +Line 76: Expected 1 errors +Line 67: Unexpected errors ['namedtuples_define_class.py:67:0 Unable to unpack [23]: Unable to unpack 3 values, 2 were expected.'] """ diff --git a/conformance/results/pyre/namedtuples_define_functional.toml b/conformance/results/pyre/namedtuples_define_functional.toml index dc132443..62b05c17 100644 --- a/conformance/results/pyre/namedtuples_define_functional.toml +++ b/conformance/results/pyre/namedtuples_define_functional.toml @@ -12,8 +12,12 @@ namedtuples_define_functional.py:42:17 Incompatible parameter type [6]: In call namedtuples_define_functional.py:43:14 Incompatible parameter type [6]: In call `Point6.__init__`, for argument `x`, expected `int` but got `float`. namedtuples_define_functional.py:52:0 Duplicate parameter [65]: Duplicate parameter name `a`. namedtuples_define_functional.py:52:0 Duplicate parameter [65]: Duplicate parameter name `a`. -namedtuples_define_functional.py:66:0 Missing argument [20]: Call `NT5.__init__` expects argument `a`. +namedtuples_define_functional.py:58:0 Unexpected keyword [28]: Unexpected keyword argument `abc` to call `NT5.__init__`. +namedtuples_define_functional.py:60:0 Unexpected keyword [28]: Unexpected keyword argument `_1` to call `NT6.__init__`. +namedtuples_define_functional.py:69:0 Missing argument [20]: Call `NT5.__init__` expects argument `a`. """ -conformance_automated = "Pass" +conformance_automated = "Fail" errors_diff = """ +Line 58: Unexpected errors ['namedtuples_define_functional.py:58:0 Unexpected keyword [28]: Unexpected keyword argument `abc` to call `NT5.__init__`.'] +Line 60: Unexpected errors ['namedtuples_define_functional.py:60:0 Unexpected keyword [28]: Unexpected keyword argument `_1` to call `NT6.__init__`.'] """ diff --git a/conformance/results/pyre/version.toml b/conformance/results/pyre/version.toml index c60d2044..94de3055 100644 --- a/conformance/results/pyre/version.toml +++ b/conformance/results/pyre/version.toml @@ -1,2 +1,2 @@ version = "pyre 0.9.23" -test_duration = 3.9 +test_duration = 7.3 diff --git a/conformance/results/pyright/namedtuples_define_class.toml b/conformance/results/pyright/namedtuples_define_class.toml index 19f9aadc..42aabbf3 100644 --- a/conformance/results/pyright/namedtuples_define_class.toml +++ b/conformance/results/pyright/namedtuples_define_class.toml @@ -10,12 +10,14 @@ namedtuples_define_class.py:47:24 - error: Argument of type "Literal[3]" cannot   "Literal[3]" is not assignable to "str" (reportArgumentType) namedtuples_define_class.py:48:22 - error: Expected 3 positional arguments (reportCallIssue) namedtuples_define_class.py:49:23 - error: No parameter named "other" (reportCallIssue) -namedtuples_define_class.py:59:5 - error: Fields without default values cannot appear after fields with default values (reportGeneralTypeIssues) -namedtuples_define_class.py:79:5 - error: Cannot override "x" because parent class "Point" is a named tuple (reportIncompatibleVariableOverride) -namedtuples_define_class.py:98:19 - error: Argument of type "float" cannot be assigned to parameter "value" of type "str" in function "__new__" +namedtuples_define_class.py:69:20 - error: Expected 2 positional arguments (reportCallIssue) +namedtuples_define_class.py:86:5 - error: Fields without default values cannot appear after fields with default values (reportGeneralTypeIssues) +namedtuples_define_class.py:106:5 - error: Cannot override "x" because parent class "Point" is a named tuple (reportIncompatibleVariableOverride) +namedtuples_define_class.py:125:19 - error: Argument of type "float" cannot be assigned to parameter "value" of type "str" in function "__new__"   "float" is not assignable to "str" (reportArgumentType) -namedtuples_define_class.py:105:7 - error: Multiple inheritance with NamedTuple is not supported (reportGeneralTypeIssues) +namedtuples_define_class.py:132:7 - error: Multiple inheritance with NamedTuple is not supported (reportGeneralTypeIssues) """ -conformance_automated = "Pass" +conformance_automated = "Fail" errors_diff = """ +Line 76: Expected 1 errors """ diff --git a/conformance/results/pyright/namedtuples_define_functional.toml b/conformance/results/pyright/namedtuples_define_functional.toml index 07c43204..37c5b7af 100644 --- a/conformance/results/pyright/namedtuples_define_functional.toml +++ b/conformance/results/pyright/namedtuples_define_functional.toml @@ -15,8 +15,11 @@ namedtuples_define_functional.py:43:17 - error: Argument of type "float" cannot namedtuples_define_functional.py:52:31 - error: Names within a named tuple must be unique (reportGeneralTypeIssues) namedtuples_define_functional.py:53:33 - error: Field names cannot be a keyword (reportGeneralTypeIssues) namedtuples_define_functional.py:54:33 - error: Field names cannot be a keyword (reportGeneralTypeIssues) -namedtuples_define_functional.py:66:1 - error: Argument missing for parameter "a" (reportCallIssue) +namedtuples_define_functional.py:60:1 - error: Argument missing for parameter "_d" (reportCallIssue) +namedtuples_define_functional.py:60:13 - error: No parameter named "_1" (reportCallIssue) +namedtuples_define_functional.py:69:1 - error: Argument missing for parameter "a" (reportCallIssue) """ -conformance_automated = "Pass" +conformance_automated = "Fail" errors_diff = """ +Line 60: Unexpected errors ['namedtuples_define_functional.py:60:1 - error: Argument missing for parameter "_d" (reportCallIssue)', 'namedtuples_define_functional.py:60:13 - error: No parameter named "_1" (reportCallIssue)'] """ diff --git a/conformance/results/pyright/version.toml b/conformance/results/pyright/version.toml index 8fb908ad..86b0b4bd 100644 --- a/conformance/results/pyright/version.toml +++ b/conformance/results/pyright/version.toml @@ -1,2 +1,2 @@ -version = "pyright 1.1.398" -test_duration = 2.3 +version = "pyright 1.1.399" +test_duration = 1.5 diff --git a/conformance/results/pytype/namedtuples_define_class.toml b/conformance/results/pytype/namedtuples_define_class.toml index 189add7c..c3213b93 100644 --- a/conformance/results/pytype/namedtuples_define_class.toml +++ b/conformance/results/pytype/namedtuples_define_class.toml @@ -59,7 +59,21 @@ namedtuples_define_class.py:49:7: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: i p10 = Point(1, 2, "", other="") # E \u001b[1m\u001b[31m~~~~~~~~~~~~~~~~~~~~~~~~~\u001b[39m\u001b[0m -namedtuples_define_class.py:95:1: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in : Any [assert-type] +namedtuples_define_class.py:69:7: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in : Function Point2.__new__ expects 3 arg(s), got 4 [wrong-arg-count] + +p12 = Point2(1, 2, "") # E + \u001b[1m\u001b[31m~~~~~~~~~~~~~~~~\u001b[39m\u001b[0m + +namedtuples_define_class.py:74:1: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in : collections.namedtuple argument '_y' is not a valid typename or field name. [invalid-namedtuple-arg] + +class Point3(NamedTuple): +\u001b[1m\u001b[31m~~~~~~~~~~~~~~~~~~~~~~~~~\u001b[39m\u001b[0m + x: int +\u001b[1m\u001b[31m~~~~~~~~~~\u001b[39m\u001b[0m + _y: int # E: illegal field name +\u001b[1m\u001b[31m~~~~~~~~~~~\u001b[39m\u001b[0m + +namedtuples_define_class.py:122:1: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in : Any [assert-type] assert_type(pr1[1], float) \u001b[1m\u001b[31m~~~~~~~~~~~~~~~~~~~~~~~~~~\u001b[39m\u001b[0m @@ -69,13 +83,15 @@ conformance_automated = "Fail" errors_diff = """ Line 32: Expected 1 errors Line 33: Expected 1 errors -Line 59: Expected 1 errors -Line 79: Expected 1 errors -Line 98: Expected 1 errors -Line 105: Expected 1 errors +Line 76: Expected 1 errors +Line 86: Expected 1 errors +Line 106: Expected 1 errors +Line 125: Expected 1 errors +Line 132: Expected 1 errors Line 27: Unexpected errors ['namedtuples_define_class.py:27:1: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in : Union[int, str] [assert-type]'] Line 28: Unexpected errors ['namedtuples_define_class.py:28:1: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in : Union[int, str] [assert-type]'] Line 29: Unexpected errors ['namedtuples_define_class.py:29:1: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in : tuple[Union[int, str], ...] [assert-type]'] Line 30: Unexpected errors ['namedtuples_define_class.py:30:1: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in : tuple[Union[int, str], ...] [assert-type]'] -Line 95: Unexpected errors ['namedtuples_define_class.py:95:1: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in : Any [assert-type]'] +Line 74: Unexpected errors ["namedtuples_define_class.py:74:1: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in : collections.namedtuple argument '_y' is not a valid typename or field name. [invalid-namedtuple-arg]"] +Line 122: Unexpected errors ['namedtuples_define_class.py:122:1: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in : Any [assert-type]'] """ diff --git a/conformance/results/pytype/namedtuples_define_functional.toml b/conformance/results/pytype/namedtuples_define_functional.toml index f18a771b..981007f1 100644 --- a/conformance/results/pytype/namedtuples_define_functional.toml +++ b/conformance/results/pytype/namedtuples_define_functional.toml @@ -59,7 +59,12 @@ namedtuples_define_functional.py:54:7: \u001b[1m\u001b[31merror\u001b[39m\u001b[ NT3 = namedtuple("NT3", ["abc", "def"], rename=False) # E?: illegal field name \u001b[1m\u001b[31m~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\u001b[39m\u001b[0m -namedtuples_define_functional.py:63:7: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in : Function collections.namedtuple was called with the wrong arguments [wrong-arg-types] +namedtuples_define_functional.py:55:7: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in : collections.namedtuple argument '_d' is not a valid typename or field name. [invalid-namedtuple-arg] + +NT4 = namedtuple("NT4", ["abc", "_d"], rename=False) # E?: illegal field name + \u001b[1m\u001b[31m~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\u001b[39m\u001b[0m + +namedtuples_define_functional.py:66:7: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in : Function collections.namedtuple was called with the wrong arguments [wrong-arg-types] NT5 = namedtuple("NT5", "a b c", defaults=(1, 2)) \u001b[1m\u001b[31m~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\u001b[39m\u001b[0m @@ -67,6 +72,6 @@ NT5 = namedtuple("NT5", "a b c", defaults=(1, 2)) """ conformance_automated = "Fail" errors_diff = """ -Line 66: Expected 1 errors -Line 63: Unexpected errors ['namedtuples_define_functional.py:63:7: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in : Function collections.namedtuple was called with the wrong arguments [wrong-arg-types]'] +Line 69: Expected 1 errors +Line 66: Unexpected errors ['namedtuples_define_functional.py:66:7: \\x1b[1m\\x1b[31merror\\x1b[39m\\x1b[0m: in : Function collections.namedtuple was called with the wrong arguments [wrong-arg-types]'] """ diff --git a/conformance/results/pytype/protocols_merging.toml b/conformance/results/pytype/protocols_merging.toml index a3102a96..28275fdd 100644 --- a/conformance/results/pytype/protocols_merging.toml +++ b/conformance/results/pytype/protocols_merging.toml @@ -6,12 +6,12 @@ Does not report attempt to instantiate abstract class downgraded from protocol c output = """ protocols_merging.py:52:1: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in : Type annotation for s6 does not match type of assignment [annotation-type-mismatch] -s6: SizedAndClosable1 = SCConcrete2() # E: doesn't implement close +s6: SizedAndClosable1 = SCConcrete2() # E: doesn't implement `__len__` \u001b[1m\u001b[31m~~\u001b[39m\u001b[0m protocols_merging.py:53:1: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in : Type annotation for s7 does not match type of assignment [annotation-type-mismatch] -s7: SizedAndClosable2 = SCConcrete2() # E: doesn't implement close +s7: SizedAndClosable2 = SCConcrete2() # E: doesn't implement `__len__` \u001b[1m\u001b[31m~~\u001b[39m\u001b[0m protocols_merging.py:54:1: \u001b[1m\u001b[31merror\u001b[39m\u001b[0m: in : Type annotation for s8 does not match type of assignment [annotation-type-mismatch] diff --git a/conformance/results/pytype/version.toml b/conformance/results/pytype/version.toml index cdc0a953..364d7813 100644 --- a/conformance/results/pytype/version.toml +++ b/conformance/results/pytype/version.toml @@ -1,2 +1,2 @@ version = "pytype 2024.10.11" -test_duration = 43.3 +test_duration = 36.6 diff --git a/conformance/results/results.html b/conformance/results/results.html index d78bd912..95af34a1 100644 --- a/conformance/results/results.html +++ b/conformance/results/results.html @@ -159,16 +159,16 @@

Python Type System Conformance Test Results

- - + - + diff --git a/conformance/tests/namedtuples_define_class.py b/conformance/tests/namedtuples_define_class.py index e345a197..5e6e9c4c 100644 --- a/conformance/tests/namedtuples_define_class.py +++ b/conformance/tests/namedtuples_define_class.py @@ -49,6 +49,33 @@ class Point(NamedTuple): p10 = Point(1, 2, "", other="") # E +# > Fields must be annotated attributes - methods and un-annotated attributes are not +# > considered fields. + + +class Point2(NamedTuple): + x: int + y: int + units = "meters" # Not a field + + def is_origin(self) -> int: # Not a field + return self.x == 0 and self.y == 0 + + +p11 = Point2(1, 2) +assert_type(p11, Point2) +x, y = p11 + +p12 = Point2(1, 2, "") # E + + +# > Field names may not start with an underscore. + +class Point3(NamedTuple): + x: int + _y: int # E: illegal field name + + # > The runtime implementation of ``NamedTuple`` enforces that fields with default # > values must come after fields without default values. Type checkers should # > likewise enforce this restriction:: diff --git a/conformance/tests/namedtuples_define_functional.py b/conformance/tests/namedtuples_define_functional.py index 432dff73..51506e3d 100644 --- a/conformance/tests/namedtuples_define_functional.py +++ b/conformance/tests/namedtuples_define_functional.py @@ -43,18 +43,21 @@ p6_4 = Point6(x=1.1, y=2) # E -# > At runtime, the ``namedtuple`` function disallows field names that are -# > illegal Python identifiers and either raises an exception or replaces these -# > fields with a parameter name of the form ``_N``. The behavior depends on -# > the value of the ``rename`` argument. Type checkers may replicate this -# > behavior statically. +# > At runtime, the ``namedtuple`` function disallows field names that begin with +# > an underscore or are illegal Python identifiers, and either raises an exception +# > or replaces these fields with a parameter name of the form ``_N``. The behavior +# > depends on the value of the ``rename`` argument. Type checkers may replicate +# > this behavior statically. NT1 = namedtuple("NT1", ["a", "a"]) # E?: duplicate field name NT2 = namedtuple("NT2", ["abc", "def"]) # E?: illegal field name NT3 = namedtuple("NT3", ["abc", "def"], rename=False) # E?: illegal field name +NT4 = namedtuple("NT4", ["abc", "_d"], rename=False) # E?: illegal field name -NT4 = namedtuple("NT4", ["abc", "def"], rename=True) # OK -NT4(abc="", _1="") # OK +NT5 = namedtuple("NT5", ["abc", "def"], rename=True) # OK +NT5(abc="", _1="") # OK +NT6 = namedtuple("NT6", ["abc", "_d"], rename=True) # OK +NT6(abc="", _1="") # OK # > The ``namedtuple`` function also supports a ``defaults`` keyword argument that diff --git a/docs/spec/namedtuples.rst b/docs/spec/namedtuples.rst index 1ac14136..936d2fa7 100644 --- a/docs/spec/namedtuples.rst +++ b/docs/spec/namedtuples.rst @@ -20,6 +20,14 @@ Type checkers should support the class syntax:: y: int units: str = "meters" +Fields must be annotated attributes - methods and un-annotated attributes are not +considered fields. Field names may not start with an underscore. + + class MyTuple(NamedTuple): + x1 = 1 # Not a field + def x2() -> None: pass # Not a field + _x3: int # Type error: illegal field name + Regardless of whether the class syntax or factory function call is used to define a named tuple, type checkers should synthesize a ``__new__`` method based on the named tuple fields. This mirrors the runtime behavior. In the example @@ -79,17 +87,21 @@ A type checker may support the factory function call in its various forms:: Point5 = NamedTuple('Point5', [('x', int), ('y', int)]) Point6 = NamedTuple('Point6', (('x', int), ('y', int))) -At runtime, the ``namedtuple`` function disallows field names that are -illegal Python identifiers and either raises an exception or replaces these -fields with a parameter name of the form ``_N``. The behavior depends on -the value of the ``rename`` argument. Type checkers may replicate this -behavior statically:: +At runtime, the ``namedtuple`` function disallows field names that begin with +an underscore or are illegal Python identifiers, and either raises an exception +or replaces these fields with a parameter name of the form ``_N``. The behavior +depends on the value of the ``rename`` argument. Type checkers may replicate +this behavior statically:: NT1 = namedtuple("NT1", ["a", "a"]) # Type error (duplicate field name) NT2 = namedtuple("NT2", ["abc", "def"], rename=False) # Type error (illegal field name) + NT3 = namedtuple("NT3", ["abc", "_d"], rename=False) # Type error (illegal field name) + + NT4 = namedtuple("NT4", ["abc", "def"], rename=True) # OK + NT4(abc="", _1="") # OK - NT3 = namedtuple("NT3", ["abc", "def"], rename=True) # OK - NT3(abc="", _1="") # OK + NT5 = namedtuple("NT5", ["abc", "_d"], rename=True) # OK + NT5(abc="", _1="") # OK The ``namedtuple`` function also supports a ``defaults`` keyword argument that specifies default values for the fields. Type checkers may support this::
 
mypy 1.15.0
-
2.1sec
+
2.0sec
pyright 1.1.398
-
2.3sec
+
pyright 1.1.399
+
1.5sec
pyre 0.9.23
-
3.9sec
+
7.3sec
pytype 2024.10.11
-
43.3sec
+
36.6sec
@@ -445,10 +445,10 @@

Python Type System Conformance Test Results

Class type compatibility
     classes_classvar
Partial

Internal error if TypeVarTuple is used in ClassVar.

Does not reject use of ParamSpec in ClassVar.

Rejects ClassVar nested in Annotated.

Does not reject use of ClassVar in TypeAlias definition.

Does not infer type of ClassVar from assignment if no type is provided.

Partial

Internal error if TypeVarTuple is used in ClassVar.

Does not reject use of ParamSpec in ClassVar.

Rejects ClassVar nested in Annotated.

Does not reject use of ClassVar in TypeAlias definition.

Pass
Partial

Does not reject use of TypeVar in ClassVar.

Does not reject use of ParamSpec in ClassVar.

Does not reject use of ClassVar as a generic type argument.

Does not reject use of ClassVar in parameter type annotation.

Does not reject use of ClassVar in local variable annotation.

Does not reject use of ClassVar in instance variable annotation.

Does not reject use of ClassVar in return type annotation.

Does not reject use of ClassVar in type alias definition.

Does not infer type from initialization for bare ClassVar.

Partial

Does not reject use of TypeVar in ClassVar.

Does not reject use of ParamSpec in ClassVar.

Does not reject use of ClassVar as a generic type argument.

Rejects initialization of ClassVar if no type argument is provided.

Does not reject use of ClassVar in parameter type annotation.

Does not reject use of ClassVar in local variable annotation.

Does not reject use of ClassVar in instance variable annotation.

Does not reject use of ClassVar in return type annotation.

Does not reject use of ClassVar in type alias definition.

Does not reject assignment of ClassVar through instance of class.

Partial

Does not reject use of TypeVar in ClassVar.

Does not reject use of ParamSpec in ClassVar.

Does not reject use of ClassVar as a generic type argument.

Rejects initialization of ClassVar if no type argument is provided.

Does not infer ClassVar with no type argument and no assigned value as Any.

Does not reject use of ClassVar in parameter type annotation.

Does not reject use of ClassVar in local variable annotation.

Does not reject use of ClassVar in instance variable annotation.

Does not reject use of ClassVar in return type annotation.

Does not reject use of ClassVar in type alias definition.

Does not reject assignment of ClassVar through instance of class.

     classes_override
Partial

Does not handle case where parent class derives from Any.