Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Literal types tracking issue #5935

Closed
38 of 42 tasks
Michael0x2a opened this issue Nov 21, 2018 · 5 comments
Closed
38 of 42 tasks

Literal types tracking issue #5935

Michael0x2a opened this issue Nov 21, 2018 · 5 comments
Assignees
Labels
meta Issues tracking a broad area of work topic-literal-types

Comments

@Michael0x2a
Copy link
Collaborator

Michael0x2a commented Nov 21, 2018

This issue tracks TODOs for literal types.

Core work

Parsing/semantic analysis follow-up tasks

Error messages

Implementing and testing type visitors

Implement and write tests that exercise the following visitors. (Introduced by #5934)

The following have preliminary implementations, but are missing associated tests:

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]] as int 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], doing type(x) ought to return a value with type Type[int], not just int.
  • Blacklist using Literal[...] in isinstance and issubclass 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

Things to do before mypy 0.660 is released if literal types aren't going to make it

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...

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]() (and Final[int]() and Protocol[blah]()...)
@JukkaL
Copy link
Collaborator

JukkaL commented Nov 22, 2018

The plan looks great! I'm looking forward to being able to use literal types.

Michael0x2a added a commit that referenced this issue Nov 22, 2018
This diff adds a 'LiteralType' class to types.py and adds a
corresponding stub method to all of the type visitors.

Most of these stub methods just throw a 'NotImplementedError',
though I did pencil in a few implementations that looked obvious.

The reason I'm doing this now instead of later is because I want
to start by getting these kind of big, gross, multi-file changes
out of the way early and try and have any subsequent pull requests
be more focused.

I also want to formally confirm that the correct approach here
*is* to create a new 'LiteralType' class before I start on the
rest of the implementation work. (Other possible approaches would
be to tack on some extra attribute to 'Instance', or make
'LiteralType' a subclass of 'Instance'.)

No tests, sorry. My plan is to work on modifying the parsing
and semantic analysis steps next before returning back to these
the unimplemented methods and add tests then --  here's the
tracking issue for these TODOs:
#5935

Tests shouldn't be necessary, in any case: everything I added
just now is basically dead code.
@Michael0x2a Michael0x2a self-assigned this Nov 24, 2018
@ilevkivskyi
Copy link
Member

I think this idea already appeared somewhere, but I think it makes sense to add this to this list: custom type-guards (like in TypeScript):

@overload
def is_spec(arg: Union[int, List[int]]) -> Literal[True]: ...
@overload
def is_spec(arg: object) -> bool: ...
def is_spec(arg):
    # some complex logic here
    ...

x: Union[int, str]
if is_spec(x):
    x += 42

essentially we just nee to teach binder how to interact with literals.

@ilevkivskyi
Copy link
Member

@Michael0x2a I propose to use #5206 to track the type-guards idea (literals + binder).

@97littleleaf11 97littleleaf11 added the meta Issues tracking a broad area of work label Nov 12, 2021
@ethanhs
Copy link
Collaborator

ethanhs commented May 19, 2022

There seem to be 3 relatively simple tasks left:

  • Add tests for Literal and TypeFixer
  • Disallow Type[Literal[4]]
  • Disallow TypeVar('T', bound=Literal[4])

the last two in particular should be good first issues if I'm not mistaken.

@hauntsaninja
Copy link
Collaborator

I don't know that we need to error for the second one, and I feel we shouldn't disallow erroring for the third one (or any bound to a final type). I can't see what specific tests we'd want to add for the first one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
meta Issues tracking a broad area of work topic-literal-types
Projects
None yet
Development

No branches or pull requests

6 participants