Overloads with Generics "does not accept all possible arguments"
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 20.6k
- Forks
- 3.3k
- PR merge metrics
- PR metrics pending
Description
I have a function whose return type is determined by the type of an input parameter (with a default value). I have attempted to type-hint it with generics. I get "error: Overloaded function implementation does not accept all possible arguments of signature".
To Reproduce
In the toy example below, the function has two return types (original-type or list) depending on two possible types of the force_list input (Force or NoForce). For completeness I have overloaded all 4 permutations of the input and output types.
Playground: https://mypy-play.net/?mypy=latest&python=3.12&gist=283290e33e2618dfcdf447513d0f4543
from typing import TypeVar, assert_type, overload
class Force: ...
ForceInstance = Force()
class NoForce: ...
NoForceInstance = NoForce()
T = TypeVar("T")
@overload
def list_or_orig(x: list[T], force_list: Force = ...) -> list[T]: ...
@overload
def list_or_orig(x: list[T], force_list: NoForce = ...) -> list[T]: ...
@overload
def list_or_orig(x: T, force_list: Force = ...) -> list[T]: ...
@overload
def list_or_orig(x: T, force_list: NoForce = ...) -> T: ...
def list_or_orig(x: list[T] | T, force_list: Force | NoForce = ForceInstance) -> list[T] | T:
"""Return a list or scalar depending on force_list flag."""
if isinstance(x, list):
return x
elif isinstance(force_list, Force):
return [x]
else:
return x
a_list = list_or_orig(1) # Since default is Force, this will return list[int]
assert_type(a_list, list[int])
b_list = list_or_orig(1, ForceInstance)
assert_type(b_list, list[int])
a_int = list_or_orig(1, NoForceInstance) # This will return int
assert_type(a_int, int)
Expected Behavior
No errors when running through mypy.
Actual Behavior
main.py:29: error: Overloaded function implementation does not accept all possible arguments of signature 1 [misc]
main.py:29: error: Overloaded function implementation does not accept all possible arguments of signature 2 [misc]
Found 2 errors in 1 file (checked 1 source file)
Notes
If I replace the generic type T with a specific type, say, int then it's fine.
I appreciate there is an ambiguity between list[T] and T but have included the less-general list[T] first in the overloads.
The same code passes in the pyright playground.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by running the minimal Python example from the issue with mypy and compare its result with the linked Pyright behavior. Trace the overload implementation-compatibility check that reports signatures 1 and 2. Done means the example produces no compatibility errors while preserving the shown assert_type results.
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
- 45/100