Merge pull request #1366 from pypa/hotfix/windows_drive_recase

Windows Drive Case Normalization
This commit is contained in:
Nate Prewitt
2018-01-27 16:50:26 -08:00
committed by GitHub
4 changed files with 53 additions and 11 deletions
+3 -3
View File
@@ -14,7 +14,7 @@ import toml
from .utils import (
mkdir_p, convert_deps_from_pip, pep423_name, recase_file,
find_requirements, is_file, is_vcs, python_version, cleanup_toml,
is_installable_file, is_valid_url
is_installable_file, is_valid_url, normalize_drive
)
from .environments import PIPENV_MAX_DEPTH, PIPENV_VENV_IN_PROJECT
from .environments import PIPENV_VIRTUALENV, PIPENV_PIPFILE
@@ -23,7 +23,7 @@ if PIPENV_PIPFILE:
if not os.path.isfile(PIPENV_PIPFILE):
raise RuntimeError('Given PIPENV_PIPFILE is not found!')
else:
PIPENV_PIPFILE = os.path.abspath(PIPENV_PIPFILE)
PIPENV_PIPFILE = normalize_drive(os.path.abspath(PIPENV_PIPFILE))
class Project(object):
@@ -224,7 +224,7 @@ class Project(object):
loc = pipfile.Pipfile.find(max_depth=PIPENV_MAX_DEPTH)
except RuntimeError:
loc = None
self._pipfile_location = loc
self._pipfile_location = normalize_drive(loc)
return self._pipfile_location
+22 -4
View File
@@ -277,7 +277,7 @@ def get_requirement(dep):
remote URIs, and package names, and that we pass only valid requirement strings
to the requirements parser. Performs necessary modifications to requirements
object if the user input was a local relative path.
:param str dep: A requirement line
:returns: :class:`requirements.Requirement` object
"""
@@ -932,11 +932,11 @@ def proper_case(package_name):
def split_section(input_file, section_suffix, test_function):
"""
Split a pipfile or a lockfile section out by section name and test function
:param dict input_file: A dictionary containing either a pipfile or lockfile
:param str section_suffix: A string of the name of the section
:param func test_function: A test function to test against the value in the key/value pair
>>> split_section(my_lockfile, 'vcs', is_vcs)
{
'default': {
@@ -992,7 +992,7 @@ def merge_deps(file_dict, project, dev=False, requirements=False, ignore_hashes=
Given a file_dict, merges dependencies and converts them to pip dependency lists.
:param dict file_dict: The result of calling :func:`pipenv.utils.split_file`
:param :class:`pipenv.project.Project` project: Pipenv project
:param bool dev=False: Flag indicating whether dev dependencies are to be installed
:param bool dev=False: Flag indicating whether dev dependencies are to be installed
:param bool requirements=False: Flag indicating whether to use a requirements file
:param bool ignore_hashes=False:
:param bool blocking=False:
@@ -1174,3 +1174,21 @@ def touch_update_stamp():
except OSError:
with open(p, 'w') as fh:
fh.write('')
def normalize_drive(path):
"""Normalize drive in path so they stay consistent.
This currently only affects local drives on Windows, which can be
identified with either upper or lower cased drive names. The case is
always converted to uppercase because it seems to be preferred.
See: <https://github.com/pypa/pipenv/issues/1218>
"""
if os.name != 'nt' or not isinstance(path, six.string_types):
return path
drive, tail = os.path.splitdrive(path)
# Only match (lower cased) local drives (e.g. 'c:'), not UNC mounts.
if drive.islower() and len(drive) == 2 and drive[1] == ':':
return '{}{}'.format(drive.upper(), tail)
return path
+4 -4
View File
@@ -8,7 +8,7 @@ import json
import pytest
from pipenv.cli import activate_virtualenv
from pipenv.utils import temp_environ, get_windows_path, mkdir_p
from pipenv.utils import temp_environ, get_windows_path, mkdir_p, normalize_drive
from pipenv.vendor import toml
from pipenv.vendor import delegator
from pipenv.project import Project
@@ -84,7 +84,7 @@ class TestPipenv:
@pytest.mark.cli
def test_pipenv_where(self):
with PipenvInstance() as p:
assert p.path in p.pipenv('--where').out
assert normalize_drive(p.path) in p.pipenv('--where').out
@pytest.mark.cli
def test_pipenv_venv(self):
@@ -652,7 +652,7 @@ requests = {version = "*"}
c = p.pipenv('install requests')
assert c.return_code == 0
assert p.path in p.pipenv('--venv').out
assert normalize_drive(p.path) in p.pipenv('--venv').out
@pytest.mark.dotvenv
@pytest.mark.install
@@ -682,7 +682,7 @@ requests = {version = "*"}
# Compare pew's virtualenv path to what we expect
venv_path = get_windows_path(project.project_directory, '.venv')
# os.path.normpath will normalize slashes
assert venv_path == os.path.normpath(c.out.strip())
assert venv_path == normalize_drive(os.path.normpath(c.out.strip()))
# Have pew run 'pip freeze' in the virtualenv
# This is functionally the same as spawning a subshell
# If we can do this we can theoretically amke a subshell
+24
View File
@@ -226,3 +226,27 @@ twine = "*"
new_toml = pipenv.utils.cleanup_toml(toml)
# testing if the end of the generated file contains a newline
assert new_toml[-1] == '\n'
@pytest.mark.parametrize('input_path, expected', [
('c:\\Program Files\\Python36\\python.exe',
'C:\\Program Files\\Python36\\python.exe'),
('C:\\Program Files\\Python36\\python.exe',
'C:\\Program Files\\Python36\\python.exe'),
('\\\\host\\share\\file.zip', '\\\\host\\share\\file.zip'),
('artifacts\\file.zip', 'artifacts\\file.zip'),
('.\\artifacts\\file.zip', '.\\artifacts\\file.zip'),
('..\\otherproject\\file.zip', '..\\otherproject\\file.zip'),
])
@pytest.mark.skipif(os.name != 'nt', reason='Windows file paths tested')
def test_win_normalize_drive(self, input_path, expected):
assert pipenv.utils.normalize_drive(input_path) == expected
@pytest.mark.parametrize('input_path, expected', [
('/usr/local/bin/python', '/usr/local/bin/python'),
('artifacts/file.zip', 'artifacts/file.zip'),
('./artifacts/file.zip', './artifacts/file.zip'),
('../otherproject/file.zip', '../otherproject/file.zip'),
])
@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