Skip to content

Commit d82601e

Browse files
dtaotusharmakkar08
authored andcommitted
make Schema.__eq__ deterministic (#316)
* add test for schema equality and fix Schema.__eq__ to deal with dicts properly (fixes #315) * add negative equality tests, implement Schema.__ne__ method to support != operator This fills in missing test coverage to ensure the __eq__ method does not return True in some potentially unexpected cases (these tests would fail before be867c5). Previously only the __eq__ method was implemented, which could lead to surprising behavior e.g.: Schema('foo') == Schema('foo') # True Schema('foo') != Schema('foo') # True This adds the __ne__ method so that these operators are complementary as one might expect.
1 parent 9204e83 commit d82601e

2 files changed

Lines changed: 70 additions & 5 deletions

File tree

voluptuous/schema_builder.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -242,10 +242,12 @@ def value_to_schema_type(value):
242242
return cls(value_to_schema_type(data), **kwargs)
243243

244244
def __eq__(self, other):
245-
if str(other) == str(self.schema):
246-
# Because repr is combination mixture of object and schema
247-
return True
248-
return False
245+
if not isinstance(other, Schema):
246+
return False
247+
return other.schema == self.schema
248+
249+
def __ne__(self, other):
250+
return not (self == other)
249251

250252
def __str__(self):
251253
return str(self.schema)

voluptuous/tests/tests.py

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import os
44
import sys
55

6-
from nose.tools import assert_equal, assert_raises, assert_true
6+
from nose.tools import assert_equal, assert_false, assert_raises, assert_true
77

88
from voluptuous import (
99
Schema, Required, Exclusive, Optional, Extra, Invalid, In, Remove, Literal,
@@ -410,6 +410,69 @@ def test_subschema_extension():
410410
assert_equal(extended.schema, {'a': {'b': str, 'c': float, 'e': int}, 'd': str})
411411

412412

413+
def test_equality():
414+
assert_equal(Schema('foo'), Schema('foo'))
415+
416+
assert_equal(Schema(['foo', 'bar', 'baz']),
417+
Schema(['foo', 'bar', 'baz']))
418+
419+
# Ensure two Schemas w/ two equivalent dicts initialized in a different
420+
# order are considered equal.
421+
dict_a = {}
422+
dict_a['foo'] = 1
423+
dict_a['bar'] = 2
424+
dict_a['baz'] = 3
425+
426+
dict_b = {}
427+
dict_b['baz'] = 3
428+
dict_b['bar'] = 2
429+
dict_b['foo'] = 1
430+
431+
assert_equal(Schema(dict_a), Schema(dict_b))
432+
433+
434+
def test_equality_negative():
435+
"""Verify that Schema objects are not equal to string representations"""
436+
assert_false(Schema('foo') == 'foo')
437+
438+
assert_false(Schema(['foo', 'bar']) == "['foo', 'bar']")
439+
assert_false(Schema(['foo', 'bar']) == Schema("['foo', 'bar']"))
440+
441+
assert_false(Schema({'foo': 1, 'bar': 2}) == "{'foo': 1, 'bar': 2}")
442+
assert_false(Schema({'foo': 1, 'bar': 2}) == Schema("{'foo': 1, 'bar': 2}"))
443+
444+
445+
def test_inequality():
446+
assert_true(Schema('foo') != 'foo')
447+
448+
assert_true(Schema(['foo', 'bar']) != "['foo', 'bar']")
449+
assert_true(Schema(['foo', 'bar']) != Schema("['foo', 'bar']"))
450+
451+
assert_true(Schema({'foo': 1, 'bar': 2}) != "{'foo': 1, 'bar': 2}")
452+
assert_true(Schema({'foo': 1, 'bar': 2}) != Schema("{'foo': 1, 'bar': 2}"))
453+
454+
455+
def test_inequality_negative():
456+
assert_false(Schema('foo') != Schema('foo'))
457+
458+
assert_false(Schema(['foo', 'bar', 'baz']) !=
459+
Schema(['foo', 'bar', 'baz']))
460+
461+
# Ensure two Schemas w/ two equivalent dicts initialized in a different
462+
# order are considered equal.
463+
dict_a = {}
464+
dict_a['foo'] = 1
465+
dict_a['bar'] = 2
466+
dict_a['baz'] = 3
467+
468+
dict_b = {}
469+
dict_b['baz'] = 3
470+
dict_b['bar'] = 2
471+
dict_b['foo'] = 1
472+
473+
assert_false(Schema(dict_a) != Schema(dict_b))
474+
475+
413476
def test_repr():
414477
"""Verify that __repr__ returns valid Python expressions"""
415478
match = Match('a pattern', msg='message')

0 commit comments

Comments
 (0)