Regression: crtp type bounds lost
- Dominant language
- Python
- Stars
- 15.6k
- Forks
- 1.8k
- Avg merge
- 12h 13m
- Merged PRs (30d)
- 52
Description
**Describe the bug**
In the example below, I have two ways of turning a function that takes a recursive visitor as a second argument into a simple-recursive one.
In the `make_rec_protocol` case, I expect that the revealed type of the return value is `Recursive[T@_protocol, T@_protocol]` and in the `make_rec_callable` that it is `Callable[[T@_callable], T@_callable]`.
In 1.1.375 this is the case.
In 1.1.376 and later, `make_rec_callable` has a type of `Callable[[Node[Any]], Node[Any]`
In 1.1.388 and later, `make_rec_protocol` has a type of `Recursive[Node[Any], Node[Any]]`.
So it appears like the actual generics are being lost and only the bound on the generic is being inferred.
Is this correct due to a tightening of the rules, or a regression?
**Code or Screenshots**
```python
from typing import Any, Protocol, Callable
class Node[T: "Node[Any]"]:
...
class Recursive[U_contra, V_co](Protocol):
def __call__(self, value: U_contra) -> V_co:
...
def _protocol[T: "Node[Any]"](node: T, fn: Recursive[T, T]) -> T:
...
def _callable[T: "Node[Any]"](node: T, fn: Callable[[T], T]) -> T:
...
def make_rec_protocol[U_contra, V_co](
fn: Callable[[U_contra, Recursive[U_contra, V_co]], V_co]
) -> Recursive[U_contra, V_co]:
...
def make_rec_callable[U_contra, V_co](
fn: Callable[[U_contra, Callable[[U_contra], V_co]], V_co]
) -> Callable[[U_contra], V_co]:
...
reveal_type(make_rec_protocol(_protocol)) # Expect Recursive[T@_protocol, T@_protocol]
reveal_type(make_rec_callable(_callable)) # Expect Callable[[T@_callable], T@_callable]
```
Contributor guide
Research direction
No repository file or test is named. Start by reproducing the supplied Python snippet with Pyright 1.1.375, 1.1.376, and 1.1.388 or later, then trace the generic inference path for make_rec_protocol and make_rec_callable. Done means determining whether the revealed types preserve the type variables or incorrectly widen them to their bounds, with a regression test covering the result.
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
- 35/100