Skip to content

Commit

Permalink
Merge pull request #476 from mattlong/ISSUE-446
Browse files Browse the repository at this point in the history
Keep second-level requirements for editable reqs after round one
  • Loading branch information
davidovich authored Mar 29, 2017
2 parents 7acc4de + cb7c0bc commit f945f6b
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 22 deletions.
3 changes: 3 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[flake8]
max-line-length = 120
exclude = build/*, dist/*, pip_tools.egg-info/*
31 changes: 19 additions & 12 deletions piptools/repositories/pypi.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ def __init__(self, pip_options, session):
# project
self._available_candidates_cache = {}

# stores InstallRequirement => list(InstallRequirement) mappings
# of all secondary dependencies for the given requirement, so we
# only have to go to disk once for each requirement
self._dependencies_cache = {}

# Setup file paths
self.freshen_build_caches()
self._download_dir = os.path.join(CACHE_DIR, 'pkgs')
Expand Down Expand Up @@ -125,18 +130,20 @@ def get_dependencies(self, ireq):
if not (ireq.editable or is_pinned_requirement(ireq)):
raise TypeError('Expected pinned or editable InstallRequirement, got {}'.format(ireq))

if not os.path.isdir(self._download_dir):
os.makedirs(self._download_dir)
if not os.path.isdir(self._wheel_download_dir):
os.makedirs(self._wheel_download_dir)

reqset = RequirementSet(self.build_dir,
self.source_dir,
download_dir=self._download_dir,
wheel_download_dir=self._wheel_download_dir,
session=self.session)
dependencies = reqset._prepare_file(self.finder, ireq)
return set(dependencies)
if ireq not in self._dependencies_cache:

if not os.path.isdir(self._download_dir):
os.makedirs(self._download_dir)
if not os.path.isdir(self._wheel_download_dir):
os.makedirs(self._wheel_download_dir)

reqset = RequirementSet(self.build_dir,
self.source_dir,
download_dir=self._download_dir,
wheel_download_dir=self._wheel_download_dir,
session=self.session)
self._dependencies_cache[ireq] = reqset._prepare_file(self.finder, ireq)
return set(self._dependencies_cache[ireq])

def get_hashes(self, ireq):
"""
Expand Down
26 changes: 16 additions & 10 deletions piptools/scripts/compile.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,16 +93,7 @@ def cli(verbose, dry_run, pre, rebuild, find_links, index_url, extra_index_url,
# Setup
###

# Use pip's parser for pip.conf management and defaults.
# General options (find_links, index_url, extra_index_url, trusted_host,
# and pre) are defered to pip.
pip_command = PipCommand()
index_opts = pip.cmdoptions.make_option_group(
pip.cmdoptions.index_group,
pip_command.parser,
)
pip_command.parser.insert_option_group(0, index_opts)
pip_command.parser.add_option(optparse.Option('--pre', action='store_true', default=False))
pip_command = get_pip_command()

pip_args = []
if find_links:
Expand Down Expand Up @@ -233,3 +224,18 @@ def cli(verbose, dry_run, pre, rebuild, find_links, index_url, extra_index_url,

if dry_run:
log.warning('Dry-run, so nothing updated.')


def get_pip_command():
# Use pip's parser for pip.conf management and defaults.
# General options (find_links, index_url, extra_index_url, trusted_host,
# and pre) are defered to pip.
pip_command = PipCommand()
index_opts = pip.cmdoptions.make_option_group(
pip.cmdoptions.index_group,
pip_command.parser,
)
pip_command.parser.insert_option_group(0, index_opts)
pip_command.parser.add_option(optparse.Option('--pre', action='store_true', default=False))

return pip_command
9 changes: 9 additions & 0 deletions tests/fixtures/small_fake_package/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from setuptools import setup

setup(
name='small_fake_with_deps',
version=0.1,
install_requires=[
"six==1.10.0",
],
)
46 changes: 46 additions & 0 deletions tests/test_top_level_editable.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import os
import pytest

from piptools.repositories import PyPIRepository
from piptools.scripts.compile import get_pip_command


class MockedPyPIRepository(PyPIRepository):
def get_dependencies(self, ireq):
# "mock" everything but editable reqs to avoid disk and network I/O
# when possible
if not ireq.editable:
return set()

return super(MockedPyPIRepository, self).get_dependencies(ireq)


def _get_repository():
pip_command = get_pip_command()
pip_args = []
pip_options, _ = pip_command.parse_args(pip_args)
session = pip_command._build_session(pip_options)
repository = MockedPyPIRepository(pip_options, session)
return repository


@pytest.mark.parametrize(
('input', 'expected'),
((tup) for tup in [
([os.path.join(os.path.dirname(__file__), 'fixtures', 'small_fake_package')],
['six']),
])
)
def test_editable_top_level_deps_preserved(base_resolver, repository, from_editable, input, expected):
input = [from_editable(line) for line in input]
repository = _get_repository()
output = base_resolver(input, prereleases=False, repository=repository).resolve()

output = set([p.name for p in output])

# sanity check that we're expecting something
assert output != set()

for package_name in expected:
assert package_name in output

0 comments on commit f945f6b

Please sign in to comment.