diff --git a/conda-recipe/meta.yaml b/conda-recipe/meta.yaml index a663664..5966a22 100644 --- a/conda-recipe/meta.yaml +++ b/conda-recipe/meta.yaml @@ -17,7 +17,7 @@ requirements: run: - python - jinja2 - - ruamel_yaml =0.15 + - ruamel.yaml >=0.15 - matplotlib - pandas >=1 - pygments diff --git a/pyproject.toml b/pyproject.toml index 299127c..4065dea 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,7 +19,7 @@ classifiers = [ description-file="README.md" requires = [ "jinja2", - "ruamel_yaml<0.18", # the code is not compatible with ruamel 0.18 + "ruamel.yaml>=0.15", "matplotlib", "pandas", "pygments", diff --git a/src/reportengine/compat.py b/src/reportengine/compat.py deleted file mode 100644 index 55eef0e..0000000 --- a/src/reportengine/compat.py +++ /dev/null @@ -1,13 +0,0 @@ -""" -compat.py - -Fix library compatibility issues. -""" - -#To learn about the mess with yaml see this: -#https://bihttps://bitbucket.org/ruamel/yaml/issues/28/consider-making-ruamelyaml-available-as-atbucket.org/ruamel/yaml/issues/28/consider-making-ruamelyaml-available-as-a -try: - import ruamel_yaml as yaml -except ImportError: - import ruamel.yaml as yaml - diff --git a/src/reportengine/configparser.py b/src/reportengine/configparser.py index 6e3bddd..bce1482 100644 --- a/src/reportengine/configparser.py +++ b/src/reportengine/configparser.py @@ -13,10 +13,10 @@ import json from copy import copy +from ruamel.yaml import YAMLError -from reportengine.compat import yaml 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 @@ -800,10 +800,10 @@ def __contains__(self, item): @classmethod def from_yaml(cls, o, *args, **kwargs): try: - return cls(yaml.round_trip_load(o), *args, **kwargs) - except yaml.error.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, Dumper=yaml.RoundTripDumper) + yaml_rt.dump(self.lockfile, stream=f) diff --git a/src/reportengine/report.py b/src/reportengine/report.py index 956c8d7..9ca5eb9 100644 --- a/src/reportengine/report.py +++ b/src/reportengine/report.py @@ -32,16 +32,14 @@ from __future__ import generator_stop import os -import os.path as osp import logging import subprocess import shutil from collections import UserList import pathlib +import dask.distributed import jinja2 -from reportengine.compat import yaml - from . import configparser from . resourcebuilder import target_map @@ -52,18 +50,18 @@ from . import styles from . import filefinder from . import floatformatting - -import dask.distributed +from . utils import yaml_rt log = logging.getLogger(__name__) + __all__ = ('report', 'Config') def _process_template_text(source, *, filename=None): if filename: #PY36 - log.debug("Processing template %s" % osp.abspath(str(filename))) + log.debug("Processing template %s" % os.path.abspath(str(filename))) root = {} d = root @@ -111,7 +109,7 @@ class JinjaEnv(jinja2.Environment): def preprocess(self, source, name=None, filename=None): if filename: - log.debug("Processing template %s" % osp.abspath(filename)) + log.debug("Processing template %s" % os.path.abspath(filename)) root = {} d = root @@ -213,12 +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') - #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.round_trip_dump(meta, f, explicit_start=True, explicit_end=True, - default_flow_style=False) + #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 68fb5a1..27ba91d 100644 --- a/src/reportengine/templateparser.py +++ b/src/reportengine/templateparser.py @@ -9,7 +9,9 @@ from collections import namedtuple import logging -from reportengine.compat import yaml +from ruamel.yaml import YAMLError + +from reportengine.utils import yaml_safe from reportengine.targets import FuzzyTarget log = logging.getLogger(__name__) @@ -43,8 +45,8 @@ def parse_assignments(args): k = m.group(1) vstring = m.group(2) try: - v = yaml.safe_load(vstring) - except 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 e518a53..602d160 100644 --- a/src/reportengine/tests/test_app.py +++ b/src/reportengine/tests/test_app.py @@ -7,8 +7,8 @@ import pytest from reportengine import app +from reportengine.utils import yaml_safe from reportengine.tests.utils import tmp -from reportengine.compat import yaml runcard =\ """ @@ -58,7 +58,7 @@ def test_app_runs(tmp): #Test meta round trip with open(output_path/'meta.yaml') as f: - meta = yaml.safe_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 7071074..2986990 100644 --- a/src/reportengine/tests/test_configparser.py +++ b/src/reportengine/tests/test_configparser.py @@ -8,12 +8,12 @@ from collections import OrderedDict import unittest -from reportengine.compat import 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) + class BaseConfig(Config): @element_of('ys') @@ -193,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.safe_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):