[constraints] provide proper comparison and hashability between constraints

closes #294378.

authorAurelien Campeas <aurelien.campeas@pythonian.fr>
changeset12acdd74842b
branchdefault
phasepublic
hiddenno
parent revision#08e1055bd492 update spec file for 0.39.1
child revision#a351ddeea779 [pkg] 0.39.2
files modified by this revision
constraints.py
test/unittest_constraints.py
# HG changeset patch
# User Aurelien Campeas <aurelien.campeas@pythonian.fr>
# Date 1435844170 -7200
# Thu Jul 02 15:36:10 2015 +0200
# Node ID 12acdd74842bd7d4c651243d367c9475c817a9e9
# Parent 08e1055bd492c2e267934978589e692f388dcc03
[constraints] provide proper comparison and hashability between constraints

closes #294378.

diff --git a/constraints.py b/constraints.py
@@ -56,10 +56,20 @@
1      def failed_message(self, key, value):
2          return _('%(KEY-cstr)s constraint failed for value %(KEY-value)r'), {
3              key+'-cstr': self,
4              key+'-value': value}
5 
6 +    def __eq__(self, other):
7 +        return (self.type(), self.serialize()) == (other.type(), other.serialize())
8 +
9 +    def __ne__(self, other):
10 +        return not self == other
11 +
12 +    def __hash__(self):
13 +        return hash((self.type(), self.serialize()))
14 +
15 +
16  # possible constraints ########################################################
17 
18  class UniqueConstraint(BaseConstraint):
19      """object of relation must be unique"""
20 
diff --git a/test/unittest_constraints.py b/test/unittest_constraints.py
@@ -21,10 +21,24 @@
21  # after import *
22  from datetime import datetime, date, timedelta
23 
24  class ConstraintTC(TestCase):
25 
26 +    def test_membership(self):
27 +        s = set()
28 +        cstrs = [UniqueConstraint(),
29 +                 SizeConstraint(min=0, max=42),
30 +                 RegexpConstraint('babar', 0),
31 +                 BoundaryConstraint('>', 1),
32 +                 IntervalBoundConstraint(minvalue=0, maxvalue=42),
33 +                 StaticVocabularyConstraint((1, 2, 3)),
34 +                 FormatConstraint()]
35 +        for cstr in cstrs:
36 +            s.add(cstr)
37 +            s.add(type(cstr).deserialize(cstr.serialize()))
38 +        self.assertEqual(7, len(s))
39 +
40      def test_interval_serialization_integers(self):
41          cstr = IntervalBoundConstraint(12, 13)
42          self.assertEqual(cstr.serialize(), '12;13')
43          cstr = IntervalBoundConstraint(maxvalue=13)
44          self.assertEqual(cstr.serialize(), 'None;13')