New PEP 'Rationalize Built-in function classes'. (#650)
* PEP 576: Rationalize Built-in function classes.
This commit is contained in:
parent
f630c7406a
commit
99575010e0
|
@ -0,0 +1,142 @@
|
||||||
|
PEP: 576
|
||||||
|
Title: Rationalize Built-in function classes
|
||||||
|
Author: Mark Shannon <mark@hotpy.org>
|
||||||
|
Status: Draft
|
||||||
|
Type: Standards Track
|
||||||
|
Content-Type: text/x-rst
|
||||||
|
Created: 10-May-2018
|
||||||
|
Python-Version: 3.8
|
||||||
|
Post-History: 17-May-2018
|
||||||
|
|
||||||
|
|
||||||
|
Abstract
|
||||||
|
========
|
||||||
|
|
||||||
|
Extend the classes for built-in functions and methods to be more like Python functions. Specifically, built-in functions and methods will gain access to the module they are declared in, and built-in methods will have access to the class they belong to. This will allow tools like Cython to use the standard built-in function and method classes, thus gaining performance parity with built-in functions like ``len`` or ``print``.
|
||||||
|
Performance of existing code is not expected to change significantly.
|
||||||
|
|
||||||
|
One new function will be added to the C API to allow third-party code to create built-in functions in an efficient and portable manner.
|
||||||
|
|
||||||
|
Motivation
|
||||||
|
==========
|
||||||
|
|
||||||
|
Currently third-party module authors face a dilemna when implementing
|
||||||
|
functions in C. Either they can use one of the pre-existing built-in function
|
||||||
|
or method classes or implement their own custom class in C.
|
||||||
|
The first choice causes them to lose the ability to access module-level data;
|
||||||
|
the second choice is an additional maintenance burden and, more importantly,
|
||||||
|
has a significant negative impact on performance.
|
||||||
|
|
||||||
|
This PEP aims to allow authors of third-party C modules, and tools like to Cython, to
|
||||||
|
utilise the pre-existing built-in function or method classes without a loss of capabilities relative to a function implemented in Python.
|
||||||
|
|
||||||
|
Enhanced access to the function's enviroment
|
||||||
|
--------------------------------------------
|
||||||
|
|
||||||
|
Built-in functions will gain efficient access to the module in which they are declared,
|
||||||
|
and if declared in a class, efficient access to that class as well.
|
||||||
|
|
||||||
|
Performance
|
||||||
|
-----------
|
||||||
|
|
||||||
|
No significant change is expected.
|
||||||
|
|
||||||
|
Introspection
|
||||||
|
-------------
|
||||||
|
|
||||||
|
No changes to built-in functions are required to support introspection.
|
||||||
|
|
||||||
|
The ``inspect.Signature.from_callable()`` function computes the signature of a callable. If an object has a ``__signature__``
|
||||||
|
property, then ``inspect.Signature.from_callable()`` simply returns that. If a builtin-callable has a ``__text_signature__``
|
||||||
|
then the ``__signature__`` is created from that.
|
||||||
|
This means that 3rd party builtin-functions can implement ``__text_signature__`` if sufficient,
|
||||||
|
and the more expensive ``__signature__`` if necessary.
|
||||||
|
|
||||||
|
New classes and changes to existing classes
|
||||||
|
===========================================
|
||||||
|
|
||||||
|
Python visible changes
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
#. A new built-in class, ``builtin_function``, will be added.
|
||||||
|
|
||||||
|
#. ``types.BuiltinFunctionType`` will refer to ``builtin_function`` not ``builtin_function_or_method``.
|
||||||
|
|
||||||
|
#. Instances of the ``builtin_function`` class will retain the ``__module__`` property of ``builtin_function_or_method`` and gain the ``func_module`` and ``func_globals`` properties. The ``func_module`` allows access to the module to which the function belongs. Note that this is different from the ``__module__`` property which merely returns the name of the module. The ``func_globals`` property is equivalent to ``func_module.__dict__`` and is provided to mimic the Python function property of the same name.
|
||||||
|
|
||||||
|
#. The ``method_descriptor`` class will become a sub-class of the new ``builtin_function`` class.
|
||||||
|
|
||||||
|
#. When binding a ``method_descriptor`` instance to an instance of its owning class, a ``bound_method`` will be created instead of a ``builtin_function_or_method``. This means that the ``method_descriptors`` now mimic the behaviour of Python functions more closely. In other words, ``[].append`` becomes a ``bound_method`` instead of a ``builtin_function_or_method``.
|
||||||
|
|
||||||
|
|
||||||
|
Note that ``method_descriptor`` instances will only have access to their module if their ``__objclass__`` class has access to its module. If PEP 573 is approved, then that will be possible.
|
||||||
|
|
||||||
|
C API changes
|
||||||
|
-------------
|
||||||
|
|
||||||
|
#. A new function ``PyBuiltinFunction_New(PyMethodDef *ml, PyObject *module)`` is added to create built-in functions.
|
||||||
|
|
||||||
|
#. ``PyCFunction_NewEx()`` and ``PyCFunction_New()`` are deprecated and will return a ``PyBuiltinFunction`` if able, otherwise a ``builtin_function_or_method``.
|
||||||
|
|
||||||
|
Retaining backwards compatibility in the C API and ABI
|
||||||
|
------------------------------------------------------
|
||||||
|
|
||||||
|
The ``PyCFunction_Type`` object will continue to exist for backwards compatibility in the ABI, but no
|
||||||
|
instances of it would be created in the interpreter or the standard library.
|
||||||
|
|
||||||
|
Internal C changes
|
||||||
|
------------------
|
||||||
|
|
||||||
|
The new C struct for built-in functions is::
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
PyObject_HEAD
|
||||||
|
PyMethodDef m_ml; /* Description of the C function to call */
|
||||||
|
PyObject *m_module; /* The func_module attribute, must be an actual module */
|
||||||
|
PyObject *m_weakreflist; /* List of weak references */
|
||||||
|
} PyBuiltinFunctionObject;
|
||||||
|
|
||||||
|
and the C struct for ``method_descriptor``\s changes to::
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
PyBuiltinFunctionObject base;
|
||||||
|
PyTypeObject *m_objclass; /* The __objclass__ attibute */
|
||||||
|
} PyMethodDescrObject;
|
||||||
|
|
||||||
|
|
||||||
|
Possible Extensions
|
||||||
|
===================
|
||||||
|
|
||||||
|
Callables for operators, like ``int.__add__``, could become instances of the ``method_descriptor`` class, instead of the ``slot_wrapper`` class.
|
||||||
|
This would further reduce the number of classes representing built-in callables, but is not necessary to fulfil the above requirements.
|
||||||
|
|
||||||
|
If the ``slot__wrapper`` class were removed, then two new ``METH_`` flags would need to be added.
|
||||||
|
The new flags would be ``METH_OO`` and ``METH_TRIO`` for two and three argument operators respectively.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Alternative Suggestions
|
||||||
|
=======================
|
||||||
|
|
||||||
|
`PEP 575 <https://www.python.org/dev/peps/pep-0575/>` is an alternative approach to solving the same problem as this PEP.
|
||||||
|
|
||||||
|
|
||||||
|
Copyright
|
||||||
|
=========
|
||||||
|
|
||||||
|
This document has been placed in the public domain.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
..
|
||||||
|
Local Variables:
|
||||||
|
mode: indented-text
|
||||||
|
indent-tabs-mode: nil
|
||||||
|
sentence-end-double-space: t
|
||||||
|
fill-column: 70
|
||||||
|
coding: utf-8
|
||||||
|
End:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue