Skip to content

Commit ed82604

Browse files
committed
Issue python#25701: Document that some C APIs can both set and delete items
Also document that using the dedicated functions to delete items is preferred. Using PyObject_SetAttr/String() and PySequence_SetItem/Slice() for deletion is deprecated.
1 parent a52b567 commit ed82604

File tree

4 files changed

+57
-32
lines changed

4 files changed

+57
-32
lines changed

Doc/c-api/object.rst

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,25 +55,35 @@ Object Protocol
5555
.. c:function:: int PyObject_SetAttr(PyObject *o, PyObject *attr_name, PyObject *v)
5656
5757
Set the value of the attribute named *attr_name*, for object *o*, to the value
58-
*v*. Returns ``-1`` on failure. This is the equivalent of the Python statement
58+
*v*. Raise an exception and return ``-1`` on failure;
59+
return ``0`` on success. This is the equivalent of the Python statement
5960
``o.attr_name = v``.
6061
62+
If *v* is *NULL*, the attribute is deleted, however this feature is
63+
deprecated in favour of using :c:func:`PyObject_DelAttr`.
64+
6165
6266
.. c:function:: int PyObject_SetAttrString(PyObject *o, const char *attr_name, PyObject *v)
6367
6468
Set the value of the attribute named *attr_name*, for object *o*, to the value
65-
*v*. Returns ``-1`` on failure. This is the equivalent of the Python statement
69+
*v*. Raise an exception and return ``-1`` on failure;
70+
return ``0`` on success. This is the equivalent of the Python statement
6671
``o.attr_name = v``.
6772
73+
If *v* is *NULL*, the attribute is deleted, however this feature is
74+
deprecated in favour of using :c:func:`PyObject_DelAttrString`.
75+
6876
6977
.. c:function:: int PyObject_GenericSetAttr(PyObject *o, PyObject *name, PyObject *value)
7078
71-
Generic attribute setter function that is meant to be put into a type
72-
object's ``tp_setattro`` slot. It looks for a data descriptor in the
79+
Generic attribute setter and deleter function that is meant
80+
to be put into a type object's :c:member:`~PyTypeObject.tp_setattro`
81+
slot. It looks for a data descriptor in the
7382
dictionary of classes in the object's MRO, and if found it takes preference
74-
over setting the attribute in the instance dictionary. Otherwise, the
75-
attribute is set in the object's :attr:`~object.__dict__` (if present).
76-
Otherwise, an :exc:`AttributeError` is raised and ``-1`` is returned.
83+
over setting or deleting the attribute in the instance dictionary. Otherwise, the
84+
attribute is set or deleted in the object's :attr:`~object.__dict__` (if present).
85+
On success, ``0`` is returned, otherwise an :exc:`AttributeError`
86+
is raised and ``-1`` is returned.
7787
7888
7989
.. c:function:: int PyObject_DelAttr(PyObject *o, PyObject *attr_name)
@@ -367,7 +377,8 @@ attribute is considered sufficient for this determination.
367377
368378
.. c:function:: int PyObject_SetItem(PyObject *o, PyObject *key, PyObject *v)
369379
370-
Map the object *key* to the value *v*. Returns ``-1`` on failure. This is the
380+
Map the object *key* to the value *v*. Raise an exception and
381+
return ``-1`` on failure; return ``0`` on success. This is the
371382
equivalent of the Python statement ``o[key] = v``.
372383
373384

