Пример #1
0
    def load_defaults(default: Union[str, dict, MinyDict]):
        """
        Set the default keys from `defaults`:

        * str/path -> must point to a yaml/json/pickle file then
            MinyDict.from_X will be used
        * dict -> Convert that dictionnary to a resolved MinyDict
        * list -> Recursively calls load_defaults on each element, then
            sequentially update an (initially empty) MinyDict to allow
            for hierarchical defaults.

        Args:
            allow (Union[str, dict, MinyDict]): The set of allowed keys as a
                (Miny)dict or a path to a file that `minydra.MinyDict` will be able to
                load (as `json`, `pickle` or `yaml`)
        """
        # `defaults` is a path: load it with MinyDict.from_X
        if isinstance(default, (str, pathlib.Path)):
            # resolve path to file
            default = resolve_path(default)
            # ensure it exists
            assert default.exists()
            assert default.is_file()
            # check for known file formats
            if default.suffix not in {".json", ".yaml", ".yml", ".pickle", ".pkl"}:
                raise ValueError(f"{str(default)} is not a valid file extension.")
            # Load from YAML
            if default.suffix in {".yaml", ".yml"}:
                default = MinyDict.from_yaml(default)
            # Load from Pickle
            elif default.suffix in {".pickle", ".pkl"}:
                default = MinyDict.from_pickle(default)
            # Load from JSON
            else:
                default = MinyDict.from_json(default)
        # `defaults` is a dictionnary: convert it to a resolved MinyDict
        elif isinstance(default, dict):
            default = MinyDict(default).resolve()
        # `defaults` is a list: recursively call load_defaults on each element
        # then sequentially merge all dictionaries to enable hierarchical defaults
        elif isinstance(default, list):
            defaults = [Parser.load_defaults(d) for d in default]
            default = MinyDict()
            for d in defaults:
                default.update(d, strict=False)

        assert isinstance(default, MinyDict)
        return default
Пример #2
0
def test_defaults():

    examples = Path(__file__).resolve().parent.parent / "examples"
    d1 = examples / "demo.json"
    d2 = examples / "demo2.json"
    y1 = examples / "demo.yaml"

    p = MinyDict({"a": "2", "c": 3, "d": {"e": {"f": 4, "g": 5}}})
    pkl = p.to_pickle(Path(__file__).resolve().parent / "test.pkl")

    with patch.object(sys, "argv", [""]):
        args = minydra.resolved_args(defaults=p)
        assert args == p

    with patch.object(sys, "argv", ["", "d.e.f=2"]):
        args = minydra.resolved_args(defaults=p)
        assert args.d.e.f == 2

    with patch.object(sys, "argv", ["", f"@defaults={str(d1)}"]):
        args = minydra.resolved_args()
        del args["@defaults"]
        assert args.to_dict() == json.loads(d1.read_text())

    with patch.object(sys, "argv", ["", f"@defaults={str(y1)}"]):
        args = minydra.resolved_args()
        del args["@defaults"]
        assert args.to_dict() == MinyDict.from_yaml(y1)

    with patch.object(sys, "argv", ["", f"@defaults={str(pkl)}"]):
        args = minydra.resolved_args()
        del args["@defaults"]
        assert args.to_dict() == MinyDict.from_pickle(pkl)
        Path(pkl).unlink()

    with pytest.raises(ValueError):
        with patch.object(
            sys, "argv", ["", f"@defaults={str(d1).replace('.json', '.py')}"]
        ):
            args = minydra.resolved_args()

    with pytest.raises(KeyError):
        with patch.object(sys, "argv", ["", f"@defaults={str(d1)}", "new_key=3"]):
            args = minydra.resolved_args()
            del args["@defaults"]
            assert args.to_dict() == json.loads(d1.read_text())

    with patch.object(
        sys, "argv", ["", f"@defaults={str(d1)}", "@strict=false", "new_key=3"]
    ):
        args = minydra.resolved_args(keep_special_kwargs=False)
        target = json.loads(d1.read_text())
        target["new_key"] = 3
        assert args.to_dict() == target

    with patch.object(
        sys, "argv", ["", f"@defaults={str(d1)}", "@strict=false", "new_key=3"]
    ):
        args = minydra.resolved_args()
        del args["@defaults"]
        del args["@strict"]
        target = json.loads(d1.read_text())
        target["new_key"] = 3
        assert args.to_dict() == target

    double_defaults = f"['{str(d1)}', '{str(d2)}']"
    with patch.object(sys, "argv", ["", f"@defaults={double_defaults}", "new_key=3"]):
        args = minydra.resolved_args()
        d1d = MinyDict.from_json(d1)
        d2d = MinyDict.from_json(d2)
        d1d = d1d.update(d2d)
        del args["@defaults"]
        assert args == d1d
Пример #3
0
def test_dump_json():
    d = MinyDict({"a": 1, "b": 2, "u": "x", "r": {"t": 5}})
    p = Path(d.to_json("d.json", verbose=1))
    assert MinyDict.from_json(p) == d
    p.unlink()