diff --git a/src/reportengine/configparser.py b/src/reportengine/configparser.py index accf9c9..bce1482 100644 --- a/src/reportengine/configparser.py +++ b/src/reportengine/configparser.py @@ -13,15 +13,14 @@ import json from copy import copy -import ruamel.yaml +from ruamel.yaml import YAMLError from reportengine import namespaces -from reportengine.utils import ChainMap, get_classmembers +from reportengine.utils import ChainMap, get_classmembers, yaml_rt from reportengine import templateparser from reportengine.baseexceptions import ErrorWithAlternatives, AsInputError log = logging.getLogger(__name__) -yaml=ruamel.yaml.YAML(typ='safe') _config_token = 'parse_' _produce_token = 'produce_' @@ -801,10 +800,10 @@ def __contains__(self, item): @classmethod def from_yaml(cls, o, *args, **kwargs): try: - return cls(yaml.load(o), *args, **kwargs) - except ruamel.yaml.YAMLError as e: + return cls(yaml_rt.load(o), *args, **kwargs) + except YAMLError as e: raise ConfigError(f"Failed to parse yaml file: {e}") def dump_lockfile(self): with open(self.environment.input_folder/"lockfile.yaml", "w+") as f: - yaml.dump(self.lockfile, stream=f) + yaml_rt.dump(self.lockfile, stream=f) diff --git a/src/reportengine/report.py b/src/reportengine/report.py index eb0043e..8f8c317 100644 --- a/src/reportengine/report.py +++ b/src/reportengine/report.py @@ -31,7 +31,6 @@ """ from __future__ import generator_stop -import os import os.path as osp import logging import subprocess @@ -41,7 +40,6 @@ import dask.distributed import jinja2 -import ruamel.yaml from . import configparser from . resourcebuilder import target_map @@ -52,10 +50,9 @@ from . import styles from . import filefinder from . import floatformatting - +from . utils import yaml_rt log = logging.getLogger(__name__) -yaml=ruamel.yaml.YAML(typ='safe') __all__ = ('report', 'Config') @@ -214,7 +211,13 @@ def meta_file(output_path, meta:(dict, type(None))=None): path = output_path/fname with open(path, 'w') as f: f.write('\n') - yaml.dump(meta, f) + #Using round_trip_dump is important here because the input dict may be a + #recursive commented map, which yaml.dump (or safe_dumo) doesn't know + #how to process correctly. + yaml_rt.explicit_start=True + yaml_rt.explicit_end=True + yaml_rt.default_flow_style=False + yaml_rt.dump(meta, f) return fname def pandoc_template(*, templatename='report.template', output_path): diff --git a/src/reportengine/templateparser.py b/src/reportengine/templateparser.py index fd27daf..27ba91d 100644 --- a/src/reportengine/templateparser.py +++ b/src/reportengine/templateparser.py @@ -9,12 +9,12 @@ from collections import namedtuple import logging -import ruamel.yaml +from ruamel.yaml import YAMLError +from reportengine.utils import yaml_safe from reportengine.targets import FuzzyTarget log = logging.getLogger(__name__) -yaml=ruamel.yaml.YAML(typ='safe') #TODO: Do a real tokenizer/lexer/parser? Would avoid having r'\s*?' @@ -45,8 +45,8 @@ def parse_assignments(args): k = m.group(1) vstring = m.group(2) try: - v = yaml.load(vstring) - except ruamel.yaml.YAMLError: + v = yaml_safe.load(vstring) + except YAMLError: raise ValueError(f"Couldn't process assignment value '{vstring}'") res.append((k, v)) else: diff --git a/src/reportengine/tests/test_app.py b/src/reportengine/tests/test_app.py index 42ea2f9..f825d9b 100644 --- a/src/reportengine/tests/test_app.py +++ b/src/reportengine/tests/test_app.py @@ -8,9 +8,7 @@ import ruamel.yaml from reportengine import app -from reportengine.tests.utils import tmp - -yaml=ruamel.yaml.YAML(typ='safe') +from reportengine.utils import yaml_safe runcard =\ @@ -61,7 +59,7 @@ def test_app_runs(tmp): #Test meta round trip with open(output_path/'meta.yaml') as f: - meta = yaml.load(f) + meta = yaml_safe.load(f) assert meta['author'] == "Zahari Kassabov" assert meta['keywords'] == ["test", "debug"] diff --git a/src/reportengine/tests/test_configparser.py b/src/reportengine/tests/test_configparser.py index 8693884..2986990 100644 --- a/src/reportengine/tests/test_configparser.py +++ b/src/reportengine/tests/test_configparser.py @@ -8,14 +8,11 @@ from collections import OrderedDict import unittest -import ruamel.yaml - -from reportengine.utils import ChainMap +from reportengine.utils import ChainMap, yaml_safe from reportengine import namespaces from reportengine.configparser import (Config, BadInputType, element_of, named_element_of, ConfigError) -yaml=ruamel.yaml.YAML(typ='safe') class BaseConfig(Config): @@ -196,7 +193,7 @@ def test_rewrite_actions(): c = BaseConfig(inp) r = c.parse_actions_(inp['actions_']) suggested_yaml = c._rewrite_old_actions(r) - newacts = yaml.load(suggested_yaml) + newacts = yaml_safe.load(suggested_yaml) newr = c.parse_actions_(newacts['actions_']) assert newr == r diff --git a/src/reportengine/utils.py b/src/reportengine/utils.py index fa9bae8..a2d5e5a 100644 --- a/src/reportengine/utils.py +++ b/src/reportengine/utils.py @@ -9,6 +9,10 @@ import re import importlib.util import pathlib +from ruamel.yaml import YAML + +yaml_rt = YAML(typ="rt") +yaml_safe = YAML(typ="safe") #TODO: Support metaclass attributes? def get_classmembers(cls, *, predicate=None):