diff --git a/CHANGELOG.rst b/CHANGELOG.rst index f871c70..04b8ab5 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,6 +2,14 @@ CHANGELOG ========= +UNRELEASED +---------- + +* Dependency order is no longer sorted automatically, instead the order is preserved as they are defined in the ``*.devenv.yml`` files. + Usually this would not matter, but it is important for ``pip`` dependencies which declare development installations, as it is important + that those happen in the specified order. + + 3.2.1 (2024-01-03) ------------------ diff --git a/src/conda_devenv/devenv.py b/src/conda_devenv/devenv.py index 3385d87..bf21a41 100644 --- a/src/conda_devenv/devenv.py +++ b/src/conda_devenv/devenv.py @@ -403,15 +403,15 @@ def merge_dependencies_version_specifications( else: raise UsageError(f"Only strings and dicts are supported, got: {dep!r}") - result = set() + # keep the order of dependencies + result: dict[str, Any] = collections.OrderedDict() for dep_name, dep_version_matchers in new_dependencies.items(): if len(dep_version_matchers) > 0: - result.add(dep_name + " " + ",".join(dep_version_matchers)) + result[dep_name + " " + ",".join(dep_version_matchers)] = None else: - result.add(dep_name) + result[dep_name] = None - new_dict_dependencies = sorted(new_dict_dependencies, key=lambda x: list(x.keys())) - yaml_dict[key_to_merge] = sorted(result) + new_dict_dependencies + yaml_dict[key_to_merge] = list(result.keys()) + new_dict_dependencies @dataclass(frozen=True) diff --git a/tests/test_load_yaml_dict.py b/tests/test_load_yaml_dict.py index cb51e7c..fc5bbe6 100644 --- a/tests/test_load_yaml_dict.py +++ b/tests/test_load_yaml_dict.py @@ -191,6 +191,17 @@ def test_downstream_overrides_platforms(tmp_path) -> None: } +def test_load_yaml_dict_dependency_order(datadir) -> None: + """ + Make sure the order of channels and pip dependencies is preserved + """ + conda_yaml_dict = load_yaml_dict(datadir / "deps_order.yml") + channels = conda_yaml_dict["channels"] + assert channels == ["pytorch", "nvidia", "conda-forge", "bioconda"] + pip_dependencies = conda_yaml_dict["dependencies"][3] + assert pip_dependencies["pip"] == ["-e c-package", "-e b-package", "-e D-package"] + + class TestConstraints: def test_no_constraints(self) -> None: data = {"dependencies": ["attrs >19", "boltons"]} diff --git a/tests/test_load_yaml_dict/deps_order.yml b/tests/test_load_yaml_dict/deps_order.yml new file mode 100644 index 0000000..b2ab624 --- /dev/null +++ b/tests/test_load_yaml_dict/deps_order.yml @@ -0,0 +1,16 @@ +name: test-env + +channels: + - pytorch + - nvidia + - conda-forge + - bioconda + +dependencies: + - pytorch + - numpy + - scikit-image + - pip: + - "-e c-package" + - "-e b-package" + - "-e D-package"