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
Handle type refs in _map_refs #166
Changes from 8 commits
2b63643
2a903ec
5d6ca96
ca536a2
744027b
79e6e03
e43cc5d
a350bf1
8d97853
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -60,28 +60,39 @@ def _map_refs(node: dict, on_refs: Callable[[str], dict]) -> dict: | |
Note: _map_refs is shallow, i.e., if calling `on_refs` on a node produces | ||
a new node that contains refs, those refs will not be resolved. | ||
""" | ||
if isinstance(node, collections.abc.Mapping) and '$ref' in node: | ||
extra_keys = set(node.keys()).difference({'$ref', '$comment'}) | ||
if extra_keys: | ||
# As for json-schema.org: | ||
# "... You will always use $ref as the only key in an object: | ||
# any other keys you put there will be ignored by the validator." | ||
# So we raise on that, to notify schema creator that s/he should not | ||
# expect those additional keys to be verified by schema validator. | ||
raise Exception(f"Schema node with '$ref' should not contain anything else (besides '$comment' for docs). \ | ||
\nOn: {node} \nOffending keys {extra_keys}") | ||
|
||
# We found a ref, so return it mapped through `on_refs` | ||
new_node = on_refs(node['$ref']) | ||
# Plus concatenated new and old '$comment' fields | ||
# which should be just ignored anyways. | ||
if '$comment' in new_node or '$comment' in node: | ||
new_node['$comment'] = new_node.get('$comment', '') + node.get('$comment', '') | ||
return new_node | ||
elif isinstance(node, collections.abc.Mapping): | ||
# Look for all refs in this mapping | ||
for k, v in node.items(): | ||
node[k] = _map_refs(v, on_refs) | ||
if isinstance(node, collections.abc.Mapping): | ||
if '$ref' in node or 'type_ref' in node: | ||
ref_key = '$ref' if '$ref' in node else 'type_ref' | ||
|
||
if ref_key == '$ref': | ||
extra_keys = set(node.keys()).difference({'$ref', '$comment'}) | ||
if extra_keys: | ||
# As for json-schema.org: | ||
# "... You will always use $ref as the only key in an object: | ||
# any other keys you put there will be ignored by the validator." | ||
# So we raise on that, to notify schema creator that s/he should not | ||
# expect those additional keys to be verified by schema validator. | ||
raise Exception(f"Schema node with '$ref' should not contain anything else (besides '$comment' for docs). \ | ||
\nOn: {node} \nOffending keys {extra_keys}") | ||
|
||
# We found a ref, so return it mapped through `on_refs` | ||
new_node = on_refs(node[ref_key]) | ||
|
||
if ref_key == 'type_ref': | ||
# For type_ref's, we don't want to clobber the other properties in node, | ||
# so merge new_node and node. | ||
new_node.update(node) | ||
|
||
# Plus concatenated new and old '$comment' fields | ||
# which should be just ignored anyways. | ||
if '$comment' in new_node or '$comment' in node: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As comments contain development related TODOs and stuff and we're now sending links to these docs to people, I think we should leave comments to ourselves and not add them in a visible manner to the docs. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nevermind |
||
new_node['$comment'] = new_node.get( | ||
'$comment', '') + node.get('$comment', '') | ||
return new_node | ||
else: | ||
# Look for all refs further down in this mapping | ||
for k, v in node.items(): | ||
node[k] = _map_refs(v, on_refs) | ||
elif isinstance(node, (list, tuple)): | ||
# Look for all refs in this list | ||
for i in range(len(node)): | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure how this works, I though map_refs will be called whenever json schema walker walks into a node with '$ref'. So from that understanding it will not be called at all on some
node : {"type_ref": "..."}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think
_map_refs
is the json schema walker you're referring to? On the next line, we look for$ref
s andtype_ref
s, then handle each case slightly differently. The testtest_json_validation.test_map_refs
might be a bit helpful, too.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
never mind