@@ -2336,37 +2336,40 @@ PyTypeObject PyDictIterItem_Type = {
23362336};
23372337
23382338
2339+ /***********************************************/
23392340/* View objects for keys(), items(), values(). */
2341+ /***********************************************/
2342+
23402343/* While this is incomplete, we use KEYS(), ITEMS(), VALUES(). */
23412344
23422345/* The instance lay-out is the same for all three; but the type differs. */
23432346
23442347typedef struct {
23452348 PyObject_HEAD
2346- dictobject * ds_dict ;
2349+ dictobject * dv_dict ;
23472350} dictviewobject ;
23482351
23492352
23502353static void
2351- dictview_dealloc (dictviewobject * ds )
2354+ dictview_dealloc (dictviewobject * dv )
23522355{
2353- Py_XDECREF (ds -> ds_dict );
2354- PyObject_Del (ds );
2356+ Py_XDECREF (dv -> dv_dict );
2357+ PyObject_Del (dv );
23552358}
23562359
23572360static Py_ssize_t
2358- dictview_len (dictviewobject * ds )
2361+ dictview_len (dictviewobject * dv )
23592362{
23602363 Py_ssize_t len = 0 ;
2361- if (ds -> ds_dict != NULL )
2362- len = ds -> ds_dict -> ma_used ;
2364+ if (dv -> dv_dict != NULL )
2365+ len = dv -> dv_dict -> ma_used ;
23632366 return len ;
23642367}
23652368
23662369static PyObject *
23672370dictview_new (PyObject * dict , PyTypeObject * type )
23682371{
2369- dictviewobject * ds ;
2372+ dictviewobject * dv ;
23702373 if (dict == NULL ) {
23712374 PyErr_BadInternalCall ();
23722375 return NULL ;
@@ -2378,23 +2381,31 @@ dictview_new(PyObject *dict, PyTypeObject *type)
23782381 type -> tp_name , dict -> ob_type -> tp_name );
23792382 return NULL ;
23802383 }
2381- ds = PyObject_New (dictviewobject , type );
2382- if (ds == NULL )
2384+ dv = PyObject_New (dictviewobject , type );
2385+ if (dv == NULL )
23832386 return NULL ;
23842387 Py_INCREF (dict );
2385- ds -> ds_dict = (dictobject * )dict ;
2386- return (PyObject * )ds ;
2388+ dv -> dv_dict = (dictobject * )dict ;
2389+ return (PyObject * )dv ;
23872390}
23882391
2389- /* dict_keys */
2392+ /*** dict_keys ** */
23902393
23912394static PyObject *
2392- dictkeys_iter (dictviewobject * ds )
2395+ dictkeys_iter (dictviewobject * dv )
23932396{
2394- if (ds -> ds_dict == NULL ) {
2397+ if (dv -> dv_dict == NULL ) {
23952398 Py_RETURN_NONE ;
23962399 }
2397- return dictiter_new (ds -> ds_dict , & PyDictIterKey_Type );
2400+ return dictiter_new (dv -> dv_dict , & PyDictIterKey_Type );
2401+ }
2402+
2403+ static int
2404+ dictkeys_contains (dictviewobject * dv , PyObject * obj )
2405+ {
2406+ if (dv -> dv_dict == NULL )
2407+ return 0 ;
2408+ return PyDict_Contains ((PyObject * )dv -> dv_dict , obj );
23982409}
23992410
24002411static PySequenceMethods dictkeys_as_sequence = {
@@ -2405,7 +2416,7 @@ static PySequenceMethods dictkeys_as_sequence = {
24052416 0 , /* sq_slice */
24062417 0 , /* sq_ass_item */
24072418 0 , /* sq_ass_slice */
2408- (objobjproc )0 , /* sq_contains */
2419+ (objobjproc )dictkeys_contains , /* sq_contains */
24092420};
24102421
24112422static PyMethodDef dictkeys_methods [] = {
@@ -2452,15 +2463,34 @@ dictkeys_new(PyObject *dict)
24522463 return dictview_new (dict , & PyDictKeys_Type );
24532464}
24542465
2455- /* dict_items */
2466+ /*** dict_items ** */
24562467
24572468static PyObject *
2458- dictitems_iter (dictviewobject * ds )
2469+ dictitems_iter (dictviewobject * dv )
24592470{
2460- if (ds -> ds_dict == NULL ) {
2471+ if (dv -> dv_dict == NULL ) {
24612472 Py_RETURN_NONE ;
24622473 }
2463- return dictiter_new (ds -> ds_dict , & PyDictIterItem_Type );
2474+ return dictiter_new (dv -> dv_dict , & PyDictIterItem_Type );
2475+ }
2476+
2477+ static int
2478+ dictitems_contains (dictviewobject * dv , PyObject * obj )
2479+ {
2480+ PyObject * key , * value , * found ;
2481+ if (dv -> dv_dict == NULL )
2482+ return 0 ;
2483+ if (!PyTuple_Check (obj ) || PyTuple_GET_SIZE (obj ) != 2 )
2484+ return 0 ;
2485+ key = PyTuple_GET_ITEM (obj , 0 );
2486+ value = PyTuple_GET_ITEM (obj , 1 );
2487+ found = PyDict_GetItem ((PyObject * )dv -> dv_dict , key );
2488+ if (found == NULL ) {
2489+ if (PyErr_Occurred ())
2490+ return -1 ;
2491+ return 0 ;
2492+ }
2493+ return PyObject_RichCompareBool (value , found , Py_EQ );
24642494}
24652495
24662496static PySequenceMethods dictitems_as_sequence = {
@@ -2471,7 +2501,7 @@ static PySequenceMethods dictitems_as_sequence = {
24712501 0 , /* sq_slice */
24722502 0 , /* sq_ass_item */
24732503 0 , /* sq_ass_slice */
2474- (objobjproc )0 , /* sq_contains */
2504+ (objobjproc )dictitems_contains , /* sq_contains */
24752505};
24762506
24772507static PyMethodDef dictitems_methods [] = {
@@ -2518,15 +2548,15 @@ dictitems_new(PyObject *dict)
25182548 return dictview_new (dict , & PyDictItems_Type );
25192549}
25202550
2521- /* dict_values */
2551+ /*** dict_values ** */
25222552
25232553static PyObject *
2524- dictvalues_iter (dictviewobject * ds )
2554+ dictvalues_iter (dictviewobject * dv )
25252555{
2526- if (ds -> ds_dict == NULL ) {
2556+ if (dv -> dv_dict == NULL ) {
25272557 Py_RETURN_NONE ;
25282558 }
2529- return dictiter_new (ds -> ds_dict , & PyDictIterValue_Type );
2559+ return dictiter_new (dv -> dv_dict , & PyDictIterValue_Type );
25302560}
25312561
25322562static PySequenceMethods dictvalues_as_sequence = {
0 commit comments