python / python/mypy

Error when only assigning one of two typevars to concrete types (but no error when assigning two or zero)

Open
#14,078 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
Python
Stars
20.6k
Forks
3.3k
PR merge metrics
PR metrics pending

Description

Bug Report

When writing a generic class with two typevars, mypy accepts classmethods that (1) assign values based on both typevars and (2) assigns values based on no typevars; but does not accept a classmethod that assigns one value based on a typevar and one value based on a concrete value.

https://stackoverflow.com/q/74417503/1669576

To Reproduce

from typing import Generic, TypeVar

U = TypeVar('U')
V = TypeVar('V')
class Example(Generic[U, V]):
    def __init__(self, a: U, b: V):
        self._a = a
        self._b = b

    @classmethod
    def first(cls, val: U):
        return cls(val, None)

Expected Behavior

mypy should infer that None binds to V

Actual Behavior

mypy gives a seemingly spurious error error: Argument 2 to "Example" has incompatible type "None"; expected "V" [arg-type]

Your Environment

name: test
channels:
  - conda-forge
  - defaults
dependencies:
  - _libgcc_mutex=0.1=conda_forge
  - _openmp_mutex=4.5=2_kmp_llvm
  - bzip2=1.0.8=h7b6447c_0
  - ca-certificates=2022.9.24=ha878542_0
  - certifi=2022.9.24=pyhd8ed1ab_0
  - ld_impl_linux-64=2.38=h1181459_1
  - libffi=3.3=he6710b0_2
  - libgcc-ng=12.2.0=h65d4601_19
  - libstdcxx-ng=11.2.0=h1234567_1
  - libuuid=1.41.5=h5eee18b_0
  - llvm-openmp=14.0.6=h9e868ea_0
  - mypy=0.990=py310h5764c6d_2
  - mypy_extensions=0.4.3=py310h06a4308_0
  - ncurses=6.3=h5eee18b_3
  - openssl=1.1.1s=h166bdaf_0
  - pip=22.2.2=py310h06a4308_0
  - psutil=5.9.0=py310h5eee18b_0
  - python=3.10.6=haa1d7c7_1
  - python_abi=3.10=2_cp310
  - readline=8.2=h5eee18b_0
  - setuptools=65.5.0=py310h06a4308_0
  - sqlite=3.39.3=h5082296_0
  - tk=8.6.12=h1ccaba5_0
  - toml=0.10.2=pyhd3eb1b0_0
  - tomli=2.0.1=pyhd8ed1ab_0
  - typing_extensions=4.3.0=py310h06a4308_0
  - tzdata=2022f=h04d1e81_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.2.6=h5eee18b_0
  - zlib=1.2.13=h5eee18b_0
prefix: /home/b/miniconda3/envs/test
  • Mypy version used: 0.990
  • Mypy command-line flags: (none)
  • Mypy configuration options from mypy.ini (and other config files): (none)
  • Python version used: 3.10.6

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by running the provided Example class with mypy 0.990 and no configuration flags to reproduce the error. Trace generic classmethod and type-variable inference in the type checker, then add a regression test covering one concrete and one type-variable argument; done means mypy accepts the example without weakening the existing errors for zero or two type variables.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
devtools
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.