Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,8 @@ def validate(self, data):
data = Schema(dict, error=e).validate(data)
new = type(data)() # new - is a dict of the validated values
x = None
coverage = set() # matched schema keys
matched_schema_keys = set()
matched_input_keys = set()
# for each key and value find a schema entry matching them, if any
sorted_skeys = sorted(s, key=priority)
for key, value in data.items():
Expand All @@ -133,7 +134,8 @@ def validate(self, data):
x = _x
raise
else:
coverage.add(skey)
matched_schema_keys.add(skey)
matched_input_keys.add(key)
valid = True
break
if valid:
Expand All @@ -143,20 +145,20 @@ def validate(self, data):
raise SchemaError(['Invalid value for key %r' % key] +
x.autos, [e] + x.errors)
required = set(k for k in s if type(k) is not Optional)
if not required.issubset(coverage):
missing_keys = required - coverage
if not required.issubset(matched_schema_keys):
missing_keys = required - matched_schema_keys
s_missing_keys = ", ".join(repr(k) for k in missing_keys)
raise SchemaError('Missing keys: ' + s_missing_keys, e)
if len(new) != len(data):
wrong_keys = set(data.keys()) - set(new.keys())
wrong_keys = set(data.keys()) - matched_input_keys
s_wrong_keys = ', '.join(repr(k) for k in sorted(wrong_keys,
key=repr))
raise SchemaError('Wrong keys %s in %r' % (s_wrong_keys, data),
e)

# Apply default-having optionals that haven't been used:
defaults = set(k for k in s if type(k) is Optional and
hasattr(k, 'default')) - coverage
hasattr(k, 'default')) - matched_schema_keys
for default in defaults:
new[default.key] = default.default

Expand Down
13 changes: 13 additions & 0 deletions test_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -415,3 +415,16 @@ def test_issue_83_iterable_validation_return_type():
data = TestSetType(["test", "strings"])
s = Schema(set([str]))
assert isinstance(s.validate(data), TestSetType)


def test_issue_80_wrong_keys_exception():
s = Schema({And(str, Use(str.lower), 'id'): int})
data = {'Id': 10, 'Name': 'me'}
with SE:
try:
s.validate(data)
except SchemaError as e:
msg = e.args[0]
assert msg.count("'Id'") == 1
assert msg.count("'Name'") == 2
raise