Repository: pypa/pipx (python)

Issue:
`pipx install pkg1 pkg2` doesn't install `pkg2` if `pkg1` already installed
<!--
Thank you for filing a bug! Please feel free to answer as much or as little of this template as you can.

Please check pipx's Troubleshooting page to see if any of those solutions help solve your issue:
https://pipx.pypa.io/stable/troubleshooting/
-->

**Describe the bug**
If I have already installed `black` by running `pipx install black` and I attempt to run `pipx install black isort`, `black` is detected as having been already installed, and `isort` is not installed.
<!-- Please be as detailed as possible! -->

**How to reproduce**
`pipx install black`
`pipx install black isort`
\# _isort not installed!_
<!-- If possible, include output of `pipx --verbose ...` -->

**Expected behavior**

`black` should be detected as already installed, and `isort` should be installed by pipx
<!-- What should have happened? -->

```[tasklist]
### Tasks
- [ ] https://github.com/pypa/pipx/pull/1510
```


Pull request description:
Fixes #1509 short-circuit of installing packages when already installed
<!-- add an 'x' in the brackets below -->

- [x] I have added a news fragment under `changelog.d/` (if the patch affects the end users)

## Summary of changes

Updates logic of `install.py` to continue installing packages if one is already installed.

## Test plan

<!-- provide evidence of testing, preferably with command(s) that can be copy+pasted by others -->

Added tests to exercise the bug and demonstrate fix:
`test_install_three_packages_with_first_already_installed`
`test_install_two_packages_with_first_two_already_installed`

Tested by running

```
nox -s tests-3.12 -- -k test_install
```


Patch:
diff --git a/changelog.d/1509.bugfix.md b/changelog.d/1509.bugfix.md
new file mode 100644
index 0000000..c539aaf
--- /dev/null
+++ b/changelog.d/1509.bugfix.md
@@ -0,0 +1,1 @@
+Fix installation abortion on multiple packages when one or more are already installed.
diff --git a/src/pipx/commands/install.py b/src/pipx/commands/install.py
index adeff2b..dbf26ba 100644
--- a/src/pipx/commands/install.py
+++ b/src/pipx/commands/install.py
@@ -84,7 +84,11 @@ def install(
                         """
                     )
                 )
-                return EXIT_CODE_INSTALL_VENV_EXISTS
+                if len(package_specs) == 1:
+                    return EXIT_CODE_INSTALL_VENV_EXISTS
+                # Reset venv_dir to None ready to install the next package in the list
+                venv_dir = None
+                continue
 
         try:
             # Enable installing shared library `pip` with `pipx`


Test patch:
diff --git a/tests/test_install.py b/tests/test_install.py
index b83310e..2cff936 100644
--- a/tests/test_install.py
+++ b/tests/test_install.py
@@ -85,6 +85,19 @@ def test_install_tricky_packages(capsys, pipx_temp_env, caplog, package_name, pa
     install_packages(capsys, pipx_temp_env, caplog, [package_spec], [package_name])
 
 
+def test_install_multiple_packages_when_some_already_installed(capsys, pipx_temp_env, caplog):
+    run_pipx_cli(["install", "black", "pycowsay"])
+    captured = capsys.readouterr()
+    assert "installed package black" in captured.out
+    assert "installed package pycowsay" in captured.out
+
+    run_pipx_cli(["install", "black", "pycowsay", "isort"])
+    captured = capsys.readouterr()
+    assert "'black' already seems to be installed" in captured.out
+    assert "'pycowsay' already seems to be installed" in captured.out
+    assert "installed package isort" in captured.out
+
+
 def test_install_tricky_multiple_packages(capsys, pipx_temp_env, caplog):
     if os.getenv("FAST"):
         pytest.skip("skipping slow tests")