On 27 September 2017 at 18:08, Terry Reedy <tjreedy@udel.edu> wrote:
On 9/27/2017 5:28 AM, Ivan Levkivskyi wrote:

It is proposed to add two special methods ``__class_getitem__`` and
``__subclass_base__`` to the core CPython for better support of
generic types.

I would not be concerned about anyone (mis)using reserved words.


These methods are quite specific (especially __subclass_base__) so there are two points:

* I would like to say that there are less backwards compatibility guarantees. Only the documented use
  is guaranteed to be backwards compatible, which is in this case Iterable[int] etc.

* I don't want to "advertise" these methods. I could imagine someone will be unpleasantly surprised when
  finding these while reading someone other's code.
 
If the new methods were for general use, I would question making them automatically class methods.  Having __new__ automatically being a static method is convenient, but occasionally throws people off.  But if they were only used for typing, perhaps it is ok.  On the other hand, I expect that others will use __class_getitem__ for the same purpose -- to avoid defining a metaclass just to make class[something] work.  So I question defining that as 'typing only'.


I think we would rather want to limit the number of use cases for SomeClass[int], so that one doesn't need to guess if it is a generic class or something else.
 
Without rereading the PEP, the use case for __subclass_base__ is not clear to me.  So I don't know if there are other uses for it.

The __subclass_base__ method is needed to avoid making the result of Iterable[int] a class object. Creating new class objects on
every subscription is too expensive. However, these objects must be subclassable, so that the only way is to introduce this new method.
For example:

class Iterable:
    def __class_getitem__(cls, item):
        return GenericAlias(cls, item)

class GenericAlias:
    def __init__(self, origin, item):
        self.origin = origin
        self.item = item
    def __subclass_base__(self, bases):
        return self.origin

class MyIterable(Iterable[int]):
    ...

Real code will be more complex, but this illustrates the idea. I don't know other use cases where one
would want to allow non-classes in base classes list.

Thanks for comments!

--
Ivan