Skip to content

does pep-646 let me make a MyTuple[_T, ...] of Element[_T] or am i misunderstanding #1001

Answered by erictraut
zzzeek asked this question in Q&A
does pep-646 let me make a MyTuple[_T, ...] of Element[_T] or am i misunderstanding #1001
Jan 2, 2022 · 1 answers · 1 reply

Starting with a really basic generic class:

from typing import Generic, TypeVar, Tuple

_T = TypeVar("_T")

class Element(Generic[_T]):
    def __init__(self, item: _T):
        self.item = item

# e1: Element[str]
e1 = Element("a string")

# e2: Element[int]
e2 = Element(45)

we can make a new class that is given an Element as a constructor argument, and is then itself a class that is also Generic[_T]:

class ContainerOfElement(Generic[_T]):
    def __init__(self, element: Element[_T]):
        self.element = element

#  c1: ContainerOfElement[str]
c1 = ContainerOfElement(e1)

my hope for pep-646, which I'm not sure now is covered at all, is the exact same pattern as above, except for a ContainerOfMultipleElements. This seems like the most simple, basic thing that would be allowed from a typing extension that grants the ability to make custom tuple-like classes, and for all the ORM use cases that I've seen discussed in some older pep-646 discussions, this would be the bare minimum thing needed. I'm currently working with the pep-646 support in pyright to test, but with no luck. Is the below possible? that is, a MyTuple[_T, ...] that's constructed from a Tuple[Element[_T], ...] ?:

from typing_extensions import TypeVarTuple
from typing_extensions import Unpack

MyTuple = TypeVarTuple("MyTuple")


class ContainerOfMultipleElements(Generic[Unpack[MyTuple]]):
    def __init__(self, elements: Tuple[Unpack[MyTuple]]):
        """doesn't work, gives me Element[str] / Element[int] as datatype"""

        self.elements = elements

    # def __init__(self, elements: Tuple[Unpack[MyTuple[_T] ??? ]]):
    #     """Need a way to move from MyTuple to _T"""
    #     self.elements = elements


# desired:
# t1: ContainerOfMultipleElements[str, int]

# what we actually get:
# t1: ContainerOfMultipleElements[Element[str], Element[int]]

t1 = ContainerOfMultipleElements((e1, e2))

Replies

1 suggested answer
·
1 reply

I think what you're looking for is a Map operation over the TypeVarTuple contents. There was something like this in an earlier version of PEP 646, but it was removed because the PEP was already very complex. It's something that could be added in a follow-on PEP assuming that 646 is accepted.

1 reply
@zzzeek

OK! well that pretty much ends pep-646 being meaningful for SQLAlchemy for the moment, thanks for the reply!

Answer selected by zzzeek
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
Q&A
Labels
None yet
2 participants