Skip to content

Commit

Permalink
Merge pull request #1235 from pypa/hotfix/parse_url_to_link
Browse files Browse the repository at this point in the history
Properly parse urls as Link objects
  • Loading branch information
kennethreitz committed Jan 16, 2018
2 parents e423719 + 5034ad6 commit d026a83
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 2 deletions.
15 changes: 13 additions & 2 deletions pipenv/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,7 @@ def get_requirement(dep):
:returns: :class:`requirements.Requirement` object
"""
path = None
uri = None
# Split out markers if they are present - similar to how pip does it
# See pip.req.req_install.InstallRequirement.from_line
if not any(dep.startswith(uri_prefix) for uri_prefix in SCHEME_LIST):
Expand All @@ -333,26 +334,36 @@ def get_requirement(dep):
markers = None
# Strip extras from the requirement so we can make a properly parseable req
dep, extras = pip.req.req_install._strip_extras(dep)
matches_uri = any(dep.startswith(uri_prefix) for uri_prefix in SCHEME_LIST)
# Only operate on local, existing, non-URI formatted paths
if (is_file(dep) and isinstance(dep, six.string_types) and
not any(dep.startswith(uri_prefix) for uri_prefix in SCHEME_LIST)):
if is_file(dep) and isinstance(dep, six.string_types) and not matches_uri:
dep_path = Path(dep)
# Only parse if it is a file or an installable dir
if dep_path.is_file() or (dep_path.is_dir() and pip.utils.is_installable_dir(dep)):
# Create pip Link objects for obtaining fragments and spotting wheels
dep_link = Link(dep_path.absolute().as_uri())
if dep_path.is_dir() or dep_link.is_wheel or is_archive_file(dep_path.as_posix()):
if dep_path.is_absolute() or dep_path.as_posix() == '.':
path = dep_path.as_posix()
else:
path = get_converted_relative_path(dep)
dep = dep_link.egg_fragment if dep_link.egg_fragment else dep_link.url_without_fragment

elif is_valid_url(dep) and matches_uri:
dep_link = Link(dep)
uri = dep_link.url_without_fragment
# Parse the requirement using just the dependency name version from the egg fragment
# if possible. Then we can drop in the URI later. This is how pip does it.
dep = dep_link.egg_fragment if dep_link.egg_fragment else dep_link.url_without_fragment
req = [r for r in requirements.parse(dep)][0]
# If the result is a local file with a URI and we have a local path, unset the URI
# and set the path instead
if path and not req.path:
req.path = path
req.uri = None
req.local_file = True
elif matches_uri and uri and not req.uri:
req.uri = uri
if markers:
req.markers = markers
if extras:
Expand Down
19 changes: 19 additions & 0 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,3 +250,22 @@ def test_win_normalize_drive(self, input_path, expected):
@pytest.mark.skipif(os.name == 'nt', reason='*nix file paths tested')
def test_nix_normalize_drive(self, input_path, expected):
assert pipenv.utils.normalize_drive(input_path) == expected

@pytest.mark.requirements
def test_get_requirements(self):
url_with_egg = pipenv.utils.get_requirement('https://github.com/IndustriaTech/django-user-clipboard/archive/0.6.1.zip#egg=django-user-clipboard==0.6.1')
assert url_with_egg.uri == 'https://github.com/IndustriaTech/django-user-clipboard/archive/0.6.1.zip'
assert url_with_egg.name == 'django-user-clipboard' and url_with_egg.specs == [('==', '0.6.1')]
url = pipenv.utils.get_requirement('https://github.com/kennethreitz/tablib/archive/0.12.1.zip')
assert url.uri == 'https://github.com/kennethreitz/tablib/archive/0.12.1.zip'
vcs_url = pipenv.utils.get_requirement('git+https://github.com/kennethreitz/tablib.git@master#egg=tablib')
assert vcs_url.vcs == 'git' and vcs_url.name == 'tablib' and vcs_url.revision == 'master'
assert vcs_url.uri == 'git+https://github.com/kennethreitz/tablib.git'
normal = pipenv.utils.get_requirement('tablib')
assert normal.name == 'tablib'
spec = pipenv.utils.get_requirement('tablib==0.12.1')
assert spec.name == 'tablib' and spec.specs == [('==', '0.12.1')]
extras_markers = pipenv.utils.get_requirement("requests[security]; os_name=='posix'")
assert extras_markers.extras == ['security']
assert extras_markers.name == 'requests'
assert extras_markers.markers == "os_name=='posix'"

0 comments on commit d026a83

Please sign in to comment.