Skip to content

Type-hint instances of types passed as TypeVarTuple? #1347

Closed

Description

@harenbrs

Say I have a function like this that tries to convert a given value to any of a list of given classes:

def convert(obj: Any, *to_classes):
    for class_ in to_classes:
        try:
            return class_(...)
        except:
            pass

Can TypeVarTuple be used to annotate *to_classes along with the corresponding return type? I tried the following:

Ts = TypeVarTuple('Ts')

def convert(obj: Any, *to_classes: Unpack[Ts]) -> Union[Unpack[Ts]]:
    for class_ in to_classes:
        try:
            return class_(...)
        except:
            pass

but that results in hints like Type[A] | Type[B] rather than A | B (for passed types A, B). Is there some way to resolve to instances of the passed types?

Activity

  1. erictraut commented on Feb 10, 2023

    @erictraut
    Collaborator

    I don't think there's a way to do this with TypeVarTuple, but you can use an unpacked tuple instead.

    from typing import Any, TypeVar, Unpack
    T = TypeVar("T")
    
    def convert(obj: Any, *to_classes: Unpack[tuple[type[T], ...]]) -> T | None:
        for class_ in to_classes:
            try:
                return class_(...)
            except:
                pass
    
    x = convert(1, int, str)
    reveal_type(x)  # int | str | None

    (Note: This causes the latest version of mypy to crash, but it works fine in pyright.)

  2. harenbrs commented on Feb 11, 2023

    @harenbrs
    Author

    Brilliant, works perfectly. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    topic: otherOther topics not covered

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions