diff --git a/pep-0575.rst b/pep-0575.rst index 45fcd73e9..0eb2fbc33 100644 --- a/pep-0575.rst +++ b/pep-0575.rst @@ -6,7 +6,7 @@ Type: Standards Track Content-Type: text/x-rst Created: 27-Mar-2018 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 @@ -180,7 +180,11 @@ cfunction --------- 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, 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``. +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``, an instance is created with ``base.m_ml = &_ml``, ``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: 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) +This also removes many use cases of ``functools.wraps``: +wrappers can be replaced by subclasses of ``function``. + bound_method ------------ @@ -493,9 +501,10 @@ it also indicates a default implementation of ``__call__`` and ``__get__``. In particular, such subclasses of ``base_function`` must follow the implementation from the section `Calling base_function instances`_. -This flag is never inherited. -Extension types should explicitly specify it if they -do not override ``__call__`` nor ``__get__`` or if they override them in a compatible way. +This flag is automatically set for extension types which +inherit the ``tp_call`` and ``tp_descr_get`` implementation from ``base_function``. +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 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. - ``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 if the type of ``op`` is ``function``. @@ -609,14 +622,16 @@ in the ``tp_methods`` array of an extension type). Non-CPython implementations =========================== -For other implementations of Python apart from CPython, -only the classes ``base_function``, ``bound_method`` and ``function`` are required. -The latter two are the only classes which can be instantiated directly -from the Python interpreter. +Most of this PEP is only relevant to CPython. +For other implementations of Python, +the two changes that are required are the ``base_function`` base class +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: it is acceptable if this is just a copy of ``object``. 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``. @@ -809,9 +824,14 @@ Backwards compatibility While designing this PEP, great care was taken to not break backwards compatibility too much. -In particular, Python code not using ``inspect`` or type checks -should not be affected by this PEP. -For example, ``staticmethod``, ``functools.partial`` or ``operator.methodcaller`` +Most of the potentially incompatible changes +are changes to CPython implementation details +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. Changes to types and inspect