Closed
Description
Bug Report
(A clear and concise description of what the bug is.)
To Reproduce
from __future__ import annotations
from attrs import evolve, frozen
from typing import Generic, TypeVar
T1 = TypeVar("T1")
T2 = TypeVar("T2")
@frozen
class Test(Generic[T1]):
var: T1
# Can't substitute equivalent typevar in method.
def update(self: Test[T2], var: T2) -> Test[T2]:
return evolve(self, var=var)
# Can't use *same* typevar in function.
def update_t1(test: Test[T1], var: T1) -> Test[T1]:
return evolve(test, var=var)
# Can't use equivalent typevar in function.
def update_t2(test: Test[T2], var: T2) -> Test[T2]:
return evolve(test, var=var)
Actual Behavior
test_mypy.py:16: error: Argument 1 to "evolve" of "Test[T2]" has incompatible type "Test[T2]"; expected "Test[T1]" [arg-type]
test_mypy.py:16: error: Argument "var" to "evolve" of "Test[T2]" has incompatible type "T2"; expected "T1" [arg-type]
test_mypy.py:21: error: Argument 1 to "evolve" of "Test[T1]" has incompatible type "Test[T1]"; expected "Test[T1]" [arg-type]
test_mypy.py:21: error: Argument "var" to "evolve" of "Test[T1]" has incompatible type "T1"; expected "T1" [arg-type]
test_mypy.py:26: error: Argument 1 to "evolve" of "Test[T2]" has incompatible type "Test[T2]"; expected "Test[T1]" [arg-type]
test_mypy.py:26: error: Argument "var" to "evolve" of "Test[T2]" has incompatible type "T2"; expected "T1" [arg-type]
Found 6 errors in 1 file (checked 1 source file)
This gets worse when using constrained typevars, because the typevar on the function/method gets expanded to every constraint, but the typevar on the class isn't expanded, so it only accepts the typevar, even though it's passing the concrete type.
Your Environment
- Mypy version used:
mypy 1.2.0 (compiled: yes)
(passes withmypy 1.1.1 (compiled: yes)
) - Mypy command-line flags:
- Mypy configuration options from
mypy.ini
(and other config files): (these approximate some past version of--strict
, and a bunch of project-specific stuff that shouldn't be relevant)
[mypy]
warn_unused_configs = True
disallow_any_generics = True
disallow_subclassing_any = True
disallow_untyped_calls = True
disallow_untyped_defs = True
disallow_untyped_decorators = True
no_implicit_optional = True
warn_redundant_casts = True
warn_unused_ignores = True
warn_return_any = True
no_implicit_reexport = True
strict_equality = True
plugins = trio_typing.plugin, plugins/type_func.py
show_error_codes = True
mypy_path = $MYPY_CONFIG_FILE_DIR/stubs
[mypy-cement.utils.version]
ignore_missing_imports = True
[mypy-cement.core.exc]
ignore_missing_imports = True
[mypy-tqdm]
ignore_missing_imports = True
- Python version used:
3.9.4