On Sun, Mar 24, 2019 at 11:43 AM Gregory P. Smith <greg@krypto.org> wrote:
On Thu, Mar 21, 2019 at 12:22 PM Michael Sullivan <sully@msully.net> wrote:
One thing that adding an explicit syntax for declaring aliases will allow us to do is create syntax for declaring a generic type alias that does not use all its type variables, or that uses them in a different order than they appear in the aliased type.

mypy currently supports an undocumented version of this, "FlexibleAlias".
`Foo = FlexibleAlias[T, U, V, Bar]` creates a type alias Foo with type parameters T, U, and V and type Bar, regardless of which of those variables occur in Bar or in what order.

Currently we use this in mypy to allow changing certain types to Any under certain configuration flags:
T = TypeVar('T')
if MYPYC:
    Bogus = FlexibleAlias[T, Any]
else:
    Bogus = FlexibleAlias[T, T]

Could you expand on what you mean by this, it's not clear to me from this description what is going on here.

A = FlexibleAlias[<typevar>, <type>] defines a generic alias over <typevar> that when invoked expands to <type>. The point of the example is that you can write Bogus[int], and depending on the compile-time value of MYPYC, this expands either to Any (if MYPYC is True) or to int (if MYPYC is False).

You can use it with multiple type vars as FlexibleAlias[Tuple[T, U], <type>] -- not a great notation IMO but was easy to implement in mypy.

The reason we added this to mypy was because mypyc (the experimental compiler) can't generate code for some cases. If there's just one case like this you could write

if MYPYC:
    Foo = Any
else:
    Foo = int

but we found more and more places where we (unfortunately) had to do that, so we ended up creating FlexibleAlias as a shorthand, so now we can write

    Foo = Bogus[int]

--
--Guido van Rossum (python.org/~guido)