python / python/mypy

Inlining a list argument into call of function that accepts a protocol produces "incompatible type" error

Open
#21,563 0 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 passing a list of ints as an argument to a function that accepts a generic protocol, for some reason it is necessary to first bind the list to a variable. Inlining the list as a literal expression in the function call produces a [list-item] error from mypy. What's interesting is that this error references a generic type T, which is not declared anywhere in my program.

To Reproduce

from typing import TypeVar, Protocol, Self

K = TypeVar('K', covariant=True)
class Concattable(Protocol[K]):
    def __add__(self, other: Self) -> Self: ...

J = TypeVar('J')
def duplicate(seq: Concattable[J]) -> Concattable[J]:
    return seq + seq

# No issue
mylist = [1,2,3]
assert duplicate(mylist) == [1,2,3,1,2,3]

# Issue
assert duplicate([1,2,3]) == [1,2,3,1,2,3]


Expected Behavior

I expect that both function calls do not produce any mypy errors.

Actual Behavior

While the first call is fine, the second one produces an error for each element of the list.
It also makes mention of a generic type T, which is not declared anywhere in my program.

construct-new-sequence.py:16: error: List item 0 has incompatible type "int"; expected "T"  [list-item]
construct-new-sequence.py:16: error: List item 1 has incompatible type "int"; expected "T"  [list-item]
construct-new-sequence.py:16: error: List item 2 has incompatible type "int"; expected "T"  [list-item]
Found 3 errors in 1 file (checked 1 source file)

Your Environment

$ pip --version
pip 26.1.1 from /venv/lib/python3.12/site-packages/pip (python 3.12)
$ python --version
Python 3.12.13
$ mypy --version
mypy 2.1.0 (compiled: yes)
$ pip freeze | grep mypy
mypy==2.1.0
mypy_extensions==1.1.0
  • There is no mypy.ini or other mypy configuration files.
  • I invoke mypy simply from the command line by running mypy --strict myfile.py

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 with the construct-new-sequence.py reproduction and run mypy --strict, comparing the bound-list call with the inline list literal. Trace the generic protocol inference that produces the unexpected T and [list-item] diagnostics. Done when both calls pass without errors and the reported type is no longer spurious.

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
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.