From 9de8d1e0faf6cc9460cd2e1e30835ac64fc6ff4d Mon Sep 17 00:00:00 2001 From: Ruslan Kuprieiev Date: Wed, 25 Mar 2020 06:17:09 +0200 Subject: [PATCH] params: use dpath for xpaths (#3531) Currently `dvc run -p angles` is broken when you use it with `params.yaml` that looks like this: ``` angles: - 2 - 3 - 100 - 3.2 - 36.2 - 3.6 ``` because we are incorrectly using `flatten` instead of simply using some xpath-like library to access params that are specified. --- dvc/dependency/param.py | 10 +++++----- setup.py | 1 + tests/unit/dependency/test_params.py | 6 ++++-- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/dvc/dependency/param.py b/dvc/dependency/param.py index c5cd4a2b3..bd1e2df39 100644 --- a/dvc/dependency/param.py +++ b/dvc/dependency/param.py @@ -2,9 +2,8 @@ import os import yaml from collections import defaultdict +import dpath.util from voluptuous import Any -from funcy import select_keys -from flatten_json import flatten from dvc.compat import fspath_py35 from dvc.dependency.local import DependencyLOCAL @@ -87,9 +86,10 @@ class DependencyPARAMS(DependencyLOCAL): "Unable to read parameters from '{}'".format(self) ) from exc - config = flatten(config, ".") - - return select_keys(lambda key: key in self.params, config) + ret = {} + for param in self.params: + ret[param] = dpath.util.get(config, param, separator=".") + return ret def save_info(self): info = self._get_info() diff --git a/setup.py b/setup.py index cff79d271..d9a29bbc3 100644 --- a/setup.py +++ b/setup.py @@ -81,6 +81,7 @@ install_requires = [ "flatten_json>=0.1.6", "texttable>=0.5.2", "pygtrie==2.3.2", + "dpath>=2.0.1,<3", ] diff --git a/tests/unit/dependency/test_params.py b/tests/unit/dependency/test_params.py index 72d82d099..9047cfd1d 100644 --- a/tests/unit/dependency/test_params.py +++ b/tests/unit/dependency/test_params.py @@ -70,9 +70,11 @@ def test_get_info_unsupported_format(tmp_dir, dvc): def test_get_info_nested(tmp_dir, dvc): - tmp_dir.gen("params.yaml", yaml.dump({"some": {"path": {"foo": "val"}}})) + tmp_dir.gen( + "params.yaml", yaml.dump({"some": {"path": {"foo": ["val1", "val2"]}}}) + ) dep = DependencyPARAMS(Stage(dvc), None, ["some.path.foo"]) - assert dep._get_info() == {"some.path.foo": "val"} + assert dep._get_info() == {"some.path.foo": ["val1", "val2"]} def test_save_info_missing_params(dvc):