Skip to content

Literal promotion should respect Literal upper bounds #2771

@ramcasa

Description

@ramcasa

Summary

Consider the following example.

from typing import TypeVar, Literal, Generic
from typing_extensions import reveal_type

TU = TypeVar('TU', Literal['ms'], Literal['us'])

class Timedelta(Generic[TU]):
  def __init__(self, epoch: int, time_unit: TU) -> None:
    self._epoch = epoch
    self._time_unit = time_unit

  def second(self) -> int:
    m = 1_000 if self._time_unit == 'ms' else 1_000_000
    return self._epoch // m % 60

def convert(nanoseconds: int, time_unit: TU) -> Timedelta[TU]:
  m = 1_000_000 if time_unit == 'ms' else 1_000
  return Timedelta[TU](nanoseconds // m, time_unit)

ns = 1_000_000_000
delta0 = Timedelta[Literal['us']](ns // 1_000, 'us')
delta1 = Timedelta(ns // 1_000, 'us')
delta2 = convert(ns, 'us')

reveal_type(delta0)
reveal_type(delta1)
reveal_type(delta2)

Only the first delta is correctly inferred as Timedelta[Literal["us"]]. The rest are Timedelta[str] even though the TU variable constraints are Literal['ms'] and Literal['us'].

Version

ty 0.0.15

Metadata

Metadata

Assignees

Labels

bugSomething isn't workinggenericsBugs or features relating to ty's generics implementation

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions