diff -r ac0f7ed0e94d Doc/whatsnew/3.6.rst --- a/Doc/whatsnew/3.6.rst Tue Dec 01 00:40:50 2015 +0200 +++ b/Doc/whatsnew/3.6.rst Tue Dec 01 16:47:30 2015 +0200 @@ -195,7 +195,13 @@ Deprecated Python modules, functions and Deprecated functions and types of the C API ------------------------------------------- -* None yet. +* Deprecated deleting attributes with :c:func:`PyObject_SetAttr` and + :c:func:`PyObject_SetAttrString` and deleting items with + :c:func:`PySequence_SetItem`. Use :c:func:`PyObject_DelAttr`, + :c:func:`PyObject_DelAttrString` and :c:func:`PySequence_DelItem` instead. + ``PyObject_DelAttr()`` and ``PyObject_DelAttrString()`` now are implemented + as functions, not macros. + (Contributed by Serhiy Storchaka in :issue:`XXXXX`.) Deprecated features diff -r ac0f7ed0e94d Include/abstract.h --- a/Include/abstract.h Tue Dec 01 00:40:50 2015 +0200 +++ b/Include/abstract.h Tue Dec 01 16:47:30 2015 +0200 @@ -207,7 +207,7 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx */ - /* implemented as a macro: + /* Implemented elsewhere: int PyObject_DelAttrString(PyObject *o, const char *attr_name); @@ -216,9 +216,8 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx statement: del o.attr_name. */ -#define PyObject_DelAttrString(O,A) PyObject_SetAttrString((O),(A),NULL) - /* implemented as a macro: + /* Implemented elsewhere: int PyObject_DelAttr(PyObject *o, PyObject *attr_name); @@ -227,7 +226,6 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx statement: del o.attr_name. */ -#define PyObject_DelAttr(O,A) PyObject_SetAttr((O),(A),NULL) /* Implemented elsewhere: diff -r ac0f7ed0e94d Include/object.h --- a/Include/object.h Tue Dec 01 00:40:50 2015 +0200 +++ b/Include/object.h Tue Dec 01 16:47:30 2015 +0200 @@ -526,9 +526,11 @@ PyAPI_FUNC(PyObject *) PyObject_RichComp PyAPI_FUNC(int) PyObject_RichCompareBool(PyObject *, PyObject *, int); PyAPI_FUNC(PyObject *) PyObject_GetAttrString(PyObject *, const char *); PyAPI_FUNC(int) PyObject_SetAttrString(PyObject *, const char *, PyObject *); +PyAPI_FUNC(int) PyObject_DelAttrString(PyObject *, const char *); PyAPI_FUNC(int) PyObject_HasAttrString(PyObject *, const char *); PyAPI_FUNC(PyObject *) PyObject_GetAttr(PyObject *, PyObject *); PyAPI_FUNC(int) PyObject_SetAttr(PyObject *, PyObject *, PyObject *); +PyAPI_FUNC(int) PyObject_DelAttr(PyObject *, PyObject *); PyAPI_FUNC(int) PyObject_HasAttr(PyObject *, PyObject *); PyAPI_FUNC(int) _PyObject_IsAbstract(PyObject *); PyAPI_FUNC(PyObject *) _PyObject_GetAttrId(PyObject *, struct _Py_Identifier *); diff -r ac0f7ed0e94d Misc/NEWS --- a/Misc/NEWS Tue Dec 01 00:40:50 2015 +0200 +++ b/Misc/NEWS Tue Dec 01 16:47:30 2015 +0200 @@ -326,6 +326,15 @@ Library - Issue #25319: When threading.Event is reinitialized, the underlying condition should use a regular lock rather than a recursive lock. +C API +----- + +- Issue #.....: Deprecated deleting attributes with PyObject_SetAttr() and + PyObject_SetAttrString() and deleting items with PySequence_SetItem(). + Use PyObject_DelAttr(), PyObject_DelAttrString() and PySequence_DelItem() + instead. PyObject_DelAttr and PyObject_DelAttrString now are implemented as + functions, not macros. + IDLE ---- diff -r ac0f7ed0e94d Objects/abstract.c --- a/Objects/abstract.c Tue Dec 01 00:40:50 2015 +0200 +++ b/Objects/abstract.c Tue Dec 01 16:47:30 2015 +0200 @@ -1591,6 +1591,12 @@ PySequence_SetItem(PyObject *s, Py_ssize return -1; } + if (o == NULL && + PyErr_WarnEx(PyExc_DeprecationWarning, + "Deleting with PySequence_SetItem) is deprecated. " + "Use PySequence_DelItem() instead.", 1) < 0) + return -1; + m = s->ob_type->tp_as_sequence; if (m && m->sq_ass_item) { if (i < 0) { diff -r ac0f7ed0e94d Objects/object.c --- a/Objects/object.c Tue Dec 01 00:40:50 2015 +0200 +++ b/Objects/object.c Tue Dec 01 16:47:30 2015 +0200 @@ -802,8 +802,10 @@ PyObject_HasAttrString(PyObject *v, cons return 0; } -int -PyObject_SetAttrString(PyObject *v, const char *name, PyObject *w) +static int _PyObject_SetDelAttr(PyObject *, PyObject *, PyObject *); + +static int +_PyObject_SetDelAttrString(PyObject *v, const char *name, PyObject *w) { PyObject *s; int res; @@ -813,12 +815,29 @@ PyObject_SetAttrString(PyObject *v, cons s = PyUnicode_InternFromString(name); if (s == NULL) return -1; - res = PyObject_SetAttr(v, s, w); + res = _PyObject_SetDelAttr(v, s, w); Py_XDECREF(s); return res; } int +PyObject_SetAttrString(PyObject *v, const char *name, PyObject *value) +{ + if (value == NULL && + PyErr_WarnEx(PyExc_DeprecationWarning, + "Deleting with PyObject_SetAttrString() is deprecated. " + "Use PyObject_DelAttrString() instead.", 1) < 0) + return -1; + return _PyObject_SetDelAttrString(v, name, value); +} + +int +PyObject_DelAttrString(PyObject *v, const char *name) +{ + return _PyObject_SetDelAttrString(v, name, NULL); +} + +int _PyObject_IsAbstract(PyObject *obj) { int res; @@ -910,8 +929,8 @@ PyObject_HasAttr(PyObject *v, PyObject * return 0; } -int -PyObject_SetAttr(PyObject *v, PyObject *name, PyObject *value) +static int +_PyObject_SetDelAttr(PyObject *v, PyObject *name, PyObject *value) { PyTypeObject *tp = Py_TYPE(v); int err; @@ -957,6 +976,23 @@ PyObject_SetAttr(PyObject *v, PyObject * return -1; } +int +PyObject_SetAttr(PyObject *v, PyObject *name, PyObject *value) +{ + if (value == NULL && + PyErr_WarnEx(PyExc_DeprecationWarning, + "Deleting with PyObject_SetAttr() is deprecated. " + "Use PyObject_DelAttr() instead.", 1) < 0) + return -1; + return _PyObject_SetDelAttr(v, name, value); +} + +int +PyObject_DelAttr(PyObject *v, PyObject *name) +{ + return _PyObject_SetDelAttr(v, name, NULL); +} + /* Helper to get a pointer to an object's __dict__ slot, if any */ PyObject ** diff -r ac0f7ed0e94d Objects/weakrefobject.c --- a/Objects/weakrefobject.c Tue Dec 01 00:40:50 2015 +0200 +++ b/Objects/weakrefobject.c Tue Dec 01 16:47:30 2015 +0200 @@ -477,6 +477,8 @@ proxy_setattr(PyWeakReference *proxy, Py { if (!proxy_checkref(proxy)) return -1; + if (value == NULL) + return PyObject_DelAttr(PyWeakref_GET_OBJECT(proxy), name); return PyObject_SetAttr(PyWeakref_GET_OBJECT(proxy), name, value); } diff -r ac0f7ed0e94d Python/bltinmodule.c --- a/Python/bltinmodule.c Tue Dec 01 00:40:50 2015 +0200 +++ b/Python/bltinmodule.c Tue Dec 01 16:47:30 2015 +0200 @@ -1352,7 +1352,7 @@ static PyObject * builtin_delattr_impl(PyModuleDef *module, PyObject *obj, PyObject *name) /*[clinic end generated code: output=ef653e698a0b4187 input=db16685d6b4b9410]*/ { - if (PyObject_SetAttr(obj, name, (PyObject *)NULL) != 0) + if (PyObject_DelAttr(obj, name) != 0) return NULL; Py_INCREF(Py_None); return Py_None; diff -r ac0f7ed0e94d Python/ceval.c --- a/Python/ceval.c Tue Dec 01 00:40:50 2015 +0200 +++ b/Python/ceval.c Tue Dec 01 16:47:30 2015 +0200 @@ -2262,7 +2262,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int PyObject *name = GETITEM(names, oparg); PyObject *owner = POP(); int err; - err = PyObject_SetAttr(owner, name, (PyObject *)NULL); + err = PyObject_DelAttr(owner, name); Py_DECREF(owner); if (err != 0) goto error;