From f5b1183610d5888db3bbd639b1a0c945dbd8f8dd Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Tue, 22 May 2018 11:02:44 +0300 Subject: bpo-5945: Improve mappings and sequences C API docs. (GH-7029) --- Doc/c-api/mapping.rst | 66 ++++++++++++++++++++++++++++---------------------- Doc/c-api/object.rst | 8 +++--- Doc/c-api/sequence.rst | 31 +++++++++++++----------- Doc/c-api/typeobj.rst | 56 ++++++++++++++++++++++++++---------------- Include/abstract.h | 16 ++++++------ 5 files changed, 101 insertions(+), 76 deletions(-) diff --git a/Doc/c-api/mapping.rst b/Doc/c-api/mapping.rst index 308a976..b8eaadb 100644 --- a/Doc/c-api/mapping.rst +++ b/Doc/c-api/mapping.rst @@ -5,11 +5,17 @@ Mapping Protocol ================ +See also :c:func:`PyObject_GetItem`, :c:func:`PyObject_SetItem` and +:c:func:`PyObject_DelItem`. + .. c:function:: int PyMapping_Check(PyObject *o) - Return ``1`` if the object provides mapping protocol, and ``0`` otherwise. This - function always succeeds. + Return ``1`` if the object provides mapping protocol or supports slicing, + and ``0`` otherwise. Note that it returns ``1`` for Python classes with + a :meth:`__getitem__` method since in general case it is impossible to + determine what the type of keys it supports. This function always + succeeds. .. c:function:: Py_ssize_t PyMapping_Size(PyObject *o) @@ -17,35 +23,49 @@ Mapping Protocol .. index:: builtin: len - Returns the number of keys in object *o* on success, and ``-1`` on failure. For - objects that do not provide mapping protocol, this is equivalent to the Python - expression ``len(o)``. + Returns the number of keys in object *o* on success, and ``-1`` on failure. + This is equivalent to the Python expression ``len(o)``. -.. c:function:: int PyMapping_DelItemString(PyObject *o, const char *key) +.. c:function:: PyObject* PyMapping_GetItemString(PyObject *o, const char *key) + + Return element of *o* corresponding to the string *key* or *NULL* on failure. + This is the equivalent of the Python expression ``o[key]``. + See also :c:func:`PyObject_GetItem`. + - Remove the mapping for object *key* from the object *o*. Return ``-1`` on - failure. This is equivalent to the Python statement ``del o[key]``. +.. c:function:: int PyMapping_SetItemString(PyObject *o, const char *key, PyObject *v) + + Map the string *key* to the value *v* in object *o*. Returns ``-1`` on + failure. This is the equivalent of the Python statement ``o[key] = v``. + See also :c:func:`PyObject_SetItem`. .. c:function:: int PyMapping_DelItem(PyObject *o, PyObject *key) - Remove the mapping for object *key* from the object *o*. Return ``-1`` on - failure. This is equivalent to the Python statement ``del o[key]``. + Remove the mapping for the object *key* from the object *o*. Return ``-1`` + on failure. This is equivalent to the Python statement ``del o[key]``. + This is an alias of :c:func:`PyObject_DelItem`. -.. c:function:: int PyMapping_HasKeyString(PyObject *o, const char *key) +.. c:function:: int PyMapping_DelItemString(PyObject *o, const char *key) - On success, return ``1`` if the mapping object has the key *key* and ``0`` - otherwise. This is equivalent to the Python expression ``key in o``. - This function always succeeds. + Remove the mapping for the string *key* from the object *o*. Return ``-1`` + on failure. This is equivalent to the Python statement ``del o[key]``. .. c:function:: int PyMapping_HasKey(PyObject *o, PyObject *key) - Return ``1`` if the mapping object has the key *key* and ``0`` otherwise. This - is equivalent to the Python expression ``key in o``. This function always - succeeds. + Return ``1`` if the mapping object has the key *key* and ``0`` otherwise. + This is equivalent to the Python expression ``key in o``. + This function always succeeds. + + +.. c:function:: int PyMapping_HasKeyString(PyObject *o, const char *key) + + Return ``1`` if the mapping object has the key *key* and ``0`` otherwise. + This is equivalent to the Python expression ``key in o``. + This function always succeeds. .. c:function:: PyObject* PyMapping_Keys(PyObject *o) @@ -73,15 +93,3 @@ Mapping Protocol .. versionchanged:: 3.7 Previously, the function returned a list or a tuple. - - -.. c:function:: PyObject* PyMapping_GetItemString(PyObject *o, const char *key) - - Return element of *o* corresponding to the object *key* or *NULL* on failure. - This is the equivalent of the Python expression ``o[key]``. - - -.. c:function:: int PyMapping_SetItemString(PyObject *o, const char *key, PyObject *v) - - Map the object *key* to the value *v* in object *o*. Returns ``-1`` on failure. - This is the equivalent of the Python statement ``o[key] = v``. diff --git a/Doc/c-api/object.rst b/Doc/c-api/object.rst index 754dedc..f0b2005 100644 --- a/Doc/c-api/object.rst +++ b/Doc/c-api/object.rst @@ -379,8 +379,8 @@ Object Protocol parameters must be non-*NULL*. -.. c:function:: Py_ssize_t PyObject_Length(PyObject *o) - Py_ssize_t PyObject_Size(PyObject *o) +.. c:function:: Py_ssize_t PyObject_Size(PyObject *o) + Py_ssize_t PyObject_Length(PyObject *o) .. index:: builtin: len @@ -414,8 +414,8 @@ Object Protocol .. c:function:: int PyObject_DelItem(PyObject *o, PyObject *key) - Delete the mapping for *key* from *o*. Returns ``-1`` on failure. This is the - equivalent of the Python statement ``del o[key]``. + Remove the mapping for the object *key* from the object *o*. Return ``-1`` + on failure. This is equivalent to the Python statement ``del o[key]``. .. c:function:: PyObject* PyObject_Dir(PyObject *o) diff --git a/Doc/c-api/sequence.rst b/Doc/c-api/sequence.rst index 81f8557..6d22f35 100644 --- a/Doc/c-api/sequence.rst +++ b/Doc/c-api/sequence.rst @@ -9,7 +9,10 @@ Sequence Protocol .. c:function:: int PySequence_Check(PyObject *o) Return ``1`` if the object provides sequence protocol, and ``0`` otherwise. - This function always succeeds. + Note that it returns ``1`` for Python classes with a :meth:`__getitem__` + method unless they are :class:`dict` subclasses since in general case it + is impossible to determine what the type of keys it supports. This + function always succeeds. .. c:function:: Py_ssize_t PySequence_Size(PyObject *o) @@ -119,18 +122,27 @@ Sequence Protocol .. index:: builtin: tuple - Return a tuple object with the same contents as the arbitrary sequence *o* or - *NULL* on failure. If *o* is a tuple, a new reference will be returned, + Return a tuple object with the same contents as the sequence or iterable *o*, + or *NULL* on failure. If *o* is a tuple, a new reference will be returned, otherwise a tuple will be constructed with the appropriate contents. This is equivalent to the Python expression ``tuple(o)``. .. c:function:: PyObject* PySequence_Fast(PyObject *o, const char *m) - Return the sequence *o* as a list, unless it is already a tuple or list, in + Return the sequence or iterable *o* as a list, unless it is already a tuple or list, in which case *o* is returned. Use :c:func:`PySequence_Fast_GET_ITEM` to access the members of the result. Returns *NULL* on failure. If the object is not - a sequence, raises :exc:`TypeError` with *m* as the message text. + a sequence or iterable, raises :exc:`TypeError` with *m* as the message text. + + +.. c:function:: Py_ssize_t PySequence_Fast_GET_SIZE(PyObject *o) + + Returns the length of *o*, assuming that *o* was returned by + :c:func:`PySequence_Fast` and that *o* is not *NULL*. The size can also be + gotten by calling :c:func:`PySequence_Size` on *o*, but + :c:func:`PySequence_Fast_GET_SIZE` is faster because it can assume *o* is a list + or tuple. .. c:function:: PyObject* PySequence_Fast_GET_ITEM(PyObject *o, Py_ssize_t i) @@ -155,12 +167,3 @@ Sequence Protocol :c:func:`PySequence_GetItem` but without checking that :c:func:`PySequence_Check` on *o* is true and without adjustment for negative indices. - - -.. c:function:: Py_ssize_t PySequence_Fast_GET_SIZE(PyObject *o) - - Returns the length of *o*, assuming that *o* was returned by - :c:func:`PySequence_Fast` and that *o* is not *NULL*. The size can also be - gotten by calling :c:func:`PySequence_Size` on *o*, but - :c:func:`PySequence_Fast_GET_SIZE` is faster because it can assume *o* is a list - or tuple. diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index 3bdf45a..6cbcc27 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -1167,21 +1167,24 @@ Mapping Object Structures .. c:member:: lenfunc PyMappingMethods.mp_length - This function is used by :c:func:`PyMapping_Length` and + This function is used by :c:func:`PyMapping_Size` and :c:func:`PyObject_Size`, and has the same signature. This slot may be set to *NULL* if the object has no defined length. .. c:member:: binaryfunc PyMappingMethods.mp_subscript - This function is used by :c:func:`PyObject_GetItem` and has the same - signature. This slot must be filled for the :c:func:`PyMapping_Check` - function to return ``1``, it can be *NULL* otherwise. + This function is used by :c:func:`PyObject_GetItem` and + :c:func:`PySequence_GetSlice`, and has the same signature as + :c:func:`!PyObject_GetItem`. This slot must be filled for the + :c:func:`PyMapping_Check` function to return ``1``, it can be *NULL* + otherwise. .. c:member:: objobjargproc PyMappingMethods.mp_ass_subscript - This function is used by :c:func:`PyObject_SetItem` and - :c:func:`PyObject_DelItem`. It has the same signature as - :c:func:`PyObject_SetItem`, but *v* can also be set to *NULL* to delete + This function is used by :c:func:`PyObject_SetItem`, + :c:func:`PyObject_DelItem`, :c:func:`PyObject_SetSlice` and + :c:func:`PyObject_DelSlice`. It has the same signature as + :c:func:`!PyObject_SetItem`, but *v* can also be set to *NULL* to delete an item. If this slot is *NULL*, the object does not support item assignment and deletion. @@ -1201,26 +1204,29 @@ Sequence Object Structures .. c:member:: lenfunc PySequenceMethods.sq_length - This function is used by :c:func:`PySequence_Size` and :c:func:`PyObject_Size`, - and has the same signature. + This function is used by :c:func:`PySequence_Size` and + :c:func:`PyObject_Size`, and has the same signature. It is also used for + handling negative indices via the :c:member:`~PySequenceMethods.sq_item` + and the :c:member:`~PySequenceMethods.sq_ass_item` slots. .. c:member:: binaryfunc PySequenceMethods.sq_concat This function is used by :c:func:`PySequence_Concat` and has the same signature. It is also used by the ``+`` operator, after trying the numeric - addition via the :c:member:`~PyTypeObject.tp_as_number.nb_add` slot. + addition via the :c:member:`~PyNumberMethods.nb_add` slot. .. c:member:: ssizeargfunc PySequenceMethods.sq_repeat This function is used by :c:func:`PySequence_Repeat` and has the same signature. It is also used by the ``*`` operator, after trying numeric - multiplication via the :c:member:`~PyTypeObject.tp_as_number.nb_multiply` - slot. + multiplication via the :c:member:`~PyNumberMethods.nb_multiply` slot. .. c:member:: ssizeargfunc PySequenceMethods.sq_item This function is used by :c:func:`PySequence_GetItem` and has the same - signature. This slot must be filled for the :c:func:`PySequence_Check` + signature. It is also used by :c:func:`PyObject_GetItem`, after trying + the subscription via the :c:member:`~PyMappingMethods.mp_subscript` slot. + This slot must be filled for the :c:func:`PySequence_Check` function to return ``1``, it can be *NULL* otherwise. Negative indexes are handled as follows: if the :attr:`sq_length` slot is @@ -1231,28 +1237,36 @@ Sequence Object Structures .. c:member:: ssizeobjargproc PySequenceMethods.sq_ass_item This function is used by :c:func:`PySequence_SetItem` and has the same - signature. This slot may be left to *NULL* if the object does not support + signature. It is also used by :c:func:`PyObject_SetItem` and + :c:func:`PyObject_DelItem`, after trying the item assignment and deletion + via the :c:member:`~PyMappingMethods.mp_ass_subscript` slot. + This slot may be left to *NULL* if the object does not support item assignment and deletion. .. c:member:: objobjproc PySequenceMethods.sq_contains This function may be used by :c:func:`PySequence_Contains` and has the same signature. This slot may be left to *NULL*, in this case - :c:func:`PySequence_Contains` simply traverses the sequence until it finds a - match. + :c:func:`!PySequence_Contains` simply traverses the sequence until it + finds a match. .. c:member:: binaryfunc PySequenceMethods.sq_inplace_concat This function is used by :c:func:`PySequence_InPlaceConcat` and has the same - signature. It should modify its first operand, and return it. + signature. It should modify its first operand, and return it. This slot + may be left to *NULL*, in this case :c:func:`!PySequence_InPlaceConcat` + will fall back to :c:func:`PySequence_Concat`. It is also used by the + augmented assignment ``+=``, after trying numeric inplace addition + via the :c:member:`~PyNumberMethods.nb_inplace_add` slot. .. c:member:: ssizeargfunc PySequenceMethods.sq_inplace_repeat This function is used by :c:func:`PySequence_InPlaceRepeat` and has the same - signature. It should modify its first operand, and return it. - -.. XXX need to explain precedence between mapping and sequence -.. XXX explains when to implement the sq_inplace_* slots + signature. It should modify its first operand, and return it. This slot + may be left to *NULL*, in this case :c:func:`!PySequence_InPlaceRepeat` + will fall back to :c:func:`PySequence_Repeat`. It is also used by the + augmented assignment ``*=``, after trying numeric inplace multiplication + via the :c:member:`~PyNumberMethods.nb_inplace_multiply` slot. .. _buffer-structs: diff --git a/Include/abstract.h b/Include/abstract.h index 3133cd1..4088f75 100644 --- a/Include/abstract.h +++ b/Include/abstract.h @@ -442,13 +442,14 @@ PyAPI_FUNC(PyObject *) PyObject_GetItem(PyObject *o, PyObject *key); This is the equivalent of the Python statement: o[key]=v. */ PyAPI_FUNC(int) PyObject_SetItem(PyObject *o, PyObject *key, PyObject *v); -/* Remove the mapping for object, key, from the object 'o'. +/* Remove the mapping for the string 'key' from the object 'o'. Returns -1 on failure. This is equivalent to the Python statement: del o[key]. */ PyAPI_FUNC(int) PyObject_DelItemString(PyObject *o, const char *key); -/* Delete the mapping for key from object 'o'. Returns -1 on failure. +/* Delete the mapping for the object 'key' from the object 'o'. + Returns -1 on failure. This is the equivalent of the Python statement: del o[key]. */ PyAPI_FUNC(int) PyObject_DelItem(PyObject *o, PyObject *key); @@ -1005,8 +1006,7 @@ PyAPI_FUNC(PyObject *) PySequence_InPlaceRepeat(PyObject *o, Py_ssize_t count); PyAPI_FUNC(int) PyMapping_Check(PyObject *o); /* Returns the number of keys in mapping object 'o' on success, and -1 on - failure. For objects that do not provide sequence protocol, this is - equivalent to the Python expression: len(o). */ + failure. This is equivalent to the Python expression: len(o). */ PyAPI_FUNC(Py_ssize_t) PyMapping_Size(PyObject *o); /* For DLL compatibility */ @@ -1019,7 +1019,7 @@ PyAPI_FUNC(Py_ssize_t) PyMapping_Length(PyObject *o); int PyMapping_DelItemString(PyObject *o, const char *key); - Remove the mapping for object 'key' from the mapping 'o'. Returns -1 on + Remove the mapping for the string 'key' from the mapping 'o'. Returns -1 on failure. This is equivalent to the Python statement: del o[key]. */ @@ -1029,7 +1029,7 @@ PyAPI_FUNC(Py_ssize_t) PyMapping_Length(PyObject *o); int PyMapping_DelItem(PyObject *o, PyObject *key); - Remove the mapping for object 'key' from the mapping object 'o'. + Remove the mapping for the object 'key' from the mapping object 'o'. Returns -1 on failure. This is equivalent to the Python statement: del o[key]. */ @@ -1063,13 +1063,13 @@ PyAPI_FUNC(PyObject *) PyMapping_Values(PyObject *o); NULL. */ PyAPI_FUNC(PyObject *) PyMapping_Items(PyObject *o); -/* Return element of o corresponding to the object, key, or NULL on failure. +/* Return element of 'o' corresponding to the string 'key' or NULL on failure. This is the equivalent of the Python expression: o[key]. */ PyAPI_FUNC(PyObject *) PyMapping_GetItemString(PyObject *o, const char *key); -/* Map the object 'key' to the value 'v' in the mapping 'o'. +/* Map the string 'key' to the value 'v' in the mapping 'o'. Returns -1 on failure. This is the equivalent of the Python statement: o[key]=v. */ -- cgit v0.12