ruff/crates/ty_python_semantic/resources/mdtest/annotations
Carl Meyer 5d3a35e071
[ty] fix implicit Self on generic class with typevar default (#20754)
## Summary

Typevar attributes (bound/constraints/default) can be either lazily
evaluated or eagerly evaluated. Currently they are lazily evaluated for
PEP 695 typevars, and eager for legacy and synthetic typevars.
https://github.com/astral-sh/ruff/pull/20598 will make them lazy also
for legacy typevars, and the ecosystem report on that PR surfaced the
issue fixed here (because legacy typevars are much more common in the
ecosystem than PEP 695 typevars.)

Applying a transform to a typevar (normalization, materialization, or
mark-inferable) will reify all lazy attributes and create a new typevar
with eager attributes. In terms of Salsa identity, this transformed
typevar will be considered different from the original typevar, whether
or not the attributes were actually transformed.

In general, this is not a problem, since all typevars in a given generic
context will be transformed, or not, together.

The exception to this was implicit-self vs explicit Self annotations.
The typevar we created for implicit self was created initially using
inferable typevars, whereas an explicit Self annotation is initially
non-inferable, then transformed via mark-inferable when accessed as part
of a function signature. If the containing class (which becomes the
upper bound of `Self`) is generic, and has e.g. a lazily-evaluated
default, then the explicit-Self annotation will reify that default in
the upper bound, and the implicit-self would not, leading them to be
treated as different typevars, and causing us to fail to solve a call to
a method such as `def method(self) -> Self` correctly.

The fix here is to treat implicit-self more like explicit-Self,
initially creating it as non-inferable and then using the mark-inferable
transform on it. This is less efficient, but restores the invariant that
all typevars in a given generic context are transformed together, or
not, fixing the bug.

In the improved-constraint-solver work, the separation of typevars into
"inferable" and "non-inferable" is expected to disappear, along with the
mark-inferable transform, which would render both this bug and the fix
moot. So this fix is really just temporary until that lands.

There is a performance regression, but not a huge one: 1-2% on most
projects, 5% on one outlier. This seems acceptable, given that it should
be fully recovered by removing the mark-inferable transform.

## Test Plan

Added mdtests that failed before this change.
2025-10-08 01:38:24 +00:00
..
annotated.md [ty] Add hints to invalid-type-form for common mistakes (#18543) 2025-06-09 00:40:05 +01:00
any.md [ty] Completely ignore typeshed's stub for Any (#20079) 2025-08-25 15:27:55 +01:00
callable.md [ty] Fall back to object for attribute access on synthesized protocols (#20286) 2025-09-08 13:04:37 +01:00
deferred.md Rename Red Knot (#17820) 2025-05-03 19:49:15 +02:00
int_float_complex.md [ty] Improve disjointness inference for NominalInstanceTypes and SubclassOfTypes (#18864) 2025-06-24 20:27:37 +00:00
invalid.md [syntax-errors] Detect yield from inside async function (#20051) 2025-09-03 10:13:05 -04:00
literal.md Fix panic for illegal Literal[…] annotations with inner subscript expressions (#19489) 2025-07-22 14:07:20 +00:00
literal_string.md Rename Red Knot (#17820) 2025-05-03 19:49:15 +02:00
never.md Rename Red Knot (#17820) 2025-05-03 19:49:15 +02:00
new_types.md ty_python_semantic: add union type context to function call type errors 2025-05-09 13:40:51 -04:00
optional.md Rename Red Knot (#17820) 2025-05-03 19:49:15 +02:00
self.md [ty] fix implicit Self on generic class with typevar default (#20754) 2025-10-08 01:38:24 +00:00
starred.md [ty] Return Option<TupleType> from infer_tuple_type_expression (#19735) 2025-08-04 13:48:19 +01:00
stdlib_typing_aliases.md [ty] Support using legacy typing aliases for generic classes in type annotations (#18404) 2025-06-03 12:09:51 +01:00
string.md [ty] Emit error for invalid binary operations in type expressions (#18991) 2025-06-30 10:06:01 +02:00
union.md [ty] Consistent use of American english (in rules) (#19488) 2025-07-22 16:10:38 +02:00
unsupported_special_forms.md [ty] Reduce false positives for ParamSpecs and TypeVarTuples (#20239) 2025-09-04 23:34:37 +01:00
unsupported_special_types.md Generalize special-casing for enums constructed with the functional syntax (#17885) 2025-05-06 11:02:55 +01:00
unsupported_type_qualifiers.md [ty] validate constructor call of TypedDict (#19810) 2025-08-25 14:45:52 +02:00