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

Forbid contravariant variable types, in addition to covariant variable types, in function signature #1190

Closed
Azureblade3808 opened this issue Apr 26, 2021 · 2 comments
Labels
bug Something isn't working fixed in next version (main) A fix has been implemented and will appear in an upcoming version

Comments

@Azureblade3808
Copy link

Azureblade3808 commented Apr 26, 2021

Environment data

  • Language Server version: 2021.4.2
  • OS and version: Windows 7
  • Python version (& distribution if applicable, e.g. Anaconda): 3.8.8 Anaconda

Sample code

from __future__ import annotations

from typing import TypeVar

T = TypeVar("T")
T_co = TypeVar("T_co", covariant=True)
T_contra = TypeVar("T_contra", contravariant=True)

def func_0(x: T, y: T) -> T:
    ...

# Faulty in input and has warnings in inputs.
def func_1(x: T_co, y: T_co) -> T_co:
    ...

# Faulty in output but has no warnings.
def func_2(x: T_contra, y: T_contra) -> T_contra:
    ...

x = int(0)  # type: int
y = str("")  # type: str

a = func_0(x, y)  # type: int | str
b = func_1(x, y)  # type: int | str
c = func_2(x, y)  # type: int | str

Expected behavior

According to PEP 484 (https://www.python.org/dev/peps/pep-0484/#covariance-and-contravariance):

Note: Covariance or contravariance is not a property of a type variable, but a property of a generic class defined using this variable. Variance is only applicable to generic types; generic functions do not have this property. The latter should be defined using only type variables without covariant or contravariant keyword arguments.

Covariant or contravariant type variables, used in functions, either in input or output, get marked as faulty.

Alternative expected behavior

Covariant type variables are allowed only in output but not input, while contravariant type variables are allowed only in input but not output.

In this ways, rule becomes consistent between functions and class methods.

Actual behavior

Covariant type variables are forbidden in input, but contravariant type variables are allowed in both input and output.

This behavior is the same as mypy, but I don't think it's right.

@erictraut
Copy link
Contributor

Thanks for the bug report. There was already a check in place for this condition, but it contained a bug where it missed some cases (in particular, cases where the contravariant TypeVar's scope was defined by the function itself rather than a containing class). This will be fixed in the next release.

@erictraut erictraut added bug Something isn't working fixed in next version (main) A fix has been implemented and will appear in an upcoming version and removed triage labels Apr 26, 2021
@jakebailey
Copy link
Member

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working 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

3 participants