microsoft / microsoft/pyright

Pyright fails to fully infer the type of a curried function when applied to a generic function

Open
#10,231 0 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
Python
Stars
15.6k
Forks
1.8k
Avg merge
12h 13m
Merged PRs (30d)
52

Description

**Describe the bug**
Pyright fails to correctly infer the type of the curried `precompose` function when used with the `id` function. Specifically, the type of `precompose(id)(id)` is partially inferred as `(Unknown) -> list[list[T@id]]`. Interestingly, if I use `postcompose` where the arguments are flipped, pyright correctly infers the type of the result.

**Code or Screenshots**
```python
from collections.abc import Callable

def curry[First, *Rest, Result](function: Callable[[First, *Rest], Result]) -> Callable[[*Rest], Callable[[First], Result]]:
return lambda *rest: lambda first: function(first, *rest)

@curry
def precompose[A, B, C](second: Callable[[B], C], first: Callable[[A], B]) -> Callable[[A], C]: ...

@curry
def postcompose[A, B, C](first: Callable[[A], B], second: Callable[[B], C]) -> Callable[[A], C]: ...

def id[T](x: T) -> list[T]: ... # any generic would do

reveal_type(precompose(id)(id)) # (Unknown) -> list[list[T@id]]
reveal_type(postcompose(id)(id)) # (T(1)@id) -> list[list[T(1)@id]]
```

Contributor guide

Open the contributing guide

Research direction

Start by running the provided Python snippet in Pyright and comparing the two reveal_type outputs. Trace the type-inference path for curried generic Callable applications, then verify that precompose(id)(id) preserves its generic parameter and produces the expected type; add a regression test for the behavior.

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
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.