Re: wx.Colour - not hashable in Phoenix/Py3
Douglas Thor <[email protected]>
| Newsgroups | gmane.comp.python.wxpython.devel |
|---|---|
| Message-ID | <[email protected]> |
Has there been any more investigation into this? Should I add it as an
issue to the wxWidgets/Phoenix github repo?
Thanks,
On Friday, May 8, 2015 at 5:29:23 PM UTC-7, Douglas Thor wrote:
>
> Until either SIP adds __hash__ or another solution is found, here's a
> workaround:
>
> In ..\site-packages\wx\core.py, add the following code around line 557,
> where the rest of the Colour class is defined:
>
> def _Colour___hash__(self):
>
> return hash(tuple(self.Get()))
>
> Colour.__hash__ = _Colour___hash__
>
> del _Colour___hash__
>
>
> I know that the top of core.py says to not edit the file, but I couldn't
> help myself :-D.
>
> I've done a tiny bit of testing, only verifying that
>
> 1. hash(wx.Colour(1,1,1,255)) does not raise a TypeError
> 2. hash(wx.Colour(1,1,1,255)) == hash((1,1,1,255))
> 3. My project actually runs.
>
>
> Robin, making this change won't cause the world to end, will it? I know
> that it will get overwritten the next time SIP generates core.py, but that
> I can live with.
>
> Thanks,
>
> On Wednesday, March 11, 2015 at 6:30:11 PM UTC-7, Robin Dunn wrote:
>>
>>
>> From the docs for both Python2 and Python3:
>> """
>> An object is hashable if it has a hash value which never changes during
>> its lifetime (it needs a __hash__() method), and can be compared to
>> other objects (it needs an __eq__() method). Hashable objects which
>> compare equal must have the same hash value.
>>
>> Hashability makes an object usable as a dictionary key and a set member,
>> because these data structures use the hash value internally.
>>
>> All of Python’s immutable built-in objects are hashable, while non
>> mutable containers (such as lists or dictionaries) are not. Objects
>> which are instances of user-defined classes are hashable by default;
>> they all compare unequal (except with themselves), and their hash value
>> is derived from their id().
>> """
>>
>> SIP doesn't add a default __hash__ in either build, it just relies on
>> the default Python behavior. In Python2 that seems to be a hash value
>> derived from the object's ID. In other words, you could think of it
>> like this:
>>
>> class HashableColour(wx.Colour):
>> def __hash__(self):
>> return do_something(id(self))
>>
>> Based on the above text I would have expected the same from Python3, but
>> perhaps the definition of "user-defined classes" was changed to not
>> include extension types. Or maybe that doc needs updating.
>>
>> Either way, I prefer the Python3 way because basing a default hash value
>> on the id() means that you must use the same instance of the key to
>> fetch the value again, you can't simply use a new key with the same
>> value. For example, in Python2:
>>
>> >>> c1 = wx.Colour(1,2,3)
>> >>> c2 = wx.Colour(1,2,3)
>> >>>
>> >>> d = {c1: 'one', c2: 'two'}
>> >>> d[c1]
>> 'one'
>> >>> d[c2]
>> 'two'
>> >>> d[wx.Colour(1,2,3)]
>> Traceback (most recent call last):
>> File "<input>", line 1, in <module>
>> KeyError: wx.Colour(1, 2, 3, 255)
>> >>>
>>
>> In Python3 Python makes you actually think about what makes sense for
>> your class's hash values, it doesn't just give you some mindless
>> substandard thing for free. For wx.Colour I might choose something like:
>>
>> class HashableColour(wx.Colour):
>> def __hash__(self):
>> return self.GetRGBA()
>>
>> or maybe even:
>>
>> return hash(self.Get()) # the hash of the tuple of color
>> components
>>
>> But I suppose the real question is whether we should be adding our own
>> __hash__ methods to at least some of the wrapped wxPython classes. I'll
>> give that some thought.
>>
>>
>> --
>> Robin Dunn
>> Software Craftsman
>> http://wxPython.org
>>
>
--
You received this message because you are subscribed to the Google Groups "wxPython-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
For more options, visit https://groups.google.com/d/optout.