set update in 2.5
Duncan Smith
buzzard at urubu.freeserve.co.uk
Mon Jan 29 20:27:08 EST 2007
Peter Otten wrote:
> 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?
>
Thanks Peter. It is 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
I will file a report. Cheers.
Duncan
More information about the Python-list
mailing list