PEP 585: https://www.python.org/dev/peps/pep-0585/

With the help of Ethan Smith (and some code review by Serhiy) I have started a prototype of PEP585. You can see my code at https://github.com/python/cpython/pull/18239 (a PR to CPython) or directly in my branch (where I take PRs too): https://github.com/gvanrossum/cpython/tree/pep585. I am cautiously optimistic that we can get this integrated into Python 3.9.

Based on this work in progress I have a bunch of questions and suggestions for PEP 585.

1. The PEP says that e.g. list[str][str] should be forbidden. But there's at least one example where we currently allow chained subscript operations. This currently works (in mypy as well as at runtime):

import typing
T = typing.TypeVar("T")
D = typing.Dict[str, T]
# Now D is a generic type
x: D[int]
# Now x has type dict[str, int]

But if, in my branch, we replace Dict with dict, we get an error on the last line:

import typing
T = typing.TypeVar("T")
D = dict[str, T]
x: D[int]  # E: TypeError: 'GenericAlias' object is not subscriptable

The last line raises a TypeError.

2. The PEP says that isinstance([1, 2, 3], list[int]) should be True. I think this is wrong -- with typing.List[int] it currently raises a TypeError, and I think we should keep forbidding this. Similar with issubclass.

3. The PEP says that list == list[str]. This currently returns false in my branch (apparently this doesn't use __getattribute__ to get the __eq__ operation), and I think I like that better. It also matches the behavior of typing.List.

4. The PEP doesn't provide a name for the proxy type. I propose to name it GenericAlias and to add it to the types.py module, so it can be imported as types.GenericAlias (note: types; not typing).

5. I think the following classes should also be made generic: re.Pattern, re.Match, io.IO.

6. How far should we go with replacing everything in typing.py that shadows something that has become generic due to the PEP's changes? (collections, collections.abc, contextlib, re, io). I expect this to be somewhat controversial (Ivan may have some ideas) and difficult to keep compatible with 3.8.

7. I haven't figured out yet how to support type[x] (which should have the same meaning as typing.Type[x]) without it also enabling int[x], which we would like to prevent. (We don't want to just add object.__class_getitem__!)

8. I have a tricky bug remaining where inheriting from Tuple[something] causes problems. Take this example:

class C(Tuple[int]): pass

If we now examine C.__mro__, we see that it is (C, tuple, typing.Generic, object). IOW, inheriting from typing.Tuple causes builtins.tuple to be inserted into the MRO. The problem is that in my branch, tuple.__class_getitem__ overrides Generic.__class_getitem__, whereas the latter is needed to satisfy some tests for typing.py (and presumably to enable certain special behavior). I'm mostly looking for suggestions on how to make those failing tests work (see https://github.com/python/cpython/commit/35cd5f477c9da985880130d72297335e010450e4/checks?check_suite_id=427090531).




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