Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions pip/req/req_install.py
Original file line number Diff line number Diff line change
Expand Up @@ -1065,6 +1065,8 @@ def parse_editable(editable_req, default_vcs=None):
.[some_extra]
"""

from pip.index import Link

url = editable_req
extras = None

Expand All @@ -1086,17 +1088,18 @@ def parse_editable(editable_req, default_vcs=None):
url_no_extras = path_to_url(url_no_extras)

if url_no_extras.lower().startswith('file:'):
package_name = Link(url_no_extras).egg_fragment
if extras:
return (
None,
package_name,
url_no_extras,
pkg_resources.Requirement.parse(
'__placeholder__' + extras
).extras,
{},
)
else:
return None, url_no_extras, None, {}
return package_name, url_no_extras, None, {}

for version_control in vcs:
if url.lower().startswith('%s:' % version_control):
Expand Down
16 changes: 13 additions & 3 deletions pip/req/req_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,13 @@ def add_requirement(self, install_req, parent_req_name=None):
# scanning.
result = []
elif not install_req.constraint:
if (install_req.link and not (existing_req.link and
install_req.link.path == existing_req.link.path)):
self.reqs_to_cleanup.append(install_req)
raise InstallationError(
"Could not satisfy constraints for '%s': "
"installation from path or url cannot be "
"constrained to a version" % name)
# If we're now installing a constraint, mark the existing
# object for real installation.
existing_req.constraint = False
Expand All @@ -267,9 +274,12 @@ def add_requirement(self, install_req, parent_req_name=None):
return result

def has_requirement(self, project_name):
for name in project_name, project_name.lower():
if name in self.requirements or name in self.requirement_aliases:
return True
name = project_name.lower()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this change still needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, without this pip will never attempt to process the package, and we'll never return to add_requirement, silently dropping the package.

Also from what I can gather, not filtering constraints from this check we're changing the meaning of the has_requirement function from "we have this requirement and we've processed it, don't worry it's been processed" to "we either have a constraint that won't be installed, or we have a package that has actually been processed".

if (name in self.requirements and
not self.requirements[name].constraint or
name in self.requirement_aliases and
not self.requirements[self.requirement_aliases[name]].constraint):
return True
return False

@property
Expand Down
57 changes: 57 additions & 0 deletions tests/functional/test_install_reqs.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,3 +256,60 @@ def test_constraints_only_causes_error(script, data):
'install', '--no-index', '-f', data.find_links, '-c',
script.scratch_path / 'c.txt', expect_error=True)
assert 'installed requiresupper' not in result.stdout


def test_constraints_local_editable_install_causes_error(script, data):
script.scratch_path.join("constraints.txt").write(
"singlemodule==0.0.0"
)
to_install = data.src.join("singlemodule")
result = script.pip(
'install', '--no-index', '-f', data.find_links, '-c',
script.scratch_path / 'constraints.txt', '-e',
to_install, expect_error=True)
assert 'Could not satisfy constraints for' in result.stderr


def test_constraints_local_install_causes_error(script, data):
script.scratch_path.join("constraints.txt").write(
"singlemodule==0.0.0"
)
to_install = data.src.join("singlemodule")
result = script.pip(
'install', '--no-index', '-f', data.find_links, '-c',
script.scratch_path / 'constraints.txt',
to_install, expect_error=True)
assert 'Could not satisfy constraints for' in result.stderr


def test_constraints_constrain_to_local_editable(script, data):
to_install = data.src.join("singlemodule")
script.scratch_path.join("constraints.txt").write(
"-e file://%s#egg=singlemodule" % to_install
)
result = script.pip(
'install', '--no-index', '-f', data.find_links, '-c',
script.scratch_path / 'constraints.txt', 'singlemodule')
assert 'Running setup.py develop for singlemodule' in result.stdout


def test_constraints_constrain_to_local(script, data):
to_install = data.src.join("singlemodule")
script.scratch_path.join("constraints.txt").write(
"file://%s#egg=singlemodule" % to_install
)
result = script.pip(
'install', '--no-index', '-f', data.find_links, '-c',
script.scratch_path / 'constraints.txt', 'singlemodule')
assert 'Running setup.py install for singlemodule' in result.stdout


def test_constrained_to_url_install_same_url(script, data):
to_install = data.src.join("singlemodule")
script.scratch_path.join("constraints.txt").write(
"file://%s#egg=singlemodule" % to_install
)
result = script.pip(
'install', '--no-index', '-f', data.find_links, '-c',
script.scratch_path / 'constraints.txt', to_install)
assert 'Running setup.py install for singlemodule' in result.stdout