-
Notifications
You must be signed in to change notification settings - Fork 1.6k
[ty] fix infinite recursion with generic type aliases #20969
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[ty] fix infinite recursion with generic type aliases #20969
Conversation
Diagnostic diff on typing conformance testsChanges were detected when running ty on typing conformance tests--- old-output.txt 2025-10-23 14:11:17.723331983 +0000
+++ new-output.txt 2025-10-23 14:11:20.852357773 +0000
@@ -1,5 +1,4 @@
-fatal[panic] Panicked at /home/runner/.cargo/git/checkouts/salsa-e6f3bb7c2a062968/d38145c/src/function/execute.rs:417:17 when checking `/home/runner/work/ruff/ruff/typing/conformance/tests/aliases_type_statement.py`: `PEP695TypeAliasType < 'db >::value_type_(Id(d817)): execute: too many cycle iterations`
-fatal[panic] Panicked at /home/runner/.cargo/git/checkouts/salsa-e6f3bb7c2a062968/d38145c/src/function/execute.rs:417:17 when checking `/home/runner/work/ruff/ruff/typing/conformance/tests/aliases_typealiastype.py`: `infer_definition_types(Id(18043)): execute: too many cycle iterations`
+fatal[panic] Panicked at /home/runner/.cargo/git/checkouts/salsa-e6f3bb7c2a062968/d38145c/src/function/execute.rs:417:17 when checking `/home/runner/work/ruff/ruff/typing/conformance/tests/aliases_typealiastype.py`: `infer_definition_types(Id(17843)): execute: too many cycle iterations`
_directives_deprecated_library.py:15:31: error[invalid-return-type] Function always implicitly returns `None`, which is not assignable to return type `int`
_directives_deprecated_library.py:30:26: error[invalid-return-type] Function always implicitly returns `None`, which is not assignable to return type `str`
_directives_deprecated_library.py:36:41: error[invalid-return-type] Function always implicitly returns `None`, which is not assignable to return type `Self@__add__`
@@ -50,6 +49,33 @@
aliases_newtype.py:18:1: error[invalid-assignment] Object of type `NewType` is not assignable to `type`
aliases_newtype.py:26:21: error[invalid-base] Invalid class base with type `NewType`
aliases_newtype.py:63:43: error[too-many-positional-arguments] Too many positional arguments to bound method `__init__`: expected 3, got 4
+aliases_type_statement.py:10:19: error[too-many-positional-arguments] Too many positional arguments: expected 1, got 3
+aliases_type_statement.py:17:1: error[unresolved-attribute] Object of type `typing.TypeAliasType` has no attribute `bit_count`
+aliases_type_statement.py:19:1: error[call-non-callable] Object of type `TypeAliasType` is not callable
+aliases_type_statement.py:23:7: error[unresolved-attribute] Object of type `typing.TypeAliasType` has no attribute `other_attrib`
+aliases_type_statement.py:26:18: error[invalid-base] Invalid class base with type `typing.TypeAliasType`
+aliases_type_statement.py:37:22: error[invalid-type-form] Function calls are not allowed in type expressions
+aliases_type_statement.py:38:22: error[invalid-type-form] List literals are not allowed in this context in a type expression: Did you mean `tuple[int, str]`?
+aliases_type_statement.py:39:22: error[invalid-type-form] Tuple literals are not allowed in this context in a type expression
+aliases_type_statement.py:39:23: error[invalid-type-form] Tuple literals are not allowed in this context in a type expression: Did you mean `tuple[int, str]`?
+aliases_type_statement.py:40:22: error[invalid-type-form] List comprehensions are not allowed in type expressions
+aliases_type_statement.py:41:22: error[invalid-type-form] Dict literals are not allowed in type expressions
+aliases_type_statement.py:42:22: error[invalid-type-form] Function calls are not allowed in type expressions
+aliases_type_statement.py:43:28: error[invalid-type-form] Int literals are not allowed in this context in a type expression
+aliases_type_statement.py:44:22: error[invalid-type-form] `if` expressions are not allowed in type expressions
+aliases_type_statement.py:45:22: error[invalid-type-form] Variable of type `Literal[1]` is not allowed in a type expression
+aliases_type_statement.py:46:23: error[invalid-type-form] Boolean literals are not allowed in this context in a type expression
+aliases_type_statement.py:47:23: error[invalid-type-form] Int literals are not allowed in this context in a type expression
+aliases_type_statement.py:48:23: error[invalid-type-form] Boolean operations are not allowed in type expressions
+aliases_type_statement.py:49:23: error[fstring-type-annotation] Type expressions cannot use f-strings
+aliases_type_statement.py:75:81: error[too-many-positional-arguments] Too many positional arguments: expected 2, got 3
+aliases_type_statement.py:77:7: error[invalid-argument-type] Argument is incorrect: Expected `int`, found `str`
+aliases_type_statement.py:77:7: error[too-many-positional-arguments] Too many positional arguments: expected 2, got 3
+aliases_type_statement.py:78:7: error[too-many-positional-arguments] Too many positional arguments: expected 2, got 3
+aliases_type_statement.py:79:7: error[invalid-argument-type] Argument is incorrect: Expected `str`, found `int`
+aliases_type_statement.py:79:7: error[too-many-positional-arguments] Too many positional arguments: expected 2, got 3
+aliases_type_statement.py:80:7: error[too-many-positional-arguments] Too many positional arguments: expected 2, got 3
+aliases_type_statement.py:80:37: error[invalid-type-form] List literals are not allowed in this context in a type expression: Did you mean `tuple[int, str]`?
aliases_variance.py:18:24: error[non-subscriptable] Cannot subscript object of type `<class 'ClassA[typing.TypeVar]'>` with no `__class_getitem__` method
aliases_variance.py:28:16: error[non-subscriptable] Cannot subscript object of type `<class 'ClassA[typing.TypeVar]'>` with no `__class_getitem__` method
aliases_variance.py:44:16: error[non-subscriptable] Cannot subscript object of type `<class 'ClassB[typing.TypeVar, typing.TypeVar]'>` with no `__class_getitem__` method
@@ -922,5 +948,5 @@
typeddicts_usage.py:28:17: error[missing-typed-dict-key] Missing required key 'name' in TypedDict `Movie` constructor
typeddicts_usage.py:28:18: error[invalid-key] Invalid key access on TypedDict `Movie`: Unknown key "title"
typeddicts_usage.py:40:24: error[invalid-type-form] The special form `typing.TypedDict` is not allowed in type expressions. Did you mean to use a concrete TypedDict or `collections.abc.Mapping[str, object]` instead?
-Found 924 diagnostics
+Found 950 diagnostics
WARN A fatal error occurred while checking some files. Not all project files were analyzed. See the diagnostics list above for details. |
|
crates/ty_python_semantic/resources/mdtest/generics/pep695/aliases.md
Outdated
Show resolved
Hide resolved
…ases.md Co-authored-by: Alex Waygood <[email protected]>
826d382 to
63333be
Compare
63333be to
7011639
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've a small suggestion. I'd appreciate it if @dcreager could give a short thumbs up because I'm not very familiar with this part of the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's interesting that apply_type_mapping_impl is the only method that causes a panic. I suspect we will need to generalize this to storing a lazily-applied specialization on Type::TypeAlias, but given that this seems to resolve the panics, it seems fine to merge the easier fix for now?
Summary
While working on #20900, I noticed that the calculation of variance for recursive type aliases was leading to a stack overflow.
This PR fixes the
apply_type_mapping_implhandling of type aliases, avoiding infinite recursion.Test Plan
New tests in
generics/pep695/aliases.mdandtypes::tests::type_alias_variance.