#4514·ty

Long if-elif chain causes Ty to take 9+ minutes on 61 lines of code

Author: NikratioCreated Sep 11, 2026Updated Sep 18, 2026
Labelsperformanceset-theoretic typesenums

Summary

The following file is unfeasible to check with Ty 0.0.80 (I aborted after 9+ minutes). With Ty 0.0.17, it still finished sub-second.

I assume there is something pathologic about this code, and I wouldn't necessarily expect Ty to typecheck it more quickly, but I would much rather have it skip the file with a warning (or abort with an error) than hanging.

The reproducer code does not do anything useful, but the pattern (and problem) was discovered in a production codebase. I think it is triggered by migration code of the form:

python
try:
    from new_location.colors import *
except ImportError:
    class Color(enum.Enum):
        ...  # identical fallback definition

Reproducer

python
import enum
import random


class _ColorA(enum.Enum):
    RED = 1
    ORANGE = 2
    YELLOW = 3
    GREEN = 4
    BLUE = 5
    INDIGO = 6
    VIOLET = 7
    BLACK = 8
    WHITE = 9
    GRAY = 10


class _ColorB(enum.Enum):
    RED = 1
    ORANGE = 2
    YELLOW = 3
    GREEN = 4
    BLUE = 5
    INDIGO = 6
    VIOLET = 7
    BLACK = 8
    WHITE = 9
    GRAY = 10


Color = _ColorA if random.random() < 0.5 else _ColorB


def describe(item):
    if isinstance(item, str):
        return item

    if item == Color.RED:
        name = "red"
    elif item == Color.ORANGE:
        name = "orange"
    elif item == Color.YELLOW:
        name = "yellow"
    elif item == Color.GREEN:
        name = "green"
    elif item == Color.BLUE:
        name = "blue"
    elif item == Color.INDIGO:
        name = "indigo"
    elif item == Color.VIOLET:
        name = "violet"
    elif item == Color.BLACK:
        name = "black"
    elif item == Color.WHITE:
        name = "white"
    elif item == Color.GRAY:
        name = "gray"
    else:
        raise ValueError(item)

    return name

Scaling

Changing the number of elif branches in the code, I found:

branches check time
6 0.19 s
7 1.12 s
8 9.25 s
9 86.5 s
10 > 300 s

Workarounds

Each of the following changesbrings check time back below a second:

  • Delete the isinstance(item, str) guard and its return
  • Replace the union with a single class (Color = _ColorA)
  • Replace the elif chain with a dict lookup (name = names[item])

Version

I've checked it with:

 uvx ty -V
ty 0.0.80

> time uvx ty check reproducer.py 
Checking --------- 0/1 files^C
________________________________________________________
Executed in    6.53 secs    fish           external
   usr time    6.25 secs    0.00 millis    6.25 secs
   sys time    0.27 secs    1.53 millis    0.27 secs

With an older version, it's much faster:

> ty --version
ty 0.0.17

> ty check reproducer.py
All checks passed!

________________________________________________________
Executed in   31.25 millis    fish           external
   usr time   21.37 millis    0.17 millis   21.20 millis
   sys time   14.08 millis    1.03 millis   13.06 millis