diff --git a/conda/models/match_spec.py b/conda/models/match_spec.py index 63bb7a1c6d9..0feeb3d0ace 100644 --- a/conda/models/match_spec.py +++ b/conda/models/match_spec.py @@ -144,7 +144,8 @@ class MatchSpec(metaclass=MatchSpecType): - version - build must be given as exact values. In the future, the namespace field will be added to this list. - Alternatively, an exact spec is given by '*[md5=12345678901234567890123456789012]'. + Alternatively, an exact spec is given by '*[md5=12345678901234567890123456789012]' + or '*[sha256=f453db4ffe2271ec492a2913af4e61d4a6c118201f07de757df0eff769b65d2e]'. """ FIELD_NAMES = ( @@ -158,6 +159,7 @@ class MatchSpec(metaclass=MatchSpecType): "features", "url", "md5", + "sha256", "license", "license_family", "fn", diff --git a/docs/source/configuration.rst b/docs/source/configuration.rst index addb21b002c..d8b409f4075 100644 --- a/docs/source/configuration.rst +++ b/docs/source/configuration.rst @@ -1,5 +1,5 @@ Conda configuration =================== -.. program-output:: cd .. && python -c 'import os; import sys; src_dir = here = os.path.abspath(os.path.dirname("../setup.py")); sys.path.insert(0, src_dir); import conda.cli.main_config; print(conda.cli.main_config.describe_all_parameters())' +.. program-output:: python -c 'import conda.cli.main_config; print(conda.cli.main_config.describe_all_parameters())' :shell: diff --git a/docs/source/user-guide/concepts/pkg-search.rst b/docs/source/user-guide/concepts/pkg-search.rst index e20e48be55d..25461328f52 100644 --- a/docs/source/user-guide/concepts/pkg-search.rst +++ b/docs/source/user-guide/concepts/pkg-search.rst @@ -40,6 +40,11 @@ example image. The search below will return the same list of packages as the sta $ conda search "numpy[channel=conda-forge, subdir=linux-64, version=1.17.*, build=py38*]" +This notation supports the following key-value pairs: + +.. program-output:: python -c 'import conda.models.match_spec as M; print("-", "\n- ".join([f"{field:20} # validated via {M._implementors.get(field, M.ExactStrMatch).__name__}" for field in sorted(M.MatchSpec.FIELD_NAMES)]))' + :shell: + Key-value pair notation can be used at the same time as standard notation. .. code-block:: none diff --git a/news/12707-sha256-matchspec b/news/12707-sha256-matchspec new file mode 100644 index 00000000000..af77d5d515b --- /dev/null +++ b/news/12707-sha256-matchspec @@ -0,0 +1,21 @@ +### Enhancements + +* Add support for `sha256` filters in the MatchSpec syntax + (e.g. `*[sha256=f453db4ffe2271ec492a2913af4e61d4a6c118201f07de757df0eff769b65d2e]`). + (#12654 via #12707) + +### Bug fixes + +* + +### Deprecations + +* + +### Docs + +* + +### Other + +* diff --git a/tests/models/test_match_spec.py b/tests/models/test_match_spec.py index ca97e624cba..0bb00beed6c 100644 --- a/tests/models/test_match_spec.py +++ b/tests/models/test_match_spec.py @@ -1216,32 +1216,37 @@ def test_build_number_merge(self): with pytest.raises(ValueError): MatchSpec.merge(specs) - def test_md5_merge_with_name(self): - specs = ( - MatchSpec("python[md5=deadbeef]"), - MatchSpec("python=1.2.3"), - MatchSpec("conda-forge::python[md5=deadbeef]"), - ) - merged = MatchSpec.merge(specs) - assert len(merged) == 1 - assert str(merged[0]) == "conda-forge::python=1.2.3[md5=deadbeef]" - - specs = ( - MatchSpec("python[md5=FFBADD11]"), - MatchSpec("python=1.2.3"), - MatchSpec("python[md5=ffbadd11]"), - ) - with pytest.raises(ValueError): - MatchSpec.merge(specs) - - def test_md5_merge_wo_name(self): - specs = (MatchSpec("*[md5=deadbeef]"), MatchSpec("*[md5=FFBADD11]")) - merged = MatchSpec.merge(specs) - assert len(merged) == 2 - str_specs = ("*[md5=deadbeef]", "*[md5=FFBADD11]") - assert str(merged[0]) in str_specs - assert str(merged[1]) in str_specs - assert str(merged[0]) != str(merged[1]) + def test_hash_merge_with_name(self): + for hash_type in ("md5", "sha256"): + specs = ( + MatchSpec(f"python[{hash_type}=deadbeef]"), + MatchSpec("python=1.2.3"), + MatchSpec(f"conda-forge::python[{hash_type}=deadbeef]"), + ) + merged = MatchSpec.merge(specs) + assert len(merged) == 1 + assert str(merged[0]) == f"conda-forge::python=1.2.3[{hash_type}=deadbeef]" + + specs = ( + MatchSpec(f"python[{hash_type}=FFBADD11]"), + MatchSpec("python=1.2.3"), + MatchSpec(f"python[{hash_type}=ffbadd11]"), + ) + with pytest.raises(ValueError): + MatchSpec.merge(specs) + + def test_hash_merge_wo_name(self): + for hash_type in ("md5", "sha256"): + specs = ( + MatchSpec(f"*[{hash_type}=deadbeef]"), + MatchSpec(f"*[{hash_type}=FFBADD11]"), + ) + merged = MatchSpec.merge(specs) + assert len(merged) == 2 + str_specs = (f"*[{hash_type}=deadbeef]", f"*[{hash_type}=FFBADD11]") + assert str(merged[0]) in str_specs + assert str(merged[1]) in str_specs + assert str(merged[0]) != str(merged[1]) def test_catch_invalid_regexes(self): # Crashing case via fuzzing found via fuzzing. Reported here: https://github.com/conda/conda/issues/11999