[red-knot] Add __init__ arguments check when doing try_call on a class literal (#16512)

## Summary

* Addresses #16511 for simple cases where only `__init__` method is
bound on class or doesn't exist at all.
* fixes a bug with argument counting in bound method diagnostics

Caveats:
* No handling of `__new__` or modified `__call__` on metaclass.
* This leads to a couple of false positive errors in tests

## Test Plan

- A couple new cases in mdtests
- cargo nextest run -p red_knot_python_semantic --no-fail-fast

---------

Co-authored-by: Carl Meyer <carl@astral.sh>
Co-authored-by: David Peter <sharkdp@users.noreply.github.com>
This commit is contained in:
Mike Perlov
2025-04-08 23:26:20 +02:00
committed by GitHub
parent ed14dbb1a2
commit fab7d820bd
11 changed files with 853 additions and 121 deletions

View File

@@ -111,6 +111,8 @@ class E[T]:
def __init__(self, x: T) -> None: ...
# TODO: revealed: E[int] or E[Literal[1]]
# TODO should not emit an error
# error: [invalid-argument-type] "Object of type `Literal[1]` cannot be assigned to parameter 2 (`x`) of bound method `__init__`; expected type `T`"
reveal_type(E(1)) # revealed: E
```
@@ -118,7 +120,8 @@ The types inferred from a type context and from a constructor parameter must be
other:
```py
# TODO: error
# TODO: the error should not leak the `T` typevar and should mention `E[int]`
# error: [invalid-argument-type] "Object of type `Literal["five"]` cannot be assigned to parameter 2 (`x`) of bound method `__init__`; expected type `T`"
wrong_innards: E[int] = E("five")
```