mirror of https://github.com/astral-sh/ruff
This fixes https://github.com/astral-sh/ty/issues/1736 where recursive generic protocols with growing specializations caused a stack overflow. The issue occurred with protocols like: ```python class C[T](Protocol): a: 'C[set[T]]' ``` When checking `C[set[int]]` against `C[Unknown]`, member `a` requires checking `C[set[set[int]]]`, which requires `C[set[set[set[int]]]]`, etc. Each level has different type specializations, so the existing cycle detection (using full types as cache keys) didn't catch the infinite recursion. The fix introduces `TypeRelationKey`, an enum that can be either a full `Type` or a `ClassLiteral` (protocol class without specialization). For protocol-to-protocol comparisons, we use `ClassLiteral` keys, which detects when we're comparing the same protocol class regardless of specialization. When a cycle is detected, we return the fallback value (assume compatible) to safely terminate the recursion. |
||
|---|---|---|
| .. | ||
| resources | ||
| src | ||
| tests | ||
| Cargo.toml | ||
| build.rs | ||
| mdtest.py | ||
| mdtest.py.lock | ||