diff --git a/pep-0576.rst b/pep-0576.rst new file mode 100644 index 000000000..e22153006 --- /dev/null +++ b/pep-0576.rst @@ -0,0 +1,142 @@ +PEP: 576 +Title: Rationalize Built-in function classes +Author: Mark Shannon +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 ` 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: + + + +