PEP 575 minor update (#642)
This commit is contained in:
parent
520405ff24
commit
abafa90f05
52
pep-0575.rst
52
pep-0575.rst
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue