Error when using Protocol and different __init__() signatures
Open
Nobody has claimed this yet.
bug
priority-2-low
topic-join-v-union
topic-protocols
- Dominant language
- Python
- Stars
- 20.6k
- Forks
- 3.3k
- PR merge metrics
- PR metrics pending
Description
I'm getting mypy errors when using Protocol with classes that have different __init__() signatures. In the following example, function bar() causes an error:
from typing import Dict, Type
from typing_extensions import Protocol
class HasName(Protocol):
name: str
class Class1(HasName):
name = 'class1'
def __init__(self, a: int):
pass
class Class2(HasName):
name = 'class2'
def __init__(self, a: int, b: int):
pass
class Class3(HasName):
name = 'class3'
def __init__(self, a: int):
pass
# OK
def foo() -> Dict[Type[HasName], int]:
d = {}
for cls in (
Class1,
Class3,
):
d[cls] = 1
return d
# error: Incompatible return value type (got "Dict[ABCMeta, int]", expected "Dict[Type[HasName], int]")
def bar() -> Dict[Type[HasName], int]:
d = {}
for cls in (
Class1,
Class2,
Class3,
):
d[cls] = 1
return d
# OK
def baz(a: int) -> Type[HasName]:
if a == 1:
return Class1
elif a == 2:
return Class2
else:
return Class3
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 issue's minimal example with mypy and inspect how heterogeneous class tuples are inferred when their init() signatures differ. Done means the example's bar() function is accepted consistently with foo() and baz(), with a regression test covering the behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- compilers, devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 30/100