Method-bound type-parameter can "leak" through a `Protocol`
Open
Nobody has claimed this yet.
bug
- Dominant language
- Python
- Stars
- 15.6k
- Forks
- 1.8k
- Avg merge
- 12h 13m
- Merged PRs (30d)
- 52
Description
I encountered this while working on https://github.com/python/typeshed/pull/14786:
from typing import Any, Protocol, final
@final
class Box[T]:
_value: T
def __init__(self, value: T, /) -> None:
self._value = value
def __replace__[VT](self, value: VT) -> Box[VT]:
return Box(value)
class CanReplace[RT](Protocol):
def __replace__(self, /, *args: Any, **kwargs: Any) -> RT: ...
def replace[RT](b: CanReplace[RT], /, **kwargs: Any) -> RT:
return b.__replace__(**kwargs)
reveal_type(replace(Box(42), value="spam")) # Box[VT@__replace__]
Change Box.__replace__ to (self, *, value: VT) and it (correctly) reveals Box[Any].
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 reproducing the reported snippet and comparing the revealed type for the generic and keyword-only versions of Box.replace. Trace the type-checker path for method-scoped type parameters passed through Protocol return types, then add a regression test that verifies the method-bound parameter does not leak and the revealed type is correct.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100