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 -- http://mail.python.org/mailman/listinfo/python-list