]> granicus.if.org Git - python/commitdiff
Extend work on rev 52962 and 53829 eliminating redundant PyObject_Hash() calls and...
authorRaymond Hettinger <python@rcn.com>
Tue, 20 Mar 2007 21:27:24 +0000 (21:27 +0000)
committerRaymond Hettinger <python@rcn.com>
Tue, 20 Mar 2007 21:27:24 +0000 (21:27 +0000)
Include/setobject.h
Lib/test/test_set.py
Objects/dictobject.c
Objects/setobject.c

index a16c2f7cdcfd6d759456ed6eaddb7433d132746f..750a2a8a21f9f0a643d428cdb4c32baf8965b558 100644 (file)
@@ -82,7 +82,8 @@ PyAPI_FUNC(int) PySet_Clear(PyObject *set);
 PyAPI_FUNC(int) PySet_Contains(PyObject *anyset, PyObject *key);
 PyAPI_FUNC(int) PySet_Discard(PyObject *set, PyObject *key);
 PyAPI_FUNC(int) PySet_Add(PyObject *set, PyObject *key);
-PyAPI_FUNC(int) _PySet_Next(PyObject *set, Py_ssize_t *pos, PyObject **entry);
+PyAPI_FUNC(int) _PySet_Next(PyObject *set, Py_ssize_t *pos, PyObject **key);
+PyAPI_FUNC(int) _PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, long *hash);
 PyAPI_FUNC(PyObject *) PySet_Pop(PyObject *set);
 PyAPI_FUNC(int) _PySet_Update(PyObject *set, PyObject *iterable);
 
index 28924d49dd24d40c4e75b55fba071c421ce99cac..e6e0ba6b5b169171b9dc58edc0ba3f47822a48d4 100644 (file)
@@ -288,6 +288,10 @@ class TestJointOps(unittest.TestCase):
         self.assertEqual(sum(elem.hash_count for elem in d), n)
         if hasattr(s, 'symmetric_difference_update'):
             s.symmetric_difference_update(d)
+        self.assertEqual(sum(elem.hash_count for elem in d), n)     
+        d2 = dict.fromkeys(set(d))
+        self.assertEqual(sum(elem.hash_count for elem in d), n)
+        d3 = dict.fromkeys(frozenset(d))
         self.assertEqual(sum(elem.hash_count for elem in d), n)
 
 class TestSet(TestJointOps):
index 587dad390e615d3400d9bc585158ce0a88e18f0b..06cc4a8bd9f44f0925949c84279acb77c0f6a829 100644 (file)
@@ -1175,6 +1175,24 @@ dict_fromkeys(PyObject *cls, PyObject *args)
        if (d == NULL)
                return NULL;
 
+       if (PyDict_CheckExact(d) && PyAnySet_CheckExact(seq)) {
+               dictobject *mp = (dictobject *)d;
+               Py_ssize_t pos = 0;
+               PyObject *key;
+               long hash;
+
+               if (dictresize(mp, PySet_GET_SIZE(seq)))
+                       return NULL;
+
+               while (_PySet_NextEntry(seq, &pos, &key, &hash)) {
+                       Py_INCREF(key);
+                       Py_INCREF(Py_None);
+                       if (insertdict(mp, key, hash, Py_None))
+                               return NULL;
+               }
+               return d;
+       }
+
        it = PyObject_GetIter(seq);
        if (it == NULL){
                Py_DECREF(d);
index 07ba99641c38401052d15c1f76862d742ff332e9..a896d937faec3046179dc5323534953a25768483 100644 (file)
@@ -2137,7 +2137,7 @@ PySet_Add(PyObject *set, PyObject *key)
 }
 
 int
-_PySet_Next(PyObject *set, Py_ssize_t *pos, PyObject **entry)
+_PySet_Next(PyObject *set, Py_ssize_t *pos, PyObject **key)
 {
        setentry *entry_ptr;
 
@@ -2147,7 +2147,23 @@ _PySet_Next(PyObject *set, Py_ssize_t *pos, PyObject **entry)
        }
        if (set_next((PySetObject *)set, pos, &entry_ptr) == 0)
                return 0;
-       *entry = entry_ptr->key;
+       *key = entry_ptr->key;
+       return 1;
+}
+
+int
+_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, long *hash)
+{
+       setentry *entry;
+
+       if (!PyAnySet_Check(set)) {
+               PyErr_BadInternalCall();
+               return -1;
+       }
+       if (set_next((PySetObject *)set, pos, &entry) == 0)
+               return 0;
+       *key = entry->key;
+       *hash = entry->hash;
        return 1;
 }