You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

81 lines
2.2 KiB

  1. class HashKey:
  2. _crasher = None
  3. def __init__(self, hash, name, *, error_on_eq_to=None):
  4. assert hash != -1
  5. self.name = name
  6. self.hash = hash
  7. self.error_on_eq_to = error_on_eq_to
  8. def __repr__(self):
  9. if self._crasher is not None and self._crasher.error_on_repr:
  10. raise ReprError
  11. return '<Key name:{} hash:{}>'.format(self.name, self.hash)
  12. def __hash__(self):
  13. if self._crasher is not None and self._crasher.error_on_hash:
  14. raise HashingError
  15. return self.hash
  16. def __eq__(self, other):
  17. if not isinstance(other, HashKey):
  18. return NotImplemented
  19. if self._crasher is not None and self._crasher.error_on_eq:
  20. raise EqError
  21. if self.error_on_eq_to is not None and self.error_on_eq_to is other:
  22. raise ValueError('cannot compare {!r} to {!r}'.format(self, other))
  23. if other.error_on_eq_to is not None and other.error_on_eq_to is self:
  24. raise ValueError('cannot compare {!r} to {!r}'.format(other, self))
  25. return (self.name, self.hash) == (other.name, other.hash)
  26. class KeyStr(str):
  27. def __hash__(self):
  28. if HashKey._crasher is not None and HashKey._crasher.error_on_hash:
  29. raise HashingError
  30. return super().__hash__()
  31. def __eq__(self, other):
  32. if HashKey._crasher is not None and HashKey._crasher.error_on_eq:
  33. raise EqError
  34. return super().__eq__(other)
  35. def __repr__(self, other):
  36. if HashKey._crasher is not None and HashKey._crasher.error_on_repr:
  37. raise ReprError
  38. return super().__eq__(other)
  39. class HashKeyCrasher:
  40. def __init__(self, *, error_on_hash=False, error_on_eq=False,
  41. error_on_repr=False):
  42. self.error_on_hash = error_on_hash
  43. self.error_on_eq = error_on_eq
  44. self.error_on_repr = error_on_repr
  45. def __enter__(self):
  46. if HashKey._crasher is not None:
  47. raise RuntimeError('cannot nest crashers')
  48. HashKey._crasher = self
  49. def __exit__(self, *exc):
  50. HashKey._crasher = None
  51. class HashingError(Exception):
  52. pass
  53. class EqError(Exception):
  54. pass
  55. class ReprError(Exception):
  56. pass