PEP 575 minor update (#642)

This commit is contained in:
jdemeyer 2018-05-07 18:20:54 +02:00 committed by Chris Angelico
parent 520405ff24
commit abafa90f05
1 changed files with 36 additions and 16 deletions

View File

@ -6,7 +6,7 @@ Type: Standards Track
Content-Type: text/x-rst Content-Type: text/x-rst
Created: 27-Mar-2018 Created: 27-Mar-2018
Python-Version: 3.8 Python-Version: 3.8
Post-History: 31-Mar-2018, 12-Apr-2018, 27-Apr-2018 Post-History: 31-Mar-2018, 12-Apr-2018, 27-Apr-2018, 5-May-2018
Abstract Abstract
@ -180,7 +180,11 @@ cfunction
--------- ---------
This is the new version of the old ``builtin_function_or_method`` class. This is the new version of the old ``builtin_function_or_method`` class.
It is a copy of ``base_function``, with the following differences: The name ``cfunction`` was chosen to avoid confusion with "built-in"
in the sense of "something in the ``builtins`` module".
It also fits better with the C API which use the `PyCFunction`` prefix.
The class ``cfunction`` is a copy of ``base_function``, with the following differences:
#. ``m_ml`` points to a ``PyMethodDef`` structure, #. ``m_ml`` points to a ``PyMethodDef`` structure,
extending ``PyCFunctionDef`` with an additional ``ml_doc`` extending ``PyCFunctionDef`` with an additional ``ml_doc``
@ -277,11 +281,12 @@ with the UTF-8 encoded name.
The ``_ml`` field reserves space to be used by ``base.m_ml``. The ``_ml`` field reserves space to be used by ``base.m_ml``.
A ``base_function`` instance must have the flag ``METH_PYTHON`` set
if and only if it is an instance of ``function``.
When constructing an instance of ``function`` from ``code`` and ``globals``, When constructing an instance of ``function`` from ``code`` and ``globals``,
an instance is created with ``base.m_ml = &_ml``, an instance is created with ``base.m_ml = &_ml``,
``base.m_self = NULL``. ``base.m_self = NULL``.
Instances of ``function`` should always have the flag ``METH_PYTHON`` set.
This is also handled by the constructors.
To make subclassing easier, we also add a copy constructor: To make subclassing easier, we also add a copy constructor:
if ``f`` is an instance of ``function``, then ``types.FunctionType(f)`` copies ``f``. if ``f`` is an instance of ``function``, then ``types.FunctionType(f)`` copies ``f``.
@ -296,6 +301,9 @@ This conveniently allows using a custom function type as decorator::
>>> type(f) >>> type(f)
<class '__main__.CustomFunction'> <class '__main__.CustomFunction'>
This also removes many use cases of ``functools.wraps``:
wrappers can be replaced by subclasses of ``function``.
bound_method bound_method
------------ ------------
@ -493,9 +501,10 @@ it also indicates a default implementation of ``__call__`` and ``__get__``.
In particular, such subclasses of ``base_function`` In particular, such subclasses of ``base_function``
must follow the implementation from the section `Calling base_function instances`_. must follow the implementation from the section `Calling base_function instances`_.
This flag is never inherited. This flag is automatically set for extension types which
Extension types should explicitly specify it if they inherit the ``tp_call`` and ``tp_descr_get`` implementation from ``base_function``.
do not override ``__call__`` nor ``__get__`` or if they override them in a compatible way. Extension types can explicitly specify it if they
override ``__call__`` or ``__get__`` in a compatible way.
The flag ``Py_TPFLAGS_BASEFUNCTION`` must never be set for a heap type The flag ``Py_TPFLAGS_BASEFUNCTION`` must never be set for a heap type
because that would not be safe (heap types can be changed dynamically). because that would not be safe (heap types can be changed dynamically).
@ -533,7 +542,11 @@ Some of these are existing (possibly changed) functions, some are new:
The old functions are kept as aliases of the new functions. The old functions are kept as aliases of the new functions.
- ``int PyFunction_Check(PyObject *op)``: return true if ``op`` - ``int PyFunction_Check(PyObject *op)``: return true if ``op``
is an instance of ``function``. is an instance of ``base_function`` with the ``METH_PYTHON`` flag set
(this is equivalent to checking whether ``op`` is an instance of ``function``).
- ``int PyFunction_CheckFast(PyObject *op)``: equivalent to
``PyFunction_Check(op) && PyBaseFunction_CheckFast(op)``.
- ``int PyFunction_CheckExact(PyObject *op)``: return true - ``int PyFunction_CheckExact(PyObject *op)``: return true
if the type of ``op`` is ``function``. if the type of ``op`` is ``function``.
@ -609,14 +622,16 @@ in the ``tp_methods`` array of an extension type).
Non-CPython implementations Non-CPython implementations
=========================== ===========================
For other implementations of Python apart from CPython, Most of this PEP is only relevant to CPython.
only the classes ``base_function``, ``bound_method`` and ``function`` are required. For other implementations of Python,
The latter two are the only classes which can be instantiated directly the two changes that are required are the ``base_function`` base class
from the Python interpreter. and the fact that ``function`` can be subclassed.
The classes ``cfunction`` and ``defined_function`` are not required.
We require ``base_function`` for consistency but we put no requirements on it: We require ``base_function`` for consistency but we put no requirements on it:
it is acceptable if this is just a copy of ``object``. it is acceptable if this is just a copy of ``object``.
Support for the new ``__parent__`` (and ``__objclass__``) attribute is not required. Support for the new ``__parent__`` (and ``__objclass__``) attribute is not required.
If there is no ``defined_function`` type, If there is no ``defined_function`` class,
then ``types.DefinedFunctionType`` should be an alias of ``types.FunctionType``. then ``types.DefinedFunctionType`` should be an alias of ``types.FunctionType``.
@ -809,9 +824,14 @@ Backwards compatibility
While designing this PEP, great care was taken to not break While designing this PEP, great care was taken to not break
backwards compatibility too much. backwards compatibility too much.
In particular, Python code not using ``inspect`` or type checks Most of the potentially incompatible changes
should not be affected by this PEP. are changes to CPython implementation details
For example, ``staticmethod``, ``functools.partial`` or ``operator.methodcaller`` which are different anyway in other Python interpreters.
In particular, Python code which correctly runs on PyPy
will very likely continue to work with this PEP.
The standard classes and functions like
``staticmethod``, ``functools.partial`` or ``operator.methodcaller``
do not need to change at all. do not need to change at all.
Changes to types and inspect Changes to types and inspect