From 49928ff7becad845575265ca34fac857c0e26790 Mon Sep 17 00:00:00 2001 From: Michael Curran Date: Mon, 17 Jun 2019 08:31:13 +1000 Subject: [PATCH 1/2] Provide __hash__ methods where ever we have provided __eq__ methods. --- source/JABHandler.py | 5 +++++ source/NVDAObjects/UIA/__init__.py | 5 +++++ source/NVDAObjects/__init__.py | 5 +++++ source/compoundDocuments.py | 5 +++++ source/locationHelper.py | 8 ++++++++ source/synthDrivers/_espeak.py | 5 +++++ source/textInfos/__init__.py | 5 +++++ source/textInfos/offsets.py | 10 ++++++++++ 8 files changed, 48 insertions(+) diff --git a/source/JABHandler.py b/source/JABHandler.py index d0562b82c42..b903367fc13 100644 --- a/source/JABHandler.py +++ b/source/JABHandler.py @@ -347,6 +347,11 @@ def __eq__(self,jabContext): else: return False + # As __eq__ was defined on this class, we must provide __hash__ to remain hashable. + # The default hash implementation is fine for our purposes. + def __hash__(self): + return super().__hash__() + def __ne__(self,jabContext): if self.vmID!=jabContext.vmID or not bridgeDll.isSameObject(self.vmID,self.accContext,jabContext.accContext): return True diff --git a/source/NVDAObjects/UIA/__init__.py b/source/NVDAObjects/UIA/__init__.py index 02a576240db..a20f51fadc4 100644 --- a/source/NVDAObjects/UIA/__init__.py +++ b/source/NVDAObjects/UIA/__init__.py @@ -321,6 +321,11 @@ def __eq__(self,other): if self.__class__ is not other.__class__: return False return bool(self._rangeObj.compare(other._rangeObj)) + # As __eq__ was defined on this class, we must provide __hash__ to remain hashable. + # The default hash implementation is fine for our purposes. + def __hash__(self): + return super().__hash__() + def _get_NVDAObjectAtStart(self): e=self.UIAElementAtStart if e: diff --git a/source/NVDAObjects/__init__.py b/source/NVDAObjects/__init__.py index 05b2877b2be..617948b9e01 100644 --- a/source/NVDAObjects/__init__.py +++ b/source/NVDAObjects/__init__.py @@ -319,6 +319,11 @@ def __eq__(self,other): return False return self._isEqual(other) + # As __eq__ was defined on this class, we must provide __hash__ to remain hashable. + # The default hash implementation is fine for our purposes. + def __hash__(self): + return super().__hash__() + def __ne__(self,other): """The opposite to L{NVDAObject.__eq__} """ diff --git a/source/compoundDocuments.py b/source/compoundDocuments.py index c424ba1bec2..36ecad43bc5 100644 --- a/source/compoundDocuments.py +++ b/source/compoundDocuments.py @@ -173,6 +173,11 @@ def __eq__(self, other): return False return self._start == other._start and self._startObj == other._startObj and self._end == other._end and self._endObj == other._endObj + # As __eq__ was defined on this class, we must provide __hash__ to remain hashable. + # The default hash implementation is fine for our purposes. + def __hash__(self): + return super().__hash__() + def __ne__(self, other): return not self == other diff --git a/source/locationHelper.py b/source/locationHelper.py index 7f76bc61f49..c9751311d30 100644 --- a/source/locationHelper.py +++ b/source/locationHelper.py @@ -152,6 +152,10 @@ def __eq__(self,other): return NotImplemented return self.x == other.x and self.y == other.y + # As __eq__ was defined on this class, we must provide __hash__ to remain hashable. + def __hash__(self): + return hash((self.x,self.y)) + def __ne__(self,other): if not isinstance(other,POINT_CLASSES): return NotImplemented @@ -320,6 +324,10 @@ def __eq__(self,other): return NotImplemented return other.left == self.left and other.top == self.top and other.right == self.right and other.bottom == self.bottom + # As __eq__ was defined on this class, we must provide __hash__ to remain hashable. + def __hash__(self): + return hash((self.left,self.top,self.right,self.bottom)) + def __ne__(self,other): if not isinstance(other,RECT_CLASSES): return NotImplemented diff --git a/source/synthDrivers/_espeak.py b/source/synthDrivers/_espeak.py index 3cefb3aaf4b..7a40a7b2c0b 100755 --- a/source/synthDrivers/_espeak.py +++ b/source/synthDrivers/_espeak.py @@ -118,6 +118,11 @@ class espeak_VOICE(Structure): def __eq__(self, other): return isinstance(other, type(self)) and addressof(self) == addressof(other) + # As __eq__ was defined on this class, we must provide __hash__ to remain hashable. + # The default hash implementation is fine for our purposes. + def __hash__(self): + return super().__hash__() + # constants that can be returned by espeak_callback CALLBACK_CONTINUE_SYNTHESIS=0 CALLBACK_ABORT_SYNTHESIS=1 diff --git a/source/textInfos/__init__.py b/source/textInfos/__init__.py index 8c1e7b87389..391d3f644bf 100755 --- a/source/textInfos/__init__.py +++ b/source/textInfos/__init__.py @@ -181,6 +181,11 @@ def __eq__(self,other): if isinstance(other,Bookmark) and self.infoClass==other.infoClass and self.data==other.data: return True + # As __eq__ was defined on this class, we must provide __hash__ to remain hashable. + # The default hash implementation is fine for our purposes. + def __hash__(self): + return super().__hash__() + def __ne__(self,other): return not self==other diff --git a/source/textInfos/offsets.py b/source/textInfos/offsets.py index 8fbcbcb517f..8fa207e59cf 100755 --- a/source/textInfos/offsets.py +++ b/source/textInfos/offsets.py @@ -39,6 +39,11 @@ def __eq__(self,other): else: return False + # As __eq__ was defined on this class, we must provide __hash__ to remain hashable. + # The default hash implementation is fine for our purposes. + def __hash__(self): + return super().__hash__() + def __ne__(self,other): return not self==other @@ -166,6 +171,11 @@ def __eq__(self,other): else: return False + # As __eq__ was defined on this class, we must provide __hash__ to remain hashable. + # The default hash implementation is fine for our purposes. + def __hash__(self): + return super().__hash__() + def _get_locationText(self): textList=[] storyLength=self._getStoryLength() or 1 From b6595fa9f4206e949c7db4cb8b1ff99694e1be9a Mon Sep 17 00:00:00 2001 From: Michael Curran Date: Mon, 17 Jun 2019 16:56:00 +1000 Subject: [PATCH 2/2] locationHelper: we can just use super's __hash__ for hashing as these are NamedTuples. --- source/locationHelper.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/locationHelper.py b/source/locationHelper.py index c9751311d30..6d7c9e323ac 100644 --- a/source/locationHelper.py +++ b/source/locationHelper.py @@ -154,7 +154,7 @@ def __eq__(self,other): # As __eq__ was defined on this class, we must provide __hash__ to remain hashable. def __hash__(self): - return hash((self.x,self.y)) + return super().__hash__() def __ne__(self,other): if not isinstance(other,POINT_CLASSES): @@ -326,7 +326,7 @@ def __eq__(self,other): # As __eq__ was defined on this class, we must provide __hash__ to remain hashable. def __hash__(self): - return hash((self.left,self.top,self.right,self.bottom)) + return super().__hash__() def __ne__(self,other): if not isinstance(other,RECT_CLASSES):