-
Notifications
You must be signed in to change notification settings - Fork 215
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Two tuples as dictionary keys report a false alarm of SchemaMissingKeyError #312
Comments
when checking a dict, keys from schema are checked against keys of data dict. This means the codes execute at some stage: Schema(('map_point', 'to', 'map_polygon')).validate(('map_point', 'to', 'map_polygon'))
# and
Schema(('map_point', 'to', 'map_polygon')).validate(('map_polygon', 'to', 'map_polygon')) which both validate considering the way class Schema(object):
(...)
def validate(self, data: Any, **kwargs: Dict[str, Any]) -> Any:
(...)
for key, value in data_items:
for skey in sorted_skeys:
svalue = s[skey]
try:
- nkey = Schema(skey, error=e).validate(key, **kwargs)
+ Schema(hash(skey), error=e).validate(hash(key), **kwargs)
+ nkey = skey
except SchemaError:
pass
else:
if isinstance(skey, Hook):
(...) it works for you case @tjyuyao but sadly it breaks a lot of tests 😞 |
restricting this to proposed solution: with exitstack:
# Evaluate dictionaries last
data_items = sorted(data.items(), key=lambda value: isinstance(value[1], dict))
for key, value in data_items:
for skey in sorted_skeys:
svalue = s[skey]
try:
if isinstance(skey, (tuple, frozenset)):
Schema(hash(skey), error=e).validate(hash(key), **kwargs)
nkey = skey
else:
nkey = Schema(skey, error=e).validate(key, **kwargs)
except SchemaError:
pass
else: tests to add: def test_tuple_key_of_dict():
# this is a simplified regression test of the bug in github issue #312
assert Schema({('map_point', 'to', 'map_polygon'): {}}).validate(
{('map_point', 'to', 'map_polygon'): {}}
) == {('map_point', 'to', 'map_polygon'): {}}
with SE:
assert Schema({('map_point', 'to', 'map_polygon'): {}}).validate(
{('map_polygon', 'to', 'map_polygon'): {}}
) == {('map_polygon', 'to', 'map_polygon'): {}}
def test_frozenset_key_of_dict():
# this is a simplified regression test of the bug in github issue #312
assert Schema({frozenset(('map_point', 'to', 'map_polygon')): {}}).validate(
{frozenset(('map_point', 'to', 'map_polygon')): {}}
) == {frozenset(('map_point', 'to', 'map_polygon')): {}}
with SE:
assert Schema({frozenset(('map_point', 'to', 'map_polygon')): {}}).validate(
{frozenset(('map_polygon', 'to', 'map_polygon')): {}}
) == {frozenset(('map_polygon', 'to', 'map_polygon')): {}} @keleshev @skorokithakis @sjakobi @dblanchette or other maintainer, are you fine with this solution ? |
I am using schema 0.7.5 and python 3.11.
Following is a minimal code to reproduce
It will give the error:
The expected behavior is to pass the validation without raise the error.
The text was updated successfully, but these errors were encountered: