diff --git a/news/11719.bugfix.rst b/news/11719.bugfix.rst new file mode 100644 index 00000000000..c2ae8bc1d5e --- /dev/null +++ b/news/11719.bugfix.rst @@ -0,0 +1 @@ +Normalize paths before checking if installed scripts are on PATH. diff --git a/src/pip/_internal/operations/install/wheel.py b/src/pip/_internal/operations/install/wheel.py index c79941398a2..a8cd1330f0f 100644 --- a/src/pip/_internal/operations/install/wheel.py +++ b/src/pip/_internal/operations/install/wheel.py @@ -143,16 +143,18 @@ def message_about_scripts_not_on_PATH(scripts: Sequence[str]) -> Optional[str]: # We don't want to warn for directories that are on PATH. not_warn_dirs = [ - os.path.normcase(i).rstrip(os.sep) + os.path.normcase(os.path.normpath(i)).rstrip(os.sep) for i in os.environ.get("PATH", "").split(os.pathsep) ] # If an executable sits with sys.executable, we don't warn for it. # This covers the case of venv invocations without activating the venv. - not_warn_dirs.append(os.path.normcase(os.path.dirname(sys.executable))) + not_warn_dirs.append( + os.path.normcase(os.path.normpath(os.path.dirname(sys.executable))) + ) warn_for: Dict[str, Set[str]] = { parent_dir: scripts for parent_dir, scripts in grouped_by_dir.items() - if os.path.normcase(parent_dir) not in not_warn_dirs + if os.path.normcase(os.path.normpath(parent_dir)) not in not_warn_dirs } if not warn_for: return None diff --git a/tests/unit/test_wheel.py b/tests/unit/test_wheel.py index c5a8f3be4f3..5e5ea17157e 100644 --- a/tests/unit/test_wheel.py +++ b/tests/unit/test_wheel.py @@ -589,6 +589,12 @@ def test_multi_script__single_dir_on_PATH(self) -> None: ) assert retval is None + def test_PATH_check_path_normalization(self) -> None: + retval = self._template( + paths=["/a/./b/../b//c/", "/d/e/bin"], scripts=["/a/b/c/foo"] + ) + assert retval is None + def test_single_script__single_dir_on_PATH(self) -> None: retval = self._template(paths=["/a/b", "/c/d/bin"], scripts=["/a/b/foo"]) assert retval is None