ty icon indicating copy to clipboard operation
ty copied to clipboard

ty hangs on combination of self-ref Union, dataclass and Protocol

Open sinon opened this issue 1 week ago • 3 comments

Summary

An attempt at an MRE for a hang we are seeing on one of our repos: Run with: uv tool run ty check mre.py

from __future__ import annotations  # removing this cause it not to hang
import dataclasses

from typing import (
    Protocol,
    Union,
)


@runtime_checkable
class Traceable(Protocol):
    """Protocol for objects that provide custom trace representations."""

    def trace_repr(self) -> TraceableValue:
        """Return a dictionary representation suitable for tracing."""
        ...


TraceableValue = Union[
    Traceable,
    bool,  # removing bool causes it to not hang
    # One of the following self-referential types are needed to hang
    # list["TraceableValue"],
    # dict[str, "TraceableValue"],
    tuple["TraceableValue", ...],
]


@dataclasses.dataclass
class FilledOutfit:
    def trace_repr(self) -> TraceableValue:
        return False

No play.ty.dev link as it causes a fun failure state:

Image

Version

ty 0.0.2 (42835578d 2025-12-16)

sinon avatar Dec 17 '25 10:12 sinon

Slightly simpler reproduction:

from typing import Protocol, Union

SomeUnion = Union[
    "SomeProtocol",
    bool,
    # Any of these cause a hang
    list["SomeUnion"],
    # dict[str, "SomeUnion"],
    # tuple["SomeUnion", ...],
]


class SomeProtocol(Protocol):
    def some_method(self) -> SomeUnion: ...


class SomeImplementation:
    def some_method(self) -> SomeUnion:
        return True

judahrand avatar Dec 17 '25 10:12 judahrand