Doc/c-api/sequence.rst

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,14 @@ Sequence Protocol
8282
8383
.. c:function:: int PySequence_SetItem(PyObject *o, Py_ssize_t i, PyObject *v)
8484
85-
Assign object *v* to the *i*\ th element of *o*. Returns ``-1`` on failure. This
85+
Assign object *v* to the *i*\ th element of *o*. Raise an exception
86+
and return ``-1`` on failure; return ``0`` on success. This
8687
is the equivalent of the Python statement ``o[i] = v``. This function *does
8788
not* steal a reference to *v*.
8889
90+
If *v* is *NULL*, the element is deleted, however this feature is
91+
deprecated in favour of using :c:func:`PySequence_DelItem`.
92+
8993
.. versionchanged:: 2.5
9094
This function used an :c:type:`int` type for *i*. This might require
9195
changes in your code for properly supporting 64-bit systems.
@@ -104,7 +108,11 @@ Sequence Protocol
104108
.. c:function:: int PySequence_SetSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2, PyObject *v)
105109
106110
Assign the sequence object *v* to the slice in sequence object *o* from *i1* to
107-
*i2*. This is the equivalent of the Python statement ``o[i1:i2] = v``.
111+
*i2*. Raise an exception and return ``-1`` on failure; return ``0`` on success.
112+
This is the equivalent of the Python statement ``o[i1:i2] = v``.
113+
114+
If *v* is *NULL*, the slice is deleted, however this feature is
115+
deprecated in favour of using :c:func:`PySequence_DelSlice`.
108116
109117
.. versionchanged:: 2.5
110118
This function used an :c:type:`int` type for *i1* and *i2*. This might

Doc/c-api/typeobj.rst

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -240,12 +240,13 @@ type objects) *must* have the :attr:`ob_size` field.
240240

241241
.. c:member:: setattrfunc PyTypeObject.tp_setattr
242242
243-
An optional pointer to the set-attribute-string function.
243+
An optional pointer to the function for setting and deleting attributes.
244244

245245
This field is deprecated. When it is defined, it should point to a function
246246
that acts the same as the :c:member:`~PyTypeObject.tp_setattro` function, but taking a C string
247247
instead of a Python string object to give the attribute name. The signature is
248-
the same as for :c:func:`PyObject_SetAttrString`.
248+
the same as for :c:func:`PyObject_SetAttrString`, but setting
249+
*v* to *NULL* to delete an attribute must be supported.
249250

250251
This field is inherited by subtypes together with :c:member:`~PyTypeObject.tp_setattro`: a subtype
251252
inherits both :c:member:`~PyTypeObject.tp_setattr` and :c:member:`~PyTypeObject.tp_setattro` from its base type when
@@ -389,9 +390,10 @@ type objects) *must* have the :attr:`ob_size` field.
389390

390391
.. c:member:: setattrofunc PyTypeObject.tp_setattro
391392
392-
An optional pointer to the set-attribute function.
393+
An optional pointer to the function for setting and deleting attributes.
393394

394-
The signature is the same as for :c:func:`PyObject_SetAttr`. It is usually
395+
The signature is the same as for :c:func:`PyObject_SetAttr`, but setting
396+
*v* to *NULL* to delete an attribute must be supported. It is usually
395397
convenient to set this field to :c:func:`PyObject_GenericSetAttr`, which
396398
implements the normal way of setting object attributes.
397399

@@ -831,7 +833,7 @@ The next fields, up to and including :c:member:`~PyTypeObject.tp_weaklist`, only
831833
typedef struct PyGetSetDef {
832834
char *name; /* attribute name */
833835
getter get; /* C function to get the attribute */
834-
setter set; /* C function to set the attribute */
836+
setter set; /* C function to set or delete the attribute */
835837
char *doc; /* optional doc string */
836838
void *closure; /* optional additional data for getter and setter */
837839
} PyGetSetDef;
@@ -877,12 +879,14 @@ The next fields, up to and including :c:member:`~PyTypeObject.tp_weaklist`, only
877879

878880
.. c:member:: descrsetfunc PyTypeObject.tp_descr_set
879881
880-
An optional pointer to a "descriptor set" function.
882+
An optional pointer to a function for setting and deleting
883+
a descriptor's value.
881884

882885
The function signature is ::
883886

884887
int tp_descr_set(PyObject *self, PyObject *obj, PyObject *value);
885888

889+
The *value* argument is set to *NULL* to delete the value.
886890
This field is inherited by subtypes.
887891

