[red-knot] Understand typing.Callable (#16493)

## Summary

Part of https://github.com/astral-sh/ruff/issues/15382

This PR implements a general callable type that wraps around a
`Signature` and it uses that new type to represent `typing.Callable`.

It also implements `Display` support for `Callable`. The format is as:
```
([<arg name>][: <arg type>][ = <default type>], ...) -> <return type>
```

The `/` and `*` separators are added at the correct boundary for
positional-only and keyword-only parameters. Now, as `typing.Callable`
only has positional-only parameters, the rendered signature would be:

```py
Callable[[int, str], None]
# (int, str, /) -> None
```

The `/` separator represents that all the arguments are positional-only.

The relationship methods that check assignability, subtype relationship,
etc. are not yet implemented and will be done so as a follow-up.

## Test Plan

Add test cases for display support for `Signature` and various mdtest
for `typing.Callable`.
This commit is contained in:
Dhruv Manilawala 2025-03-08 09:28:52 +05:30 committed by GitHub
parent 24c8b1242e
commit 0361021863
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 895 additions and 57 deletions

View file

@ -2179,6 +2179,13 @@ impl ExprName {
pub fn id(&self) -> &Name {
&self.id
}
/// Returns `true` if this node represents an invalid name i.e., the `ctx` is [`Invalid`].
///
/// [`Invalid`]: ExprContext::Invalid
pub const fn is_invalid(&self) -> bool {
matches!(self.ctx, ExprContext::Invalid)
}
}
impl ExprList {