Small edits for PEP 560 (#459)
This commit is contained in:
parent
2c212e0086
commit
99b1665d94
54
pep-0560.rst
54
pep-0560.rst
|
@ -25,19 +25,19 @@ generic types.
|
||||||
Rationale
|
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
|
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
|
performance of the ``typing`` module, metaclass conflicts, and the large
|
||||||
number of hacks currently used in ``typing``.
|
number of hacks currently used in ``typing``.
|
||||||
|
|
||||||
|
|
||||||
Performance:
|
Performance
|
||||||
------------
|
-----------
|
||||||
|
|
||||||
The ``typing`` module is one of the heaviest and slowest modules in
|
The ``typing`` module is one of the heaviest and slowest modules in
|
||||||
the standard library even with all the optimizations made. Mainly this is
|
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
|
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:
|
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).
|
(this is minor however).
|
||||||
|
|
||||||
|
|
||||||
Metaclass conflicts:
|
Metaclass conflicts
|
||||||
--------------------
|
-------------------
|
||||||
|
|
||||||
All generic types are instances of ``GenericMeta``, so if a user uses
|
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.
|
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.
|
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,
|
instances with a type differing form the type whose ``__new__`` was called,
|
||||||
``C[int]().__class__ is C``.
|
``C[int]().__class__ is C``.
|
||||||
|
|
||||||
- ``_next_in_mro`` speed hack will be not necessary since subscription will
|
- ``_next_in_mro`` speed hack will be not necessary since subscription will
|
||||||
not create new classes.
|
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``.
|
like we can't remove it without changes outside ``typing``.
|
||||||
|
|
||||||
- Currently generics do dangerous things with private ABC caches
|
- 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.
|
re-implement ``ABCMeta`` in C.
|
||||||
|
|
||||||
- Problems with sharing attributes between subscripted generics,
|
- 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
|
but it is still incomplete, and solving this without the current proposal
|
||||||
will be hard and will need ``__getattribute__``.
|
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__``.
|
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
|
only allow to remove the above mentioned hacks/bugs, but also simplify
|
||||||
the implementation, so that it will be easier to maintain.
|
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
|
Specification
|
||||||
=============
|
=============
|
||||||
|
|
||||||
|
``__class_getitem__``
|
||||||
|
---------------------
|
||||||
|
|
||||||
The idea of ``__class_getitem__`` is simple: it is an exact analog of
|
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
|
``__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]``.
|
``GenericMeta.__getitem__`` for things like ``Iterable[int]``.
|
||||||
The ``__class_getitem__`` is automatically a class method and
|
The ``__class_getitem__`` is automatically a class method and
|
||||||
does not require ``@classmethod`` decorator (similar to
|
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
|
Note that this method is used as a fallback, so if a metaclass defines
|
||||||
``__getitem__``, then that will have the priority.
|
``__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
|
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
|
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.
|
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
|
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
|
NOTE: These two method names are reserved for exclusive use by
|
||||||
the ``typing`` module and the generic types machinery, and any other use is
|
the ``typing`` module and the generic types machinery, and any other use is
|
||||||
strongly discouraged. The reference implementation (with tests) can be found
|
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]_.
|
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
|
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
|
This proposal will support almost complete backwards compatibility with
|
||||||
the current public generic types API; moreover the ``typing`` module is still
|
the current public generic types API; moreover the ``typing`` module is still
|
||||||
provisional. The only two exceptions are that currently
|
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)``
|
``TypeError``. Also ``issubclass(collections.abc.Iterable, typing.Iterable)``
|
||||||
will return ``False``, which is probably desirable, since currently we have
|
will return ``False``, which is probably desirable, since currently we have
|
||||||
a (virtual) inheritance cycle between these two classes.
|
a (virtual) inheritance cycle between these two classes.
|
||||||
|
@ -172,7 +180,7 @@ References
|
||||||
.. [1] Discussion following Mark Shannon's presentation at Language Summit
|
.. [1] Discussion following Mark Shannon's presentation at Language Summit
|
||||||
(https://github.com/python/typing/issues/432)
|
(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)
|
(https://github.com/python/typing/pull/383)
|
||||||
|
|
||||||
.. [3] An old bug with setting/accessing attributes on generic types
|
.. [3] An old bug with setting/accessing attributes on generic types
|
||||||
|
@ -184,6 +192,8 @@ References
|
||||||
.. [5] Original proposal
|
.. [5] Original proposal
|
||||||
(https://github.com/python/typing/issues/468)
|
(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
|
Copyright
|
||||||
=========
|
=========
|
||||||
|
|
Loading…
Reference in New Issue