-
-
Save petri/008e63aa279e940cb364a36b5cc71988 to your computer and use it in GitHub Desktop.
YAML Loader with include constructor (Python 3)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import yaml | |
import os.path | |
class LoaderMeta(type): | |
def __new__(metacls, __name__, __bases__, __dict__): | |
"""Add include constructer to class.""" | |
# register the include constructor on the class | |
cls = super().__new__(metacls, __name__, __bases__, __dict__) | |
cls.add_constructor('!include', cls.construct_include) | |
return cls | |
class Loader(yaml.Loader, metaclass=LoaderMeta): | |
"""YAML Loader with `!include` constructor.""" | |
def __init__(self, stream): | |
"""Initialise Loader.""" | |
try: | |
self._root = os.path.split(stream.name)[0] | |
except AttributeError: | |
self._root = os.path.curdir | |
super().__init__(stream) | |
def construct_include(self, node): | |
"""Include file referenced at node.""" | |
filename = os.path.abspath(os.path.join( | |
self._root, self.construct_scalar(node) | |
)) | |
extension = os.path.splitext(filename)[1].lstrip('.') | |
with open(filename, 'r') as f: | |
if extension in ('yaml', 'yml'): | |
return yaml.load(f, Loader) | |
else: | |
return ''.join(f.readlines()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment