diff --git a/README.rst b/README.rst index 7715b8f..011cbde 100644 --- a/README.rst +++ b/README.rst @@ -272,6 +272,10 @@ Version History * Add python 3.9 and 3.10 to the test matrix. + * Preserve lexigraphical order of hashes for the output of the + ``get_releases_hashes`` function. + See https://github.com/peterbe/hashin/issues/126 + 0.16.0 * Preserve indented comments when updating requirements files. See https://github.com/peterbe/hashin/issues/124 diff --git a/hashin.py b/hashin.py index 27ecc62..b2937d8 100755 --- a/hashin.py +++ b/hashin.py @@ -246,7 +246,7 @@ def run_packages( maybe_restriction = "" if not restriction else "; {0}".format(restriction) new_lines = "{0}=={1}{2} \\\n".format(req, data["version"], maybe_restriction) padding = " " * 4 - for i, release in enumerate(sorted(data["hashes"], key=lambda r: r["hash"])): + for i, release in enumerate(data["hashes"]): new_lines += "{0}--hash={1}:{2}".format(padding, algorithm, release["hash"]) if i != len(data["hashes"]) - 1: new_lines += " \\" @@ -707,8 +707,9 @@ def get_package_hashes( else: raise PackageError("No releases could be found for {0}".format(version)) - hashes = list( - get_releases_hashes(releases=releases, algorithm=algorithm, verbose=verbose) + hashes = sorted( + get_releases_hashes(releases=releases, algorithm=algorithm, verbose=verbose), + key=lambda r: r["hash"], ) return {"package": package, "version": version, "hashes": hashes} diff --git a/tests/test_cli.py b/tests/test_cli.py index 0ba7f74..725a159 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -2370,10 +2370,10 @@ def mocked_get(url, **options): "version": "0.10", "hashes": [ { - "hash": "45d1c5d2237a3b4f78b4198709fb2ecf1f781c8234ce3d94356f2100a36739433952c6c13b2843952f608949e6baa9f95055a314487cd8fb3f9d76522d8edb50" + "hash": "0d63bf4c115154781846ecf573049324f06b021a1d4b92da4fae2bf491da2b83a13096b14d73e73cefad36855f4fa936bac4b2357dabf05a2b1e7329ff1e5455" }, { - "hash": "0d63bf4c115154781846ecf573049324f06b021a1d4b92da4fae2bf491da2b83a13096b14d73e73cefad36855f4fa936bac4b2357dabf05a2b1e7329ff1e5455" + "hash": "45d1c5d2237a3b4f78b4198709fb2ecf1f781c8234ce3d94356f2100a36739433952c6c13b2843952f608949e6baa9f95055a314487cd8fb3f9d76522d8edb50" }, { "hash": "c32e6d9fb09dc36ab9222c4606a1f43a2dcc183a8c64bdd9199421ef779072c174fa044b155babb12860cf000e36bc4d358694fa22420c997b1dd75b623d4daa" @@ -2442,6 +2442,48 @@ def mocked_get(url, **options): hashin.get_package_hashes(package="uggamugga") +def test_get_package_hashes_consistant_order(murlopen): + def mocked_get(url, **options): + if url == "https://pypi.org/pypi/hashin/json": + return _Response( + { + "info": {"version": "0.10", "name": "hashin"}, + "releases": { + "0.10": [ + { + "url": "https://pypi.org/packages/3.3/p/hashin/hashin-0.10-py3-none-any.whl", + "digests": {"sha256": "bbbbb"}, + }, + { + "url": "https://pypi.org/packages/source/p/hashin/hashin-0.10.tar.gz", + "digests": {"sha256": "ccccc"}, + }, + { + "url": "https://pypi.org/packages/2.7/p/hashin/hashin-0.10-py2-none-any.whl", + "digests": {"sha256": "aaaaa"}, + }, + ] + }, + } + ) + + raise NotImplementedError(url) + + murlopen.side_effect = mocked_get + + result = hashin.get_package_hashes( + package="hashin", version="0.10", algorithm="sha256" + ) + + expected = { + "package": "hashin", + "version": "0.10", + "hashes": [{"hash": "aaaaa"}, {"hash": "bbbbb"}, {"hash": "ccccc"}], + } + + assert result == expected + + def test_with_extras_syntax(murlopen, tmpfile): """When you want to add the hashes of a package by using the "extras notation". E.g `requests[security]`.