On Thu, May 12, 2022, at 6:01 AM, Matthew Rahtz via Typing-sig wrote:
Hey James!

I think this is the functionality provided by the Map operator that we included in early drafts of PEP 646, but removed to keep the size of the PEP manageable. We intend to introduce this in a future PEP - a (very) early draft of which is available here.

wow this is exciting.      In SQLAlchemy , we were not able to make any use of pep-646 due to mapping and easy interoperability with Tuple not being present.

I was wondering, will this "map" operator allow for the production of arbitrary Tuple types from a variable set of arguments?    For an explicit example, see the series of overloads we are using at https://github.com/sqlalchemy/sqlalchemy/blob/9e7bed9df601ead02fd96bf2fc787b23b536d2d6/lib/sqlalchemy/sql/_selectable_constructors.py#L337 where we must hardcode a series of overloads defining one to ten arguments.    This pattern can also be seen in projects such as SQLModel at https://github.com/tiangolo/sqlmodel/blob/4d200517934c38b44c8ce372425a1db67917a545/sqlmodel/sql/expression.py#L154 .

in both of the above code examples, there are two things happening that originally I had hoped pep-646 would have solved, but does not.  One is that we can easily map between different TypeVarTuple types without hardcoding for the number of elements.  The other is that we can allow for Tuple-specific operations such as __getitem__ with an integer index working with types (that is, (1, 'foo')[0] is int and (1, 'foo')[1] is str).      We currently need to use Tuple directly in order to have a working __getitem__ scheme, and the generated code approach seen in the links above in order to map from *varargs to tuples.

I haven't looked at the spec yet but just putting out some things that I was dealing with in case they are helpful.





Best,
Matthew

On Wed, 11 May 2022 at 20:05, James Murphy via Typing-sig <typing-sig@python.org> wrote:

Hi All,

I'm new to this list so forgive me if this has been previously discussed.

Is there any work currently towards allowing mapping dependent types of variadic generic TypeVarTuples? For instance, consider this function:

def pair_with_ids(*args):
    return tuple((id(x), x) for x in args)

The single-arg version of this function I could type as:

T = TypeVar('T')

def pair_with_ids(x: T) -> tuple[tuple[int, T]]:
    return ((id(x), x),)

Something similar could be done for any fixed number of parameters, e.g.

T1 = TypeVar('T1')
T2 = TypeVar('T2')

def pair_with_ids(x1: T2, x2: T2) -> tuple[tuple[int, T1], tuple[int, T2]]:
    return ((id(x1), x1), (id(x2), x2))

I would like to be able to type the whole thing at once with something like:

Ts = TypeVarTuple('Ts')
def pair_with_ids(*args: *Ts) -> tuple[*tuple[int, Ts]]:
    return tuple((id(x), x) for x in args)


I realize this breaks the "TypeVarTuple is always starred" rule, but I'm wondering if any kind of dynamic type mapping like this has been considered before.

The idea here being that you always need a star applying to a TypeVarTuple but not necessarily _immediately_ before. The star could be applied to any generic that has a single free type variable filled by a TypeVarTuple.


Thanks,

James




_______________________________________________
Typing-sig mailing list -- typing-sig@python.org
To unsubscribe send an email to typing-sig-leave@python.org
https://mail.python.org/mailman3/lists/typing-sig.python.org/
Member address: mrahtz@google.com
_______________________________________________
Typing-sig mailing list -- typing-sig@python.org
To unsubscribe send an email to typing-sig-leave@python.org
https://mail.python.org/mailman3/lists/typing-sig.python.org/
Member address: mike_mp@zzzcomputing.com