set update in 2.5
Peter Otten
__peter__ at web.de
Sun Jan 28 04:15:39 EST 2007
Duncan Smith wrote:
> In moving from 2.4 to 2.5 I find that some of my unit tests are now
> failing. I've worked out that the problem relates to the set update
> method. In 2.4 I could update a set with an iterable type derived from
> dict as the argument. I now find that the set is updated with the hash
> values of the items in my iterable, rather than the items themselves.
> Converting to a list first gets round the problem.
>
> My iterable type has the same API as 'set' but requires items to have
> hashable 'uid' attributes, so they can also be looked up by uid. I hope
> this, and the fact that this worked fine in 2.4 will be enough to track
> down the issue without me having to paste reams of code (other than the
> following, pasted from IDLE). Any ideas? Cheers.
>
> Duncan
>
>
>>>> from graphItems import Node
>>>> from keyed_sets import KeyedSet
>>>> n = Node(1)
>>>> n.uid
> 1
>>>> k = KeyedSet([n])
>>>> k
> KeyedSet([1])
>>>> type(iter(k).next())
> <class 'graphItems.Node'>
>>>> type(k[1])
> <class 'graphItems.Node'>
>>>> s = set()
>>>> s.update(list(k))
>>>> type(iter(s).next())
> <class 'graphItems.Node'>
>>>> s = set()
>>>> s.update(k)
>>>> type(iter(s).next())
> <type 'int'>
>>>> s = set()
>>>> s.add(n)
>>>> type(iter(s).next())
> <class 'graphItems.Node'>
>>>> hash(n)
> 1
>>>>
Is your KeyedSet derived from dict?
$ python2.5
[snip]
>>> class D(dict):
... def __iter__(self): return self.itervalues()
...
>>> d = D(a=1, b=2)
>>> set(d)
set(['a', 'b'])
>>>
$ python2.4
[snip]
>>> class D(dict):
... def __iter__(self): return self.itervalues()
...
>>> d = D(a=1, b=2)
>>> set(d)
set([1, 2])
I think you should file a bug report. The fix is probably
--- setobject.c 2006-09-08 08:02:26.000000000 +0200
+++ setobject_new.c 2007-01-28 10:02:24.071688248 +0100
@@ -854,7 +854,7 @@
if (PyAnySet_Check(other))
return set_merge(so, other);
- if (PyDict_Check(other)) {
+ if (PyDict_CheckExact(other)) {
PyObject *value;
Py_ssize_t pos = 0;
while (PyDict_Next(other, &pos, &key, &value)) {
Peter
More information about the Python-list
mailing list