ruff/crates/ty_python_semantic/resources/mdtest
Carl Meyer 8248193ed9
[ty] defer inference of legacy TypeVar bound/constraints/defaults (#20598)
## Summary

This allows us to handle self-referential bounds/constraints/defaults
without panicking.

Handles more cases from https://github.com/astral-sh/ty/issues/256

This also changes the way we infer the types of legacy TypeVars. Rather
than understanding a constructor call to `typing[_extension].TypeVar`
inside of any (arbitrarily nested) expression, and having to use a
special `assigned_to` field of the semantic index to try to best-effort
figure out what name the typevar was assigned to, we instead understand
the creation of a legacy `TypeVar` only in the supported syntactic
position (RHS of a simple un-annotated assignment with one target). In
any other position, we just infer it as creating an opaque instance of
`typing.TypeVar`. (This behavior matches all other type checkers.)

So we now special-case TypeVar creation in `TypeInferenceBuilder`, as a
special case of an assignment definition, rather than deeper inside call
binding. This does mean we re-implement slightly more of
argument-parsing, but in practice this is minimal and easy to handle
correctly.

This is easier to implement if we also make the RHS of a simple (no
unpacking) one-target assignment statement no longer a standalone
expression. Which is fine to do, because simple one-target assignments
don't need to infer the RHS more than once. This is a bonus performance
(0-3% across various projects) and significant memory-usage win, since
most assignment statements are simple one-target assignment statements,
meaning we now create many fewer standalone-expression salsa
ingredients.

This change does mean that inference of manually-constructed
`TypeAliasType` instances can no longer find its Definition in
`assigned_to`, which regresses go-to-definition for these aliases. In a
future PR, `TypeAliasType` will receive the same treatment that
`TypeVar` did in this PR (moving its special-case inference into
`TypeInferenceBuilder` and supporting it only in the correct syntactic
position, and lazily inferring its value type to support recursion),
which will also fix the go-to-definition regression. (I decided a
temporary edge-case regression is better in this case than doubling the
size of this PR.)

This PR also tightens up and fixes various aspects of the validation of
`TypeVar` creation, as seen in the tests.

We still (for now) treat all typevars as instances of `typing.TypeVar`,
even if they were created using `typing_extensions.TypeVar`. This means
we'll wrongly error on e.g. `T.__default__` on Python 3.11, even if `T`
is a `typing_extensions.TypeVar` instance at runtime. We share this
wrong behavior with both mypy and pyrefly. It will be easier to fix
after we pull in https://github.com/python/typeshed/pull/14840.

There are some issues that showed up here with typevar identity and
`MarkTypeVarsInferable`; the fix here (using the new `original` field
and `is_identical_to` methods on `BoundTypeVarInstance` and
`TypeVarInstance`) is a bit kludgy, but it can go away when we eliminate
`MarkTypeVarsInferable`.

## Test Plan

Added and updated mdtests.

### Conformance suite impact

The impact here is all positive:

* We now correctly error on a legacy TypeVar with exactly one constraint
type given.
* We now correctly error on a legacy TypeVar with both an upper bound
and constraints specified.

### Ecosystem impact

Basically none; in the setuptools case we just issue slightly different
errors on an invalid TypeVar definition, due to the modified validation
code.

---------

Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
2025-10-09 21:08:37 +00:00
..
annotations [ty] fix implicit Self on generic class with typevar default (#20754) 2025-10-08 01:38:24 +00:00
assignment [ty] Type-context aware literal promotion (#20776) 2025-10-09 16:53:53 -04:00
binary Update default and latest Python versions for 3.14 (#20725) 2025-10-07 12:23:11 -04:00
boolean
boundness_declaredness [ty] Reformulation of public symbol inference test suite (#20667) 2025-10-01 14:26:17 +02:00
call [ty] Improve assignability/subtyping between two protocol types (#20368) 2025-10-08 18:37:30 +00:00
class [ty] Rename "possibly unbound" diagnostics to "possibly missing" (#20492) 2025-09-23 14:26:55 +00:00
comparison [ty] detect cycles in binary comparison inference (#20446) 2025-09-17 09:45:25 +02:00
comprehensions
conditional [ty] Support as-patterns in reachability analysis (#19728) 2025-08-04 20:13:50 +02:00
dataclasses [ty] Respect dataclass_transform parameters for metaclass-based models (#20780) 2025-10-09 13:24:20 +00:00
declaration
diagnostics [ty] defer inference of legacy TypeVar bound/constraints/defaults (#20598) 2025-10-09 21:08:37 +00:00
directives [ty] Use annotated parameters as type context (#20635) 2025-10-03 17:14:51 -04:00
doc
exception [ty] Use separate Rust types for bound and unbound type variables (#19796) 2025-08-11 15:29:58 -04:00
expression [ty] Rename "possibly unbound" diagnostics to "possibly missing" (#20492) 2025-09-23 14:26:55 +00:00
function [ty] Improve disambiguation of types via fully qualified names (#20141) 2025-08-29 08:44:18 +00:00
generics [ty] defer inference of legacy TypeVar bound/constraints/defaults (#20598) 2025-10-09 21:08:37 +00:00
ide_support [ty] Include NamedTupleFallback members in NamedTuple instance completions (#20356) 2025-09-15 11:00:03 +02:00
import [ty] No union with Unknown for module-global symbols (#20664) 2025-10-01 16:40:30 +02:00
literal [ty] More precise type inference for dictionary literals (#20523) 2025-09-24 18:12:00 -04:00
loops [ty] Improve assignability/subtyping between two protocol types (#20368) 2025-10-08 18:37:30 +00:00
narrow [ty] No union with Unknown for module-global symbols (#20664) 2025-10-01 16:40:30 +02:00
regression
scopes Update default and latest Python versions for 3.14 (#20725) 2025-10-07 12:23:11 -04:00
shadowing
snapshots [ty] defer inference of legacy TypeVar bound/constraints/defaults (#20598) 2025-10-09 21:08:37 +00:00
stubs Update default and latest Python versions for 3.14 (#20725) 2025-10-07 12:23:11 -04:00
subscript [ty] Rename "possibly unbound" diagnostics to "possibly missing" (#20492) 2025-09-23 14:26:55 +00:00
suppressions
type_compendium [ty] Type-context aware literal promotion (#20776) 2025-10-09 16:53:53 -04:00
type_of
type_properties [ty] Introduce TypeRelation::Redundancy (#20602) 2025-10-03 18:35:30 +01:00
type_qualifiers [ty] Allow annotation expressions to be ast::Attribute nodes (#20413) 2025-09-15 12:06:48 +01:00
unary
with [ty] Use typing.Self for the first parameter of instance methods (#20517) 2025-09-29 21:08:08 +02:00
.mdformat.toml
async.md
attributes.md [ty] Add tests for instance attributes in class hierarchies (#20767) 2025-10-08 17:46:47 +02:00
classes.md [ty] don't assume that deferred type inference means deferred name resolution (#20160) 2025-08-29 16:19:45 -07:00
cycle.md
decorators.md
del.md [ty] No union with Unknown for module-global symbols (#20664) 2025-10-01 16:40:30 +02:00
deprecated.md
descriptor_protocol.md [ty] Use typing.Self for the first parameter of instance methods (#20517) 2025-09-29 21:08:08 +02:00
enums.md [ty] Enums: allow multiple aliases to point to the same member (#20669) 2025-10-01 15:51:53 +02:00
exhaustiveness_checking.md [ty] Fix subtyping for dynamic specializations (#20592) 2025-09-26 15:05:03 +02:00
final.md
implicit_type_aliases.md [ty] no more diverging query cycles in type expressions (#20359) 2025-09-16 16:44:11 -07:00
instance_layout_conflict.md [ty] initial support for slots=True in dataclasses (#20278) 2025-09-07 18:25:35 +01:00
intersection_types.md
invalid_syntax.md
known_constants.md
mdtest_config.md
mdtest_custom_typeshed.md [ty] Remove Type::Tuple (#19669) 2025-08-11 22:03:32 +01:00
metaclass.md
mro.md [ty] Treat Hashable, and similar protocols, equivalently to object for subtyping/assignability (#20284) 2025-09-10 11:38:58 +01:00
named_tuple.md [ty] Use typing.Self for the first parameter of instance methods (#20517) 2025-09-29 21:08:08 +02:00
overloads.md [ty] Improve diagnostics for bad @overload definitions (#20745) 2025-10-07 21:52:57 +00:00
pep695_type_aliases.md [ty] defer inference of legacy TypeVar bound/constraints/defaults (#20598) 2025-10-09 21:08:37 +00:00
properties.md [ty] "foo".startswith is not an instance of types.MethodWrapperType (#20317) 2025-09-10 11:14:26 +00:00
protocols.md [ty] Improve assignability/subtyping between two protocol types (#20368) 2025-10-08 18:37:30 +00:00
public_types.md [ty] Disambiguate classes that live in different modules but have the same fully qualified names (#20756) 2025-10-08 18:27:40 +01:00
statically_known_branches.md [ty] Rename "possibly unbound" diagnostics to "possibly missing" (#20492) 2025-09-23 14:26:55 +00:00
sys_platform.md
sys_version_info.md
t_strings.md [ty] Add support for PEP 750 t-strings (#20085) 2025-08-25 18:49:49 +00:00
terminal_statements.md
ty_extensions.md [ty] Fix CallableTypeOf[…] for classmethods (#20345) 2025-09-11 10:14:38 +02:00
typed_dict.md [ty] allow any string Literal type expression as a key when constructing a TypedDict (#20792) 2025-10-09 18:24:11 +00:00
union_types.md [ty] Introduce TypeRelation::Redundancy (#20602) 2025-10-03 18:35:30 +01:00
unpacking.md [ty] Infer more precise types for collection literals (#20360) 2025-09-17 18:51:50 -04:00
unreachable.md [ty] Rename "possibly unbound" diagnostics to "possibly missing" (#20492) 2025-09-23 14:26:55 +00:00