mirror of https://github.com/python/cpython
Issue #24348: Drop superfluous increfs/decrefs.
This commit is contained in:
parent
a762af74b2
commit
d171975609
|
@ -2055,6 +2055,18 @@ class CPythonOrderedDictTests(OrderedDictTests, unittest.TestCase):
|
||||||
with self.assertRaises(KeyError):
|
with self.assertRaises(KeyError):
|
||||||
od.copy()
|
od.copy()
|
||||||
|
|
||||||
|
def test_issue24348(self):
|
||||||
|
OrderedDict = self.module.OrderedDict
|
||||||
|
|
||||||
|
class Key:
|
||||||
|
def __hash__(self):
|
||||||
|
return 1
|
||||||
|
|
||||||
|
od = OrderedDict()
|
||||||
|
od[Key()] = 0
|
||||||
|
# This should not crash.
|
||||||
|
od.popitem()
|
||||||
|
|
||||||
|
|
||||||
class PurePythonGeneralMappingTests(mapping_tests.BasicTestMappingProtocol):
|
class PurePythonGeneralMappingTests(mapping_tests.BasicTestMappingProtocol):
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,8 @@ Library
|
||||||
|
|
||||||
- Issue #24347: Set KeyError if PyDict_GetItemWithError returns NULL.
|
- Issue #24347: Set KeyError if PyDict_GetItemWithError returns NULL.
|
||||||
|
|
||||||
|
- Issue #24348: Drop superfluous incref/decref.
|
||||||
|
|
||||||
|
|
||||||
What's New in Python 3.5.0 beta 2?
|
What's New in Python 3.5.0 beta 2?
|
||||||
==================================
|
==================================
|
||||||
|
|
|
@ -1073,36 +1073,32 @@ PyDoc_STRVAR(odict_setdefault__doc__,
|
||||||
static PyObject *
|
static PyObject *
|
||||||
odict_setdefault(register PyODictObject *od, PyObject *args)
|
odict_setdefault(register PyODictObject *od, PyObject *args)
|
||||||
{
|
{
|
||||||
_ODictNode *node;
|
|
||||||
PyObject *key, *result = NULL;
|
PyObject *key, *result = NULL;
|
||||||
PyObject *failobj = Py_None;
|
PyObject *failobj = Py_None;
|
||||||
|
|
||||||
/* both borrowed */
|
/* both borrowed */
|
||||||
if (!PyArg_UnpackTuple(args, "setdefault", 1, 2, &key, &failobj))
|
if (!PyArg_UnpackTuple(args, "setdefault", 1, 2, &key, &failobj))
|
||||||
return NULL;
|
return NULL;
|
||||||
Py_INCREF(key);
|
|
||||||
Py_INCREF(failobj);
|
|
||||||
|
|
||||||
if (PyODict_CheckExact(od)) {
|
if (PyODict_CheckExact(od)) {
|
||||||
node = _odict_find_node(od, key);
|
result = PyODict_GetItemWithError(od, key); /* borrowed */
|
||||||
if (node == NULL) {
|
if (result == NULL) {
|
||||||
if (PyErr_Occurred()) {
|
if (PyErr_Occurred())
|
||||||
goto done;
|
return NULL;
|
||||||
}
|
assert(_odict_find_node(od, key) == NULL);
|
||||||
else if (PyODict_SetItem((PyObject *)od, key, failobj) >= 0) {
|
if (PyODict_SetItem((PyObject *)od, key, failobj) >= 0) {
|
||||||
result = failobj;
|
result = failobj;
|
||||||
Py_INCREF(failobj);
|
Py_INCREF(failobj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
result = PyODict_GetItem(od, key); /* borrowed reference */
|
Py_INCREF(result);
|
||||||
Py_XINCREF(result);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int exists = PySequence_Contains((PyObject *)od, key);
|
int exists = PySequence_Contains((PyObject *)od, key);
|
||||||
if (exists < 0) {
|
if (exists < 0) {
|
||||||
goto done;
|
return NULL;
|
||||||
}
|
}
|
||||||
else if (exists) {
|
else if (exists) {
|
||||||
result = PyObject_GetItem((PyObject *)od, key);
|
result = PyObject_GetItem((PyObject *)od, key);
|
||||||
|
@ -1113,9 +1109,6 @@ odict_setdefault(register PyODictObject *od, PyObject *args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
|
||||||
Py_DECREF(failobj);
|
|
||||||
Py_DECREF(key);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1150,21 +1143,18 @@ _odict_popkey(PyObject *od, PyObject *key, PyObject *failobj)
|
||||||
_ODictNode *node;
|
_ODictNode *node;
|
||||||
PyObject *value = NULL;
|
PyObject *value = NULL;
|
||||||
|
|
||||||
Py_INCREF(key);
|
|
||||||
Py_XINCREF(failobj);
|
|
||||||
|
|
||||||
/* Pop the node first to avoid a possible dict resize (due to
|
/* Pop the node first to avoid a possible dict resize (due to
|
||||||
eval loop reentrancy) and complications due to hash collision
|
eval loop reentrancy) and complications due to hash collision
|
||||||
resolution. */
|
resolution. */
|
||||||
node = _odict_find_node((PyODictObject *)od, key);
|
node = _odict_find_node((PyODictObject *)od, key);
|
||||||
if (node == NULL) {
|
if (node == NULL) {
|
||||||
if (PyErr_Occurred())
|
if (PyErr_Occurred())
|
||||||
goto done;
|
return NULL;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int res = _odict_clear_node((PyODictObject *)od, node, key);
|
int res = _odict_clear_node((PyODictObject *)od, node, key);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
goto done;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1178,7 +1168,7 @@ _odict_popkey(PyObject *od, PyObject *key, PyObject *failobj)
|
||||||
else {
|
else {
|
||||||
int exists = PySequence_Contains(od, key);
|
int exists = PySequence_Contains(od, key);
|
||||||
if (exists < 0)
|
if (exists < 0)
|
||||||
goto done;
|
return NULL;
|
||||||
if (exists) {
|
if (exists) {
|
||||||
value = PyObject_GetItem(od, key);
|
value = PyObject_GetItem(od, key);
|
||||||
if (value != NULL) {
|
if (value != NULL) {
|
||||||
|
@ -1200,9 +1190,6 @@ _odict_popkey(PyObject *od, PyObject *key, PyObject *failobj)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
|
||||||
Py_DECREF(key);
|
|
||||||
Py_XDECREF(failobj);
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1229,19 +1216,19 @@ odict_popitem(PyObject *od, PyObject *args)
|
||||||
|
|
||||||
if (!PyArg_UnpackTuple(args, "popitem", 0, 1, &last)) /* borrowed */
|
if (!PyArg_UnpackTuple(args, "popitem", 0, 1, &last)) /* borrowed */
|
||||||
return NULL;
|
return NULL;
|
||||||
Py_XINCREF(last);
|
|
||||||
|
|
||||||
if (last == NULL || last == Py_True)
|
if (last == NULL || last == Py_True)
|
||||||
node = _odict_LAST((PyODictObject *)od);
|
node = _odict_LAST((PyODictObject *)od);
|
||||||
else
|
else
|
||||||
node = _odict_FIRST((PyODictObject *)od);
|
node = _odict_FIRST((PyODictObject *)od);
|
||||||
Py_XDECREF(last);
|
|
||||||
|
|
||||||
key = _odictnode_KEY(node);
|
key = _odictnode_KEY(node);
|
||||||
|
Py_INCREF(key);
|
||||||
value = _odict_popkey(od, key, NULL);
|
value = _odict_popkey(od, key, NULL);
|
||||||
if (value == NULL)
|
if (value == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
item = PyTuple_Pack(2, key, value);
|
item = PyTuple_Pack(2, key, value);
|
||||||
|
Py_DECREF(key);
|
||||||
Py_DECREF(value);
|
Py_DECREF(value);
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
@ -1381,17 +1368,13 @@ odict_move_to_end(PyODictObject *od, PyObject *args)
|
||||||
/* both borrowed */
|
/* both borrowed */
|
||||||
if (!PyArg_UnpackTuple(args, "move_to_end", 1, 2, &key, &last))
|
if (!PyArg_UnpackTuple(args, "move_to_end", 1, 2, &key, &last))
|
||||||
return NULL;
|
return NULL;
|
||||||
Py_INCREF(key);
|
|
||||||
if (_odict_EMPTY(od)) {
|
if (_odict_EMPTY(od)) {
|
||||||
PyErr_SetObject(PyExc_KeyError, key);
|
PyErr_SetObject(PyExc_KeyError, key);
|
||||||
Py_DECREF(key);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (last != NULL) {
|
if (last != NULL) {
|
||||||
int is_true;
|
int is_true;
|
||||||
Py_INCREF(last);
|
|
||||||
is_true = PyObject_IsTrue(last);
|
is_true = PyObject_IsTrue(last);
|
||||||
Py_DECREF(last);
|
|
||||||
if (is_true == -1)
|
if (is_true == -1)
|
||||||
return NULL;
|
return NULL;
|
||||||
pos = is_true ? -1 : 0;
|
pos = is_true ? -1 : 0;
|
||||||
|
@ -1410,7 +1393,6 @@ odict_move_to_end(PyODictObject *od, PyObject *args)
|
||||||
else {
|
else {
|
||||||
if (!PyErr_Occurred())
|
if (!PyErr_Occurred())
|
||||||
PyErr_SetObject(PyExc_KeyError, key);
|
PyErr_SetObject(PyExc_KeyError, key);
|
||||||
Py_DECREF(key);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1429,12 +1411,10 @@ odict_move_to_end(PyODictObject *od, PyObject *args)
|
||||||
else {
|
else {
|
||||||
if (!PyErr_Occurred())
|
if (!PyErr_Occurred())
|
||||||
PyErr_SetObject(PyExc_KeyError, key);
|
PyErr_SetObject(PyExc_KeyError, key);
|
||||||
Py_DECREF(key);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Py_DECREF(key);
|
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue