PEP 580: update (#751)
This commit is contained in:
parent
c567006fbc
commit
2270327061
54
pep-0580.rst
54
pep-0580.rst
|
@ -125,8 +125,12 @@ The ``cc_parent`` field (accessed for example by a ``__parent__``
|
|||
or ``__objclass__`` descriptor from Python code) can be any Python object.
|
||||
For methods of extension types, this is set to the class.
|
||||
For functions of modules, this is set to the module.
|
||||
However, custom classes are free to set ``cc_parent`` to whatever they want,
|
||||
it can also be ``NULL``.
|
||||
It is only used by the C call protocol if the ``CCALL_OBJCLASS`` flag is set.
|
||||
|
||||
The parent serves multiple purposes: for methods of extension types,
|
||||
The parent serves multiple purposes: for methods of extension types
|
||||
(more precisely, when the flag ``CCALL_OBJCLASS`` is set),
|
||||
it is used for type checks like the following::
|
||||
|
||||
>>> list.append({}, "x")
|
||||
|
@ -136,15 +140,20 @@ it is used for type checks like the following::
|
|||
|
||||
PEP 573 specifies that every function should have access to the
|
||||
module in which it is defined.
|
||||
For functions of a module, this is given by the parent.
|
||||
It is recommended to use the parent for this,
|
||||
which works directly for functions of a module.
|
||||
For methods, this works indirectly through the class,
|
||||
assuming that the class has a pointer to the module.
|
||||
|
||||
The parent would also typically be used to implement ``__qualname__``.
|
||||
The new C API function ``PyCCall_GenericGetQualname()`` does exactly that.
|
||||
|
||||
Custom classes are free to set ``cc_parent`` to whatever they want.
|
||||
It is only used by the C call protocol if the ``CCALL_OBJCLASS`` flag is set.
|
||||
**NOTE**: for functions of modules,
|
||||
the parent is exactly the same as ``__self__``.
|
||||
However, using ``__self__`` for the module is a quirk of the current implementation:
|
||||
in the future, we want to allow functions which use ``__self__``
|
||||
in the normal way, for implementing methods.
|
||||
Such functions can still use ``cc_parent`` instead to refer to the module.
|
||||
|
||||
Using tp_print
|
||||
--------------
|
||||
|
@ -172,7 +181,8 @@ if it has the ``Py_TPFLAGS_HAVE_CCALL`` flag set
|
|||
Such a class must implement ``__call__`` as described in this section
|
||||
(in practice, this just means setting ``tp_call`` to ``PyCCall_Call``).
|
||||
|
||||
The ``cc_func`` field is a C function pointer.
|
||||
The ``cc_func`` field is a C function pointer,
|
||||
which plays the same role as the existing ``ml_meth`` field of ``PyMethodDef``.
|
||||
Its precise signature depends on flags.
|
||||
Below are the possible values for ``cc_flags & CCALL_SIGNATURE``
|
||||
together with the arguments that the C function takes.
|
||||
|
@ -191,20 +201,29 @@ signature flags:
|
|||
|
||||
- ``CCALL_FASTCALL | CCALL_KEYWORDS``:
|
||||
``cc_func(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)``
|
||||
(``kwnames`` is either ``NULL`` or a non-empty tuple of keyword names)
|
||||
|
||||
- ``CCALL_NOARGS``:
|
||||
``cc_func(PyObject *self)``
|
||||
``cc_func(PyObject *self, PyObject *unused)`` (second argument is always ``NULL``)
|
||||
|
||||
- ``CCALL_O``:
|
||||
``cc_func(PyObject *self, PyObject *arg)``
|
||||
|
||||
The flag ``CCALL_FUNCARG`` may be combined with any of these.
|
||||
If so, the C function takes an additional argument as second argument
|
||||
after ``self``.
|
||||
This argument is used to pass the function object (the ``self`` in ``__call__``).
|
||||
If so, the C function takes an additional argument
|
||||
as first argument before ``self``.
|
||||
This argument is used to pass the function object
|
||||
(the ``self`` in ``__call__`` but see NOTE below).
|
||||
For example, we have the following signature:
|
||||
|
||||
- ``CCALL_VARARGS | CCALL_FUNCARG``: ``cc_func(PyObject *self, PyObject *func, PyObject *args)``
|
||||
- ``CCALL_FUNCARG | CCALL_VARARGS``:
|
||||
``cc_func(PyObject *func, PyObject *self, PyObject *args)``
|
||||
|
||||
One exception is ``CCALL_FUNCARG | CCALL_NOARGS``:
|
||||
the ``unused`` argument is dropped, so the signature becomes
|
||||
|
||||
- ``CCALL_FUNCARG | CCALL_NOARGS``:
|
||||
``cc_func(PyObject *func, PyObject *self)``
|
||||
|
||||
**NOTE**: in the case of bound methods, it is currently unspecified
|
||||
whether the "function object" in the paragraph above refers
|
||||
|
@ -215,10 +234,6 @@ Despite this ambiguity, the implementation of bound methods
|
|||
guarantees that ``PyCCall_CCALLDEF(func)``
|
||||
points to the ``PyCCallDef`` of the original function.
|
||||
|
||||
**NOTE**: ``METH_NOARGS`` takes a second unused argument.
|
||||
This is compatible with ``CCALL_NOARGS | CCALL_FUNCARG``,
|
||||
which also takes two arguments.
|
||||
|
||||
**NOTE**: unlike the existing ``METH_...`` flags,
|
||||
the ``CCALL_...`` constants do not necessarily represent single bits.
|
||||
So checking ``(cc_flags & CCALL_VARARGS) == 0`` is not a valid way
|
||||
|
@ -250,12 +265,12 @@ then the first positional argument is removed from
|
|||
Effectively, the first positional argument is treated as ``__self__``.
|
||||
If there are no positional arguments, ``TypeError`` is raised.
|
||||
|
||||
This process is called self slicing and a function is said to have self
|
||||
This process is called "self slicing" and a function is said to have self
|
||||
slicing if ``cr_self`` is NULL and ``CCALL_SELFARG`` is set.
|
||||
|
||||
Note that a ``METH_NULLARG`` function with self slicing effectively has
|
||||
Note that a ``CCALL_NOARGS`` function with self slicing effectively has
|
||||
one argument, namely ``self``.
|
||||
Analogously, a ``METH_O`` function with self slicing has two arguments.
|
||||
Analogously, a ``CCALL_O`` function with self slicing has two arguments.
|
||||
|
||||
Descriptor behavior
|
||||
-------------------
|
||||
|
@ -411,8 +426,9 @@ The following function is added (also to the stable ABI [#pep384]_):
|
|||
|
||||
- ``PyObject * PyCFunction_ClsNew(PyTypeObject *cls, PyMethodDef *ml, PyObject *self, PyObject *module, PyObject *parent)``:
|
||||
create a new object with object structure ``PyCFunctionObject`` and class ``cls``.
|
||||
Note that the entries of the ``PyMethodDef`` structure are used to construct
|
||||
the new object, but it is no longer stored in the object.
|
||||
The entries of the ``PyMethodDef`` structure are used to construct
|
||||
the new object, but the pointer to the ``PyMethodDef`` structure
|
||||
is not stored.
|
||||
The flags for the C call protocol are automatically determined in terms
|
||||
of ``ml->ml_flags``, ``self`` and ``parent``.
|
||||
|
||||
|
|
Loading…
Reference in New Issue