[Python-checkins] CVS: python/dist/src/Objects dictobject.c,2.72,2.73
Guido van Rossum
gvanrossum@users.sourceforge.net
Wed, 17 Jan 2001 16:39:04 -0800
Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv2822
Modified Files:
dictobject.c
Log Message:
Rich comparisons:
- Use PyObject_RichCompareBool() when comparing keys; this makes the
error handling cleaner.
- There were two implementations for dictionary comparison, an old one
(#ifdef'ed out) and a new one. Got rid of the old one, which was
abandoned years ago.
- In the characterize() function, part of dictionary comparison, use
PyObject_RichCompareBool() to compare keys and values instead. But
continue to use PyObject_Compare() for comparing the final
(deciding) elements.
- Align the comments in the type struct initializer.
Note: I don't implement rich comparison for dictionaries -- there
doesn't seem to be much to be gained. (The existing comparison
already decides that shorter dicts are always smaller than longer
dicts.)
Index: dictobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v
retrieving revision 2.72
retrieving revision 2.73
diff -C2 -r2.72 -r2.73
*** dictobject.c 2001/01/03 22:34:59 2.72
--- dictobject.c 2001/01/18 00:39:02 2.73
***************
*** 208,215 ****
PyErr_Fetch(&err_type, &err_value, &err_tb);
}
! cmp = PyObject_Compare(ep->me_key, key);
! if (PyErr_Occurred())
! PyErr_Clear();
! else if (cmp == 0) {
if (restore_error)
PyErr_Restore(err_type, err_value,
--- 208,213 ----
PyErr_Fetch(&err_type, &err_value, &err_tb);
}
! cmp = PyObject_RichCompareBool(ep->me_key, key, Py_EQ);
! if (cmp > 0) {
if (restore_error)
PyErr_Restore(err_type, err_value,
***************
*** 217,220 ****
--- 215,220 ----
return ep;
}
+ else if (cmp < 0)
+ PyErr_Clear();
}
freeslot = NULL;
***************
*** 253,260 ****
}
}
! cmp = PyObject_Compare(ep->me_key, key);
! if (PyErr_Occurred())
! PyErr_Clear();
! else if (cmp == 0) {
if (restore_error)
PyErr_Restore(err_type, err_value,
--- 253,258 ----
}
}
! cmp = PyObject_RichCompareBool(ep->me_key, key, Py_EQ);
! if (cmp > 0) {
if (restore_error)
PyErr_Restore(err_type, err_value,
***************
*** 262,265 ****
--- 260,265 ----
return ep;
}
+ else if (cmp < 0)
+ PyErr_Clear();
}
/* Cycle through GF(2^n)-{0} */
***************
*** 913,920 ****
}
- #define NEWCMP
-
- #ifdef NEWCMP
-
/* Subroutine which returns the smallest key in a for which b's value
is different or absent. The value is returned too, through the
--- 913,916 ----
***************
*** 925,929 ****
{
PyObject *diff = NULL;
! int i;
*pval = NULL;
--- 921,925 ----
{
PyObject *diff = NULL;
! int i, cmp;
*pval = NULL;
***************
*** 932,942 ****
PyObject *key = a->ma_table[i].me_key;
PyObject *aval, *bval;
! /* XXX What if PyObject_Compare raises an exception? */
! if (diff != NULL && PyObject_Compare(key, diff) > 0)
continue;
aval = a->ma_table[i].me_value;
bval = PyDict_GetItem((PyObject *)b, key);
! /* XXX What if PyObject_Compare raises an exception? */
! if (bval == NULL || PyObject_Compare(aval, bval) != 0)
{
diff = key;
--- 928,948 ----
PyObject *key = a->ma_table[i].me_key;
PyObject *aval, *bval;
! if (diff != NULL) {
! cmp = PyObject_RichCompareBool(diff, key, Py_LT);
! if (cmp < 0)
! return NULL;
! if (cmp > 0)
continue;
+ }
aval = a->ma_table[i].me_value;
bval = PyDict_GetItem((PyObject *)b, key);
! if (bval == NULL)
! cmp = 0;
! else {
! cmp = PyObject_RichCompareBool(aval, bval, Py_EQ);
! if (cmp < 0)
! return NULL;
! }
! if (cmp == 0)
{
diff = key;
***************
*** 961,970 ****
/* Same length -- check all keys */
adiff = characterize(a, b, &aval);
! if (PyErr_Occurred())
return -1;
if (adiff == NULL)
return 0; /* a is a subset with the same length */
bdiff = characterize(b, a, &bval);
! if (PyErr_Occurred())
return -1;
/* bdiff == NULL would be impossible now */
--- 967,976 ----
/* Same length -- check all keys */
adiff = characterize(a, b, &aval);
! if (adiff == NULL && PyErr_Occurred())
return -1;
if (adiff == NULL)
return 0; /* a is a subset with the same length */
bdiff = characterize(b, a, &bval);
! if (bdiff == NULL && PyErr_Occurred())
return -1;
/* bdiff == NULL would be impossible now */
***************
*** 975,1058 ****
}
- #else /* !NEWCMP */
-
- static int
- dict_compare(dictobject *a, dictobject *b)
- {
- PyObject *akeys, *bkeys;
- int i, n, res;
- if (a == b)
- return 0;
- if (a->ma_used == 0) {
- if (b->ma_used != 0)
- return -1;
- else
- return 0;
- }
- else {
- if (b->ma_used == 0)
- return 1;
- }
- akeys = dict_keys(a, (PyObject *)NULL);
- bkeys = dict_keys(b, (PyObject *)NULL);
- if (akeys == NULL || bkeys == NULL) {
- /* Oops, out of memory -- what to do? */
- /* For now, sort on address! */
- Py_XDECREF(akeys);
- Py_XDECREF(bkeys);
- if (a < b)
- return -1;
- else
- return 1;
- }
- PyList_Sort(akeys);
- PyList_Sort(bkeys);
- n = a->ma_used < b->ma_used ? a->ma_used : b->ma_used; /* smallest */
- res = 0;
- for (i = 0; i < n; i++) {
- PyObject *akey, *bkey, *aval, *bval;
- long ahash, bhash;
- akey = PyList_GetItem(akeys, i);
- bkey = PyList_GetItem(bkeys, i);
- res = PyObject_Compare(akey, bkey);
- if (res != 0)
- break;
- #ifdef CACHE_HASH
- if (!PyString_Check(akey) ||
- (ahash = ((PyStringObject *) akey)->ob_shash) == -1)
- #endif
- {
- ahash = PyObject_Hash(akey);
- if (ahash == -1)
- PyErr_Clear(); /* Don't want errors here */
- }
- #ifdef CACHE_HASH
- if (!PyString_Check(bkey) ||
- (bhash = ((PyStringObject *) bkey)->ob_shash) == -1)
- #endif
- {
- bhash = PyObject_Hash(bkey);
- if (bhash == -1)
- PyErr_Clear(); /* Don't want errors here */
- }
- aval = (a->ma_lookup)(a, akey, ahash) -> me_value;
- bval = (b->ma_lookup)(b, bkey, bhash) -> me_value;
- res = PyObject_Compare(aval, bval);
- if (res != 0)
- break;
- }
- if (res == 0) {
- if (a->ma_used < b->ma_used)
- res = -1;
- else if (a->ma_used > b->ma_used)
- res = 1;
- }
- Py_DECREF(akeys);
- Py_DECREF(bkeys);
- return res;
- }
-
- #endif /* !NEWCMP */
-
static PyObject *
dict_has_key(register dictobject *mp, PyObject *args)
--- 981,984 ----
***************
*** 1299,1321 ****
sizeof(dictobject) + PyGC_HEAD_SIZE,
0,
! (destructor)dict_dealloc, /*tp_dealloc*/
! (printfunc)dict_print, /*tp_print*/
! (getattrfunc)dict_getattr, /*tp_getattr*/
! 0, /*tp_setattr*/
! (cmpfunc)dict_compare, /*tp_compare*/
! (reprfunc)dict_repr, /*tp_repr*/
! 0, /*tp_as_number*/
! 0, /*tp_as_sequence*/
! &dict_as_mapping, /*tp_as_mapping*/
! 0, /* tp_hash */
! 0, /* tp_call */
! 0, /* tp_str */
! 0, /* tp_getattro */
! 0, /* tp_setattro */
! 0, /* tp_as_buffer */
! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /*tp_flags*/
! 0, /* tp_doc */
! (traverseproc)dict_traverse, /* tp_traverse */
! (inquiry)dict_tp_clear, /* tp_clear */
};
--- 1225,1248 ----
sizeof(dictobject) + PyGC_HEAD_SIZE,
0,
! (destructor)dict_dealloc, /* tp_dealloc */
! (printfunc)dict_print, /* tp_print */
! (getattrfunc)dict_getattr, /* tp_getattr */
! 0, /* tp_setattr */
! (cmpfunc)dict_compare, /* tp_compare */
! (reprfunc)dict_repr, /* tp_repr */
! 0, /* tp_as_number */
! 0, /* tp_as_sequence */
! &dict_as_mapping, /* tp_as_mapping */
! 0, /* tp_hash */
! 0, /* tp_call */
! 0, /* tp_str */
! 0, /* tp_getattro */
! 0, /* tp_setattro */
! 0, /* tp_as_buffer */
! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /* tp_flags */
! 0, /* tp_doc */
! (traverseproc)dict_traverse, /* tp_traverse */
! (inquiry)dict_tp_clear, /* tp_clear */
! 0, /* tp_richcompare */
};