PEP 575: two-phase implementation

This commit is contained in:
Jeroen Demeyer 2018-04-24 14:40:27 +02:00 committed by Chris Angelico
parent 5ce2015e4f
commit 91f2de3928
1 changed files with 66 additions and 1 deletions

View File

@ -95,6 +95,8 @@ with some differences:
replacing ``method_descriptor``.
Also ``__qualname__`` will use ``__objclass__`` as namespace
(instead of ``m_self`` before).
For methods of extension types, it is automatically assigned as the defining class
(``__class__`` in plain Python).
#. Argument Clinic [#clinic]_ is not supported.
@ -139,7 +141,7 @@ These are the relevant C structures::
PyObject_HEAD
PyCFunctionDef *m_ml; /* Description of the C function to call */
PyObject *m_self; /* __self__: anything, can be NULL; readonly */
PyObject *m_module; /* __module__: anything */
PyObject *m_module; /* __module__: anything (typically str) */
PyTypeObject *m_objclass; /* __objclass__: type or NULL; readonly */
PyObject *m_weakreflist; /* List of weak references */
} PyBaseFunctionObject;
@ -224,6 +226,11 @@ And ``__defaults__`` is not required to be used for calling the function.
Apart from adding these extra attributes,
``defined_function`` behaves exactly the same as ``base_function``.
**TODO**: maybe find a better name for ``defined_function``.
Other proposals: ``builtout_function`` (a function that is better built out; pun on builtin),
``generic_function`` (original proposal but conflicts with ``functools.singledispatch`` generic functions),
``user_function`` (defined by the user as opposed to CPython).
function
--------
@ -808,6 +815,64 @@ are deprecated and no longer used by CPython itself.
For now, they are kept for backwards compatibility.
Two-phase Implementation
========================
**TODO**: this section is optional. When accepting this PEP, it should
be decided whether to apply this two-phase implementation or not.
As mentioned above, the `changes to types and inspect`_ can break some
existing code.
In order to further minimize breakage, this PEP could be implemented
in two phases.
Phase one: duplicate classes
----------------------------
Implement this PEP but duplicate the classes ``bound_method``
and ``builtin_function``.
Add a new class ``builtin_method`` which is an exact copy of ``builtin_function``
add a new class ``bound_builtin_method`` which is an exact copy
of ``bound_method`` (in both cases, only the name would differ).
The class ``builtin_method`` will be used for unbound methods
of extension types.
It should be seen as continuation of the existing class
``method-descriptor``.
This ensures 100% backwards compatibility for these objects
(except for added attributes and maybe the ``repr()``).
The same would be done for bound methods of extension types:
these will be instances of ``bound_builtin_method``.
This ensures full backwards compatibility, except for code
assuming that ``types.BuiltinFunctionType`` is the same as ``types.BuiltinMethodType``.
For ``inspect``, we keep but deprecate the functions
``isbuiltin``, ``ismethod`` and ``ismethoddescriptor``.
To replace these, new functions ``isbuiltinfunction``, ``isboundmethod``
and ``isgetdescriptor`` (other possible names: ``isreaddescriptor`` or ``isdescriptor``)
are added.
The function ``isbuiltinfunction`` checks for instances of ``builtin_function``
and ``builtin_method``.
``isboundmethod`` checks for both ``bound_method`` and ``bound_builtin_method``.
And ``isgetdescriptor`` checks for non-data descriptors
which are not instances of ``base_function``.
Since showing an actual ``DeprecationWarning`` would affect a lot
of correctly-functioning code,
the deprecations would only appear in the documentation.
Another reason is that it is hard to show warnings for calling ``isinstance(x, t)``
(but it could be done using ``__instancecheck__`` hacking)
and impossible for ``type(x) is t``.
Phase two
---------
Phase two is what is actually described in the rest of this PEP:
the duplicate classes would be merged and the ``inspect`` functions
adjusted accordingly.
Reference Implementation
========================