You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Final may be wrapped only by other type qualifiers (e.g. ClassVar or Annotation).
In particular, nesting ClassVar and Final is a special case for dataclasses:
Type checkers should infer a final attribute that is initialized in a class
body as being a class variable, except in the case of dataclasses, where x: Final[int] = 3 creates a dataclass field and instance-level final
attribute x with default value 3; x: ClassVar[Final[int]] = 3 is
necessary to create a final class variable with value 3. In
non-dataclasses, combining ClassVar and Final is redundant, and type
checkers may choose to warn or error on the redundancy.
To Reproduce
In both classes below the foo statement is not accepted by mypy:
Note that the docs only mention ClassVar[Final[int]] and not Final[ClassVar[int]]. In fact, the latter is not considered a class variable by the current dataclasses implementation:
>>>Bar(foo=1) # foo is a class variableTraceback (mostrecentcalllast):
File"<python-input-2>", line1, in<module>Bar(foo=1)
~~~^^^^^^^TypeError: Bar.__init__() gotanunexpectedkeywordargument'foo'>>>Baz(foo=1) # foo is an instance variableBaz(foo=1)
Expected Behavior
[Python 3.13] mypy should accept ClassVar[Final[<type>]] in the body of a dataclass
The form ClassVar[Final[int]] conforms with the official typing specs and behaves as expected. I think it should be accepted as part of Python 3.13 support.
The typing specs allow for a warning or error when ClassVar and Final are nested outside of a dataclass body. I think this should result in an error since it is redundant, perhaps only in strict mode.
For the form Final[ClassVar[int]] I am not sure. It could either result in an error or simply be parsed as a final instance variable.
Actual Behavior
The form ClassVar[Final[int]] results in: error: Final can be only used as an outermost qualifier in a variable annotation [valid-type]
The form Final[ClassVar[int]] results in: error: Variable should not be annotated with both ClassVar and Final [misc]
The behavior is the same with or without the @dataclass decorator.
Your Environment
Mypy version used: 1.13.0
Mypy command-line flags:
Mypy configuration options from mypy.ini (and other config files): strict = true
For additional context, this case is covered by the typing spec conformance tests, and mypy does not currently pass this test case. This is reflected in the conformance test result summary page. (Scroll to the dataclasses_final line and hover over the mypy results in the table.)
Bug Report
[Python 3.13]
mypy
does not accept nestingClassVar
andFinal
in class bodyThe official docs of the
typing
module say:The typing specs on qualifiers are more specific:
In particular, nesting
ClassVar
andFinal
is a special case for dataclasses:To Reproduce
In both classes below the
foo
statement is not accepted bymypy
:Note that the docs only mention
ClassVar[Final[int]]
and notFinal[ClassVar[int]]
. In fact, the latter is not considered a class variable by the currentdataclasses
implementation:Expected Behavior
[Python 3.13]
mypy
should acceptClassVar[Final[<type>]]
in the body of a dataclassThe form
ClassVar[Final[int]]
conforms with the official typing specs and behaves as expected. I think it should be accepted as part of Python 3.13 support.The typing specs allow for a warning or error when
ClassVar
andFinal
are nested outside of a dataclass body. I think this should result in an error since it is redundant, perhaps only in strict mode.For the form
Final[ClassVar[int]]
I am not sure. It could either result in an error or simply be parsed as a final instance variable.Actual Behavior
The form
ClassVar[Final[int]]
results in:error: Final can be only used as an outermost qualifier in a variable annotation [valid-type]
The form
Final[ClassVar[int]]
results in:error: Variable should not be annotated with both ClassVar and Final [misc]
The behavior is the same with or without the
@dataclass
decorator.Your Environment
mypy.ini
(and other config files):strict = true
Notes
The typing specs were changed in python/typing#1669
Related discussion is found in python/cpython#89547
The difference between
ClassVar[Final[int]]
andFinal[ClassVar[int]]
was noticed in microsoft/pyright#8676 (comment)This issue is about Python 3.13 so could be added to #17264
This issue is related to #12061
The text was updated successfully, but these errors were encountered: