mirror of https://github.com/python/cpython
Issue #24368: Support keyword arguments in OrderedDict methods.
This commit is contained in:
parent
eb698fe68c
commit
ac02ef373f
|
@ -1696,6 +1696,15 @@ class OrderedDictTests:
|
||||||
self.assertRaises(TypeError, OrderedDict().update, (), ())
|
self.assertRaises(TypeError, OrderedDict().update, (), ())
|
||||||
self.assertRaises(TypeError, OrderedDict.update)
|
self.assertRaises(TypeError, OrderedDict.update)
|
||||||
|
|
||||||
|
def test_fromkeys(self):
|
||||||
|
OrderedDict = self.module.OrderedDict
|
||||||
|
od = OrderedDict.fromkeys('abc')
|
||||||
|
self.assertEqual(list(od.items()), [(c, None) for c in 'abc'])
|
||||||
|
od = OrderedDict.fromkeys('abc', value=None)
|
||||||
|
self.assertEqual(list(od.items()), [(c, None) for c in 'abc'])
|
||||||
|
od = OrderedDict.fromkeys('abc', value=0)
|
||||||
|
self.assertEqual(list(od.items()), [(c, 0) for c in 'abc'])
|
||||||
|
|
||||||
def test_abc(self):
|
def test_abc(self):
|
||||||
OrderedDict = self.module.OrderedDict
|
OrderedDict = self.module.OrderedDict
|
||||||
self.assertIsInstance(OrderedDict(), MutableMapping)
|
self.assertIsInstance(OrderedDict(), MutableMapping)
|
||||||
|
@ -1801,7 +1810,8 @@ class OrderedDictTests:
|
||||||
for i in range(8):
|
for i in range(8):
|
||||||
obj.popitem(True)
|
obj.popitem(True)
|
||||||
obj.popitem(True)
|
obj.popitem(True)
|
||||||
self.assertEqual(len(obj), 21)
|
obj.popitem(last=True)
|
||||||
|
self.assertEqual(len(obj), 20)
|
||||||
|
|
||||||
def test_pop(self):
|
def test_pop(self):
|
||||||
OrderedDict = self.module.OrderedDict
|
OrderedDict = self.module.OrderedDict
|
||||||
|
@ -1825,6 +1835,7 @@ class OrderedDictTests:
|
||||||
self.assertEqual(m.pop('b', 5), 5)
|
self.assertEqual(m.pop('b', 5), 5)
|
||||||
self.assertEqual(m.pop('a', 6), 1)
|
self.assertEqual(m.pop('a', 6), 1)
|
||||||
self.assertEqual(m.pop('a', 6), 6)
|
self.assertEqual(m.pop('a', 6), 6)
|
||||||
|
self.assertEqual(m.pop('a', default=6), 6)
|
||||||
with self.assertRaises(KeyError):
|
with self.assertRaises(KeyError):
|
||||||
m.pop('a')
|
m.pop('a')
|
||||||
|
|
||||||
|
@ -1931,6 +1942,7 @@ class OrderedDictTests:
|
||||||
self.assertEqual(od.setdefault('x', 10), 10)
|
self.assertEqual(od.setdefault('x', 10), 10)
|
||||||
# make sure 'x' is added to the end
|
# make sure 'x' is added to the end
|
||||||
self.assertEqual(list(od.items())[-1], ('x', 10))
|
self.assertEqual(list(od.items())[-1], ('x', 10))
|
||||||
|
self.assertEqual(od.setdefault('g', default=9), 9)
|
||||||
|
|
||||||
# make sure setdefault still works when __missing__ is defined
|
# make sure setdefault still works when __missing__ is defined
|
||||||
class Missing(OrderedDict):
|
class Missing(OrderedDict):
|
||||||
|
@ -1962,6 +1974,8 @@ class OrderedDictTests:
|
||||||
self.assertEqual(list(od), list('cabde'))
|
self.assertEqual(list(od), list('cabde'))
|
||||||
od.move_to_end('e')
|
od.move_to_end('e')
|
||||||
self.assertEqual(list(od), list('cabde'))
|
self.assertEqual(list(od), list('cabde'))
|
||||||
|
od.move_to_end('b', last=False)
|
||||||
|
self.assertEqual(list(od), list('bcade'))
|
||||||
with self.assertRaises(KeyError):
|
with self.assertRaises(KeyError):
|
||||||
od.move_to_end('x')
|
od.move_to_end('x')
|
||||||
with self.assertRaises(KeyError):
|
with self.assertRaises(KeyError):
|
||||||
|
|
|
@ -21,6 +21,8 @@ Library
|
||||||
|
|
||||||
- Issue #24359: Check for changed OrderedDict size during iteration.
|
- Issue #24359: Check for changed OrderedDict size during iteration.
|
||||||
|
|
||||||
|
- Issue #24368: Support keyword arguments in OrderedDict methods.
|
||||||
|
|
||||||
|
|
||||||
What's New in Python 3.5.0 beta 2?
|
What's New in Python 3.5.0 beta 2?
|
||||||
==================================
|
==================================
|
||||||
|
|
|
@ -930,12 +930,17 @@ PyDoc_STRVAR(odict_fromkeys__doc__,
|
||||||
");
|
");
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
odict_fromkeys(PyObject *cls, PyObject *args)
|
odict_fromkeys(PyObject *cls, PyObject *args, PyObject *kwargs)
|
||||||
{
|
{
|
||||||
|
static char *kwlist[] = {"iterable", "value", 0};
|
||||||
PyObject *seq;
|
PyObject *seq;
|
||||||
PyObject *value = Py_None;
|
PyObject *value = Py_None;
|
||||||
if (!PyArg_UnpackTuple(args, "fromkeys", 1, 2, &seq, &value)) /* borrowed */
|
|
||||||
|
/* both borrowed */
|
||||||
|
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:fromkeys", kwlist,
|
||||||
|
&seq, &value)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
return _PyDict_FromKeys(cls, seq, value);
|
return _PyDict_FromKeys(cls, seq, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1071,14 +1076,17 @@ PyDoc_STRVAR(odict_setdefault__doc__,
|
||||||
|
|
||||||
/* Skips __missing__() calls. */
|
/* Skips __missing__() calls. */
|
||||||
static PyObject *
|
static PyObject *
|
||||||
odict_setdefault(register PyODictObject *od, PyObject *args)
|
odict_setdefault(register PyODictObject *od, PyObject *args, PyObject *kwargs)
|
||||||
{
|
{
|
||||||
|
static char *kwlist[] = {"key", "default", 0};
|
||||||
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_ParseTupleAndKeywords(args, kwargs, "O|O:setdefault", kwlist,
|
||||||
|
&key, &failobj)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (PyODict_CheckExact(od)) {
|
if (PyODict_CheckExact(od)) {
|
||||||
result = PyODict_GetItemWithError(od, key); /* borrowed */
|
result = PyODict_GetItemWithError(od, key); /* borrowed */
|
||||||
|
@ -1126,11 +1134,14 @@ static PyObject * _odict_popkey(PyObject *, PyObject *, PyObject *);
|
||||||
|
|
||||||
/* Skips __missing__() calls. */
|
/* Skips __missing__() calls. */
|
||||||
static PyObject *
|
static PyObject *
|
||||||
odict_pop(PyObject *od, PyObject *args)
|
odict_pop(PyObject *od, PyObject *args, PyObject *kwargs)
|
||||||
{
|
{
|
||||||
|
static char *kwlist[] = {"key", "default", 0};
|
||||||
PyObject *key, *failobj = NULL;
|
PyObject *key, *failobj = NULL;
|
||||||
|
|
||||||
if (!PyArg_UnpackTuple(args, "pop", 1, 2, &key, &failobj)) { /* borrowed */
|
/* borrowed */
|
||||||
|
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:pop", kwlist,
|
||||||
|
&key, &failobj)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1202,10 +1213,12 @@ PyDoc_STRVAR(odict_popitem__doc__,
|
||||||
");
|
");
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
odict_popitem(PyObject *od, PyObject *args)
|
odict_popitem(PyObject *od, PyObject *args, PyObject *kwargs)
|
||||||
{
|
{
|
||||||
|
static char *kwlist[] = {"last", 0};
|
||||||
PyObject *key, *value, *item = NULL, *last = NULL;
|
PyObject *key, *value, *item = NULL, *last = NULL;
|
||||||
_ODictNode *node;
|
_ODictNode *node;
|
||||||
|
int pos = -1;
|
||||||
|
|
||||||
if (_odict_EMPTY((PyODictObject *)od)) {
|
if (_odict_EMPTY((PyODictObject *)od)) {
|
||||||
PyErr_SetString(PyExc_KeyError, "dictionary is empty");
|
PyErr_SetString(PyExc_KeyError, "dictionary is empty");
|
||||||
|
@ -1214,13 +1227,23 @@ odict_popitem(PyObject *od, PyObject *args)
|
||||||
|
|
||||||
/* pull the item */
|
/* pull the item */
|
||||||
|
|
||||||
if (!PyArg_UnpackTuple(args, "popitem", 0, 1, &last)) /* borrowed */
|
/* borrowed */
|
||||||
|
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O:popitem", kwlist,
|
||||||
|
&last)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (last == NULL || last == Py_True)
|
if (last != NULL) {
|
||||||
node = _odict_LAST((PyODictObject *)od);
|
int is_true;
|
||||||
else
|
is_true = PyObject_IsTrue(last);
|
||||||
|
if (is_true == -1)
|
||||||
|
return NULL;
|
||||||
|
pos = is_true ? -1 : 0;
|
||||||
|
}
|
||||||
|
if (pos == 0)
|
||||||
node = _odict_FIRST((PyODictObject *)od);
|
node = _odict_FIRST((PyODictObject *)od);
|
||||||
|
else
|
||||||
|
node = _odict_LAST((PyODictObject *)od);
|
||||||
|
|
||||||
key = _odictnode_KEY(node);
|
key = _odictnode_KEY(node);
|
||||||
Py_INCREF(key);
|
Py_INCREF(key);
|
||||||
|
@ -1360,14 +1383,17 @@ PyDoc_STRVAR(odict_move_to_end__doc__,
|
||||||
");
|
");
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
odict_move_to_end(PyODictObject *od, PyObject *args)
|
odict_move_to_end(PyODictObject *od, PyObject *args, PyObject *kwargs)
|
||||||
{
|
{
|
||||||
|
static char *kwlist[] = {"key", "last", 0};
|
||||||
PyObject *key, *last = NULL;
|
PyObject *key, *last = NULL;
|
||||||
Py_ssize_t pos = -1;
|
Py_ssize_t pos = -1;
|
||||||
|
|
||||||
/* both borrowed */
|
/* both borrowed */
|
||||||
if (!PyArg_UnpackTuple(args, "move_to_end", 1, 2, &key, &last))
|
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:move_to_end", kwlist,
|
||||||
|
&key, &last)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
if (_odict_EMPTY(od)) {
|
if (_odict_EMPTY(od)) {
|
||||||
PyErr_SetObject(PyExc_KeyError, key);
|
PyErr_SetObject(PyExc_KeyError, key);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1439,20 +1465,20 @@ static PyMethodDef odict_methods[] = {
|
||||||
odict_repr__doc__},
|
odict_repr__doc__},
|
||||||
{"__setitem__", (PyCFunction)odict_mp_ass_sub, METH_NOARGS,
|
{"__setitem__", (PyCFunction)odict_mp_ass_sub, METH_NOARGS,
|
||||||
odict_setitem__doc__},
|
odict_setitem__doc__},
|
||||||
{"fromkeys", (PyCFunction)odict_fromkeys, METH_VARARGS | METH_CLASS,
|
{"fromkeys", (PyCFunction)odict_fromkeys,
|
||||||
odict_fromkeys__doc__},
|
METH_VARARGS | METH_KEYWORDS | METH_CLASS, odict_fromkeys__doc__},
|
||||||
|
|
||||||
/* overridden dict methods */
|
/* overridden dict methods */
|
||||||
{"__sizeof__", (PyCFunction)odict_sizeof, METH_NOARGS,
|
{"__sizeof__", (PyCFunction)odict_sizeof, METH_NOARGS,
|
||||||
odict_sizeof__doc__},
|
odict_sizeof__doc__},
|
||||||
{"__reduce__", (PyCFunction)odict_reduce, METH_NOARGS,
|
{"__reduce__", (PyCFunction)odict_reduce, METH_NOARGS,
|
||||||
odict_reduce__doc__},
|
odict_reduce__doc__},
|
||||||
{"setdefault", (PyCFunction)odict_setdefault, METH_VARARGS,
|
{"setdefault", (PyCFunction)odict_setdefault,
|
||||||
odict_setdefault__doc__},
|
METH_VARARGS | METH_KEYWORDS, odict_setdefault__doc__},
|
||||||
{"pop", (PyCFunction)odict_pop, METH_VARARGS,
|
{"pop", (PyCFunction)odict_pop,
|
||||||
odict_pop__doc__},
|
METH_VARARGS | METH_KEYWORDS, odict_pop__doc__},
|
||||||
{"popitem", (PyCFunction)odict_popitem, METH_VARARGS,
|
{"popitem", (PyCFunction)odict_popitem,
|
||||||
odict_popitem__doc__},
|
METH_VARARGS | METH_KEYWORDS, odict_popitem__doc__},
|
||||||
{"keys", (PyCFunction)odictkeys_new, METH_NOARGS,
|
{"keys", (PyCFunction)odictkeys_new, METH_NOARGS,
|
||||||
odict_keys__doc__},
|
odict_keys__doc__},
|
||||||
{"values", (PyCFunction)odictvalues_new, METH_NOARGS,
|
{"values", (PyCFunction)odictvalues_new, METH_NOARGS,
|
||||||
|
@ -1469,8 +1495,8 @@ static PyMethodDef odict_methods[] = {
|
||||||
/* new methods */
|
/* new methods */
|
||||||
{"__reversed__", (PyCFunction)odict_reversed, METH_NOARGS,
|
{"__reversed__", (PyCFunction)odict_reversed, METH_NOARGS,
|
||||||
odict_reversed__doc__},
|
odict_reversed__doc__},
|
||||||
{"move_to_end", (PyCFunction)odict_move_to_end, METH_VARARGS,
|
{"move_to_end", (PyCFunction)odict_move_to_end,
|
||||||
odict_move_to_end__doc__},
|
METH_VARARGS | METH_KEYWORDS, odict_move_to_end__doc__},
|
||||||
|
|
||||||
{NULL, NULL} /* sentinel */
|
{NULL, NULL} /* sentinel */
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue