Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 83825ac

Browse files
committed
Endow dict views with a proper length method.
1 parent b90c848 commit 83825ac

2 files changed

Lines changed: 42 additions & 12 deletions

File tree

Lib/test/test_dictviews.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,19 @@ def test_dict_keys(self):
77
d = {1: 10, "a": "ABC"}
88
keys = d.KEYS()
99
self.assertEqual(set(keys), {1, "a"})
10+
self.assertEqual(len(keys), 2)
1011

1112
def test_dict_items(self):
1213
d = {1: 10, "a": "ABC"}
1314
items = d.ITEMS()
1415
self.assertEqual(set(items), {(1, 10), ("a", "ABC")})
16+
self.assertEqual(len(items), 2)
1517

1618
def test_dict_values(self):
1719
d = {1: 10, "a": "ABC"}
1820
values = d.VALUES()
1921
self.assertEqual(set(values), {10, "ABC"})
22+
self.assertEqual(len(values), 2)
2023

2124
def test_main():
2225
test_support.run_unittest(DictSetTest)

Objects/dictobject.c

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2354,13 +2354,13 @@ dictview_dealloc(dictviewobject *ds)
23542354
PyObject_Del(ds);
23552355
}
23562356

2357-
static PyObject *
2358-
dictview_length_hint(dictviewobject *ds)
2357+
static Py_ssize_t
2358+
dictview_len(dictviewobject *ds)
23592359
{
23602360
Py_ssize_t len = 0;
23612361
if (ds->ds_dict != NULL)
23622362
len = ds->ds_dict->ma_used;
2363-
return PyInt_FromSize_t(len);
2363+
return len;
23642364
}
23652365

23662366
static PyObject *
@@ -2397,9 +2397,18 @@ dictkeys_iter(dictviewobject *ds)
23972397
return dictiter_new(ds->ds_dict, &PyDictIterKey_Type);
23982398
}
23992399

2400+
static PySequenceMethods dictkeys_as_sequence = {
2401+
(lenfunc)dictview_len, /* sq_length */
2402+
0, /* sq_concat */
2403+
0, /* sq_repeat */
2404+
0, /* sq_item */
2405+
0, /* sq_slice */
2406+
0, /* sq_ass_item */
2407+
0, /* sq_ass_slice */
2408+
(objobjproc)0, /* sq_contains */
2409+
};
2410+
24002411
static PyMethodDef dictkeys_methods[] = {
2401-
{"__length_hint__", (PyCFunction)dictview_length_hint, METH_NOARGS,
2402-
length_hint_doc},
24032412
{NULL, NULL} /* sentinel */
24042413
};
24052414

@@ -2417,7 +2426,7 @@ PyTypeObject PyDictKeys_Type = {
24172426
0, /* tp_compare */
24182427
0, /* tp_repr */
24192428
0, /* tp_as_number */
2420-
0, /* tp_as_sequence */
2429+
&dictkeys_as_sequence, /* tp_as_sequence */
24212430
0, /* tp_as_mapping */
24222431
0, /* tp_hash */
24232432
0, /* tp_call */
@@ -2454,9 +2463,18 @@ dictitems_iter(dictviewobject *ds)
24542463
return dictiter_new(ds->ds_dict, &PyDictIterItem_Type);
24552464
}
24562465

2466+
static PySequenceMethods dictitems_as_sequence = {
2467+
(lenfunc)dictview_len, /* sq_length */
2468+
0, /* sq_concat */
2469+
0, /* sq_repeat */
2470+
0, /* sq_item */
2471+
0, /* sq_slice */
2472+
0, /* sq_ass_item */
2473+
0, /* sq_ass_slice */
2474+
(objobjproc)0, /* sq_contains */
2475+
};
2476+
24572477
static PyMethodDef dictitems_methods[] = {
2458-
{"__length_hint__", (PyCFunction)dictview_length_hint, METH_NOARGS,
2459-
length_hint_doc},
24602478
{NULL, NULL} /* sentinel */
24612479
};
24622480

@@ -2474,7 +2492,7 @@ PyTypeObject PyDictItems_Type = {
24742492
0, /* tp_compare */
24752493
0, /* tp_repr */
24762494
0, /* tp_as_number */
2477-
0, /* tp_as_sequence */
2495+
&dictitems_as_sequence, /* tp_as_sequence */
24782496
0, /* tp_as_mapping */
24792497
0, /* tp_hash */
24802498
0, /* tp_call */
@@ -2511,9 +2529,18 @@ dictvalues_iter(dictviewobject *ds)
25112529
return dictiter_new(ds->ds_dict, &PyDictIterValue_Type);
25122530
}
25132531

2532+
static PySequenceMethods dictvalues_as_sequence = {
2533+
(lenfunc)dictview_len, /* sq_length */
2534+
0, /* sq_concat */
2535+
0, /* sq_repeat */
2536+
0, /* sq_item */
2537+
0, /* sq_slice */
2538+
0, /* sq_ass_item */
2539+
0, /* sq_ass_slice */
2540+
(objobjproc)0, /* sq_contains */
2541+
};
2542+
25142543
static PyMethodDef dictvalues_methods[] = {
2515-
{"__length_hint__", (PyCFunction)dictview_length_hint, METH_NOARGS,
2516-
length_hint_doc},
25172544
{NULL, NULL} /* sentinel */
25182545
};
25192546

@@ -2531,7 +2558,7 @@ PyTypeObject PyDictValues_Type = {
25312558
0, /* tp_compare */
25322559
0, /* tp_repr */
25332560
0, /* tp_as_number */
2534-
0, /* tp_as_sequence */
2561+
&dictvalues_as_sequence, /* tp_as_sequence */
25352562
0, /* tp_as_mapping */
25362563
0, /* tp_hash */
25372564
0, /* tp_call */

0 commit comments

Comments
 (0)