Make scheduler.Timeout exception hashable

The python standard library in Python 3.6.3 and earlier has a bug with
handling unhashable exceptions:

Although oslo_log will catch the error, make scheduler.Timeout hashable so
that all exceptions will be printable.

Prior to 640abe0c12 we just used __cmp__(),
but that isn't used in Python 3. Defining __eq__(), which is required for
the total_ordering decorator, makes the class unhashable in Python 3.

Change-Id: Idde65b2d41490ab8318b5a8b95ea74e9b96b4e5c
Related-Bug: #1724366
Related-Bug: #1721654
Zane Bitter 2017-10-18 16:46:39 -04:00
parent fe45b745e5
commit 6a9672a264
2 changed files with 8 additions and 15 deletions

View File

@ -11,7 +11,6 @@
# License for the specific language governing permissions and limitations
# under the License.
import functools
import sys
import types
@ -47,7 +46,6 @@ def task_description(task):
return encodeutils.safe_decode(repr(task))
class Timeout(BaseException):
"""Raised when task has exceeded its allotted (wallclock) running time.
@ -78,14 +76,11 @@ class Timeout(BaseException):
return False
def __eq__(self, other):
if not isinstance(other, Timeout):
return NotImplemented
return not (self < other or other < self)
def earlier_than(self, other):
if other is None:
return True
def __lt__(self, other):
if not isinstance(other, Timeout):
return NotImplemented
assert isinstance(other, Timeout), "Invalid type for Timeout compare"
return self._duration.endtime() < other._duration.endtime()
@ -245,7 +240,7 @@ class TaskRunner(object):
if timeout is not None:
new_timeout = Timeout(self, timeout)
if self._timeout is None or new_timeout < self._timeout:
if new_timeout.earlier_than(self._timeout):
self._timeout = new_timeout
done = self.step() if resuming else self.done()
@ -281,7 +276,7 @@ class TaskRunner(object):
timeout = TimedCancel(self, grace_period)
if self._timeout is None or timeout < self._timeout:
if timeout.earlier_than(self._timeout):
self._timeout = timeout
def started(self):

View File

@ -1283,10 +1283,8 @@ class TimeoutTest(common.HeatTestCase):
later = scheduler.Timeout(task, 10)
self.assertLess(earlier, later)
self.assertGreater(later, earlier)
self.assertEqual(earlier, earlier)
self.assertNotEqual(earlier, later)
class DescriptionTest(common.HeatTestCase):