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

Pylance reports "Illegal type annotation" error for dict with complex Literal types #4262

Closed
PabloLION opened this issue Apr 19, 2023 · 2 comments
Assignees

Comments

@PabloLION
Copy link

When using complex Literal types to define the key-value types of a dictionary, Pylance reports an "Illegal type annotation" error if the Literal types are not defined as separate type aliases.

Environment data

  • Language Server version: Pylance language server 2023.4.20 (pyright 64a33975)
  • OS and version: macOS Monterey 12.6 (21G115)
  • Python version (& distribution if applicable, e.g. Anaconda): 3.11.2 (installed via homebrew)

Code Snippet

from typing import Literal

Foo, Bar = int, str
d: dict[Foo, Bar] = {1: "a", 2: "b"}

GoodFoo = Literal[1, 2]
GoodBar = Literal["a", "b"]
good_d: dict[GoodFoo, GoodBar] = {1: "a", 2: "b"}

SameFoo, SameBar = Literal[1, 2], Literal["a", "b"]
same_d: dict[SameFoo, SameBar] = {1: "a", 2: "b"}
# Illegal type annotation: variable not allowed unless it is a type alias Pylance reportGeneralTypeIssues

Repro Steps

I offer two options but there might be better ones:

  1. use correct type definition instead of the last one in the file.
  2. (compromise) report error when user reassigns a type definition

Expected behavior

No error on assigning multiple type definitions with tuple destructuring

Actual behavior

Pylance reported an error

Logs

log.txt (same as #4260)

@erictraut
Copy link
Contributor

This behavior is correct. You cannot use variables in type annotations. In your example, SameFoo and SameBar are variables.

You are allowed to use type aliases in type annotations. Python doesn't (yet) have a dedicated syntax for declaring type annotations, as most languages do. Traditionally, a type alias is defined using a simple assignment statement where the LHS is a simple name and the RHS is an expression that is a legal type annotation. An example is:

SameBar = Literal["a", "b"]

Note that tuple-based assignments are not legal type alias declarations, which is why the symbols SameFoo and SameBar in your code sample above are considered regular variables and not type aliases.

PEP 613 introduced the notion of an "explicit type alias" using the symbol typing.TypeAlias.

SameBar: TypeAlias = Literal["a", "b"]

PEP 695, which was just accepted by the Python Steering Council for inclusion in Python 3.12, introduces a dedicated syntax for declaring type aliases. It takes the form:

type SameBar = Literal["a", "b"]

Pylance already has support for PEP 695, but it is obviously not yet supported by the Python interpreter.

@rchiodo rchiodo closed this as completed Apr 19, 2023
@PabloLION
Copy link
Author

Thanks for the education 😃
BTW, rchiodo is a bot right? I was trying to close the issue and I have to admit that he has very fast hand.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants