Closed
Description
This issue tracks TODOs for literal types.
Core work
- Modify the parser so it can handle literal expressions in types (Add basic end-to-end support for Literal types #5947)
- Make any necessary changes to semantic analysis (see below) (Add basic end-to-end support for Literal types #5947)
- Implement the core type-checking logic (also see below)
- Implement logic for determining when and when not to infer Literal (Make literal exprs have inferred type of 'Literal' based on context #5990)
- Validate that everything works in incremental mode and with the mypy daemon (Add tests for Literal types with incremental and fine-grained mode #6075)
- Add "extra" features (again see below)
- Write docs
Parsing/semantic analysis follow-up tasks
- Distinguish between byte strings, native strings, and unicode in Python 2 and Python 3 (Add support for byte and unicode Literal strings #6087)
- Make sure everything still works with
from __future__ import unicode_literals
(Add support for byte and unicode Literal strings #6087) - Add more tests for forward references and related shenanigans
- Add logic to make sure literal expressions are coerced to the correct type based on context (Make literal exprs have inferred type of 'Literal' based on context #5990)
Error messages
- Add better error messages for complex numbers (Improve error messages related to literal types #6149)
- Add better error messages for weird expressions in general (e.g. disallowing
Literal[1 + 2]
. This will probably involve moving all invalid type checking into the semantic analysis layer? (Improve error messages related to literal types #6149) - Resolve Regression: error messages for literal expressions in invalid places are worse #5989 (Improve error messages related to literal types #6149)
Implementing and testing type visitors
Implement and write tests that exercise the following visitors. (Introduced by #5934)
- constraints.ConstraintBuilderVisitor (Make literal exprs have inferred type of 'Literal' based on context #5990)
- join.TypeJoinVisitor (Make literal exprs have inferred type of 'Literal' based on context #5990)
- meet.TypeMeetVisitor (Implement meet for literal types; add tests for 'is_same_type' #6043)
- subtypes.ProperSubtypeVisitor (Add basic end-to-end support for Literal types #5947)
- subtypes.SubtypeVisitor (Add basic end-to-end support for Literal types #5947)
- typeanal.TypeAnalyzer (Add basic end-to-end support for Literal types #5947)
- typeanal.TypeAnalyzerPass3 (Add basic end-to-end support for Literal types #5947)
- types.TypeStrVisitor (Add basic end-to-end support for Literal types #5947)
- type_visitor.TypeVisitor (indirectly, by other tests)
- type_visitor.TypeTranslator (indirectly, by other tests)
The following have preliminary implementations, but are missing associated tests:
- erasetype.EraseTypeVisitor (indirectly, by Add tests for literals and generics #6035)
- expandtype.ExpandTypeVisitor (indirectly, by Add tests for literals and generics #6035)
- fixup.TypeFixer (important for Enums)
- sametypes.SameTypeVisitor (Implement meet for literal types; add tests for 'is_same_type' #6043)
- server.astdiff.SnapshotTypeVisitor (Add tests for Literal types with incremental and fine-grained mode #6075)
- server.deps.TypeTriggersVisitor (Add tests for Literal types with incremental and fine-grained mode #6075)
Other checks to add in the type-checking layer
- Make sure we cannot subclass Literals (Prohibit some illegal uses of Literal #6034)
- Blacklist constructs like
Type[Literal[4]]
- Actually, should we? Maybe we should treat
Type[Literal[4]]
asint
instead -- this might make certain TypeVar shenanigans more smooth. Need to discuss. - Actually, the above idea seems like a bad idea: if we do
x: Literal[3]
, doingtype(x)
ought to return a value with typeType[int]
, not justint
.
- Actually, should we? Maybe we should treat
- Blacklist using
Literal[...]
inisinstance
andissubclass
checks (Prohibit some illegal uses of Literal #6034) - Validate
Literal
works as expected when used in generics (Add tests for literals and generics #6035) - Consider having mypy warn if somebody tries doing literally
TypeVar('T', bound=Literal[4])
? Need to discuss first.
"Extra" features to add
- Intelligent indexing of tuples, NamedTuples, TypedDict, getattr, and setattr (Add intelligent indexing of tuples, NamedTuples, and TypedDict #6124)
- While I'm at it, design a more intelligent "macro replace" system and try and fix the misc errors we get when using
--disallow-any-expr
?
- While I'm at it, design a more intelligent "macro replace" system and try and fix the misc errors we get when using
- Type narrowing with equality and inequality checks
- Interactions with
Final
(Add interactions between Literal and Final #6081) - Add custom type guards (see Ivan's comment below, also type refinement in function call #5206)
- Treat bool as a union of
Literal[True]
andLiteral[False]
(see Treat bool as equivalent to Literal[True, False] to allow better type inference #6113)
Things to do before mypy 0.660 is released if literal types aren't going to make it
- Address Regression: error messages for literal expressions in invalid places are worse #5989 -- restore old error messages, and expunge any reference to literal types in any error messages we added. (Remove RawLiteralType synthetic type #6121)
Other things
- Try replacing one of the functions we currently manage using plugins with literal types instead, and see what happens.
- I tried replacing the "open(...)" plugin and re-ran mypy on one of our smaller internal codebases. Out of approximately 680 calls to
open
, about 610 of them had 2 or more arguments. We inferred the correct type for about 560 of those. About another 20 of these were passing in string variable arguments as the mode. The remaining 30 require a little more investigation -- some people were passing in**kwargs
or**args
in as the argument, etc...
- I tried replacing the "open(...)" plugin and re-ran mypy on one of our smaller internal codebases. Out of approximately 680 calls to
Things that have been deferred to after this project is completed
- Adding support for enums in literal types (and while I'm at it, I might as well investigate overhauling enums in general). Related tasks:
- Treat enum classes as roughly a union of their values
- Better error messages for bad imports (e.g. enums with a coerced type of 'Any')
- In error messages, we seem to quote types using either single quotes or double quotes. This can sometimes lead to messy-looking error messages (e.g.
Revealed type is 'Literal['foo']'
). We should standardize on a specific quoting scheme + avoid this weird "nesting" issue. - Make sure we report an error when somebody tries doing
Literal[3]()
(andFinal[int]()
andProtocol[blah]()
...)