Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 79 additions & 10 deletions Doc/c-api/descriptor.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,31 @@ Descriptor Objects
"Descriptors" are objects that describe some attribute of an object. They are
found in the dictionary of type objects.

.. XXX document these!

.. c:function:: PyObject* PyDescr_NewGetSet(PyTypeObject *type, struct PyGetSetDef *getset)

Create a new get-set descriptor for extension type *type* from the
:c:type:`PyGetSetDef` structure *getset*.
Comment on lines +13 to +14
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's elaborate a little more (the same goes for the ones below):

  1. What is a get-set descriptor, exactly?
  2. Why do users care? (Or, what might they use this for?)
  3. What does this correspond to in Python?


Get-set descriptors expose attributes implemented by C getter and setter
functions rather than stored directly in the instance. This is the same kind
of descriptor created for entries in :c:member:`~PyTypeObject.tp_getset`, and
it appears in Python as a :class:`types.GetSetDescriptorType` object.

On success, return a :term:`strong reference` to the descriptor. Return
``NULL`` with an exception set on failure.

.. c:function:: PyObject* PyDescr_NewMember(PyTypeObject *type, struct PyMemberDef *member)

.. c:function:: PyObject* PyDescr_NewMember(PyTypeObject *type, struct PyMemberDef *meth)
Create a new member descriptor for extension type *type* from the
:c:type:`PyMemberDef` structure *member*.

Member descriptors expose fields in the type's C struct as Python
attributes. This is the same kind of descriptor created for entries in
:c:member:`~PyTypeObject.tp_members`, and it appears in Python as a
:class:`types.MemberDescriptorType` object.

On success, return a :term:`strong reference` to the descriptor. Return
``NULL`` with an exception set on failure.

.. c:var:: PyTypeObject PyMemberDescr_Type

Expand All @@ -30,22 +48,53 @@ found in the dictionary of type objects.
The type object for get/set descriptor objects created from
:c:type:`PyGetSetDef` structures. These descriptors implement attributes
whose value is computed by C getter and setter functions, and are used
for many built-in type attributes.
for many built-in type attributes. They correspond to
:class:`types.GetSetDescriptorType` objects in Python.


.. c:function:: PyObject* PyDescr_NewMethod(PyTypeObject *type, struct PyMethodDef *meth)

Create a new method descriptor for extension type *type* from the
:c:type:`PyMethodDef` structure *meth*.

Method descriptors expose C functions as methods on a type. This is the same
kind of descriptor created for entries in
:c:member:`~PyTypeObject.tp_methods`, and it appears in Python as a
:class:`types.MethodDescriptorType` object.

On success, return a :term:`strong reference` to the descriptor. Return
``NULL`` with an exception set on failure.

.. c:var:: PyTypeObject PyMethodDescr_Type

The type object for method descriptor objects created from
:c:type:`PyMethodDef` structures. These descriptors expose C functions as
methods on a type, and correspond to :class:`types.MemberDescriptorType`
methods on a type, and correspond to :class:`types.MethodDescriptorType`
objects in Python.


.. c:function:: PyObject* PyDescr_NewWrapper(PyTypeObject *type, struct wrapperbase *wrapper, void *wrapped)
.. c:struct:: wrapperbase

Describes a slot wrapper used by :c:func:`PyDescr_NewWrapper`.

Each ``wrapperbase`` record stores the Python-visible name and metadata for a
special method implemented by a type slot, together with the wrapper
function used to adapt that slot to Python's calling convention.

.. c:function:: PyObject* PyDescr_NewWrapper(PyTypeObject *type, struct wrapperbase *base, void *wrapped)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wrapperbase is undocumented as well -- can we fix that in this PR?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I'll be working on it


Create a new wrapper descriptor for extension type *type* from the
:c:struct:`wrapperbase` structure *base* and the wrapped slot function
pointer
*wrapped*.

Wrapper descriptors expose special methods implemented by type slots. This
is the same kind of descriptor that CPython creates for slot-based special
methods such as ``__repr__`` or ``__add__``, and it appears in Python as a
:class:`types.WrapperDescriptorType` object.

On success, return a :term:`strong reference` to the descriptor. Return
``NULL`` with an exception set on failure.

.. c:var:: PyTypeObject PyWrapperDescr_Type

Expand All @@ -58,6 +107,16 @@ found in the dictionary of type objects.

.. c:function:: PyObject* PyDescr_NewClassMethod(PyTypeObject *type, PyMethodDef *method)

Create a new class method descriptor for extension type *type* from the
:c:type:`PyMethodDef` structure *method*.

Class method descriptors expose C methods that receive the class rather than
an instance when accessed. This is the same kind of descriptor created for
``METH_CLASS`` entries in :c:member:`~PyTypeObject.tp_methods`, and it
appears in Python as a :class:`types.ClassMethodDescriptorType` object.

On success, return a :term:`strong reference` to the descriptor. Return
``NULL`` with an exception set on failure.

.. c:function:: int PyDescr_IsData(PyObject *descr)

Expand All @@ -66,8 +125,18 @@ found in the dictionary of type objects.
no error checking.


.. c:function:: PyObject* PyWrapper_New(PyObject *, PyObject *)
.. c:function:: PyObject* PyWrapper_New(PyObject *d, PyObject *self)

Create a new bound wrapper object from the wrapper descriptor *d* and the
instance *self*.

This is the bound form of a wrapper descriptor created by
:c:func:`PyDescr_NewWrapper`. CPython creates these objects when a slot
wrapper is accessed through an instance, and they appear in Python as
:class:`types.MethodWrapperType` objects.

On success, return a :term:`strong reference` to the wrapper object. Return
``NULL`` with an exception set on failure.

.. c:macro:: PyDescr_COMMON

Expand Down Expand Up @@ -104,9 +173,9 @@ Built-in descriptors
.. c:var:: PyTypeObject PyClassMethodDescr_Type

The type object for C-level class method descriptor objects.
This is the type of the descriptors created for :func:`classmethod` defined in
C extension types, and is the same object as :class:`classmethod`
in Python.
This is the type of the descriptors created for :func:`classmethod` defined
in C extension types, and corresponds to
:class:`types.ClassMethodDescriptorType` objects in Python.


.. c:function:: PyObject *PyClassMethod_New(PyObject *callable)
Expand Down
1 change: 0 additions & 1 deletion Doc/tools/.nitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
# as tested on the CI via check-warnings.py in reusable-docs.yml.
# Keep lines sorted lexicographically to help avoid merge conflicts.

Doc/c-api/descriptor.rst
Doc/c-api/init_config.rst
Doc/c-api/intro.rst
Doc/c-api/stable.rst
Expand Down
Loading