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

Type annotation error for generic list that includes union #1526

Closed
vishwa-raj opened this issue Jul 5, 2021 · 4 comments
Closed

Type annotation error for generic list that includes union #1526

vishwa-raj opened this issue Jul 5, 2021 · 4 comments
Labels
enhancement New feature or request fixed in next version (main) A fix has been implemented and will appear in an upcoming version

Comments

@vishwa-raj
Copy link

Environment data

  • Language Server version: 2021.6.3
  • OS and version: win32 x64
  • Python version (and distribution if applicable, e.g. Anaconda):
  • python.analysis.indexing: undefined
  • python.analysis.typeCheckingMode: basic

Code Snippet / Additional information

from __future__ import annotations

from typing import TypeVar


NUM_T = TypeVar('NUM_T', int, float)


def funcA(value: list[NUM_T | list[NUM_T]]):
    ...


def funcB(value: list[NUM_T | list[NUM_T]]):
    funcA(value)

Expected behaviour

No error.

Actual behaviour

Error shown on line 14:

Argument of type "list[NUM_T@func_B | list[NUM_T@func_B]]" cannot be assigned to parameter "value" of type "list[NUM_T@func_A | list[NUM_T@func_A]]" in function "func_A"
  TypeVar "_T@list" is invariant
    Type "NUM_T@func_B | list[NUM_T@func_B]" cannot be assigned to type "NUM_T@func_A | list[NUM_T@func_A]"
      Type "int* | float*" cannot be assigned to type "NUM_T@func_A | list[NUM_T@func_A]"
        Type "int*" cannot be assigned to type "NUM_T@func_A | list[NUM_T@func_A]"
          "int*" is incompatible with "list[NUM_T@func_A]"
        Type "float*" cannot be assigned to type "NUM_T@func_A | list[NUM_T@func_A]"
          "float*" is incompatible with "list[NUM_T@func_A]"
      Type "list[NUM_T@func_B]" cannot be assigned to type "NUM_T@func_A | list[NUM_T@func_A]"

image

@github-actions github-actions bot added the triage label Jul 5, 2021
@erictraut
Copy link
Contributor

Why are you using a type variable in this case? Do you mean to use a union type?

NUM_T = Union[int, float]

or

T = TypeVar("T")
LIST_T = list[T | list[T]]
NUM_T = Union[LIST_T[int], LIST_T[float]]

@vishwa-raj
Copy link
Author

vishwa-raj commented Jul 5, 2021

@erictraut It's a fabricated example from a larger piece of code whose type annotation may look like list[NUM_T] | list[tuple[NUM_T, NUM_T]].
What we need here is to be able to allow both int and float type inputs.
If I just use float or float | int instead of NUM_T, I cannot pass an input like [1, 2, 3] without raising a type-annotation error as the input is of of type list[int] and list is invariant.
I can enumerate all combinations of int and float, like list[int] | list[float] | list[tuple[int, int]] | list[tuple[int, float]] ... but that will get unwieldy as the original type annotation includes many more combinations.

@erictraut
Copy link
Contributor

This will be fixed in the next release. I've improved the heuristics for type matching when the source and destination types are both unions and invariance is enforced. The rules for matching in this case are not well defined and can be ambiguous in some cases where generics are involved in the destination type, but I've improved the heuristics to work in more cases including the one above.

@erictraut erictraut added enhancement New feature or request fixed in next version (main) A fix has been implemented and will appear in an upcoming version and removed in backlog needs investigation Could be an issue - needs investigation labels Jul 11, 2021
@bschnurr
Copy link
Member

This issue has been fixed in version 2021.7.3, which we've just released. You can find the changelog here: https://github.com/microsoft/pylance-release/blob/main/CHANGELOG.md#202173-14-july-2021

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request fixed in next version (main) A fix has been implemented and will appear in an upcoming version
Projects
None yet
Development

No branches or pull requests

4 participants