diff --git a/changelog.d/1611.bugfix.md b/changelog.d/1611.bugfix.md new file mode 100644 index 0000000000..ba6c97f5c6 --- /dev/null +++ b/changelog.d/1611.bugfix.md @@ -0,0 +1 @@ +`pipx reinstall`: An exception will now be raised if package is pinned. diff --git a/src/pipx/commands/reinstall.py b/src/pipx/commands/reinstall.py index 72011c5deb..5600563425 100644 --- a/src/pipx/commands/reinstall.py +++ b/src/pipx/commands/reinstall.py @@ -54,6 +54,9 @@ def reinstall( else: package_or_url = venv.main_package_name + if venv.pipx_metadata.main_package.pinned: + raise PipxError(f"{error} Package {venv_dir} is pinned. Run `pipx unpin {venv_dir.name}` to unpin it first.") + uninstall(venv_dir, local_bin_dir, local_man_dir, verbose) # in case legacy original dir name diff --git a/tests/test_reinstall.py b/tests/test_reinstall.py index 6c7886680f..838d8c32ae 100644 --- a/tests/test_reinstall.py +++ b/tests/test_reinstall.py @@ -68,3 +68,16 @@ def test_reinstall_with_path(pipx_temp_env, capsys, tmp_path): captured = capsys.readouterr() assert "Expected the name of an installed package" in captured.err.replace("\n", " ") + + +def test_reinstall_pinned_package(pipx_temp_env, capsys): + assert not run_pipx_cli(["install", "black"]) + assert not run_pipx_cli(["pin", "black"]) + assert run_pipx_cli(["reinstall", "black"]) + captured = capsys.readouterr() + assert "pinned" in captured.err + + assert not run_pipx_cli(["unpin", "black"]) + assert not run_pipx_cli(["reinstall", "black"]) + captured = capsys.readouterr() + assert "installed package black" in captured.out