Skip to content

Feature: Implement variadic Union[*Ts] for unpacked comprehensions #20

@AliiiBenn

Description

@AliiiBenn

Description

Implement variadic Union[*Ts] as specified in PEP 827.

From the PEP:

Union[*Ts]: Union will become able to take variadic arguments, so that it can take unpacked comprehension arguments.

This enables using Union with unpacked type comprehensions like:

type MyUnion = Union[*[int for t in Iter[SomeTuple]]]

Implementation Notes

Current State

  • Python's typing.Union already accepts multiple arguments
  • The PEP proposes allowing *Ts unpacking syntax

Approach

This is more of a syntax/semantic change than a new evaluator. The implementation might involve:

  1. Type checker changes: The type checker would need to understand Union[*Ts] syntax
  2. Runtime support: At runtime, this would need to:
    • Detect when Union is subscripted with unpacked args
    • Flatten the unpacked tuple into individual Union arguments

Challenges

  • Python's __class_getitem__ doesn't naturally support *args unpacking
  • Would need to intercept the unpacking at the type alias level
  • May require changes to how typing.Union handles its arguments

Potential Implementation

# In typing.py
class Union[*Ts]:
    pass

# In _eval_operators.py
# The evaluator would need to handle unpacking the Ts tuple
@type_eval.register_evaluator(Union)
def _eval_Union(*types, ctx):
    # Unpack and evaluate each type
    evaluated = [_eval_types(t, ctx) for t in types]
    return typing.Union[tuple(evaluated)]

However, this requires proper variadic generic support in Python 3.14+.

Test Cases

  • Basic variadic Union: Union[int, str, float]
  • With unpacked comprehension: Union[*[int for t in Iter[tuple[int, str, float]]]]
  • With nested types

Status

  • Research Python 3.14 variadic generic support
  • Determine if this is a type checker or runtime feature
  • Prototype implementation
  • Add tests
  • Update documentation

Related PEP 827 Section: Union processing (lines 628-629)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions