microsoft / microsoft/pyright

Generic ParamSpec on class produces `reportCallIssue` error after conditional check `len(args) == x` or `len(args) != x`

Open
#10,656 2 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**

The below code produces the error `Arguments for ParamSpec "P@MyClass" are missing (reportCallIssue)` on the second call to the method `MyClass.func()` within `MyClass.__call__()`.

Code sample in [pyright playground](https://pyright-play.net/?code=MYGwhgzhAECyCeBhcUDaAqdAFAugLgChpjoATAUwDNoB9G4MEEOgCgnJEoBpp0wAnAOYQ80LADoBwnpgDWAdykix4hUoCU0ALQA%2BaAEsAdgBdCJc7WgBeaO07jKAV0PAWfIRBno1HzdADE0IYA9tAADvD8%2BoIAFsbQ5Pz8wfxEFsT61CDkhiwa1jYADGbpFmFRJiwA5AASHCChAOopIKQAhFXqaen85MaO-Ia2HJQOzq7u0rzeir7EgRFRsfGJyandZFTQTi5sIzJKohJKXj7CR6qzwpq6BiYlPX0DQ4UEQA)

```python
class MyClass[**P]:
def __call__(self, *args: P.args, **kwargs: P.kwargs) -> int:
_ = self.func(*args, **kwargs) # no pyright error
if len(args) == 0:
print('Hello World!')
return self.func(*args, **kwargs) # pyright error

def func(self, *args: P.args, **kwargs: P.kwargs) -> int:
return 0
```

I did some testing with different conditions in place of `len(args) == 0` to better understand what does/doesn't produce the same error:

- Produces same error:
- `len(args) != 0`
- `len(args) == 1`
- `len(args) != 1`
- `len(args) == 314`
- `len(args) != 314`
- Doesn't error:
- `len(kwargs) == 0`
- `len(args) > 10`
- `len(args) >= 10`
- `len(args) < 10`
- `len(args) <= 10`

**Workaround**

This bug can be worked around by simply assigning the result of the equality check to a variable and then using that variable in the conditional, e.g.:

```python
class MyClass[**P]:
def __call__(self, *args: P.args, **kwargs: P.kwargs) -> int:
_ = self.func(*args, **kwargs) # no pyright error
comp = len(args) == 0
if comp:
print('Hello World!')
return self.func(*args, **kwargs) # no pyright error

def func(self, *args: P.args, **kwargs: P.kwargs) -> int:
return 0
```

**VS Code extension or command-line**

I am running pyright via the command line, using version 1.1.402.

Contributor guide

Open the contributing guide

Research direction

Start with the linked Pyright playground example and reproduce it using the command-line version 1.1.402. Trace the ParamSpec handling for the second self.func call after equality checks on len(args), then add a regression test for the failing conditions and confirm the workaround behavior remains correct.

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
Clearly specified
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.