From 83825acd1bd02148c75bd2f4469767d4839196d3 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Sat, 10 Feb 2007 04:54:19 +0000 Subject: Endow dict views with a proper length method. --- Lib/test/test_dictviews.py | 3 +++ Objects/dictobject.c | 51 +++++++++++++++++++++++++++++++++++----------- 2 files changed, 42 insertions(+), 12 deletions(-) diff --git a/Lib/test/test_dictviews.py b/Lib/test/test_dictviews.py index 15c933f..c0c1da1 100644 --- a/Lib/test/test_dictviews.py +++ b/Lib/test/test_dictviews.py @@ -7,16 +7,19 @@ class DictSetTest(unittest.TestCase): d = {1: 10, "a": "ABC"} keys = d.KEYS() self.assertEqual(set(keys), {1, "a"}) + self.assertEqual(len(keys), 2) def test_dict_items(self): d = {1: 10, "a": "ABC"} items = d.ITEMS() self.assertEqual(set(items), {(1, 10), ("a", "ABC")}) + self.assertEqual(len(items), 2) def test_dict_values(self): d = {1: 10, "a": "ABC"} values = d.VALUES() self.assertEqual(set(values), {10, "ABC"}) + self.assertEqual(len(values), 2) def test_main(): test_support.run_unittest(DictSetTest) diff --git a/Objects/dictobject.c b/Objects/dictobject.c index bb527dd..e2e98db 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -2354,13 +2354,13 @@ dictview_dealloc(dictviewobject *ds) PyObject_Del(ds); } -static PyObject * -dictview_length_hint(dictviewobject *ds) +static Py_ssize_t +dictview_len(dictviewobject *ds) { Py_ssize_t len = 0; if (ds->ds_dict != NULL) len = ds->ds_dict->ma_used; - return PyInt_FromSize_t(len); + return len; } static PyObject * @@ -2397,9 +2397,18 @@ dictkeys_iter(dictviewobject *ds) return dictiter_new(ds->ds_dict, &PyDictIterKey_Type); } +static PySequenceMethods dictkeys_as_sequence = { + (lenfunc)dictview_len, /* sq_length */ + 0, /* sq_concat */ + 0, /* sq_repeat */ + 0, /* sq_item */ + 0, /* sq_slice */ + 0, /* sq_ass_item */ + 0, /* sq_ass_slice */ + (objobjproc)0, /* sq_contains */ +}; + static PyMethodDef dictkeys_methods[] = { - {"__length_hint__", (PyCFunction)dictview_length_hint, METH_NOARGS, - length_hint_doc}, {NULL, NULL} /* sentinel */ }; @@ -2417,7 +2426,7 @@ PyTypeObject PyDictKeys_Type = { 0, /* tp_compare */ 0, /* tp_repr */ 0, /* tp_as_number */ - 0, /* tp_as_sequence */ + &dictkeys_as_sequence, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ @@ -2454,9 +2463,18 @@ dictitems_iter(dictviewobject *ds) return dictiter_new(ds->ds_dict, &PyDictIterItem_Type); } +static PySequenceMethods dictitems_as_sequence = { + (lenfunc)dictview_len, /* sq_length */ + 0, /* sq_concat */ + 0, /* sq_repeat */ + 0, /* sq_item */ + 0, /* sq_slice */ + 0, /* sq_ass_item */ + 0, /* sq_ass_slice */ + (objobjproc)0, /* sq_contains */ +}; + static PyMethodDef dictitems_methods[] = { - {"__length_hint__", (PyCFunction)dictview_length_hint, METH_NOARGS, - length_hint_doc}, {NULL, NULL} /* sentinel */ }; @@ -2474,7 +2492,7 @@ PyTypeObject PyDictItems_Type = { 0, /* tp_compare */ 0, /* tp_repr */ 0, /* tp_as_number */ - 0, /* tp_as_sequence */ + &dictitems_as_sequence, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ @@ -2511,9 +2529,18 @@ dictvalues_iter(dictviewobject *ds) return dictiter_new(ds->ds_dict, &PyDictIterValue_Type); } +static PySequenceMethods dictvalues_as_sequence = { + (lenfunc)dictview_len, /* sq_length */ + 0, /* sq_concat */ + 0, /* sq_repeat */ + 0, /* sq_item */ + 0, /* sq_slice */ + 0, /* sq_ass_item */ + 0, /* sq_ass_slice */ + (objobjproc)0, /* sq_contains */ +}; + static PyMethodDef dictvalues_methods[] = { - {"__length_hint__", (PyCFunction)dictview_length_hint, METH_NOARGS, - length_hint_doc}, {NULL, NULL} /* sentinel */ }; @@ -2531,7 +2558,7 @@ PyTypeObject PyDictValues_Type = { 0, /* tp_compare */ 0, /* tp_repr */ 0, /* tp_as_number */ - 0, /* tp_as_sequence */ + &dictvalues_as_sequence, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ -- cgit v0.12