From 5213363c901a7ea36b5d4fb65f6da97e70c37e6c Mon Sep 17 00:00:00 2001 From: Evan Lewis Date: Sat, 2 Dec 2023 13:22:28 -0700 Subject: [PATCH 1/4] Run subprocesses in destination dir --- CHANGELOG.md | 277 ++++++++++++++--------------------------------- src/pipx/util.py | 4 + src/pipx/venv.py | 8 +- 3 files changed, 92 insertions(+), 197 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 24b12b0854..007aaa1ecd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,219 +1,106 @@ -# Changelog +## dev -All notable changes to this project will be documented in this file. +- Run venv creation and install_package subprocesses inside distination directory self.root instead of current directory -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -This project uses [*towncrier*](https://towncrier.readthedocs.io/) for keeping the changelog. DO NOT commit any changes to this file. -{% include '_draft_changelog.md' ignore missing %} - - - -## [1.4.3](https://github.com/pypa/pipx/tree/1.4.3) - 2024-01-16 - - -### Bugfixes - -- Autofix python version for pylauncher, when version is provided prefixed with `python` ([#1150](https://github.com/pypa/pipx/issues/1150)) -- Support building pipx wheels with setuptools-scm<7, such as on FreeBSD. ([#1208](https://github.com/pypa/pipx/issues/1208)) - -### Improved Documentation - -- Provide useful error messages when unresolvable python version is passed ([#1150](https://github.com/pypa/pipx/issues/1150)) -- Introduce towncrier for managing the changelog ([#1161](https://github.com/pypa/pipx/issues/1161)) -- Add workaround for using pipx applications in shebang under macOS ([#1198](https://github.com/pypa/pipx/issues/1198)) - - -## [1.4.2](https://github.com/pypa/pipx/tree/1.4.2) - -### Features - -- Allow skipping maintenance tasks during list command -- Raise more user friendly error when provided `--python` version is not found -- Update `pipx run` on scripts using `/// script` and no `run` table following the updated version of PEP 723 (#1180) - -### Bugfixes - -- Include `tomli` into `pipx.pyz` (zipapp) so that it can be executed with Python 3.10 or earlier (#1142) -- Fix resolving the python executable path on linux -- `pipx run`: Verify whether the script name provided is a file before running it -- Avoid repeated exception logging in a few rare cases (#1192) - -## [1.4.1](https://github.com/pypa/pipx/tree/1.4.1) - -### Bugfixes - -- Set default logging level to WARNING, so debug log messages won't be shown without passing additional flags such as `--verbose` - -## [1.4.0](https://github.com/pypa/pipx/tree/1.4.0) - -### Features - -- Add `--quiet` and `--verbose` options for the `pipx` subcommands -- Add ability to install multiple packages at once -- Delete directories directly instead of spawning rmdir on Windows - -### Improved Documentation - -- Add Scoop installation instructions - -### Bugfixes - -- "Failed to delete" error when using Microsoft Store Python -- "No pyvenv.cfg file" error when using Microsoft Store Python (#1164) - -## [1.3.3](https://github.com/pypa/pipx/tree/1.3.3) - -### Improved Documentation - -- Make the logo more visible in dark mode - -## [1.3.2](https://github.com/pypa/pipx/tree/1.3.2) - -### Features - -- The project version number is now dynamic and generated from the VCS at build time - -### Improved Documentation - -- Add additional example for --pip-args option, to docs/examples.md - -## [1.3.1](https://github.com/pypa/pipx/tree/1.3.1) - -### Bugfixes +## 1.3.1 - Fix combining of --editable and --force flag -## [1.3.0](https://github.com/pypa/pipx/tree/1.3.0) - -### Features +## 1.3.0 -- Allow running `pip` with `pipx run` -- Add `--with-suffix` for `pipx inject` command -- `pipx install`: emit a warning when `--force` and `--python` were passed at the same time -- Add explicit 3.12 support -- Make usage message in `pipx run` show `package_or_url`, so extra will be printed out as well -- Use the py launcher, if available, to select Python version with the `--python` option -- add pre-commit hook support -- Add `pipx install --preinstall` to support preinstalling build requirements -- Return an error message when directory can't be added to PATH successfully -- Expose manual pages included in an application installed with `pipx install` - Check whether pip module exists in shared lib before performing any actions, such as `reinstall-all`. - Drop `setuptools` and `wheel` from the shared libraries. This results in less time consumption when the libraries are automatically upgraded. -- Support [inline script metadata](https://packaging.python.org/en/latest/specifications/inline-script-metadata/) - in `pipx run`. +- Allow running `pip` with `pipx run` +- Support PEP 723 run requirements in `pipx run`. - Imply `--include-apps` when running `pipx inject --include-deps` +- Add `--with-suffix` for `pipx inject` command +- `pipx install`: emit a warning when `--force` and `--python` were passed at the same time +- Drop support for Python 3.7 +- Make usage message in `pipx run` show `package_or_url`, so extra will be printed out as well - Add `--force-reinstall` to pip arguments when `--force` was passed +- Use the py launcher, if available, to select Python version with the `--python` option - Support including requirements in scripts run using `pipx run` (#916) - Pass `pip_args` to `shared_libs.upgrade()` - Fallback to user's log path if the default log path (`$PIPX_HOME/logs`) is not writable to aid with pipx being used for multi-user (e.g. system-wide) installs of applications +- Fix wrong interpreter usage when injecting local pip-installable dependencies into venvs +- add pre-commit hook support - Don't show escaped backslashes for paths in console output - Move `pipx` paths to ensure compatibility with the platform-specific user directories +- [docs] Add more examples for `pipx run` +- [docs] Add subsection to make README easier to read +- Add `pipx install --preinstall` to support preinstalling build requirements - Pass `--no-input` to pip when output is not piped to parent stdout -- Print all environment variables in `pipx environment` - -### Improved Documentation - -- Add more examples for `pipx run` -- Add subsection to make README easier to read - -### Deprecations and Removals - -- Drop support for Python 3.7 - -### Bugfixes - -- Fix wrong interpreter usage when injecting local pip-installable dependencies into venvs - Fix program name in generated manual page +- Print all environment variables in `pipx environment` +- Return an error message when directory can't be added to PATH successfully +- Expose manual pages included in an application installed with `pipx install` +- Add explicit 3.12 support -## [1.2.1](https://github.com/pypa/pipx/tree/1.2.1) - -### Bugfixes +## 1.2.1 - Fix compatibility to packaging 23.2+ by removing reliance on packaging's requirement validation logic and detecting a URL-based requirement in pipx. (#1070) -## [1.2.0](https://github.com/pypa/pipx/tree/1.2.0) - -### Features +## 1.2.0 +- Add test for pip module in `pipx reinstall` to fix an issue with `pipx reinstall-all` (#935) - Add `pipx uninject` command (#820) -- Ship a [zipapp](https://docs.python.org/3/library/zipapp.html) of pipx +- [docs] Fix `pipx run` examples and update Python versions used by `pipx install` examples +- [docs] Add an example for installation from source with extras - Match pip's behaviour when package name ends with archive extension (treat it as a path) +- Ship a [zipapp](https://docs.python.org/3/library/zipapp.html) of pipx - Change the program name to `path/to/python -m pipx` when running as `python -m pipx` - Improve the detection logic for MSYS2 to avoid entering infinite loop (#908) (#938) - Remove extra trailing quote from exception message - Fix EncodingWarning in `pipx_metadata_file`. -### Improved Documentation - -- Add an example for installation from source with extras -- Fix `pipx run` examples and update Python versions used by `pipx install` examples - -### Bugfixes - -- Add test for pip module in `pipx reinstall` to fix an issue with `pipx reinstall-all` (#935) - -## [1.1.0](https://github.com/pypa/pipx/tree/1.1.0) - -### Features +## 1.1.0 -- Add `pipx environment` command (#793) -- Add `list --short` option to list only package names (#804) +- Fix encoding issue on Windows when pip fails to install a package - Improve the behaviour of `shlex.split` on Windows, so paths on Windows can be handled properly when they are passed in `--pip-args`. (#794) +- Add `pipx environment` command (#793) +- Add `list --short` option to list only package names (#804) +- [docs] Fix the command for + [installing development version](https://pipx.pypa.io/stable/installation/#install-pipx-development-versions). (#801) +- [docs] Fix test status badge in readme file +- [docs] Add more examples - [dev] Change github action job names -- Add additional examples for installation from git repos +- [docs] Add additional examples for installation from git repos - [packaging] Switch to [PEP 621](https://www.python.org/dev/peps/pep-0621/) - Add a CACHEDIR.TAG to the cache directory to prevent it from being included in archives and backups. For more information about cache directory tags, see https://bford.info/cachedir -### Bugfixes - -- Fix encoding issue on Windows when pip fails to install a package - -### Improved Documentation - -- Add more examples -- Fix the command for - [installing development version](https://pipx.pypa.io/stable/installation/#install-pipx-development-versions). (#801) -- Fix test status badge in readme file - -## [1.0.0](https://github.com/pypa/pipx/tree/1.0.0) - -### Features +## 1.0.0 - Support [argcomplete 2.0.0](https://pypi.org/project/argcomplete/2.0.0) (#790) - Include machinery to build a manpage for pipx with [argparse-manpage](https://pypi.org/project/argparse-manpage/). - Add better handling for 'app not found' when a single app is present in the project, and an improved error message (#733) - -### Bugfixes - - Fixed animations sending output to stdout, which can break JSON output. (#769) - Fix typo in `pipx upgrade-all` output -## [0.17.0](https://github.com/pypa/pipx/tree/0.17.0) +## 0.17.0 - Support `pipx run` with version constraints and extras. (#697) -## [0.16.5](https://github.com/pypa/pipx/tree/0.16.5) +## 0.16.5 - Fixed `pipx list` output phrasing to convey that python version displayed is the one with which package was installed. - Fixed `pipx install` to provide return code 0 if venv already exists, similar to pip’s behavior. (#736) - [docs] Update ansible's install command in [Programs to Try document](https://pipx.pypa.io/stable/programs-to-try/#ansible) to work with Ansible 2.10+ (#742) -## [0.16.4](https://github.com/pypa/pipx/tree/0.16.4) +## 0.16.4 - Fix to `pipx ensurepath` to fix behavior in user locales other than UTF-8, to fix #644. The internal change is to use userpath v1.6.0 or greater. (#700) - Fix virtual environment inspection for Python releases that uses an int for its release serial number. (#706) - Fix PermissionError in windows when pipx manages itself. (#718) -## [0.16.3](https://github.com/pypa/pipx/tree/0.16.3) +## 0.16.3 - Organization: pipx is extremely pleased to now be a project of the Python Packaging Authority (PyPA)! Note that our github URL has changed to [pypa/pipx](https://github.com/pypa/pipx) @@ -231,14 +118,14 @@ This project uses [*towncrier*](https://towncrier.readthedocs.io/) for keeping t * Colorama is now only installed on Windows. (#691) -## [0.16.2.1](https://github.com/pypa/pipx/tree/0.16.2.1) +## 0.16.2.1 - Changed non-venv-info warnings and notices from `pipx list` to print to stderr. This especially prevents `pipx list --json` from printing invalid json to stdout. (#680) - Fixed bug that could cause uninstall on Windows with injected packages to uninstall too many apps from the local binary directory. (#679) -## [0.16.2.0](https://github.com/pypa/pipx/tree/0.16.2.0) +## 0.16.2.0 - Fixed bug #670 where uninstalling a venv could erroneously uninstall other apps from the local binary directory. (#672) @@ -251,7 +138,7 @@ This project uses [*towncrier*](https://towncrier.readthedocs.io/) for keeping t binaries for suffixed-venvs. (#653) - Changed venv minimum python version to 3.6, removing python 3.5 which is End of Life. (#666) -## [0.16.1.0](https://github.com/pypa/pipx/tree/0.16.1.0) +## 0.16.1.0 - Introduce the `pipx.run` entry point group as an alternative way to declare an application for `pipx run`. - Fix cursor show/hide to work with older versions of Windows. (#610) @@ -264,7 +151,7 @@ This project uses [*towncrier*](https://towncrier.readthedocs.io/) for keeping t - For `reinstall-all`, fixed bug where missing python executable would cause error. (#634) - Fix regression which prevented pipx from working with pythonloc (and `__pypackages__` folder). (#636) -## [0.16.0.0](https://github.com/pypa/pipx/tree/0.16.0.0) +## 0.16.0.0 - New venv inspection! The code that pipx uses to examine and determine metadata in an installed venv has been made faster, better, and more reliable. It now uses modern python libraries like `packaging` and `importlib.metadata` to @@ -305,7 +192,7 @@ This project uses [*towncrier*](https://towncrier.readthedocs.io/) for keeping t - pipx error, warning, and other messages now word-wrap so words are not split across lines. Their appearance is also now more consistent. -## [0.15.6.0](https://github.com/pypa/pipx/tree/0.15.6.0) +## 0.15.6.0 - [docs] Update license - [docs] Display a more idiomatic command for registering completions on fish. @@ -316,12 +203,12 @@ This project uses [*towncrier*](https://towncrier.readthedocs.io/) for keeping t among other uses. - [bugfix] Fixed bug where extras were ignored with a PEP 508 package specification with a URL. -## [0.15.5.1](https://github.com/pypa/pipx/tree/0.15.5.1) +## 0.15.5.1 - [bugfix] Fixed regression of 0.15.5.0 which erroneously made installing from a local path with package extras not possible. -## [0.15.5.0](https://github.com/pypa/pipx/tree/0.15.5.0) +## 0.15.5.0 - pipx now parses package specification before install. It removes (with warning) the `--editable` install option for any package specification that is not a local path. It also removes (with warning) any environment markers. @@ -338,20 +225,20 @@ This project uses [*towncrier*](https://towncrier.readthedocs.io/) for keeping t - [feature] `--suffix` option for `install` to allow multiple versions of same tool to be installed (#445) - [feature] pipx can now be used with the Windows embeddable Python distribution -## [0.15.4.0](https://github.com/pypa/pipx/tree/0.15.4.0) +## 0.15.4.0 - [feature] `list` now has a new option `--include-injected` to show the injected packages in the main apps - [bugfix] Fixed bug that can cause crash when installing an app -## [0.15.3.1](https://github.com/pypa/pipx/tree/0.15.3.1) +## 0.15.3.1 - [bugfix] Workaround multiprocessing issues on certain platforms (#229) -## [0.15.3.0](https://github.com/pypa/pipx/tree/0.15.3.0) +## 0.15.3.0 - [feature] Use symlinks on Windows when symlinks are available -## [0.15.2.0](https://github.com/pypa/pipx/tree/0.15.2.0) +## 0.15.2.0 - [bugfix] Improved error reporting during venv metadata inspection. - [bugfix] Fixed incompatibility with pypy as venv interpreter (#372). @@ -363,30 +250,30 @@ This project uses [*towncrier*](https://towncrier.readthedocs.io/) for keeping t - [bugfix] Ignore system shared libraries when installing shared libraries pip, wheel, and setuptools. This also fixes an incompatibility with Debian/Ubuntu's version of pip (#386). -## [0.15.1.3](https://github.com/pypa/pipx/tree/0.15.1.3) +## 0.15.1.3 - [bugfix] On Windows, pipx now lists correct Windows apps (#217) - [bugfix] Fixed a `pipx install` bug causing incorrect python binary to be used when using the optional --python argument in certain situations, such as running pipx from a Framework python on macOS and specifying a non-Framework python. -## [0.15.1.2](https://github.com/pypa/pipx/tree/0.15.1.2) +## 0.15.1.2 - [bugfix] Fix recursive search of dependencies' apps so no apps are missed. - `upgrade-all` now skips editable packages, because pip disallows upgrading editable packages. -## [0.15.1.1](https://github.com/pypa/pipx/tree/0.15.1.1) +## 0.15.1.1 - [bugfix] fix regression that caused installing with --editable flag to fail package name determination. -## [0.15.1.0](https://github.com/pypa/pipx/tree/0.15.1.0) +## 0.15.1.0 - Add Python 3.8 to PyPI classifier and travis test matrix - [feature] auto-upgrade shared libraries, including pip, if older than one month. Hide all pip warnings that a new version is available. (#264) - [bugfix] pass pip arguments to pip when determining package name (#320) -## [0.15.0.0](https://github.com/pypa/pipx/tree/0.15.0.0) +## 0.15.0.0 Upgrade instructions: When upgrading to 0.15.0.0 or above from a pre-0.15.0.0 version, you must re-install all packages to take advantage of the new persistent pipx metadata files introduced in this release. These metadata files store pip @@ -417,7 +304,7 @@ by running `pipx reinstall-all` or `pipx uninstall-all`, then reinstalling manua - Use threads on OS's without support for semaphores - Stricter parsing when passing `--` argument as delimiter -## [0.14.0.0](https://github.com/pypa/pipx/tree/0.14.0.0) +## 0.14.0.0 - Speed up operations by using shared venv for `pip`, `setuptools`, and `wheel`. You can see more detail in the 'how pipx works' section of the documentation. (#164, @pfmoore) @@ -427,22 +314,22 @@ by running `pipx reinstall-all` or `pipx uninstall-all`, then reinstalling manua - If `--force` is passed, remove existing files in PIPX_BIN_DIR - Move animation to start of line, hide cursor when animating -## [0.13.2.3](https://github.com/pypa/pipx/tree/0.13.2.3) +## 0.13.2.3 - Fix regression when installing a package that doesn't have any entry points -## [0.13.2.2](https://github.com/pypa/pipx/tree/0.13.2.2) +## 0.13.2.2 - Remove unnecessary and sometimes incorrect check after `pipx inject` (#195) - Make status text/animation reliably disappear before continuing - Update animation symbols -## [0.13.2.1](https://github.com/pypa/pipx/tree/0.13.2.1) +## 0.13.2.1 - Remove virtual environment if installation did not complete. For example, if it was interrupted by ctrl+c or if an exception occurred for any reason. (#193) -## [0.13.2.0](https://github.com/pypa/pipx/tree/0.13.2.0) +## 0.13.2.0 - Add shell autocompletion. Also add `pipx completions` command to print instructions on how to add pipx completions to your shell. @@ -453,12 +340,12 @@ by running `pipx reinstall-all` or `pipx uninstall-all`, then reinstalling manua - swap out of order logic in order to correctly recommend --include-deps (@joshuarli) - [dev] Migrate from tox to nox -## [0.13.1.1](https://github.com/pypa/pipx/tree/0.13.1.1) +## 0.13.1.1 - Do not raise bare exception if no binaries found (#150) - Update pipsi migration script -## [0.13.1.0](https://github.com/pypa/pipx/tree/0.13.1.0) +## 0.13.1.0 - Deprecate `ensurepath` command. Use `userpath append ~/.local/bin` - Support redirects and proxies when downloading python files (i.e. `pipx run http://url/file.py`) @@ -467,34 +354,34 @@ by running `pipx reinstall-all` or `pipx uninstall-all`, then reinstalling manua - Use mkdocs for documentation - Change default cache duration for `pipx run` from 2 to 14 days -## [0.13.0.1](https://github.com/pypa/pipx/tree/0.13.0.1) +## 0.13.0.1 - Fix upgrade-all and reinstall-all regression -## [0.13.0.0](https://github.com/pypa/pipx/tree/0.13.0.0) +## 0.13.0.0 - Add `runpip` command to run arbitrary pip commands in pipx-managed virtual environments - Do not raise error when running `pipx install PACKAGE` and the package has already been installed by pipx (#125). This is the cause of the major version change from 0.12 to 0.13. - Add `--skip` argument to `upgrade-all` and `reinstall-all` commands, to let the user skip particular packages -## [0.12.3.3](https://github.com/pypa/pipx/tree/0.12.3.3) +## 0.12.3.3 - Update logic in determining a package's binaries during installation. This removes spurious binaries from the installation. (#104) - Improve compatibility with Debian distributions by using `shutil.which` instead of `distutils.spawn.find_executable` (#102) -## [0.12.3.2](https://github.com/pypa/pipx/tree/0.12.3.2) +## 0.12.3.2 - Fix infinite recursion error when installing package such as `cloudtoken==0.1.84` (#103) - Fix windows type errors (#96, #98) -## [0.12.3.1](https://github.com/pypa/pipx/tree/0.12.3.1) +## 0.12.3.1 - Fix "WindowsPath is not iterable" bug -## [0.12.3.0](https://github.com/pypa/pipx/tree/0.12.3.0) +## 0.12.3.0 - Add `--include-deps` argument to include binaries of dependent packages when installing with pipx. This improves compatibility with packages that depend on other installed packages, such as `jupyter`. @@ -503,7 +390,7 @@ by running `pipx reinstall-all` or `pipx uninstall-all`, then reinstalling manua - More aggressive cache directory removal when `--no-cache` is passed to `pipx run` - [dev] Move inline text passed to subprocess calls to their own files to enable autoformatting, linting, unit testing -## [0.12.2.0](https://github.com/pypa/pipx/tree/0.12.2.0) +## 0.12.2.0 - Add support for PEP 582's `__pypackages__` (experimental). `pipx run BINARY` will first search in `__pypackages__` for binary, then fallback to installing from PyPI. `pipx run --pypackages BINARY` will raise an error if the binary is not @@ -511,7 +398,7 @@ by running `pipx reinstall-all` or `pipx uninstall-all`, then reinstalling manua - Fix regression when installing with `--editable` flag (#93) - [dev] improve unit tests -## [0.12.1.0](https://github.com/pypa/pipx/tree/0.12.1.0) +## 0.12.1.0 - Cache and reuse temporary Virtual Environments created with `pipx run` (#61) - Update binary discovery logic to find "scripts" like awscli (#91) @@ -521,54 +408,54 @@ by running `pipx reinstall-all` or `pipx uninstall-all`, then reinstalling manua at `$PIPX_HOME`. - [dev] refactor into multiple files, add more unit tests -## [0.12.0.4](https://github.com/pypa/pipx/tree/0.12.0.4) +## 0.12.0.4 - Fix parsing bug in pipx run -## [0.12.0.3](https://github.com/pypa/pipx/tree/0.12.0.3) +## 0.12.0.3 - list python2 as supported language so that pip installs with python2 will no longer install the pipx on PyPI from the original pipx owner. Running pipx with python2 will fail, but at least it will not be as confusing as running the pipx package from the original owner. -## [0.12.0.2](https://github.com/pypa/pipx/tree/0.12.0.2) +## 0.12.0.2 - forward arguments to run command correctly #90 -## [0.12.0.1](https://github.com/pypa/pipx/tree/0.12.0.1) +## 0.12.0.1 - stop using unverified context #89 -## [0.12.0.0](https://github.com/pypa/pipx/tree/0.12.0.0) +## 0.12.0.0 - Change installation instructions to use `pipx` PyPI name - Add `ensurepath` command -## [0.11.0.2](https://github.com/pypa/pipx/tree/0.11.0.2) +## 0.11.0.2 - add version argument parsing back in (fixes regression) -## [0.11.0.1](https://github.com/pypa/pipx/tree/0.11.0.1) +## 0.11.0.1 - add version check, command check, fix printed version update installation instructions -## [0.11.0.0](https://github.com/pypa/pipx/tree/0.11.0.0) +## 0.11.0.0 - Replace `pipx BINARY` with `pipx run BINARY` to run a binary in an ephemeral environment. This is a breaking API change so the major version has been incremented. (Issue #69) - upgrade pip when upgrading packages (Issue #72) - support --system-site-packages flag (Issue #64) -## [0.10.4.1](https://github.com/pypa/pipx/tree/0.10.4.1) +## 0.10.4.1 - Fix version printed when `pipx --version` is run -## [0.10.4.0](https://github.com/pypa/pipx/tree/0.10.4.0) +## 0.10.4.0 - Add --index-url, --editable, and --pip-args flags - Updated README with pipsi migration instructions -## [0.10.3.0](https://github.com/pypa/pipx/tree/0.10.3.0) +## 0.10.3.0 - Display python version in list - Do not reinstall package if already installed (added `--force` flag to override) diff --git a/src/pipx/util.py b/src/pipx/util.py index fad47c82cf..e7b320c968 100644 --- a/src/pipx/util.py +++ b/src/pipx/util.py @@ -158,6 +158,7 @@ def run_subprocess( log_cmd_str: Optional[str] = None, log_stdout: bool = True, log_stderr: bool = True, + run_dir: Optional[str] = None, ) -> "subprocess.CompletedProcess[str]": """Run arbitrary command as subprocess, capturing stderr and stout""" env = dict(os.environ) @@ -166,6 +167,8 @@ def run_subprocess( if log_cmd_str is None: log_cmd_str = " ".join(str(c) for c in cmd) logger.info(f"running {log_cmd_str}") + if run_dir: + os.makedirs(run_dir, exist_ok=True) # windows cannot take Path objects, only strings cmd_str_list = [str(c) for c in cmd] # Make sure to call the binary using its real path. This matters especially on Windows when using the packaged app @@ -184,6 +187,7 @@ def run_subprocess( encoding="utf-8", universal_newlines=True, check=False, + cwd=run_dir if run_dir else None, ) if capture_stdout and log_stdout: diff --git a/src/pipx/venv.py b/src/pipx/venv.py index fc330164b4..d723414f64 100644 --- a/src/pipx/venv.py +++ b/src/pipx/venv.py @@ -157,7 +157,9 @@ def create_venv(self, venv_args: List[str], pip_args: List[str], override_shared cmd = [self.python, "-m", "venv"] if not override_shared: cmd.append("--without-pip") - venv_process = run_subprocess(cmd + venv_args + [str(self.root)]) + venv_process = run_subprocess( + cmd + venv_args + [str(self.root)], run_dir=str(self.root) + ) subprocess_post_check(venv_process) shared_libs.create(self.verbose) @@ -248,7 +250,9 @@ def install_package( ] # no logging because any errors will be specially logged by # subprocess_post_check_handle_pip_error() - pip_process = run_subprocess(cmd, log_stdout=False, log_stderr=False) + pip_process = run_subprocess( + cmd, log_stdout=False, log_stderr=False, run_dir=str(self.root) + ) subprocess_post_check_handle_pip_error(pip_process) if pip_process.returncode: raise PipxError(f"Error installing {full_package_description(package_name, package_or_url)}.") From 0edd2da8d2dd82c60aa0b293354e6ff76c7ea30a Mon Sep 17 00:00:00 2001 From: chrysle Date: Wed, 31 Jan 2024 10:56:46 +0100 Subject: [PATCH 2/4] Amend overlooked subprocess calls and add test --- CHANGELOG.md | 277 ++++++++++++++++++++++++++++------------ src/pipx/shared_libs.py | 4 +- src/pipx/util.py | 5 +- src/pipx/venv.py | 4 +- tests/test_install.py | 8 ++ 5 files changed, 212 insertions(+), 86 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 007aaa1ecd..24b12b0854 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,106 +1,219 @@ -## dev +# Changelog -- Run venv creation and install_package subprocesses inside distination directory self.root instead of current directory +All notable changes to this project will be documented in this file. -## 1.3.1 +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +This project uses [*towncrier*](https://towncrier.readthedocs.io/) for keeping the changelog. DO NOT commit any changes to this file. +{% include '_draft_changelog.md' ignore missing %} + + + +## [1.4.3](https://github.com/pypa/pipx/tree/1.4.3) - 2024-01-16 + + +### Bugfixes + +- Autofix python version for pylauncher, when version is provided prefixed with `python` ([#1150](https://github.com/pypa/pipx/issues/1150)) +- Support building pipx wheels with setuptools-scm<7, such as on FreeBSD. ([#1208](https://github.com/pypa/pipx/issues/1208)) + +### Improved Documentation + +- Provide useful error messages when unresolvable python version is passed ([#1150](https://github.com/pypa/pipx/issues/1150)) +- Introduce towncrier for managing the changelog ([#1161](https://github.com/pypa/pipx/issues/1161)) +- Add workaround for using pipx applications in shebang under macOS ([#1198](https://github.com/pypa/pipx/issues/1198)) + + +## [1.4.2](https://github.com/pypa/pipx/tree/1.4.2) + +### Features + +- Allow skipping maintenance tasks during list command +- Raise more user friendly error when provided `--python` version is not found +- Update `pipx run` on scripts using `/// script` and no `run` table following the updated version of PEP 723 (#1180) + +### Bugfixes + +- Include `tomli` into `pipx.pyz` (zipapp) so that it can be executed with Python 3.10 or earlier (#1142) +- Fix resolving the python executable path on linux +- `pipx run`: Verify whether the script name provided is a file before running it +- Avoid repeated exception logging in a few rare cases (#1192) + +## [1.4.1](https://github.com/pypa/pipx/tree/1.4.1) + +### Bugfixes + +- Set default logging level to WARNING, so debug log messages won't be shown without passing additional flags such as `--verbose` + +## [1.4.0](https://github.com/pypa/pipx/tree/1.4.0) + +### Features + +- Add `--quiet` and `--verbose` options for the `pipx` subcommands +- Add ability to install multiple packages at once +- Delete directories directly instead of spawning rmdir on Windows + +### Improved Documentation + +- Add Scoop installation instructions + +### Bugfixes + +- "Failed to delete" error when using Microsoft Store Python +- "No pyvenv.cfg file" error when using Microsoft Store Python (#1164) + +## [1.3.3](https://github.com/pypa/pipx/tree/1.3.3) + +### Improved Documentation + +- Make the logo more visible in dark mode + +## [1.3.2](https://github.com/pypa/pipx/tree/1.3.2) + +### Features + +- The project version number is now dynamic and generated from the VCS at build time + +### Improved Documentation + +- Add additional example for --pip-args option, to docs/examples.md + +## [1.3.1](https://github.com/pypa/pipx/tree/1.3.1) + +### Bugfixes - Fix combining of --editable and --force flag -## 1.3.0 +## [1.3.0](https://github.com/pypa/pipx/tree/1.3.0) + +### Features -- Check whether pip module exists in shared lib before performing any actions, such as `reinstall-all`. -- Drop `setuptools` and `wheel` from the shared libraries. This results in less time consumption when the libraries are - automatically upgraded. - Allow running `pip` with `pipx run` -- Support PEP 723 run requirements in `pipx run`. -- Imply `--include-apps` when running `pipx inject --include-deps` - Add `--with-suffix` for `pipx inject` command - `pipx install`: emit a warning when `--force` and `--python` were passed at the same time -- Drop support for Python 3.7 +- Add explicit 3.12 support - Make usage message in `pipx run` show `package_or_url`, so extra will be printed out as well -- Add `--force-reinstall` to pip arguments when `--force` was passed - Use the py launcher, if available, to select Python version with the `--python` option +- add pre-commit hook support +- Add `pipx install --preinstall` to support preinstalling build requirements +- Return an error message when directory can't be added to PATH successfully +- Expose manual pages included in an application installed with `pipx install` +- Check whether pip module exists in shared lib before performing any actions, such as `reinstall-all`. +- Drop `setuptools` and `wheel` from the shared libraries. This results in less time consumption when the libraries are + automatically upgraded. +- Support [inline script metadata](https://packaging.python.org/en/latest/specifications/inline-script-metadata/) + in `pipx run`. +- Imply `--include-apps` when running `pipx inject --include-deps` +- Add `--force-reinstall` to pip arguments when `--force` was passed - Support including requirements in scripts run using `pipx run` (#916) - Pass `pip_args` to `shared_libs.upgrade()` - Fallback to user's log path if the default log path (`$PIPX_HOME/logs`) is not writable to aid with pipx being used for multi-user (e.g. system-wide) installs of applications -- Fix wrong interpreter usage when injecting local pip-installable dependencies into venvs -- add pre-commit hook support - Don't show escaped backslashes for paths in console output - Move `pipx` paths to ensure compatibility with the platform-specific user directories -- [docs] Add more examples for `pipx run` -- [docs] Add subsection to make README easier to read -- Add `pipx install --preinstall` to support preinstalling build requirements - Pass `--no-input` to pip when output is not piped to parent stdout -- Fix program name in generated manual page - Print all environment variables in `pipx environment` -- Return an error message when directory can't be added to PATH successfully -- Expose manual pages included in an application installed with `pipx install` -- Add explicit 3.12 support -## 1.2.1 +### Improved Documentation + +- Add more examples for `pipx run` +- Add subsection to make README easier to read + +### Deprecations and Removals + +- Drop support for Python 3.7 + +### Bugfixes + +- Fix wrong interpreter usage when injecting local pip-installable dependencies into venvs +- Fix program name in generated manual page + +## [1.2.1](https://github.com/pypa/pipx/tree/1.2.1) + +### Bugfixes - Fix compatibility to packaging 23.2+ by removing reliance on packaging's requirement validation logic and detecting a URL-based requirement in pipx. (#1070) -## 1.2.0 +## [1.2.0](https://github.com/pypa/pipx/tree/1.2.0) + +### Features -- Add test for pip module in `pipx reinstall` to fix an issue with `pipx reinstall-all` (#935) - Add `pipx uninject` command (#820) -- [docs] Fix `pipx run` examples and update Python versions used by `pipx install` examples -- [docs] Add an example for installation from source with extras -- Match pip's behaviour when package name ends with archive extension (treat it as a path) - Ship a [zipapp](https://docs.python.org/3/library/zipapp.html) of pipx +- Match pip's behaviour when package name ends with archive extension (treat it as a path) - Change the program name to `path/to/python -m pipx` when running as `python -m pipx` - Improve the detection logic for MSYS2 to avoid entering infinite loop (#908) (#938) - Remove extra trailing quote from exception message - Fix EncodingWarning in `pipx_metadata_file`. -## 1.1.0 +### Improved Documentation + +- Add an example for installation from source with extras +- Fix `pipx run` examples and update Python versions used by `pipx install` examples + +### Bugfixes + +- Add test for pip module in `pipx reinstall` to fix an issue with `pipx reinstall-all` (#935) + +## [1.1.0](https://github.com/pypa/pipx/tree/1.1.0) + +### Features -- Fix encoding issue on Windows when pip fails to install a package -- Improve the behaviour of `shlex.split` on Windows, so paths on Windows can be handled properly when they are passed in - `--pip-args`. (#794) - Add `pipx environment` command (#793) - Add `list --short` option to list only package names (#804) -- [docs] Fix the command for - [installing development version](https://pipx.pypa.io/stable/installation/#install-pipx-development-versions). (#801) -- [docs] Fix test status badge in readme file -- [docs] Add more examples +- Improve the behaviour of `shlex.split` on Windows, so paths on Windows can be handled properly when they are passed in + `--pip-args`. (#794) - [dev] Change github action job names -- [docs] Add additional examples for installation from git repos +- Add additional examples for installation from git repos - [packaging] Switch to [PEP 621](https://www.python.org/dev/peps/pep-0621/) - Add a CACHEDIR.TAG to the cache directory to prevent it from being included in archives and backups. For more information about cache directory tags, see https://bford.info/cachedir -## 1.0.0 +### Bugfixes + +- Fix encoding issue on Windows when pip fails to install a package + +### Improved Documentation + +- Add more examples +- Fix the command for + [installing development version](https://pipx.pypa.io/stable/installation/#install-pipx-development-versions). (#801) +- Fix test status badge in readme file + +## [1.0.0](https://github.com/pypa/pipx/tree/1.0.0) + +### Features - Support [argcomplete 2.0.0](https://pypi.org/project/argcomplete/2.0.0) (#790) - Include machinery to build a manpage for pipx with [argparse-manpage](https://pypi.org/project/argparse-manpage/). - Add better handling for 'app not found' when a single app is present in the project, and an improved error message (#733) + +### Bugfixes + - Fixed animations sending output to stdout, which can break JSON output. (#769) - Fix typo in `pipx upgrade-all` output -## 0.17.0 +## [0.17.0](https://github.com/pypa/pipx/tree/0.17.0) - Support `pipx run` with version constraints and extras. (#697) -## 0.16.5 +## [0.16.5](https://github.com/pypa/pipx/tree/0.16.5) - Fixed `pipx list` output phrasing to convey that python version displayed is the one with which package was installed. - Fixed `pipx install` to provide return code 0 if venv already exists, similar to pip’s behavior. (#736) - [docs] Update ansible's install command in [Programs to Try document](https://pipx.pypa.io/stable/programs-to-try/#ansible) to work with Ansible 2.10+ (#742) -## 0.16.4 +## [0.16.4](https://github.com/pypa/pipx/tree/0.16.4) - Fix to `pipx ensurepath` to fix behavior in user locales other than UTF-8, to fix #644. The internal change is to use userpath v1.6.0 or greater. (#700) - Fix virtual environment inspection for Python releases that uses an int for its release serial number. (#706) - Fix PermissionError in windows when pipx manages itself. (#718) -## 0.16.3 +## [0.16.3](https://github.com/pypa/pipx/tree/0.16.3) - Organization: pipx is extremely pleased to now be a project of the Python Packaging Authority (PyPA)! Note that our github URL has changed to [pypa/pipx](https://github.com/pypa/pipx) @@ -118,14 +231,14 @@ * Colorama is now only installed on Windows. (#691) -## 0.16.2.1 +## [0.16.2.1](https://github.com/pypa/pipx/tree/0.16.2.1) - Changed non-venv-info warnings and notices from `pipx list` to print to stderr. This especially prevents `pipx list --json` from printing invalid json to stdout. (#680) - Fixed bug that could cause uninstall on Windows with injected packages to uninstall too many apps from the local binary directory. (#679) -## 0.16.2.0 +## [0.16.2.0](https://github.com/pypa/pipx/tree/0.16.2.0) - Fixed bug #670 where uninstalling a venv could erroneously uninstall other apps from the local binary directory. (#672) @@ -138,7 +251,7 @@ binaries for suffixed-venvs. (#653) - Changed venv minimum python version to 3.6, removing python 3.5 which is End of Life. (#666) -## 0.16.1.0 +## [0.16.1.0](https://github.com/pypa/pipx/tree/0.16.1.0) - Introduce the `pipx.run` entry point group as an alternative way to declare an application for `pipx run`. - Fix cursor show/hide to work with older versions of Windows. (#610) @@ -151,7 +264,7 @@ - For `reinstall-all`, fixed bug where missing python executable would cause error. (#634) - Fix regression which prevented pipx from working with pythonloc (and `__pypackages__` folder). (#636) -## 0.16.0.0 +## [0.16.0.0](https://github.com/pypa/pipx/tree/0.16.0.0) - New venv inspection! The code that pipx uses to examine and determine metadata in an installed venv has been made faster, better, and more reliable. It now uses modern python libraries like `packaging` and `importlib.metadata` to @@ -192,7 +305,7 @@ - pipx error, warning, and other messages now word-wrap so words are not split across lines. Their appearance is also now more consistent. -## 0.15.6.0 +## [0.15.6.0](https://github.com/pypa/pipx/tree/0.15.6.0) - [docs] Update license - [docs] Display a more idiomatic command for registering completions on fish. @@ -203,12 +316,12 @@ among other uses. - [bugfix] Fixed bug where extras were ignored with a PEP 508 package specification with a URL. -## 0.15.5.1 +## [0.15.5.1](https://github.com/pypa/pipx/tree/0.15.5.1) - [bugfix] Fixed regression of 0.15.5.0 which erroneously made installing from a local path with package extras not possible. -## 0.15.5.0 +## [0.15.5.0](https://github.com/pypa/pipx/tree/0.15.5.0) - pipx now parses package specification before install. It removes (with warning) the `--editable` install option for any package specification that is not a local path. It also removes (with warning) any environment markers. @@ -225,20 +338,20 @@ - [feature] `--suffix` option for `install` to allow multiple versions of same tool to be installed (#445) - [feature] pipx can now be used with the Windows embeddable Python distribution -## 0.15.4.0 +## [0.15.4.0](https://github.com/pypa/pipx/tree/0.15.4.0) - [feature] `list` now has a new option `--include-injected` to show the injected packages in the main apps - [bugfix] Fixed bug that can cause crash when installing an app -## 0.15.3.1 +## [0.15.3.1](https://github.com/pypa/pipx/tree/0.15.3.1) - [bugfix] Workaround multiprocessing issues on certain platforms (#229) -## 0.15.3.0 +## [0.15.3.0](https://github.com/pypa/pipx/tree/0.15.3.0) - [feature] Use symlinks on Windows when symlinks are available -## 0.15.2.0 +## [0.15.2.0](https://github.com/pypa/pipx/tree/0.15.2.0) - [bugfix] Improved error reporting during venv metadata inspection. - [bugfix] Fixed incompatibility with pypy as venv interpreter (#372). @@ -250,30 +363,30 @@ - [bugfix] Ignore system shared libraries when installing shared libraries pip, wheel, and setuptools. This also fixes an incompatibility with Debian/Ubuntu's version of pip (#386). -## 0.15.1.3 +## [0.15.1.3](https://github.com/pypa/pipx/tree/0.15.1.3) - [bugfix] On Windows, pipx now lists correct Windows apps (#217) - [bugfix] Fixed a `pipx install` bug causing incorrect python binary to be used when using the optional --python argument in certain situations, such as running pipx from a Framework python on macOS and specifying a non-Framework python. -## 0.15.1.2 +## [0.15.1.2](https://github.com/pypa/pipx/tree/0.15.1.2) - [bugfix] Fix recursive search of dependencies' apps so no apps are missed. - `upgrade-all` now skips editable packages, because pip disallows upgrading editable packages. -## 0.15.1.1 +## [0.15.1.1](https://github.com/pypa/pipx/tree/0.15.1.1) - [bugfix] fix regression that caused installing with --editable flag to fail package name determination. -## 0.15.1.0 +## [0.15.1.0](https://github.com/pypa/pipx/tree/0.15.1.0) - Add Python 3.8 to PyPI classifier and travis test matrix - [feature] auto-upgrade shared libraries, including pip, if older than one month. Hide all pip warnings that a new version is available. (#264) - [bugfix] pass pip arguments to pip when determining package name (#320) -## 0.15.0.0 +## [0.15.0.0](https://github.com/pypa/pipx/tree/0.15.0.0) Upgrade instructions: When upgrading to 0.15.0.0 or above from a pre-0.15.0.0 version, you must re-install all packages to take advantage of the new persistent pipx metadata files introduced in this release. These metadata files store pip @@ -304,7 +417,7 @@ by running `pipx reinstall-all` or `pipx uninstall-all`, then reinstalling manua - Use threads on OS's without support for semaphores - Stricter parsing when passing `--` argument as delimiter -## 0.14.0.0 +## [0.14.0.0](https://github.com/pypa/pipx/tree/0.14.0.0) - Speed up operations by using shared venv for `pip`, `setuptools`, and `wheel`. You can see more detail in the 'how pipx works' section of the documentation. (#164, @pfmoore) @@ -314,22 +427,22 @@ by running `pipx reinstall-all` or `pipx uninstall-all`, then reinstalling manua - If `--force` is passed, remove existing files in PIPX_BIN_DIR - Move animation to start of line, hide cursor when animating -## 0.13.2.3 +## [0.13.2.3](https://github.com/pypa/pipx/tree/0.13.2.3) - Fix regression when installing a package that doesn't have any entry points -## 0.13.2.2 +## [0.13.2.2](https://github.com/pypa/pipx/tree/0.13.2.2) - Remove unnecessary and sometimes incorrect check after `pipx inject` (#195) - Make status text/animation reliably disappear before continuing - Update animation symbols -## 0.13.2.1 +## [0.13.2.1](https://github.com/pypa/pipx/tree/0.13.2.1) - Remove virtual environment if installation did not complete. For example, if it was interrupted by ctrl+c or if an exception occurred for any reason. (#193) -## 0.13.2.0 +## [0.13.2.0](https://github.com/pypa/pipx/tree/0.13.2.0) - Add shell autocompletion. Also add `pipx completions` command to print instructions on how to add pipx completions to your shell. @@ -340,12 +453,12 @@ by running `pipx reinstall-all` or `pipx uninstall-all`, then reinstalling manua - swap out of order logic in order to correctly recommend --include-deps (@joshuarli) - [dev] Migrate from tox to nox -## 0.13.1.1 +## [0.13.1.1](https://github.com/pypa/pipx/tree/0.13.1.1) - Do not raise bare exception if no binaries found (#150) - Update pipsi migration script -## 0.13.1.0 +## [0.13.1.0](https://github.com/pypa/pipx/tree/0.13.1.0) - Deprecate `ensurepath` command. Use `userpath append ~/.local/bin` - Support redirects and proxies when downloading python files (i.e. `pipx run http://url/file.py`) @@ -354,34 +467,34 @@ by running `pipx reinstall-all` or `pipx uninstall-all`, then reinstalling manua - Use mkdocs for documentation - Change default cache duration for `pipx run` from 2 to 14 days -## 0.13.0.1 +## [0.13.0.1](https://github.com/pypa/pipx/tree/0.13.0.1) - Fix upgrade-all and reinstall-all regression -## 0.13.0.0 +## [0.13.0.0](https://github.com/pypa/pipx/tree/0.13.0.0) - Add `runpip` command to run arbitrary pip commands in pipx-managed virtual environments - Do not raise error when running `pipx install PACKAGE` and the package has already been installed by pipx (#125). This is the cause of the major version change from 0.12 to 0.13. - Add `--skip` argument to `upgrade-all` and `reinstall-all` commands, to let the user skip particular packages -## 0.12.3.3 +## [0.12.3.3](https://github.com/pypa/pipx/tree/0.12.3.3) - Update logic in determining a package's binaries during installation. This removes spurious binaries from the installation. (#104) - Improve compatibility with Debian distributions by using `shutil.which` instead of `distutils.spawn.find_executable` (#102) -## 0.12.3.2 +## [0.12.3.2](https://github.com/pypa/pipx/tree/0.12.3.2) - Fix infinite recursion error when installing package such as `cloudtoken==0.1.84` (#103) - Fix windows type errors (#96, #98) -## 0.12.3.1 +## [0.12.3.1](https://github.com/pypa/pipx/tree/0.12.3.1) - Fix "WindowsPath is not iterable" bug -## 0.12.3.0 +## [0.12.3.0](https://github.com/pypa/pipx/tree/0.12.3.0) - Add `--include-deps` argument to include binaries of dependent packages when installing with pipx. This improves compatibility with packages that depend on other installed packages, such as `jupyter`. @@ -390,7 +503,7 @@ by running `pipx reinstall-all` or `pipx uninstall-all`, then reinstalling manua - More aggressive cache directory removal when `--no-cache` is passed to `pipx run` - [dev] Move inline text passed to subprocess calls to their own files to enable autoformatting, linting, unit testing -## 0.12.2.0 +## [0.12.2.0](https://github.com/pypa/pipx/tree/0.12.2.0) - Add support for PEP 582's `__pypackages__` (experimental). `pipx run BINARY` will first search in `__pypackages__` for binary, then fallback to installing from PyPI. `pipx run --pypackages BINARY` will raise an error if the binary is not @@ -398,7 +511,7 @@ by running `pipx reinstall-all` or `pipx uninstall-all`, then reinstalling manua - Fix regression when installing with `--editable` flag (#93) - [dev] improve unit tests -## 0.12.1.0 +## [0.12.1.0](https://github.com/pypa/pipx/tree/0.12.1.0) - Cache and reuse temporary Virtual Environments created with `pipx run` (#61) - Update binary discovery logic to find "scripts" like awscli (#91) @@ -408,54 +521,54 @@ by running `pipx reinstall-all` or `pipx uninstall-all`, then reinstalling manua at `$PIPX_HOME`. - [dev] refactor into multiple files, add more unit tests -## 0.12.0.4 +## [0.12.0.4](https://github.com/pypa/pipx/tree/0.12.0.4) - Fix parsing bug in pipx run -## 0.12.0.3 +## [0.12.0.3](https://github.com/pypa/pipx/tree/0.12.0.3) - list python2 as supported language so that pip installs with python2 will no longer install the pipx on PyPI from the original pipx owner. Running pipx with python2 will fail, but at least it will not be as confusing as running the pipx package from the original owner. -## 0.12.0.2 +## [0.12.0.2](https://github.com/pypa/pipx/tree/0.12.0.2) - forward arguments to run command correctly #90 -## 0.12.0.1 +## [0.12.0.1](https://github.com/pypa/pipx/tree/0.12.0.1) - stop using unverified context #89 -## 0.12.0.0 +## [0.12.0.0](https://github.com/pypa/pipx/tree/0.12.0.0) - Change installation instructions to use `pipx` PyPI name - Add `ensurepath` command -## 0.11.0.2 +## [0.11.0.2](https://github.com/pypa/pipx/tree/0.11.0.2) - add version argument parsing back in (fixes regression) -## 0.11.0.1 +## [0.11.0.1](https://github.com/pypa/pipx/tree/0.11.0.1) - add version check, command check, fix printed version update installation instructions -## 0.11.0.0 +## [0.11.0.0](https://github.com/pypa/pipx/tree/0.11.0.0) - Replace `pipx BINARY` with `pipx run BINARY` to run a binary in an ephemeral environment. This is a breaking API change so the major version has been incremented. (Issue #69) - upgrade pip when upgrading packages (Issue #72) - support --system-site-packages flag (Issue #64) -## 0.10.4.1 +## [0.10.4.1](https://github.com/pypa/pipx/tree/0.10.4.1) - Fix version printed when `pipx --version` is run -## 0.10.4.0 +## [0.10.4.0](https://github.com/pypa/pipx/tree/0.10.4.0) - Add --index-url, --editable, and --pip-args flags - Updated README with pipsi migration instructions -## 0.10.3.0 +## [0.10.3.0](https://github.com/pypa/pipx/tree/0.10.3.0) - Display python version in list - Do not reinstall package if already installed (added `--force` flag to override) diff --git a/src/pipx/shared_libs.py b/src/pipx/shared_libs.py index 9429b01252..eaa4920970 100644 --- a/src/pipx/shared_libs.py +++ b/src/pipx/shared_libs.py @@ -43,7 +43,9 @@ def site_packages(self) -> Path: def create(self, verbose: bool = False) -> None: if not self.is_valid: with animate("creating shared libraries", not verbose): - create_process = run_subprocess([DEFAULT_PYTHON, "-m", "venv", "--clear", self.root]) + create_process = run_subprocess( + [DEFAULT_PYTHON, "-m", "venv", "--clear", self.root], run_dir=str(self.root) + ) subprocess_post_check(create_process) # ignore installed packages to ensure no unexpected patches from the OS vendor diff --git a/src/pipx/util.py b/src/pipx/util.py index e7b320c968..15031ceecb 100644 --- a/src/pipx/util.py +++ b/src/pipx/util.py @@ -179,6 +179,9 @@ def run_subprocess( # symlink in argv[0] so that it can locate the venv. if not os.path.islink(cmd_str_list[0]) and WINDOWS: cmd_str_list[0] = os.path.realpath(cmd_str_list[0]) + + # TODO: Switch to using `-P` / PYTHONSAFEPATH instead of running in + # separate directory in Python 3.11 completed_process = subprocess.run( cmd_str_list, env=env, @@ -187,7 +190,7 @@ def run_subprocess( encoding="utf-8", universal_newlines=True, check=False, - cwd=run_dir if run_dir else None, + cwd=run_dir, ) if capture_stdout and log_stdout: diff --git a/src/pipx/venv.py b/src/pipx/venv.py index d723414f64..567992e67c 100644 --- a/src/pipx/venv.py +++ b/src/pipx/venv.py @@ -296,7 +296,7 @@ def install_unmanaged_packages(self, requirements: List[str], pip_args: List[str ] # no logging because any errors will be specially logged by # subprocess_post_check_handle_pip_error() - pip_process = run_subprocess(cmd, log_stdout=False, log_stderr=False) + pip_process = run_subprocess(cmd, log_stdout=False, log_stderr=False, run_dir=str(self.root)) subprocess_post_check_handle_pip_error(pip_process) if pip_process.returncode: raise PipxError(f"Error installing {', '.join(requirements)}.") @@ -458,7 +458,7 @@ def _run_pip(self, cmd: List[str]) -> "CompletedProcess[str]": cmd = [str(self.python_path), "-m", "pip"] + cmd if not self.verbose: cmd.append("-q") - return run_subprocess(cmd) + return run_subprocess(cmd, run_dir=str(self.root)) def run_pip_get_exit_code(self, cmd: List[str]) -> ExitCode: cmd = [str(self.python_path), "-m", "pip"] + cmd diff --git a/tests/test_install.py b/tests/test_install.py index b814b736a0..fcc301ac11 100644 --- a/tests/test_install.py +++ b/tests/test_install.py @@ -337,3 +337,11 @@ def test_passed_python_and_force_flag_warning(pipx_temp_env, capsys): assert not run_pipx_cli(["install", "pycowsay", "--force"]) captured = capsys.readouterr() assert "--python is ignored when --force is passed." not in captured.out + + +def test_install_run_in_separate_directory(caplog, capsys, pipx_temp_env, monkeypatch, tmp_path): + monkeypatch.chdir(tmp_path) + f = Path("argparse.py") + f.touch() + + install_package(capsys, pipx_temp_env, caplog, "pycowsay", "pycowsay") From b511eaae2b345fb6bcb91a660913f91a9a2b42f7 Mon Sep 17 00:00:00 2001 From: chrysle Date: Wed, 31 Jan 2024 11:08:11 +0100 Subject: [PATCH 3/4] Add changelog --- changelog.d/1091.bugfix.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/1091.bugfix.md diff --git a/changelog.d/1091.bugfix.md b/changelog.d/1091.bugfix.md new file mode 100644 index 0000000000..67f22bc049 --- /dev/null +++ b/changelog.d/1091.bugfix.md @@ -0,0 +1 @@ +Fix installation issues when files in the working directory interfere with venv creation process. From 8c3d168c94c8f40a6a9696e4940b4b764e063862 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 31 Jan 2024 10:12:17 +0000 Subject: [PATCH 4/4] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/pipx/util.py | 2 +- src/pipx/venv.py | 8 ++------ tests/test_install.py | 2 +- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/pipx/util.py b/src/pipx/util.py index 15031ceecb..8a498e853a 100644 --- a/src/pipx/util.py +++ b/src/pipx/util.py @@ -179,7 +179,7 @@ def run_subprocess( # symlink in argv[0] so that it can locate the venv. if not os.path.islink(cmd_str_list[0]) and WINDOWS: cmd_str_list[0] = os.path.realpath(cmd_str_list[0]) - + # TODO: Switch to using `-P` / PYTHONSAFEPATH instead of running in # separate directory in Python 3.11 completed_process = subprocess.run( diff --git a/src/pipx/venv.py b/src/pipx/venv.py index 567992e67c..96de4e3731 100644 --- a/src/pipx/venv.py +++ b/src/pipx/venv.py @@ -157,9 +157,7 @@ def create_venv(self, venv_args: List[str], pip_args: List[str], override_shared cmd = [self.python, "-m", "venv"] if not override_shared: cmd.append("--without-pip") - venv_process = run_subprocess( - cmd + venv_args + [str(self.root)], run_dir=str(self.root) - ) + venv_process = run_subprocess(cmd + venv_args + [str(self.root)], run_dir=str(self.root)) subprocess_post_check(venv_process) shared_libs.create(self.verbose) @@ -250,9 +248,7 @@ def install_package( ] # no logging because any errors will be specially logged by # subprocess_post_check_handle_pip_error() - pip_process = run_subprocess( - cmd, log_stdout=False, log_stderr=False, run_dir=str(self.root) - ) + pip_process = run_subprocess(cmd, log_stdout=False, log_stderr=False, run_dir=str(self.root)) subprocess_post_check_handle_pip_error(pip_process) if pip_process.returncode: raise PipxError(f"Error installing {full_package_description(package_name, package_or_url)}.") diff --git a/tests/test_install.py b/tests/test_install.py index fcc301ac11..23cfc52fc0 100644 --- a/tests/test_install.py +++ b/tests/test_install.py @@ -344,4 +344,4 @@ def test_install_run_in_separate_directory(caplog, capsys, pipx_temp_env, monkey f = Path("argparse.py") f.touch() - install_package(capsys, pipx_temp_env, caplog, "pycowsay", "pycowsay") + install_packages(capsys, pipx_temp_env, caplog, ["pycowsay"], ["pycowsay"])