|
1 | 1 | """ |
2 | 2 | Creation and extension of validators, with implementations for existing drafts. |
3 | 3 | """ |
| 4 | +from collections import deque |
4 | 5 | from collections.abc import Sequence |
5 | 6 | from functools import lru_cache |
6 | 7 | from urllib.parse import unquote, urldefrag, urljoin, urlsplit |
@@ -717,16 +718,14 @@ def resolving(self, ref): |
717 | 718 | self.pop_scope() |
718 | 719 |
|
719 | 720 | def _finditem(self, schema, key): |
720 | | - results = [] |
721 | | - if isinstance(schema, dict): |
722 | | - if key in schema: |
723 | | - results.append(schema) |
724 | | - |
725 | | - for v in schema.values(): |
726 | | - if isinstance(v, dict): |
727 | | - results += self._finditem(v, key) |
728 | | - |
729 | | - return results |
| 721 | + values = deque([schema]) |
| 722 | + while values: |
| 723 | + each = values.pop() |
| 724 | + if not isinstance(each, dict): |
| 725 | + continue |
| 726 | + if key in each: |
| 727 | + yield each |
| 728 | + values.extendleft(each.values()) |
730 | 729 |
|
731 | 730 | def resolve(self, ref): |
732 | 731 | """ |
@@ -786,6 +785,10 @@ def resolve_fragment(self, document, fragment): |
786 | 785 | for subschema in self._finditem(document, keyword): |
787 | 786 | if fragment == subschema[keyword]: |
788 | 787 | return subschema |
| 788 | + for keyword in ["id", "$id"]: |
| 789 | + for subschema in self._finditem(document, keyword): |
| 790 | + if "#" + fragment == subschema[keyword]: |
| 791 | + return subschema |
789 | 792 |
|
790 | 793 | # Resolve via path |
791 | 794 | parts = unquote(fragment).split("/") if fragment else [] |
|
0 commit comments