Commit graph

18 commits

Author SHA1 Message Date
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
Micha Reiser
5fab97f1ef
[red-knot] Diagnostics for incorrect bool usages (#16238) 2025-02-21 19:26:05 +01:00
David Peter
8198668fc3
[red-knot] MDTest: Use custom class names instead of builtins (#16269)
## Summary

Follow up on the discussion
[here](https://github.com/astral-sh/ruff/pull/16121#discussion_r1962973298).
Replace builtin classes with custom placeholder names, which should
hopefully make the tests a bit easier to understand.

I carefully renamed things one after the other, to make sure that there
is no functional change in the tests.
2025-02-20 12:25:55 +00: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
d296f602e7
[red-knot] Merge Markdown code blocks inside a single section (#15950)
## Summary

Allow for literate style in Markdown tests and merge multiple (unnamed)
code blocks into a single embedded file.

closes #15941

## Test Plan

- Interactively made sure that error-lines were reported correctly in
  multi-snippet sections.
2025-02-05 22:26:15 +01:00
InSync
11cfe2ea8a
[red-knot] Enforce specifying paths for mdtest code blocks in a separate preceding line (#15890)
## Summary

Resolves #15695, rework of #15704.

This change modifies the Mdtests framework so that:

* Paths must now be specified in a separate preceding line:

	`````markdown
	`a.py`:

	```py
	x = 1
	```
	`````

If the path of a file conflicts with its `lang`, an error will be
thrown.

* Configs are no longer accepted. The pattern still take them into
account, however, to avoid "Unterminated code block" errors.
* Unnamed files are now assigned unique, `lang`-respecting paths
automatically.

Additionally, all legacy usages have been updated.

## Test Plan

Unit tests and Markdown tests.

---------

Co-authored-by: Carl Meyer <carl@astral.sh>
2025-02-04 08:27:17 +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
cake-monotone
6a4d207db7
[red-knot] Refactoring the inference logic of lexicographic comparisons (#14422)
## Summary

closes #14279

### Limitations of the Current Implementation
#### Incorrect Error Propagation

In the current implementation of lexicographic comparisons, if the
result of an Eq operation is Ambiguous, the comparison stops
immediately, returning a bool instance. While this may yield correct
inferences, it fails to capture unsupported-operation errors that might
occur in subsequent comparisons.
```py
class A: ...

(int_instance(), A()) < (int_instance(), A())  # should error
```

#### Weak Inference in Specific Cases

> Example: `(int_instance(), "foo") == (int_instance(), "bar")`
> Current result: `bool`
> Expected result: `Literal[False]`

`Eq` and `NotEq` have unique behavior in lexicographic comparisons
compared to other operators. Specifically:
- For `Eq`, if any non-equal pair exists within the tuples being
compared, we can immediately conclude that the tuples are not equal.
- For `NotEq`, if any equal pair exists, we can conclude that the tuples
are unequal.

```py
a = (str_instance(), int_instance(), "foo")

reveal_type(a == a)  # revealed: bool
reveal_type(a != a)  # revealed: bool

b = (str_instance(), int_instance(), "bar")

reveal_type(a == b)  # revealed: bool  # should be Literal[False]
reveal_type(a != b)  # revealed: bool  # should be Literal[True]
```
#### Incorrect Support for Non-Boolean Rich Comparisons

In CPython, aside from `==` and `!=`, tuple comparisons return a
non-boolean result as-is. Tuples do not convert the value into `bool`.

Note: If all pairwise `==` comparisons between elements in the tuples
return Truthy, the comparison then considers the tuples' lengths.
Regardless of the return type of the dunder methods, the final result
can still be a boolean.

```py
from __future__ import annotations

class A:
    def __eq__(self, o: object) -> str:
        return "hello"

    def __ne__(self, o: object) -> bytes:
        return b"world"

    def __lt__(self, o: A) -> float:
        return 3.14

a = (A(), A())

reveal_type(a == a)  # revealed: bool
reveal_type(a != a)  # revealed: bool
reveal_type(a < a)  # revealed: bool # should be: `float | Literal[False]`

```

### Key Changes
One of the major changes is that comparisons no longer end with a `bool`
result when a pairwise `Eq` result is `Ambiguous`. Instead, the function
attempts to infer all possible cases and unions the results. This
improvement allows for more robust type inference and better error
detection.

Additionally, as the function is now optimized for tuple comparisons,
the name has been changed from the more general
`infer_lexicographic_comparison` to `infer_tuple_rich_comparison`.

## Test Plan

mdtest included
2024-11-19 17:32:43 -08: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
cake-monotone
b6ffa51c16
[red-knot] Type inference for comparisons between arbitrary instances (#13903)
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
Co-authored-by: Carl Meyer <carl@oddbird.net>
2024-10-26 18:19:56 +00:00
TomerBin
35f007f17f
[red-knot] Type narrow in else clause (#13918)
## Summary

Add support for type narrowing in elif and else scopes as part of
#13694.

## Test Plan

- mdtest
- builder unit test for union negation.

---------

Co-authored-by: Carl Meyer <carl@astral.sh>
2024-10-26 16:22:57 +00:00
Alex Waygood
3eb454699a
[red-knot] Format mdtest Python snippets more concisely (#13905) 2024-10-24 11:09:31 +00:00
Alex Waygood
36cb1199cc
[red-knot] Autoformat mdtest Python snippets using blacken-docs (#13809) 2024-10-19 15:57:06 +01:00
David Peter
c2f7c39987
[red-knot] mdtest suite: formatting and cleanup (#13806)
Minor cleanup and consistent formatting of the Markdown-based tests.

- Removed lots of unnecessary `a`, `b`, `c`, … variables.
- Moved test assertions (`# revealed:` comments) closer to the tested
object.
- Always separate `# revealed` and `# error` comments from the code by
two spaces, according to the discussion
[here](https://github.com/astral-sh/ruff/pull/13746/files#r1799385758).
This trades readability for consistency in some cases.
- Fixed some headings
2024-10-18 11:07:53 +02:00
cake-monotone
2ffc3fad47
[red-knot] Implement Type::Tuple Comparisons (#13712)
## Summary

This PR implements comparisons for (tuple, tuple).

It will close #13688 and complete an item in #13618 once merged.

## Test Plan

Basic tests are included for (tuple, tuple) comparisons.

---------

Co-authored-by: Carl Meyer <carl@astral.sh>
2024-10-16 11:39:55 +00:00