Commit graph

18 commits

Author SHA1 Message Date
David Peter
ae2cf91a36
[red-knot] Decorators and properties (#17017)
## Summary

Add support for decorators on function as well as support
for properties by adding special handling for `@property` and `@<name of
property>.setter`/`.getter` decorators.

closes https://github.com/astral-sh/ruff/issues/16987

## Ecosystem results

- ✔️ A lot of false positives are fixed by our new
understanding of properties
- 🔴 A bunch of new false positives (typically
`possibly-unbound-attribute` or `invalid-argument-type`) occur because
we currently do not perform type narrowing on attributes. And with the
new understanding of properties, this becomes even more relevant. In
many cases, the narrowing occurs through an assertion, so this is also
something that we need to implement to get rid of these false positives.
- 🔴 A few new false positives occur because we do not
understand generics, and therefore some calls to custom setters fail.
- 🔴 Similarly, some false positives occur because we do not
understand protocols yet.
- ✔️ Seems like a true positive to me. [The
setter](e624d8edfa/src/packaging/specifiers.py (L752-L754))
only accepts `bools`, but `None` is assigned in [this
line](e624d8edfa/tests/test_specifiers.py (L688)).
  ```
+ error[lint:invalid-assignment]
/tmp/mypy_primer/projects/packaging/tests/test_specifiers.py:688:9:
Invalid assignment to data descriptor attribute `prereleases` on type
`SpecifierSet` with custom `__set__` method
  ```
- ✔️ This is arguable also a true positive. The setter
[here](0c6c75644f/rich/table.py (L359-L363))
returns `Table`, but typeshed wants [setters to return
`None`](bf8d2a9912/stdlib/builtins.pyi (L1298)).
  ```
+ error[lint:invalid-argument-type]
/tmp/mypy_primer/projects/rich/rich/table.py:359:5: Object of type
`Literal[padding]` cannot be assigned to parameter 2 (`fset`) of bound
method `setter`; expected type `(Any, Any, /) -> None`
  ```  

## Follow ups

- Fix the `@no_type_check` regression
- Implement class decorators

## Test Plan

New Markdown test suites for decorators and properties.
2025-04-02 09:27:46 +02:00
David Peter
2d7f118f52
[red-knot] Binary operator inference: generalize code for non-instances (#17081)
## Summary

Generalize the rich-comparison fallback code for binary operator
inference. This gets rid of one `todo_type!(…)` and implements the last
remaining failing case from
https://github.com/astral-sh/ruff/issues/14200.

closes https://github.com/astral-sh/ruff/issues/14200

## Test Plan

New Markdown tests.
2025-03-31 13:01:25 +02:00
Shunsuke Shibayama
aca6254e82
[red-knot] fix eager nested scopes handling (#16916)
## Summary

From #16861, and the continuation of #16915.

This PR fixes the incorrect behavior of
`TypeInferenceBuilder::infer_name_load` in eager nested scopes.

And this PR closes #16341.

## Test Plan

New test cases are added in `annotations/deferred.md`.
2025-03-28 11:11:56 -04:00
Douglas Creager
23ccb52fa6
[red-knot] Handle unions of callables better (#16716)
This cleans up how we handle calling unions of types. #16568 adding a
three-level structure for callable signatures (`Signatures`,
`CallableSignature`, and `Signature`) to handle unions and overloads.

This PR updates the bindings side to mimic that structure. What used to
be called `CallOutcome` is now `Bindings`, and represents the result of
binding actual arguments against a possible union of callables.
`CallableBinding` is the result of binding a single, possibly
overloaded, callable type. `Binding` is the result of binding a single
overload.

While we're here, this also cleans up `CallError` greatly. It was
previously extracting error information from the bindings and storing it
in the error result. It is now a simple enum, carrying no data, that's
used as a status code to talk about whether the overall binding was
successful or not. We are now more consistent about walking the binding
itself to get detailed information about _how_ the binding was
unsucessful.

---------

Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
Co-authored-by: Carl Meyer <carl@astral.sh>
2025-03-17 10:35:52 -04:00
Shunsuke Shibayama
78b5f0b165
[red-knot] detect invalid return type (#16540)
## Summary

This PR closes #16248.

If the return type of the function isn't assignable to the one
specified, an `invalid-return-type` error occurs.
I thought it would be better to report this as a different kind of error
than the `invalid-assignment` error, so I defined this as a new error.

## Test Plan

All type inconsistencies in the test cases have been replaced with
appropriate ones.

---------

Co-authored-by: Carl Meyer <carl@astral.sh>
2025-03-12 01:58:59 +00:00
David Peter
86b01d2d3c
[red-knot] Correct modeling of dunder calls (#16368)
## Summary

Model dunder-calls correctly (and in one single place), by implementing
this behavior (using `__getitem__` as an example).

```py
def getitem_desugared(obj: object, key: object) -> object:
    getitem_callable = find_in_mro(type(obj), "__getitem__")
    if hasattr(getitem_callable, "__get__"):
        getitem_callable = getitem_callable.__get__(obj, type(obj))

    return getitem_callable(key)
```

See the new `calls/dunder.md` test suite for more information. The new
behavior also needs much fewer lines of code (the diff is positive due
to new tests).

## Test Plan

New tests; fix TODOs in existing tests.
2025-02-25 20:38:15 +01:00
David Peter
141ba253da
[red-knot] Add support for @classmethods (#16305)
## Summary

Add support for `@classmethod`s.

```py
class C:
    @classmethod
    def f(cls, x: int) -> str:
        return "a"

reveal_type(C.f(1))  # revealed: str
```

## Test Plan

New Markdown tests
2025-02-24 09:55:34 +01:00
Micha Reiser
5fab97f1ef
[red-knot] Diagnostics for incorrect bool usages (#16238) 2025-02-21 19:26:05 +01:00
Micha Reiser
4ed5db0d42
Refactor CallOutcome to Result (#16161) 2025-02-18 13:34:39 +01:00
Carl Meyer
dcabb948f3
[red-knot] add special case for float/complex (#16166)
When adjusting the existing tests, I aimed to avoid dealing with the
special case in other tests if it's not necessary to do so (that is,
avoid using `float` and `complex` as examples where we just need "some
type"), and keep the tests for the special case mostly collected in the
mdtest dedicated to that purpose.

Fixes https://github.com/astral-sh/ruff/issues/14932
2025-02-14 12:24:10 -08:00
David Peter
1feb3cf41a
[red-knot] Use Unknown | T_inferred for undeclared public symbols (#15674)
## Summary

Use `Unknown | T_inferred` as the type for *undeclared* public symbols.

## Test Plan

- Updated existing tests
- New test for external `__slots__` modifications.
- New tests for external modifications of public symbols.
2025-01-24 12:47:48 +01:00
InSync
15fe540251
Improve mdtests style (#14884)
Co-authored-by: Alex Waygood <alex.waygood@gmail.com>
2024-12-10 13:05:51 +00:00
David Peter
47f39ed1a0
[red-knot] Meta data for Type::Todo (#14500)
## Summary

Adds meta information to `Type::Todo`, allowing developers to easily
trace back the origin of a particular `@Todo` type they encounter.

Instead of `Type::Todo`, we now write either `type_todo!()` which
creates a `@Todo[path/to/source.rs:123]` type with file and line
information, or using `type_todo!("PEP 604 unions not supported")`,
which creates a variant with a custom message.

`Type::Todo` now contains a `TodoType` field. In release mode, this is
just a zero-sized struct, in order not to create any overhead. In debug
mode, this is an `enum` that contains the meta information.

`Type` implements `Copy`, which means that `TodoType` also needs to be
copyable. This limits the design space. We could intern `TodoType`, but
I discarded this option, as it would require us to have access to the
salsa DB everywhere we want to use `Type::Todo`. And it would have made
the macro invocations less ergonomic (requiring us to pass `db`).

So for now, the meta information is simply a `&'static str` / `u32` for
the file/line variant, or a `&'static str` for the custom message.
Anything involving a chain/backtrace of several `@Todo`s or similar is
therefore currently not implemented. Also because we currently don't see
any direct use cases for this, and because all of this will eventually
go away.

Note that the size of `Type` increases from 16 to 24 bytes, but only in
debug mode.

## Test Plan

- Observed the changes in Markdown tests.
- Added custom messages for all `Type::Todo`s that were revealed in the
tests
- Ran red knot in release and debug mode on the following Python file:
  ```py
  def f(x: int) -> int:
      reveal_type(x)
  ```
Prints `@Todo` in release mode and `@Todo(function parameter type)` in
debug mode.
2024-11-21 09:59:47 +01:00
Alex Waygood
df45a0e3f9
[red-knot] Add MRO resolution for classes (#14027) 2024-11-04 13:31:38 +00:00
Carl Meyer
b8acadd6a2
[red-knot] have mdformat wrap mdtest files to 100 columns (#14020)
This makes it easier to read and edit (and review changes to) these
files as source, even though it doesn't affect the rendering.
2024-10-31 21:00:51 +00:00
Alex Waygood
3eb454699a
[red-knot] Format mdtest Python snippets more concisely (#13905) 2024-10-24 11:09:31 +00:00
Alex Waygood
55bccf6680
[red-knot] Fix edge case for binary-expression inference where the lhs and rhs are the exact same type (#13823)
## Summary

This fixes an edge case that @carljm and I missed when implementing
https://github.com/astral-sh/ruff/pull/13800. Namely, if the left-hand
operand is the _exact same type_ as the right-hand operand, the
reflected dunder on the right-hand operand is never tried:

```pycon
>>> class Foo:
...     def __radd__(self, other):
...         return 42
...         
>>> Foo() + Foo()
Traceback (most recent call last):
  File "<python-input-1>", line 1, in <module>
    Foo() + Foo()
    ~~~~~~^~~~~~~
TypeError: unsupported operand type(s) for +: 'Foo' and 'Foo'
```

This edge case _is_ covered in Brett's blog at
https://snarky.ca/unravelling-binary-arithmetic-operations-in-python/,
but I missed it amongst all the other subtleties of this algorithm. The
motivations and history behind it were discussed in
https://mail.python.org/archives/list/python-dev@python.org/thread/7NZUCODEAPQFMRFXYRMGJXDSIS3WJYIV/

## Test Plan

I added an mdtest for this cornercase.
2024-10-19 11:09:54 -07:00
Carl Meyer
f4b5e70fae
[red-knot] binary arithmetic on instances (#13800)
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
2024-10-19 15:22:54 +00:00