888892
.. XXX explain.
@@ -1263,9 +1267,11 @@ Mapping Object Structures
12631267

12641268
.. c:member:: objobjargproc PyMappingMethods.mp_ass_subscript
12651269
1266-
This function is used by :c:func:`PyObject_SetItem` and has the same
1267-
signature. If this slot is *NULL*, the object does not support item
1268-
assignment.
1270+
This function is used by :c:func:`PyObject_SetItem` and
1271+
:c:func:`PyObject_DelItem`. It has the same signature as
1272+
:c:func:`PyObject_SetItem`, but *v* can also be set to *NULL* to delete
1273+
an item. If this slot is *NULL*, the object does not support item
1274+
assignment and deletion.
12691275

12701276

12711277
.. _sequence-structs:
@@ -1314,7 +1320,7 @@ Sequence Object Structures
13141320
13151321
This function is used by :c:func:`PySequence_SetItem` and has the same
13161322
signature. This slot may be left to *NULL* if the object does not support
1317-
item assignment.
1323+
item assignment and deletion.
13181324

13191325
.. c:member:: objobjproc PySequenceMethods.sq_contains
13201326

Include/abstract.h

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -191,8 +191,8 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
191191
int PyObject_SetAttrString(PyObject *o, char *attr_name, PyObject *v);
192192
193193
Set the value of the attribute named attr_name, for object o,
194-
to the value, v. Returns -1 on failure. This is
195-
the equivalent of the Python statement: o.attr_name=v.
194+
to the value v. Raise an exception and return -1 on failure; return 0 on
195+
success. This is the equivalent of the Python statement o.attr_name=v.
196196
197197
*/
198198

@@ -201,8 +201,8 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
201201
int PyObject_SetAttr(PyObject *o, PyObject *attr_name, PyObject *v);
202202
203203
Set the value of the attribute named attr_name, for object o,
204-
to the value, v. Returns -1 on failure. This is
205-
the equivalent of the Python statement: o.attr_name=v.
204+
to the value v. Raise an exception and return -1 on failure; return 0 on
205+
success. This is the equivalent of the Python statement o.attr_name=v.
206206
207207
*/
208208

@@ -453,9 +453,9 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
453453
PyAPI_FUNC(int) PyObject_SetItem(PyObject *o, PyObject *key, PyObject *v);
454454

455455
/*
456-
Map the object, key, to the value, v. Returns
457-
-1 on failure. This is the equivalent of the Python
458-
statement: o[key]=v.
456+
Map the object key to the value v. Raise an exception and return -1
457+
on failure; return 0 on success. This is the equivalent of the Python
458+
statement o[key]=v.
459459
*/
460460

461461
PyAPI_FUNC(int) PyObject_DelItemString(PyObject *o, char *key);
@@ -1102,10 +1102,9 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
11021102
PyAPI_FUNC(int) PySequence_SetItem(PyObject *o, Py_ssize_t i, PyObject *v);
11031103

11041104
/*
1105-
Assign object v to the ith element of o. Returns
1106-
-1 on failure. This is the equivalent of the Python
1107-
statement: o[i]=v.
1108-
1105+
Assign object v to the ith element of o. Raise an exception and return
1106+
-1 on failure; return 0 on success. This is the equivalent of the
1107+
Python statement o[i]=v.
11091108
*/
11101109

11111110
PyAPI_FUNC(int) PySequence_DelItem(PyObject *o, Py_ssize_t i);
@@ -1121,7 +1120,8 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
11211120

11221121
/*
11231122
Assign the sequence object, v, to the slice in sequence
1124-
object, o, from i1 to i2. Returns -1 on failure. This is the
1123+
object, o, from i1 to i2. Raise an exception and return
1124+
-1 on failure; return 0 on success. This is the
11251125
equivalent of the Python statement: o[i1:i2]=v.
11261126
*/
11271127

0 commit comments

Comments
 (0)