set update in 2.5

Duncan Smith buzzard at urubu.freeserve.co.uk
Tue Jan 30 02:27:08 CET 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