class Expander: def __init__(self, resolver): self.resolver = resolver self.accessor = StackedAccessor(resolver) self.accessing = Accessor() self.ref_walking = DictWalker(["$ref"]) self.errors = [] def expand(self, doc=None, resolver=None, ctx=None): doc = doc or self.resolver.doc resolver = resolver or self.resolver if "$ref" in doc: original = self.accessor.access(doc["$ref"]) new_doc = self.expand(original, resolver=self.accessor.resolver, ctx=ctx) self.accessor.pop_stack() return new_doc else: for path, sd in self.ref_walking.iterate(doc): try: new_sd = self.expand(sd, resolver=resolver, ctx=ctx) container = self.accessing.access(doc, path[:-1]) if not hasattr(container, "parents"): container = ChainMap(make_dict(), container) container.update(new_sd) self.accessing.assign(doc, path[:-1], container) except Exception as e: self.errors.append(ReferenceError(e, path=path[:], data=sd)) return doc
class Scaner: def __init__(self, resolver, *, store: Store): self.resolver = resolver self.store = store self.accessor = StackedAccessor(resolver) self.accessing = Accessor() self.ref_walking = DictWalker([is_ref]) self.errors = [] def scan(self, doc=None, resolver=None): if not doc and doc is not None: return doc resolver = resolver or self.resolver try: doc = doc or resolver.doc except MarkedYAMLError as e: if e.problem_mark is not None: self.errors.append(ParseError(e, store=self.store)) if doc is None: doc = {} doc, _ = self._scan(doc, resolver=resolver, seen={}) return doc def _scan(self, doc, *, resolver, seen: dict): if "$ref" in doc: original = self.accessor.access(doc["$ref"]) new_doc, _ = self._scan( original, resolver=self.accessor.resolver, seen=seen ) return new_doc, self.accessor.pop_stack() else: for path, sd in self.ref_walking.iterate(doc): try: uid = id(sd) if uid in seen: continue seen[uid] = sd new_sd, sresolver = self._scan(sd, resolver=resolver, seen=seen) if resolver.filename != sresolver.filename: container = self.accessing.access(doc, path[:-1]) if not hasattr(container, "parents"): container = ChainMap(make_dict(), container) container.update(new_sd) self.accessing.assign(doc, path[:-1], container) except (KeyError, FileNotFoundError) as e: self.errors.append( ReferenceError(e, store=self.store, path=path[:], data=sd) ) except MarkedYAMLError as e: if e.problem_mark is not None: self.errors.append( ParseError(e, store=self.store, path=path[:], data=sd) ) return doc, resolver
class Scaner: def __init__(self, resolver, *, store: Store): self.resolver = resolver self.store = store self.accessor = StackedAccessor(resolver) self.accessing = Accessor() self.ref_walking = DictWalker(["$ref"]) self.errors = [] def scan(self, doc=None, resolver=None, ctx=None): resolver = resolver or self.resolver try: doc = doc or resolver.doc except MarkedYAMLError as e: if e.problem_mark is not None: self.errors.append(ParseError(e, store=self.store)) if doc is None: doc = {} if "$ref" in doc: original = self.accessor.access(doc["$ref"]) new_doc = self.scan(original, resolver=self.accessor.resolver, ctx=ctx) self.accessor.pop_stack() return new_doc else: for path, sd in self.ref_walking.iterate(doc): try: new_sd = self.scan(sd, resolver=resolver, ctx=ctx) container = self.accessing.access(doc, path[:-1]) if not hasattr(container, "parents"): container = ChainMap(make_dict(), container) container.update(new_sd) self.accessing.assign(doc, path[:-1], container) except (KeyError, FileNotFoundError) as e: self.errors.append( ReferenceError(e, store=self.store, path=path[:], data=sd)) except MarkedYAMLError as e: if e.problem_mark is not None: self.errors.append( ParseError(e, store=self.store, path=path[:], data=sd)) return doc
class Loader: def __init__(self, resolver, *, store: _yaml.NodeStore): self.resolver = resolver self.accessor = StackedAccessor(resolver) self.accessing = Accessor() self.ref_walking = DictWalker([is_ref]) self.errors = [] self.store = store @property def filename(self) -> str: return self.resolver.filename def load(self, doc=None, resolver=None): if not doc and doc is not None: return doc resolver = resolver or self.resolver try: doc = doc or resolver.doc except _yaml.MarkedYAMLError as e: if e.problem_mark is not None: self.errors.append(ParseError(e, history=[resolver.filename])) if doc is None: doc = {} doc, _ = self._load(doc, resolver=resolver, seen={}) return doc def _load(self, doc, *, resolver, seen: dict): if "$ref" in doc: original = self.accessor.access(doc["$ref"]) new_doc, _ = self._load(original, resolver=self.accessor.resolver, seen=seen) return new_doc, self.accessor.pop_stack() else: for path, sd in self.ref_walking.iterate(doc): try: uid = id(sd) if uid in seen: continue seen[uid] = sd new_sd, sresolver = self._load(sd, resolver=resolver, seen=seen) if resolver.filename != sresolver.filename: container = self.accessing.access(doc, path[:-1]) if not hasattr(container, "parents"): container = ChainMap(make_dict(), container) container.update(new_sd) self.accessing.assign(doc, path[:-1], container) except FileNotFoundError as e: self.errors.append( ResolutionError( e, path=path[:], data=sd, history=[ r.filename for r in self.accessor.stack[:-1] ], )) except KeyError as e: self.errors.append( ResolutionError( e, path=path[:], data=sd, history=[r.filename for r in self.accessor.stack], )) except _yaml.MarkedYAMLError as e: if e.problem_mark is not None: self.errors.append( ParseError( e, path=path[:], data=sd, history=[ r.filename for r in self.accessor.stack ], )) return doc, resolver