Skip to content

Commit

Permalink
Warn if a path in PATH starts with tilde during install
Browse files Browse the repository at this point in the history
  • Loading branch information
mdebi authored and xavfernandez committed Nov 15, 2019
1 parent 9e1b1c7 commit f6aaba9
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 0 deletions.
1 change: 1 addition & 0 deletions news/6414.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Warn if a path in PATH starts with tilde during ``pip install``.
11 changes: 11 additions & 0 deletions src/pip/_internal/wheel.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,17 @@ def message_about_scripts_not_on_PATH(scripts):
else:
msg_lines.append(last_line_fmt.format("these directories"))

# Add a note if any directory starts with ~
warn_for_tilde = any(
i[0] == "~" for i in os.environ.get("PATH", "").split(os.pathsep) if i
)
if warn_for_tilde:
tilde_warning_msg = (
"NOTE: The current PATH contains path(s) starting with `~`, "
"which may not be expanded by all applications."
)
msg_lines.append(tilde_warning_msg)

# Returns the formatted multiline message
return "\n".join(msg_lines)

Expand Down
46 changes: 46 additions & 0 deletions tests/unit/test_wheel.py
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,11 @@ def test_dist_info_contains_empty_dir(self, data, tmpdir):

class TestMessageAboutScriptsNotOnPATH(object):

tilde_warning_msg = (
"NOTE: The current PATH contains path(s) starting with `~`, "
"which may not be expanded by all applications."
)

def _template(self, paths, scripts):
with patch.dict('os.environ', {'PATH': os.pathsep.join(paths)}):
return wheel.message_about_scripts_not_on_PATH(scripts)
Expand All @@ -543,6 +548,7 @@ def test_single_script__single_dir_not_on_PATH(self):
assert retval is not None
assert "--no-warn-script-location" in retval
assert "foo is installed in '/c/d'" in retval
assert self.tilde_warning_msg not in retval

def test_two_script__single_dir_not_on_PATH(self):
retval = self._template(
Expand All @@ -552,6 +558,7 @@ def test_two_script__single_dir_not_on_PATH(self):
assert retval is not None
assert "--no-warn-script-location" in retval
assert "baz and foo are installed in '/c/d'" in retval
assert self.tilde_warning_msg not in retval

def test_multi_script__multi_dir_not_on_PATH(self):
retval = self._template(
Expand All @@ -562,6 +569,7 @@ def test_multi_script__multi_dir_not_on_PATH(self):
assert "--no-warn-script-location" in retval
assert "bar, baz and foo are installed in '/c/d'" in retval
assert "spam is installed in '/a/b/c'" in retval
assert self.tilde_warning_msg not in retval

def test_multi_script_all__multi_dir_not_on_PATH(self):
retval = self._template(
Expand All @@ -575,6 +583,7 @@ def test_multi_script_all__multi_dir_not_on_PATH(self):
assert "--no-warn-script-location" in retval
assert "bar, baz and foo are installed in '/c/d'" in retval
assert "eggs and spam are installed in '/a/b/c'" in retval
assert self.tilde_warning_msg not in retval

def test_two_script__single_dir_on_PATH(self):
retval = self._template(
Expand Down Expand Up @@ -613,6 +622,7 @@ def test_PATH_check_case_insensitive_on_windows(self):
assert retval is None
else:
assert retval is not None
assert self.tilde_warning_msg not in retval

def test_trailing_ossep_removal(self):
retval = self._template(
Expand All @@ -634,6 +644,42 @@ def test_missing_PATH_env_treated_as_empty_PATH_env(self):

assert retval_missing == retval_empty

def test_no_script_tilde_in_path(self):
retval = self._template(
paths=['/a/b', '/c/d/bin', '~/e', '/f/g~g'],
scripts=[]
)
assert retval is None

def test_multi_script_all_tilde__multi_dir_not_on_PATH(self):
retval = self._template(
paths=['/a/b', '/c/d/bin', '~e/f'],
scripts=[
'/c/d/foo', '/c/d/bar', '/c/d/baz',
'/a/b/c/spam', '/a/b/c/eggs', '/e/f/tilde'
]
)
assert retval is not None
assert "--no-warn-script-location" in retval
assert "bar, baz and foo are installed in '/c/d'" in retval
assert "eggs and spam are installed in '/a/b/c'" in retval
assert "tilde is installed in '/e/f'" in retval
assert self.tilde_warning_msg in retval

def test_multi_script_all_tilde_not_at_start__multi_dir_not_on_PATH(self):
retval = self._template(
paths=['/e/f~f', '/c/d/bin'],
scripts=[
'/c/d/foo', '/c/d/bar', '/c/d/baz',
'/e/f~f/c/spam', '/e/f~f/c/eggs'
]
)
assert retval is not None
assert "--no-warn-script-location" in retval
assert "bar, baz and foo are installed in '/c/d'" in retval
assert "eggs and spam are installed in '/e/f~f/c'" in retval
assert self.tilde_warning_msg not in retval


class TestWheelHashCalculators(object):

Expand Down

0 comments on commit f6aaba9

Please sign in to comment.