ruff/crates/red_knot_python_semantic/resources/mdtest
Alex Waygood c2bb5d5250
[red-knot] Fix equivalence of differently ordered unions that contain Callable types (#17145)
## Summary

Fixes https://github.com/astral-sh/ruff/issues/17058.

Equivalent callable types were not understood as equivalent when they
appeared nested inside unions and intersections. This PR fixes that by
ensuring that `Callable` elements nested inside unions, intersections
and tuples have their representations normalized before one union type
is compared with another for equivalence, or before one intersection
type is compared with another for equivalence.

The normalizations applied to a `Callable` type are:
- the type of the default value is stripped from all parameters (only
whether the parameter _has_ a default value is relevant to whether one
`Callable` type is equivalent to another)
- The names of the parameters are stripped from positional-only
parameters, variadic parameters and keyword-variadic parameters
- Unions and intersections that are present (top-level or nested) inside
parameter annotations or return annotations are normalized.

Adding a `CallableType::normalized()` method also allows us to simplify
the implementation of `CallableType::is_equivalent_to()`.

### Should these normalizations be done eagerly as part of a
`CallableType` constructor?

I considered this. It's something that we could still consider doing in
the future; this PR doesn't rule it out as a possibility. However, I
didn't pursue it for now, for several reasons:
1. Our current `Display` implementation doesn't handle well the
possibility that a parameter might not have a name or an annotated type.
Callable types with parameters like this would be displayed as follows:
   ```py
   (, ,) -> None: ...
   ```

That's fixable! It could easily become something like `(Unknown,
Unknown) -> None: ...`. But it also illustrates that we probably want to
retain the parameter names when displaying the signature of a `lambda`
function if you're hovering over a reference to the lambda in an IDE.
Currently we don't have a `LambdaType` struct for representing `lambda`
functions; if we wanted to eagerly normalize signatures when creating
`CallableType`s, we'd probably have to add a `LambdaType` struct so that
we would retain the full signature of a `lambda` function, rather than
representing it as an eagerly simplified `CallableType`.
2. In order to ensure that it's impossible to create `CallableType`s
without the parameters being normalized, I'd either have to create an
alternative `SimplifiedSignature` struct (which would duplicate a lot of
code), or move `CallableType` to a new module so that the only way of
constructing a `CallableType` instance would be via a constructor method
that performs the normalizations eagerly on the callable's signature.
Again, this isn't a dealbreaker, and I think it's still an option, but
it would be a lot of churn, and it didn't seem necessary for now. Doing
it this way, at least to start with, felt like it would create a diff
that's easier to review and felt like it would create fewer merge
conflicts for others.

## Test Plan

- Added a regression mdtest for
https://github.com/astral-sh/ruff/issues/17058
- Ran `QUICKCHECK_TESTS=1000000 cargo test --release -p
red_knot_python_semantic -- --ignored types::property_tests::stable`
2025-04-02 17:43:34 +00:00
..
annotations [red-knot] Decorators and properties (#17017) 2025-04-02 09:27:46 +02:00
assignment [red-knot] Don't infer Todo for quite so many tuple type expressions (#17116) 2025-04-01 15:44:02 +01:00
binary [red-knot] Detect division-by-zero in unions and intersections (#17157) 2025-04-02 18:21:27 +02:00
boolean [red-knot] Statically known branches (#15019) 2024-12-21 11:33:10 +01:00
boundness_declaredness [red-knot] detect invalid return type (#16540) 2025-03-12 01:58:59 +00:00
call [red-knot] Decorators and properties (#17017) 2025-04-02 09:27:46 +02:00
comparison [red-knot] fix eager nested scopes handling (#16916) 2025-03-28 11:11:56 -04:00
comprehensions [red-knot] detect invalid return type (#16540) 2025-03-12 01:58:59 +00:00
conditional [red-knot] Handle unions of callables better (#16716) 2025-03-17 10:35:52 -04:00
declaration [red-knot] Avoid undeclared path when raising conflicting declarations (#14958) 2024-12-17 09:49:39 +05:30
diagnostics [red-knot] Document current state of attribute assignment diagnostics (#16746) 2025-03-14 20:34:43 +01:00
directives [red-knot] Fix more redundant-cast false positives (#17119) 2025-04-01 19:03:42 +01:00
doc [red-knot] Document 'public type of undeclared symbols' behavior (#16096) 2025-02-12 08:52:11 +01:00
exception Fixing various spelling errors (#16924) 2025-03-23 08:08:40 +00:00
expression [red-knot] Add initial support for * imports (#16923) 2025-03-24 17:15:58 +00:00
function [red-knot] Fix _NotImplementedType check for Python >=3.10 (#17143) 2025-04-02 10:02:59 +00:00
generics [red-knot] fix ordering of ClassDef semantic index building (#16915) 2025-03-23 13:23:12 +00:00
import [red-knot] Fix panic on cyclic * imports (#16958) 2025-03-24 18:23:02 +00:00
literal [red-knot] Migrate bool/str/repr unit tests to Markdown tests (#15534) 2025-01-16 11:21:56 -08:00
loops [red-knot] Handle unions of callables better (#16716) 2025-03-17 10:35:52 -04:00
narrow [red-knot] Narrowing on in tuple[...] and in str (#17059) 2025-03-31 23:38:09 +00:00
regression [red-knot] Enforce specifying paths for mdtest code blocks in a separate preceding line (#15890) 2025-02-04 08:27:17 +01:00
scopes [red-knot] Decorators and properties (#17017) 2025-04-02 09:27:46 +02:00
shadowing [red-knot] Merge Markdown code blocks inside a single section (#15950) 2025-02-05 22:26:15 +01:00
snapshots [red-knot] fix eager nested scopes handling (#16916) 2025-03-28 11:11:56 -04:00
stubs Fixing more spelling errors (#16926) 2025-03-23 10:55:14 -07:00
subscript [red-knot] Decorators and properties (#17017) 2025-04-02 09:27:46 +02:00
suppressions [red-knot] Decorators and properties (#17017) 2025-04-02 09:27:46 +02:00
type_of [red-knot] Method calls and the descriptor protocol (#16121) 2025-02-20 23:22:26 +01:00
type_properties [red-knot] Fix equivalence of differently ordered unions that contain Callable types (#17145) 2025-04-02 17:43:34 +00:00
type_qualifiers [red-knot] Preliminary tests for typing.Final (#15917) 2025-03-14 12:30:13 +01:00
unary [red-knot] Handle unions of callables better (#16716) 2025-03-17 10:35:52 -04:00
with [red-knot] detect invalid return type (#16540) 2025-03-12 01:58:59 +00:00
.mdformat.toml [red-knot] have mdformat wrap mdtest files to 100 columns (#14020) 2024-10-31 21:00:51 +00:00
attributes.md [red-knot] Decorators and properties (#17017) 2025-04-02 09:27:46 +02:00
decorators.md [red-knot] Decorators and properties (#17017) 2025-04-02 09:27:46 +02:00
descriptor_protocol.md [red-knot] Decorators and properties (#17017) 2025-04-02 09:27:46 +02:00
final.md [red-knot] Add support for @final classes (#15070) 2024-12-19 21:02:14 +00:00
intersection_types.md [red-knot] add test cases result in false positive errors (#16856) 2025-03-20 17:17:54 +00:00
invalid_syntax.md [red-knot] Understand typing.Callable (#16493) 2025-03-08 03:58:52 +00:00
known_constants.md [red-knot] Add rule invalid-type-checking-constant (#16501) 2025-03-04 19:49:34 +00:00
mdtest_config.md [red-knot] Add missing imports in mdtests (#15869) 2025-02-03 09:27:29 +00:00
mdtest_custom_typeshed.md [red-knot] Enforce specifying paths for mdtest code blocks in a separate preceding line (#15890) 2025-02-04 08:27:17 +01:00
metaclass.md [red-knot] detect invalid return type (#16540) 2025-03-12 01:58:59 +00:00
mro.md [red-knot] Enforce specifying paths for mdtest code blocks in a separate preceding line (#15890) 2025-02-04 08:27:17 +01:00
pep695_type_aliases.md [red-knot] Decorators and properties (#17017) 2025-04-02 09:27:46 +02:00
properties.md [red-knot] Decorators and properties (#17017) 2025-04-02 09:27:46 +02:00
protocols.md [red-knot] Make' Type::in_type_expression()' exhaustive for Type::KnownInstance (#16836) 2025-03-19 07:36:28 -07:00
slots.md [red-knot] fix: improve type inference for binary ops on tuples (#16725) 2025-03-14 12:29:57 +01:00
statically_known_branches.md [red-knot] Litate tests: minor follow-up (#15987) 2025-02-06 07:15:26 +00:00
sys_platform.md [red-knot] Method calls and the descriptor protocol (#16121) 2025-02-20 23:22:26 +01:00
sys_version_info.md [red-knot] Decorators and properties (#17017) 2025-04-02 09:27:46 +02:00
terminal_statements.md [red-knot] detect invalid return type (#16540) 2025-03-12 01:58:59 +00:00
type_api.md [red-knot] Allow CallableTypeFromFunction to display the signatures of callable types that are not function literals (#17047) 2025-03-28 20:23:04 +00:00
union_types.md [red-knot] add special case for float/complex (#16166) 2025-02-14 12:24:10 -08:00
unpacking.md [red-knot] Support unpacking with target (#16469) 2025-03-08 02:36:35 +00:00
unreachable.md [red-knot] Add initial set of tests for unreachable code (#17159) 2025-04-02 19:39:44 +02:00