Finals and Literals: Spec contradiction #2351
Description
This came up in python/typeshed#16301. I assume this is mostly a clerical/historical error, but let me know if we should follow the whole spec change process.
The typing spec says about Final:
Example:
ID: Final = 1The typechecker should apply its usual type inference mechanisms to determine the type of ID (here, likely, int).
And then a bit later:
Type checkers should treat uses of a final name that was initialized with a literal as if it was replaced by the literal.
Both sentences are copied directly from PEP 591, which overlapped with the Literals PEP 586.
I assume that we should change the first sentence to "here, likely, Literal[1]" and change the second sentence to be a bit more concrete along these lines:
Type checkers should infer uses of a final name that was initialized with a literal
XasLiteral[X]ifXis an allowed literal type (cf. to the literals section). Otherwise, they should infer the type of theX.
(And maybe extend the example after a bit.)
In fact, this is what the conformance tests already check:
typing/conformance/tests/qualifiers_final_annotation.py
Lines 11 to 13 in cf943cc
| ID2: Final = 1 | |
| assert_type(ID2, Literal[1]) | |
(Although the tests could be extended a bit.)
Activity
carljm commentedon Aug 31, 2026
I do think a clarification to the spec text is warranted here; the current text is confusing. I think we should remove
(here, likely, int)and instead mention the later "replacement" rule. And we should probably also clarify that the replacement rule applies to a bareFinalannotation with valid literal initializer.I would consider this a spec clarification, not a change in specification.
srittau commentedon Aug 31, 2026
As @carljm points out in #2352, the Literal section of the spec has a whole section about the interaction with
Finalthat actually is already correct. We should probably just change the mentions in theFinalspec part to point to that section.