Small edits for PEP 560 (#459)

This commit is contained in:
Guido van Rossum 2017-11-10 11:45:03 -08:00 committed by GitHub
parent 2c212e0086
commit 99b1665d94
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 32 additions and 22 deletions

View File

@ -25,19 +25,19 @@ generic types.
Rationale
=========
The restriction to not modify the core CPython interpreter lead to some
The restriction to not modify the core CPython interpreter led to some
design decisions that became questionable when the ``typing`` module started
to be widely used. There are three main points of concerns:
to be widely used. There are three main points of concern:
performance of the ``typing`` module, metaclass conflicts, and the large
number of hacks currently used in ``typing``.
Performance:
------------
Performance
-----------
The ``typing`` module is one of the heaviest and slowest modules in
the standard library even with all the optimizations made. Mainly this is
because subscripted generic types (see PEP 484 for definition of terms
because of subscripted generic types (see PEP 484 for definition of terms
used in this PEP) are class objects (see also [1]_). The three main ways how
the performance can be improved with the help of the proposed special methods:
@ -52,8 +52,8 @@ the performance can be improved with the help of the proposed special methods:
(this is minor however).
Metaclass conflicts:
--------------------
Metaclass conflicts
-------------------
All generic types are instances of ``GenericMeta``, so if a user uses
a custom metaclass, then it is hard to make a corresponding class generic.
@ -70,17 +70,17 @@ but this is not always practical or even possible. With the help of the
proposed special attributes the ``GenericMeta`` metaclass will not be needed.
Hacks and bugs that will be removed by this proposal:
-----------------------------------------------------
Hacks and bugs that will be removed by this proposal
----------------------------------------------------
- ``_generic_new`` hack that exists since ``__init__`` is not called on
- ``_generic_new`` hack that exists because ``__init__`` is not called on
instances with a type differing form the type whose ``__new__`` was called,
``C[int]().__class__ is C``.
- ``_next_in_mro`` speed hack will be not necessary since subscription will
not create new classes.
- Ugly ``sys._getframe`` hack, this one is particularly nasty, since it looks
- Ugly ``sys._getframe`` hack. This one is particularly nasty since it looks
like we can't remove it without changes outside ``typing``.
- Currently generics do dangerous things with private ABC caches
@ -89,14 +89,14 @@ Hacks and bugs that will be removed by this proposal:
re-implement ``ABCMeta`` in C.
- Problems with sharing attributes between subscripted generics,
see [3]_. Current solution already uses ``__getattr__`` and ``__setattr__``,
see [3]_. The current solution already uses ``__getattr__`` and ``__setattr__``,
but it is still incomplete, and solving this without the current proposal
will be hard and will need ``__getattribute__``.
- ``_no_slots_copy`` hack, where we clean-up the class dictionary on every
- ``_no_slots_copy`` hack, where we clean up the class dictionary on every
subscription thus allowing generics with ``__slots__``.
- General complexity of the ``typing`` module, the new proposal will not
- General complexity of the ``typing`` module. The new proposal will not
only allow to remove the above mentioned hacks/bugs, but also simplify
the implementation, so that it will be easier to maintain.
@ -104,9 +104,12 @@ Hacks and bugs that will be removed by this proposal:
Specification
=============
``__class_getitem__``
---------------------
The idea of ``__class_getitem__`` is simple: it is an exact analog of
``__getitem__`` with an exception that it is called on a class that
defines it, not on its instances, this allows us to avoid
defines it, not on its instances. This allows us to avoid
``GenericMeta.__getitem__`` for things like ``Iterable[int]``.
The ``__class_getitem__`` is automatically a class method and
does not require ``@classmethod`` decorator (similar to
@ -131,8 +134,11 @@ For example::
Note that this method is used as a fallback, so if a metaclass defines
``__getitem__``, then that will have the priority.
``__subclass_base__``
---------------------
If an object that is not a class object appears in the bases of a class
definition, the ``__subclass_base__`` is searched on it. If found,
definition, then ``__subclass_base__`` is searched on it. If found,
it is called with the original tuple of bases as an argument. If the result
of the call is not ``None``, then it is substituted instead of this object.
Otherwise (if the result is ``None``), the base is just removed. This is
@ -144,20 +150,22 @@ done by the metaclass).
NOTE: These two method names are reserved for exclusive use by
the ``typing`` module and the generic types machinery, and any other use is
strongly discouraged. The reference implementation (with tests) can be found
in [4]_, the proposal was originally posted and discussed on
in [4]_, and the proposal was originally posted and discussed on
the ``typing`` tracker, see [5]_.
Backwards compatibility and impact on users who don't use ``typing``:
=====================================================================
Backwards compatibility and impact on users who don't use ``typing``
====================================================================
This proposal may break code that currently uses the names
``__class_getitem__`` and ``__subclass_base__``.
``__class_getitem__`` and ``__subclass_base__``. (But the language
reference explicitly reserves *all* undocumented dunder names, and
allows "breakage without warning"; see [6]_.)
This proposal will support almost complete backwards compatibility with
the current public generic types API; moreover the ``typing`` module is still
provisional. The only two exceptions are that currently
``issubclass(List[int], List)`` returns True, with this proposal it will raise
``issubclass(List[int], List)`` returns True, while with this proposal it will raise
``TypeError``. Also ``issubclass(collections.abc.Iterable, typing.Iterable)``
will return ``False``, which is probably desirable, since currently we have
a (virtual) inheritance cycle between these two classes.
@ -172,7 +180,7 @@ References
.. [1] Discussion following Mark Shannon's presentation at Language Summit
(https://github.com/python/typing/issues/432)
.. [2] Pull Request to implement shared generic ABC caches
.. [2] Pull Request to implement shared generic ABC caches (merged)
(https://github.com/python/typing/pull/383)
.. [3] An old bug with setting/accessing attributes on generic types
@ -184,6 +192,8 @@ References
.. [5] Original proposal
(https://github.com/python/typing/issues/468)
.. [6] Reserved classes of identifiers
(https://docs.python.org/3/reference/lexical_analysis.html#reserved-classes-of-identifiers)
Copyright
=========