TypeVarTuple escapes method with very nested recursive tuple aliases
bug
**Describe the bug**
When calling a method generic over a `TypeVarTuple` on a instance that contains deeply nested recursive tuples in type aliases, the generic "escapes" into the code.
```
Type "ForwardRefParser[tuple[Whitespace, Whitespace, tuple[BlockItem], OO@unpack_then], None]" is not assignable to declared type "ForwardRefParser[tuple[Whitespace, Whitespace, tuple[BlockItem], Whitespace], None]"
```
The issue is the `OO@unpack_then`, which escaped from the method.
On the code sample provided there should be no error.
If on the code sample you remove any of the levels of nesting of the type aliases, the issue goes away.
Eg applying this diff makes the code pass
```diff
- type Whitespace = tuple[tuple[tuple[tuple[Whitespace]]]]
+ type Whitespace = tuple[tuple[tuple[Whitespace]]]
```
Applying these two diffs at the same time makes the code pass:
```diff
tuple[BlockItem],
- Whitespace,
],
```
```diff
- lambda: ws.then(ws).unpack_then(block).unpack_then(ws)
+ lambda: ws.then(ws).unpack_then(block)
```
**Code or Screenshots**
Code sample in [pyright playground](https://pyright-play.net/?code=GYJw9gtgBALgngBwJYDsDmUkQWEMrCoCGANgDRRgBuApiCEgCY0BQokUAxmCSTZzCRgUAZwB0RAEadM2XPgDCpElL4t1AAUIpSLTipEioAeQDWAbQAqAXQBcLKI6gB9ZxCIxOAC2dEQaEVcoAF4oAAoAImcqUgBXGgiyAEp1JyhmYBdnVCQYVzCRGhJgChiSeNsoSyT7NLTC4rFouJpKyxCoMvj1Fi1iEj0DIwBRenNhuwcnDKycvOcCopLOlsrhmqm6qAbgJq7WqGGO-Z74BBooACUaEViSGCsKCY6zK2soAB9DsYn1M4uAAp%2BQoga63e7mYxPd6hMF3B4wWIIPjmVAwCjGazQlj-KBAkAggBisRQnEh0I6Sl4qho5nMIhgIAoaKxeOBdDhEKhh2s1h6%2BiIhjZBLo5J5tWmNEyrjm%2BR2FGAJM4lXxRKVYomGy2jh2TUVpJV7JAxNJGphBCVqUlmRgXhoKEh3OME0WxQozjAtrohpFIEdGM1UAAtAA%2BYUg8yI5G0p2Yp6fEwTCVbEBEJCFKAAOU9AElsHwIPaYDRGKNwCArY4ZiSEEROKZnF6HQAqSwAZQxTpdmzqOx9EajKNbbdZE3dnrtIH7ouMXb5aSSwbDqtFg9pw87o4Tzsm2qgqfTF2zMDz0cLKGLpfouHUMwQ4EYsU4tJsYWcbQT2ZQF1CX5oi9DKpKgPDNj1PAsixLMsb0GQUjEJXAAHc-EYa5gBXP1uRdDCzS1JwNGoOgGGYHsZhlFBcjlJYFSVSoqRUSQUXMVkcKw3k8K2XU3BoGAiGcfVlSgeiaTpFijTNc0BJ7eokToMIkiabIKPmMJ7zAR9n3klI-kQC4AHUvFyG5a2fDo10jJEUXM8yDKMkQTJoXleRYRCREqBCQGQkBUKlHDbOLey6xoCg-3NNSNJoeT1BQMAwAQac-QZJks2ERyOnCp9Iu04BcBIWL4qgDyvJ89DxJ7czpKcfzjKCshKscarAufOq93MgAhPL6xzYsICxeqoEahyWqcPq0j-OrzSKlC0IwsIexUCBJEYIhKlcsQmzCVyFJrOsGw2xiwHrbaUBMva7RQTaRBSbTcXAmhz14wRhCMUJrMs2kbMMgKHNZO6Ho8IRRGcrAzyLAHnvcpDpt88S-rBp7RBC1KwofTKopxXSoA6w7TG6%2B6zPeizo3MOGL3BoH3i%2BdrOtxnq%2BQO%2BsEqJlFsa6umke-FH1LRlIgA)
<details>
<summary>Collapsed for readability</summary>
```python
from typing import final, override
from collections.abc import Callable
@final
class Ok[T]:
__match_args__ = ("_value",)
def __init__(self, value: T):
self._value: T = value
@final
class Err[E]:
def __init__(self, value: E):
self._value: E = value
type Result[T, E] = Ok[T] | Err[E]
type ParserResult[O, E] = Result[tuple[int, O], E]
type ParserFunc[O, E] = Callable[[str, int], ParserResult[O, E]]
class Parser[O, E]:
def __init__(self, func: ParserFunc[O, E]):
self._func: ParserFunc[O, E] = func
def then[OO, OE](self, _other: Parser[OO, OE]) -> Parser[tuple[O, OO], E | OE]:
raise NotImplementedError
def unpack_then[*TS, OO, OE](
self: Parser[tuple[*TS], E], _other: Parser[OO, OE]
) -> Parser[tuple[*TS, OO], E | OE]:
raise NotImplementedError
def produce[T](_: T | None = None) -> T: raise NotImplementedError
class ForwardRefParser[O, E](Parser[O, E]):
@override
def __init__(self, func: Callable[[], Parser[O, E]]):
self._meta_func: Callable[[], Parser[O, E]] = func
super().__init__(produce())
type Whitespace = tuple[tuple[tuple[tuple[Whitespace]]]]
ws: ForwardRefParser[Whitespace, None] = produce()
noop: Parser[str, None] = produce()
forloop: ForwardRefParser[
tuple[
Whitespace,
Whitespace,
tuple[BlockItem],
Whitespace,
],
None,
] = ForwardRefParser(
lambda: ws.then(ws).unpack_then(block).unpack_then(ws)
)
type Implementations = tuple[tuple[tuple[Whitespace], Implementations]]
implementations: ForwardRefParser[Implementations, None] = produce()
type BlockItem = tuple[tuple[Implementations]] | tuple[BlockItem]
block: Parser[tuple[BlockItem], None] = produce()
```
</details>
**VS Code extension or command-line**
Tested on online playground pyright version `1.1.410`
0 条评论