From a838aca9e1253651ede7096c1c7809a25e7a60ae Mon Sep 17 00:00:00 2001 From: Jon Dufresne Date: Thu, 1 Jun 2017 06:44:33 -0700 Subject: [PATCH] Allow editable packages in requirements.in with --generate-hashes --- piptools/repositories/pypi.py | 11 +++++++---- tests/test_cli.py | 23 +++++++++++++++++++++++ tests/test_repository_pypi.py | 9 +++++++++ 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/piptools/repositories/pypi.py b/piptools/repositories/pypi.py index 26b0d080c..edc2e57a3 100644 --- a/piptools/repositories/pypi.py +++ b/piptools/repositories/pypi.py @@ -159,13 +159,16 @@ def get_dependencies(self, ireq): def get_hashes(self, ireq): """ - Given a pinned InstallRequire, returns a set of hashes that represent - all of the files for a given requirement. It is not acceptable for an - editable or unpinned requirement to be passed to this function. + Given an InstallRequirement, return a set of hashes that represent all + of the files for a given requirement. Editable requirements return an + empty set. Unpinned requirements raise a TypeError. """ + if ireq.editable: + return set() + if not is_pinned_requirement(ireq): raise TypeError( - "Expected pinned requirement, not unpinned or editable, got {}".format(ireq)) + "Expected pinned requirement, got {}".format(ireq)) # We need to get all of the candidates that match our current version # pin, these will represent all of the files that could possibly diff --git a/tests/test_cli.py b/tests/test_cli.py index d4aef076d..2c2d1fd69 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -315,3 +315,26 @@ def test_upgrade_packages_option(tmpdir): assert out.exit_code == 0 assert 'small-fake-a==0.1' in out.output assert 'small-fake-b==0.2' in out.output + + +def test_generate_hashes_with_editable(): + runner = CliRunner() + with runner.isolated_filesystem(): + with open('requirements.in', 'w') as fp: + fp.write('-e git+https://github.com/django/django.git@1.11.1#egg=django\n') + fp.write('pytz==2017.2\n') + out = runner.invoke(cli, ['--generate-hashes']) + expected = ( + '#\n' + '# This file is autogenerated by pip-compile\n' + '# To update, run:\n' + '#\n' + '# pip-compile --generate-hashes --output-file requirements.txt requirements.in\n' + '#\n' + '-e git+https://github.com/django/django.git@1.11.1#egg=django\n' + 'pytz==2017.2 \\\n' + ' --hash=sha256:d1d6729c85acea5423671382868627129432fba9a89ecbb248d8d1c7a9f01c67 \\\n' + ' --hash=sha256:f5c056e8f62d45ba8215e5cb8f50dfccb198b4b9fbea8500674f3443e4689589\n' + ) + assert out.exit_code == 0 + assert expected in out.output diff --git a/tests/test_repository_pypi.py b/tests/test_repository_pypi.py index 97c4156de..60137179d 100644 --- a/tests/test_repository_pypi.py +++ b/tests/test_repository_pypi.py @@ -63,3 +63,12 @@ def test_generate_hashes_without_interfering_with_each_other(from_line): repository = PyPIRepository(pip_options, session) repository.get_hashes(from_line('cffi==1.9.1')) repository.get_hashes(from_line('matplotlib==2.0.2')) + + +def test_get_hashes_editable_empty_set(from_editable): + pip_command = get_pip_command() + pip_options, _ = pip_command.parse_args([]) + session = pip_command._build_session(pip_options) + repository = PyPIRepository(pip_options, session) + ireq = from_editable('git+https://github.com/django/django.git#egg=django') + assert repository.get_hashes(ireq) == set()