Skip to content

Commit 0335a46

Browse files
committed
Dict validation: Keep track of matched input keys
Fixes #80.
1 parent 9221714 commit 0335a46

File tree

2 files changed

+21
-6
lines changed

2 files changed

+21
-6
lines changed

schema.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,8 @@ def validate(self, data):
114114
data = Schema(dict, error=e).validate(data)
115115
new = type(data)() # new - is a dict of the validated values
116116
x = None
117-
coverage = set() # matched schema keys
117+
matched_schema_keys = set()
118+
matched_input_keys = set()
118119
# for each key and value find a schema entry matching them, if any
119120
sorted_skeys = sorted(s, key=priority)
120121
for key, value in data.items():
@@ -133,7 +134,8 @@ def validate(self, data):
133134
x = _x
134135
raise
135136
else:
136-
coverage.add(skey)
137+
matched_schema_keys.add(skey)
138+
matched_input_keys.add(key)
137139
valid = True
138140
break
139141
if valid:
@@ -143,20 +145,20 @@ def validate(self, data):
143145
raise SchemaError(['Invalid value for key %r' % key] +
144146
x.autos, [e] + x.errors)
145147
required = set(k for k in s if type(k) is not Optional)
146-
if not required.issubset(coverage):
147-
missing_keys = required - coverage
148+
if not required.issubset(matched_schema_keys):
149+
missing_keys = required - matched_schema_keys
148150
s_missing_keys = ", ".join(repr(k) for k in missing_keys)
149151
raise SchemaError('Missing keys: ' + s_missing_keys, e)
150152
if len(new) != len(data):
151-
wrong_keys = set(data.keys()) - set(new.keys())
153+
wrong_keys = set(data.keys()) - matched_input_keys
152154
s_wrong_keys = ', '.join(repr(k) for k in sorted(wrong_keys,
153155
key=repr))
154156
raise SchemaError('Wrong keys %s in %r' % (s_wrong_keys, data),
155157
e)
156158

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

test_schema.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,3 +415,16 @@ def test_issue_83_iterable_validation_return_type():
415415
data = TestSetType(["test", "strings"])
416416
s = Schema(set([str]))
417417
assert isinstance(s.validate(data), TestSetType)
418+
419+
420+
def test_issue_80_wrong_keys_exception():
421+
s = Schema({And(str, Use(str.lower), 'id'): int})
422+
data = {'Id': 10, 'Name': 'me'}
423+
with SE:
424+
try:
425+
s.validate(data)
426+
except SchemaError as e:
427+
msg = e.args[0]
428+
assert msg.count("'Id'") == 1
429+
assert msg.count("'Name'") == 2
430+
raise

0 commit comments

Comments
 (0)