pax_global_header 0000666 0000000 0000000 00000000064 14551526321 0014516 g ustar 00root root 0000000 0000000 52 comment=18a0784a048870e2644405696c29508b5f261fa9
pipx-1.4.3/ 0000775 0000000 0000000 00000000000 14551526321 0012503 5 ustar 00root root 0000000 0000000 pipx-1.4.3/.deepsource.toml 0000664 0000000 0000000 00000000270 14551526321 0015613 0 ustar 00root root 0000000 0000000 version = 1
test_patterns = ["tests/**"]
[[analyzers]]
name = "python"
enabled = true
[analyzers.meta]
runtime_version = "3.x.x"
[[transformers]]
name = "black"
enabled = true
pipx-1.4.3/.github/ 0000775 0000000 0000000 00000000000 14551526321 0014043 5 ustar 00root root 0000000 0000000 pipx-1.4.3/.github/ISSUE_TEMPLATE/ 0000775 0000000 0000000 00000000000 14551526321 0016226 5 ustar 00root root 0000000 0000000 pipx-1.4.3/.github/ISSUE_TEMPLATE/bug.md 0000664 0000000 0000000 00000001023 14551526321 0017321 0 ustar 00root root 0000000 0000000 ---
name: Bug
about: Report a bug or unexpected behavior.
---
**Describe the bug**
**How to reproduce**
**Expected behavior**
pipx-1.4.3/.github/ISSUE_TEMPLATE/feature_request.md 0000664 0000000 0000000 00000000651 14551526321 0021755 0 ustar 00root root 0000000 0000000 ---
name: Feature request
about: Suggest an idea or new feature for this project
---
**How would this feature be useful?**
**Describe the solution you'd like**
**Describe alternatives you've considered**
pipx-1.4.3/.github/PULL_REQUEST_TEMPLATE.md 0000664 0000000 0000000 00000000524 14551526321 0017645 0 ustar 00root root 0000000 0000000
- [ ] I have added a news fragment under `changelog.d/` (if the patch affects the end users)
## Summary of changes
## Test plan
Tested by running
```
# command(s) to exercise these changes
```
pipx-1.4.3/.github/dependabot.yml 0000664 0000000 0000000 00000000262 14551526321 0016673 0 ustar 00root root 0000000 0000000 version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
groups:
actions:
patterns:
- "*"
pipx-1.4.3/.github/workflows/ 0000775 0000000 0000000 00000000000 14551526321 0016100 5 ustar 00root root 0000000 0000000 pipx-1.4.3/.github/workflows/create_tests_package_lists.yml 0000664 0000000 0000000 00000002163 14551526321 0024203 0 ustar 00root root 0000000 0000000 name: Create tests package lists for offline tests
on:
workflow_dispatch:
concurrency:
group: create-tests-package-lists-${{ github.ref }}
cancel-in-progress: true
jobs:
create_package_lists:
name: Create package lists
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest]
python-version: ["3.12", "3.11", "3.10", "3.9", "3.8"]
include:
- os: macos-latest
python-version: "3.12"
- os: windows-latest
python-version: "3.12"
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: "pip"
- name: Install nox
run: python -m pip install nox
- name: Create lists
run:
nox --non-interactive --session create_test_package_list-${{ matrix.python-version }} -- ./new_tests_packages
- name: Store reports as artifacts
uses: actions/upload-artifact@v3
with:
name: lists
path: ./new_tests_packages
pipx-1.4.3/.github/workflows/exhaustive_package_test.yml 0000664 0000000 0000000 00000004317 14551526321 0023527 0 ustar 00root root 0000000 0000000 name: Exhaustive Package Test (slow)
on:
workflow_dispatch:
concurrency:
group: exhaustive-package-test-${{ github.ref }}
cancel-in-progress: true
jobs:
test_all_packages:
name: Exhaustive Package Test
continue-on-error: true
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ["3.12", "3.11", "3.10", "3.9", "3.8"]
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: "pip"
- name: Install nox
run: python -m pip install nox
- name: Execute Tests
continue-on-error: true
run: nox --non-interactive --session test_all_packages-${{ matrix.python-version }}
- name: Store reports as artifacts
uses: actions/upload-artifact@v3
with:
name: reports-raw
path: reports
report_all_packages:
name: Collate test reports
needs: test_all_packages
runs-on: ubuntu-latest
steps:
- name: Get report artifacts
uses: actions/download-artifact@v3
with:
name: reports-raw
- name: Collate reports
run: |
ls # DEBUG
mkdir reports
cat all_packages_report_legend.txt > all_nodeps_reports_lf.txt
cat all_packages_nodeps_report_* >> all_nodeps_reports_lf.txt
tr -d '\r' < all_nodeps_reports_lf.txt > reports/all_nodeps_reports.txt
cat all_packages_nodeps_errors_* > all_nodeps_errors_lf.txt
tr -d '\r' < all_nodeps_errors_lf.txt > reports/all_nodeps_errors.txt
cat all_packages_report_legend.txt > all_deps_reports_lf.txt
cat all_packages_deps_report_* >> all_deps_reports_lf.txt
tr -d '\r' < all_deps_reports_lf.txt > reports/all_deps_reports.txt
cat all_packages_deps_errors_* > all_deps_errors_lf.txt
tr -d '\r' < all_deps_errors_lf.txt > reports/all_deps_errors.txt
- name: Store collated and raw reports as artifacts
uses: actions/upload-artifact@v3
with:
name: reports-final
path: reports
pipx-1.4.3/.github/workflows/tests.yml 0000664 0000000 0000000 00000011554 14551526321 0017773 0 ustar 00root root 0000000 0000000 name: tests
on:
workflow_dispatch:
push:
pull_request:
schedule:
- cron: "0 8 * * *"
concurrency:
group: tests-${{ github.ref }}
cancel-in-progress: true
env:
default-python: "3.12"
minimum-supported-python: "3.8"
jobs:
tests:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
python-version: ["3.12", "3.11", "3.10", "3.9", "3.8"]
include:
- os: windows-latest
python-version: "3.12"
- os: macos-latest
python-version: "3.12"
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: "pip"
- name: Persistent .pipx_tests/package_cache
uses: actions/cache@v3
with:
path: ${{ github.workspace }}/.pipx_tests/package_cache/${{ matrix.python-version }}
key: pipx-tests-package-cache-${{ runner.os }}-${{ matrix.python-version }}
- name: Install nox
run: python -m pip install nox
- name: Execute Tests
run: nox --error-on-missing-interpreters --non-interactive --session tests-${{ matrix.python-version }}
man:
name: Build man page
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ env.default-python }}
uses: actions/setup-python@v5
with:
python-version: ${{ env.default-python }}
cache: "pip"
- name: Install nox
run: python -m pip install nox
- name: Build man page
run: nox --error-on-missing-interpreters --non-interactive --session build_man
- name: Show man page
run: man -l pipx.1
zipapp:
name: Build zipapp
runs-on: ubuntu-latest
steps:
- name: Checkout ${{ github.ref }}
uses: actions/checkout@v4
- name: Set up Python ${{ env.minimum-supported-python }}
uses: actions/setup-python@v5
with:
python-version: ${{ env.minimum-supported-python }}
cache: "pip"
- name: Install nox
run: pip install nox
- name: Build zipapp
run: nox --error-on-missing-interpreters --non-interactive --session zipapp
- name: Test zipapp by installing black
run: python ./pipx.pyz install black
- uses: actions/upload-artifact@v3
with:
name: pipx.pyz
path: pipx.pyz
retention-days: 3
pypi-publish:
name: Publish pipx to PyPI on release
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags')
needs: [tests, man, zipapp]
runs-on: ubuntu-latest
environment:
name: release
url: https://pypi.org/p/pipx
permissions:
id-token: write
steps:
- name: Checkout ${{ github.ref }}
uses: actions/checkout@v4
- name: Set up Python ${{ env.default-python }}
uses: actions/setup-python@v5
with:
python-version: ${{ env.default-python }}
cache: "pip"
- name: Install nox
run: pip install nox
- name: Build sdist and wheel
run: nox --error-on-missing-interpreters --non-interactive --session build
- name: Publish to PyPi
uses: pypa/gh-action-pypi-publish@v1.8.11
upload-zipapp:
name: Upload zipapp to GitHub Release on release
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags')
needs: [tests, man, zipapp]
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v3
with:
name: pipx.pyz
- name: Upload to release
uses: softprops/action-gh-release@v1
with:
files: pipx.pyz
bump-changelog:
name: Bump changelog on release
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags')
needs: [pypi-publish, upload-zipapp]
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- name: Checkout ${{ github.ref }}
uses: actions/checkout@v4
- name: Extract release tag
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
- name: Create pull request branch
run: git switch -c "bump-changelog-for-${RELEASE_VERSION}"
- name: Update changelog
run: pipx run towncrier build --yes --version $RELEASE_VERSION
- name: Commit and push change
run: |
git config --global user.name 'github-actions[bot]'
git config --global user.email '41898282+github-actions[bot]@users.noreply.github.com'
git commit -am "Bump changelog for $RELEASE_VERSION"
git push origin "bump-changelog-for-${RELEASE_VERSION}"
- name: Create pull request
run: |
git fetch origin
gh pr create --base main --fill
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
pipx-1.4.3/.gitignore 0000664 0000000 0000000 00000000324 14551526321 0014472 0 ustar 00root root 0000000 0000000 /.*_cache
/build
/dist
/src/pipx/version.py
/noxfile.py
/.nox
*.py[co]
__pycache__
/site
/.coverage*
/.pipx_tests
/testdata/tests_packages/*.txt
/pipx.pyz
*.egg-info
build
*.whl
/pipx.1
/docs/_draft_changelog.md
pipx-1.4.3/.pre-commit-config.yaml 0000664 0000000 0000000 00000001555 14551526321 0016772 0 ustar 00root root 0000000 0000000 repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: end-of-file-fixer
- id: check-added-large-files
- id: trailing-whitespace
- id: check-yaml
- repo: https://github.com/tox-dev/pyproject-fmt
rev: "1.5.3"
hooks:
- id: pyproject-fmt
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.1.11
hooks:
- id: ruff-format
- id: ruff
args: [ "--fix", "--unsafe-fixes", "--exit-non-zero-on-fix"]
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.8.0
hooks:
- id: mypy
args: ['--warn-unused-ignores', '--strict-equality','--no-implicit-optional', '--check-untyped-defs']
exclude: 'testdata/test_package_specifier/local_extras/setup.py'
additional_dependencies:
- "mkdocs-gen-files"
- "nox"
- "packaging>=20"
- "platformdirs>=2.1"
- "tomli; python_version < '3.11'"
pipx-1.4.3/.pre-commit-hooks.yaml 0000664 0000000 0000000 00000000206 14551526321 0016640 0 ustar 00root root 0000000 0000000 - id: pipx
name: pipx
entry: pipx run
require_serial: true
language: python
minimum_pre_commit_version: '2.9.2'
pipx-1.4.3/.readthedocs.yml 0000664 0000000 0000000 00000000236 14551526321 0015572 0 ustar 00root root 0000000 0000000 version: 2
build:
os: ubuntu-22.04
tools:
python: "3.12"
commands:
- pip install nox
- nox --session build_docs -- "${READTHEDOCS_OUTPUT}"/html
pipx-1.4.3/CHANGELOG.md 0000664 0000000 0000000 00000070270 14551526321 0014322 0 ustar 00root root 0000000 0000000 # Changelog
All notable changes to this project will be documented in this file.
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.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 additonal 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](https://github.com/pypa/pipx/tree/1.3.0)
### Features
- 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`.
- 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
- Don't show escaped backslashes for paths in console output
- Move `pipx` paths to ensure compatibility with the platform-specific user directories
- 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
## [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](https://github.com/pypa/pipx/tree/1.2.0)
### Features
- Add `pipx uninject` command (#820)
- 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`.
### 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
- Add `pipx environment` command (#793)
- Add `list --short` option to list only package names (#804)
- 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
- 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
- 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)
- Support `pipx run` with version constraints and extras. (#697)
## [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](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](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)
- Fixed `pipx list --json` to return valid json with no venvs installed. Previously would return an empty string to
stdout. (#681)
- Changed `pipx ensurepath` bash behavior so that only one of {`~/.profile`, `~/.bash\_profile`} is modified with the
extra pipx paths, not both. Previously, if a `.bash_profile` file was created where one didn't exist, it could cause
problems, e.g. #456. The internal change is to use userpath v1.5.0 or greater. (#684)
- Changed default nox tests, Github Workflow tests, and pytest behavior to use local pypi server with fixed lists of
available packages. This allows greater test isolation (no network pypi access needed) and determinism (fixed
available dependencies.) It also allows running the tests offline with some extra preparation beforehand (See
[Running Unit Tests Offline](https://pipx.pypa.io/stable/contributing/#running-unit-tests-offline)). The old style
tests that use the internet to access pypi.org are still available using `nox -s tests_internet` or
`pytest --net-pypiserver tests`. (#686)
* Colorama is now only installed on Windows. (#691)
## [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](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)
- Added `--json` switch to `pipx list` to output rich json-metadata for all venvs.
- Ensured log files are utf-8 encoded to prevent Unicode encoding errors from occurring with emojis. (#646)
- Fixed issue which made pipx incorrectly list apps as part of a venv when they were not installed by pipx. (#650)
- Fixed old regression that would prevent pipx uninstall from cleaning up linked binaries if the venv was old and did
not have pipx metadata. (#651)
- Fixed bugs with suffixed-venvs on Windows. Now properly summarizes install, and actually uninstalls associated
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)
- 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)
- Support text colors on Windows. (#612)
- Better platform unicode detection to avoid errors and allow showing emojis when possible. (#614)
- Don't emit show cursor or hide cursor codes if STDERR is not a tty. (#620)
- Sped up `pipx list` (#624).
- pip errors no longer stream to the shell when pip fails during a pipx install. pip's output is now saved to a log
file. In the shell, pipx will tell you the location of the log file and attempt to summarize why pip failed. (#625)
- 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)
- 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
examine installed venvs. It also now properly handles installed package extras. In addition, some problems pipx has
had with certain characters (like periods) in package names should be remedied.
- Added reinstall command for reinstalling a single venv.
- Changed `pipx run` on non-Windows systems to actually replace pipx process with the app process instead of running it
as a subprocess. (Now using python's `os.exec*`)
- [bugfix] Fixed bug with reinstall-all command when package have been installed using a specifier. Now the initial
specifier is used.
- [bugfix] Override display of `PIPX_DEFAULT_PYTHON` value when generating web documentation for `pipx install` #523
- [bugfix] Wrap help documentation for environment variables.
- [bugfix] Fixed uninstall crash that could happen on Windows for certain packages
- [feature] Venv package name arguments now do not have to match exactly as pipx has them stored, but can be specified
in any python-package-name-equivalent way. (i.e. case does not matter, and `.`, `-`, `_` characters are
interchangeable.)
- [change] Venvs with a suffix: A suffix can contain any characters, but for purposes of uniqueness, python package name
rules apply--upper- and lower-case letters are equivalent, and any number of `.`, `-`, or `_` characters in a row are
equivalent. (e.g. if you have a suffixed venv `pylint_1.0A` you could not add another suffixed venv called
`pylint--1-0a`, as it would not be a unique name.)
- [implementation detail] Pipx shared libraries (providing pip, setuptools, wheel to pipx) are no longer installed using
pip arguments taken from the last regular pipx install. If you need to apply pip arguments to pipx's use of pip for
its internal shared libraries, use PIP\_\* environment variables.
- [feature] Autocomplete for venv names is no longer restricted to an exact match to the literal venv name, but will
autocomplete any logically-similar python package name (i.e. case does not matter, and `.`, `-`, `_` characters are
all equivalent.)
- pipx now reinstall its internal shared libraries when the user executes `reinstall-all`.
- Made sure shell exit codes from every pipx command are correct. In the past some (like from `pipx upgrade`) were
wrong. The exit code from `pipx runpip` is now the exit code from the `pip` command run. The exit code from
`pipx list` will be 1 if one or more venvs have problems that need to be addressed.
- pipx now writes a log file for each pipx command executed to `$PIPX_HOME/logs`, typically `~/.local/pipx/logs`. pipx
keeps the most recent 10 logs and deletes others.
- `pipx upgrade` and `pipx upgrade-all` now have a `--upgrade-injected` option which directs pipx to also upgrade
injected packages.
- `pipx list` now detects, identifies, and suggests a remedy for venvs with old-internal data (internal venv names) that
need to be updated.
- Added a "Troubleshooting" page to the pipx web documentation for common problems pipx users may encounter.
- 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)
- [docs] Update license
- [docs] Display a more idiomatic command for registering completions on fish.
- [bugfix] Fixed regression in list, inject, upgrade, reinstall-all commands when suffixed packages are used.
- [bugfix] Do not reset package url during upgrade when main package is `pipx`
- Updated help text to show description for `ensurepath` and `completions` help
- Added support for user-defined default python interpreter via new `PIPX_DEFAULT_PYTHON`. Helpful for use with pyenv
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)
- [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)
- 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.
- Disabled animation when we cannot determine terminal size or if the number of columns is too small. (Fixes #444)
- [feature] Version of each injected package is now listed after name for `pipx list --include-injected`
- Change metadata recorded from version-specified install to allow upgrades in future. Adds pipx dependency on
`packaging` package.
- [bugfix] Prevent python error in case where package has no pipx metadata and advise user how to fix.
- [feature] `ensurepath` now also ensures that pip user binary path containing pipx itself is in user's PATH if pipx was
installed using `pip install --user`.
- [bugfix] For `pipx install`, fixed failure to install if user has `PIP_USER=1` or `user=true` in pip.conf. (#110)
- [bugfix] Requiring userpath v1.4.1 or later so ensure Windows bug is fixed for `ensurepath` (#437)
- [feature] log pipx version (#423)
- [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)
- [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)
- [bugfix] Workaround multiprocessing issues on certain platforms (#229)
## [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](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).
- [bugfix] Replaced implicit dependency on setuptools with an explicit dependency on packaging (#339).
- [bugfix] Continue reinstalling packages after failure
- [bugfix] Hide cursor while pipx runs
- [feature] Add environment variable `USE_EMOJI` to allow enabling/disabling emojis (#376)
- [refactor] Moved all commands to separate files within the commands module (#255).
- [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)
- [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)
- [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)
- [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)
- 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)
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
specification values, injected packages, any custom pip arguments, and more in each main package's venv. You can do this
by running `pipx reinstall-all` or `pipx uninstall-all`, then reinstalling manually.
- `install` now has no `--spec` option. You may specify any valid pip specification for `install`'s main argument.
- `inject` will now accept pip specifications for dependency arguments
- Metadata is now stored for each application installed, including install options like `--spec`, and injected packages.
This information allows upgrade, upgrade-all and reinstall-all to work properly even with non-pypi installed packages.
(#222)
- `upgrade` options `--spec` and `--include-deps` were removed. Pipx now uses the original options used to install each
application instead. (#222)
- `upgrade-all` options `--include-deps`, `--system-site-packages`, `--index-url`, `--editable`, and `--pip-args` were
removed. Pipx now uses the original options used to install each application instead. (#222)
- `reinstall-all` options `--include-deps`, `--system-site-packages`, `--index-url`, `--editable`, and `--pip-args` were
removed. Pipx now uses the original options used to install each application instead. (#222)
- Handle missing interpreters more gracefully (#146)
- Change `reinstall-all` to use system python by default for apps. Now use `--python` option to specify a different
python version.
- Remove the PYTHONPATH environment variable when executing any command to prevent conflicts between pipx dependencies
and package dependencies when pipx is installed via homebrew. Homebrew can use PYTHONPATH manipulation instead of
virtual environments. (#233)
- Add printed summary after successful call to `pipx inject`
- Support associating apps with Python 3.5
- Improvements to animation status text
- Make `--python` argument in `reinstall-all` command optional
- 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)
- 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)
- Breaking change: for the `inject` command, change `--include-binaries` to `--include-apps`
- Change all terminology from `binary` to `app` or `application`
- Improve argument parsing for `pipx run` and `pipx runpip`
- 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)
- 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)
- 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)
- 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)
- Add shell autocompletion. Also add `pipx completions` command to print instructions on how to add pipx completions to
your shell.
- Un-deprecate `ensurepath`. Use `userpath` internally instead of instructing users to run the `userpath` cli command.
- Improve detection of PIPX_BIN_DIR not being on PATH
- Improve error message when an existing symlink exists in PIPX_BIN_DIR and points to the wrong location
- Improve handling of unexpected files in PIPX_HOME (@uranusjr)
- 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)
- 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)
- Deprecate `ensurepath` command. Use `userpath append ~/.local/bin`
- Support redirects and proxies when downloading python files (i.e. `pipx run http://url/file.py`)
- Use tox for document generation and CI testing (CI tests are now functional rather than static tests on style and
formatting!)
- 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)
- Fix upgrade-all and reinstall-all regression
## [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](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](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](https://github.com/pypa/pipx/tree/0.12.3.1)
- Fix "WindowsPath is not iterable" bug
## [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`.
- Speed up `pipx list` output (by running multiple processes in parallel) and by collecting all metadata in a single
subprocess call
- 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)
- 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
found in `__pypackages__`.
- 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)
- Cache and reuse temporary Virtual Environments created with `pipx run` (#61)
- Update binary discovery logic to find "scripts" like awscli (#91)
- Forward `--pip-args` to the pip upgrade command (previously the args were forwarded to install/upgrade commands for
packages) (#77)
- When using environment variable PIPX_HOME, Virtual Environments will now be created at `$PIPX_HOME/venvs` rather than
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)
- Fix parsing bug in pipx run
## [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](https://github.com/pypa/pipx/tree/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)
- stop using unverified context #89
## [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](https://github.com/pypa/pipx/tree/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)
- 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)
- 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)
- Fix version printed when `pipx --version` is run
## [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](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)
- When upgrading all packages, print message only when package is updated
- Avoid accidental execution of pipx.**main**
pipx-1.4.3/CONTRIBUTING.md 0000664 0000000 0000000 00000016756 14551526321 0014753 0 ustar 00root root 0000000 0000000 Thanks for your interest in contributing to pipx!
Everyone who interacts with the pipx project via codebase, issue tracker, chat rooms, or otherwise is expected to follow
the [PSF Code of Conduct](https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md).
## Submitting changes
1. Fork [the GitHub repository](https://github.com/pypa/pipx).
2. Make a branch off of `main` and commit your changes to it.
3. Add a changelog entry.
4. Submit a pull request to the `main` branch on GitHub, referencing an
open issue.
### Changelog entries
The `CHANGELOG.md` file is built by
[towncrier](https://pypi.org/project/towncrier/) from news fragments in the
`changelog.d/` directory. To add an entry, create a news fragment in that directory
named `{number}.{type}.md`, where `{number}` is the issue number,
and `{type}` is one of `feature`, `bugfix`, `doc`, `removal`, or `misc`.
For example, if your issue number is 1234 and it's fixing a bug, then you
would create `changelog.d/1234.bugfix.md`. PRs can span multiple
categories by creating multiple files: if you added a feature and
deprecated/removed an old feature for issue #5678, you would create
`changelog.d/5678.feature.md` and `changelog.d/5678.removal.md`.
A changelog entry is meant for end users and should only contain details
relevant to them. In order to maintain a consistent style, please keep
the entry to the point, in sentence case, shorter than 80 characters,
and in an imperative tone. An entry should complete the sentence "This
change will ...". If one line is not enough, use a summary line in an
imperative tone, followed by a description of the change in one or more
paragraphs, each wrapped at 80 characters and separated by blank lines.
You don't need to reference the pull request or issue number in a
changelog entry, since towncrier will add a link using the number in the
file name. Similarly, you don't need to add your name to the entry,
since that will be associated with the pull request.
## Running pipx For Development
To develop `pipx`, either create a [developer environment](#creating-a-developer-environment), or perform an editable
install:
```
python -m pip install -e .
python -m pipx --version
```
## Running Tests
### Setup
pipx uses an automation tool called [nox](https://pypi.org/project/nox/) for development, continuous integration
testing, and various tasks.
`nox` defines tasks or "sessions" in `noxfile.py` which can be run with `nox -s SESSION_NAME`. Session names can be
listed with `nox -l`.
Install nox for pipx development:
```
python -m pip install --user nox
```
Tests are defined as `nox` sessions. You can see all nox sessions with
```
nox -l
```
At the time of this writing, the output looks like this
```
- refresh_packages_cache-3.12 -> Populate .pipx_tests/package_cache
- refresh_packages_cache-3.11 -> Populate .pipx_tests/package_cache
- refresh_packages_cache-3.10 -> Populate .pipx_tests/package_cache
- refresh_packages_cache-3.9 -> Populate .pipx_tests/package_cache
- refresh_packages_cache-3.8 -> Populate .pipx_tests/package_cache
- tests_internet-3.12 -> Tests using internet pypi only
- tests_internet-3.11 -> Tests using internet pypi only
- tests_internet-3.10 -> Tests using internet pypi only
- tests_internet-3.9 -> Tests using internet pypi only
- tests_internet-3.8 -> Tests using internet pypi only
* tests-3.12 -> Tests using local pypiserver only
* tests-3.11 -> Tests using local pypiserver only
* tests-3.10 -> Tests using local pypiserver only
* tests-3.9 -> Tests using local pypiserver only
* tests-3.8 -> Tests using local pypiserver only
- test_all_packages-3.12
- test_all_packages-3.11
- test_all_packages-3.10
- test_all_packages-3.9
- test_all_packages-3.8
- cover -> Coverage analysis
* lint
- develop-3.12
- develop-3.11
- develop-3.10
- develop-3.9
- develop-3.8
- build
- publish
* build_docs
- watch_docs
* build_man
- create_test_package_list-3.12
- create_test_package_list-3.11
- create_test_package_list-3.10
- create_test_package_list-3.9
- create_test_package_list-3.8
```
### Creating a developer environment
For developing the tool (and to attach to your IDE) we recommend creating a Python environment via
`nox -s develop-3.12`, afterwards use the Python interpreter available under `.nox/develop-3.12/bin/python`.
### Unit Tests
To run unit tests in Python3.12, you can run
```
nox -s tests-3.12
```
!!! tip You can run a specific unit test by passing arguments to pytest, the test runner pipx uses:
```
nox -s tests-3.8 -- -k EXPRESSION
```
`EXPRESSION` can be a test name, such as
```
nox -s tests-3.8 -- -k test_uninstall
```
Coverage errors can usually be ignored when only running a subset of tests.
### Running Unit Tests Offline
Running the unit tests requires a directory `.pipx_tests/package_cache` to be populated from a fixed list of package
distribution files (wheels or source files). If you have network access, `nox -s tests` automatically makes sure this
directory is populated (including downloading files if necessary) as a first step. Thus, if you are running the tests
with network access, you can ignore the rest of this section.
If, however, you wish to run tests offline without the need for network access, you can populate
`.pipx_tests/package_cache` yourself manually beforehand when you do have network access.
### Populating the cache directory using nox
To populate `.pipx_tests/package_cache` manually using nox, execute:
```
nox -s refresh_packages_cache
```
This will sequence through available python executable versions to populate the cache directory for each version of
python on your platform.
### Lint Tests
Linting is done via `pre-commit`, setting it up and running it can be done via `nox` by typing:
```
nox -s lint
```
### Installing or injecting new packages in tests
If the tests are modified such that a new package / version combination is `pipx install`ed or `pipx inject`ed that
wasn't used in other tests, then one must make sure it's added properly to the packages lists in
`testdata/tests_packages`.
To accomplish this:
- Edit `testdata/tests_packages/primary_packages.txt` to add the new package(s) that you wish to `pipx install` or
`pipx inject` in the tests.
Then using Github workflows to generate all platforms in the Github CI:
- Manually activate the Github workflow: Create tests package lists for offline tests
- Download the artifact `lists` and put the files from it into `testdata/tests_packages/`
Or to locally generate these lists from `testdata/tests_packages/primary_packages.txt`, on the target platform execute:
- `nox -s create_test_package_list`
Finally, check-in the new or modified list files in the directory `testdata/tests_packages`
## Testing pipx on Continuous Integration builds
Upon opening pull requests GitHub Actions will automatically trigger.
## Building Documentation
`pipx` autogenerate API documentation, and also uses templates.
When updating pipx docs, make sure you are modifying the `docs` directory.
You can generate the documentation with
```
nox -s build_docs
```
This will capture CLI documentation for any pipx argument modifications, as well as generate templates to the docs
directory.
To preview changes, including live reloading, open another terminal and run
```
nox -s watch_docs
```
## Releasing New `pipx` Versions
To publish to PyPI simply create a "published" release on GitHub. This will trigger GitHub workflows that publishes:
- the pipx version to PyPI,
- the documentation to readthedocs,
- the `zipapp` to the GitHub release created.
No need for any other pre or post publish steps.
pipx-1.4.3/LICENSE 0000664 0000000 0000000 00000002074 14551526321 0013513 0 ustar 00root root 0000000 0000000 MIT License
Copyright (c) 2018 Chad Smith and contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
pipx-1.4.3/README.md 0000664 0000000 0000000 00000037376 14551526321 0014002 0 ustar 00root root 0000000 0000000
# pipx — Install and Run Python Applications in Isolated Environments
**Documentation**:
**Source Code**:
_For comparison to other tools including pipsi, see
[Comparison to Other Tools](https://pipx.pypa.io/stable/comparisons/)._
## Install pipx
> [!NOTE] It is not recommended to install `pipx` via `pipx`. If you'd like to do this anyway, take a look at the
> [`pipx-in-pipx`](https://github.com/mattsb42-meta/pipx-in-pipx) project and read about the limitations there.
### On macOS
```
brew install pipx
pipx ensurepath
```
Upgrade pipx with `brew update && brew upgrade pipx`.
### On Linux
- Ubuntu 23.04 or above
```
sudo apt update
sudo apt install pipx
pipx ensurepath
```
- Ubuntu 22.04 or below
```
python3 -m pip install --user pipx
python3 -m pipx ensurepath
```
Upgrade pipx with `python3 -m pip install --user --upgrade pipx`.
### On Windows
- install via [Scoop](https://scoop.sh/)
```
scoop install pipx
pipx ensurepath
```
Upgrade pipx with `scoop update pipx`.
- install via pip (requires pip 19.0 or later)
```
# If you installed python using Microsoft Store, replace `py` with `python3` in the next line.
py -m pip install --user pipx
```
It is possible (even most likely) the above finishes with a WARNING looking similar to this:
```
WARNING: The script pipx.exe is installed in `\AppData\Roaming\Python\Python3x\Scripts` which is not on PATH
```
If so, go to the mentioned folder, allowing you to run the pipx executable directly. Enter the following line (even if
you did not get the warning):
```
.\pipx.exe ensurepath
```
This will add both the above mentioned path and the `%USERPROFILE%\.local\bin` folder to your search path. Restart your
terminal session and verify `pipx` does run.
Upgrade pipx with `py -m pip install --user --upgrade pipx`.
### Using pipx without installing (via zipapp)
You can also use pipx without installing it. The zipapp can be downloaded from
[Github releases](https://github.com/pypa/pipx/releases) and you can invoke it with a Python 3.7+ interpreter:
```
python pipx.pyz ensurepath
```
### Use with pre-commit
pipx [has pre-commit support](installation.md#pre-commit).
### Shell completions
Shell completions are available by following the instructions printed with this command:
```
pipx completions
```
For more details, see the [installation instructions](https://pipx.pypa.io/stable/installation/).
## Overview: What is `pipx`?
pipx is a tool to help you install and run end-user applications written in Python. It's roughly similar to macOS's
`brew`, JavaScript's [npx](https://medium.com/@maybekatz/introducing-npx-an-npm-package-runner-55f7d4bd282b), and
Linux's `apt`.
It's closely related to pip. In fact, it uses pip, but is focused on installing and managing Python packages that can be
run from the command line directly as applications.
### How is it Different from pip?
pip is a general-purpose package installer for both libraries and apps with no environment isolation. pipx is made
specifically for application installation, as it adds isolation yet still makes the apps available in your shell: pipx
creates an isolated environment for each application and its associated packages.
pipx does not ship with pip, but installing it is often an important part of bootstrapping your system.
### Where Does `pipx` Install Apps From?
By default, pipx uses the same package index as pip, [PyPI](https://pypi.org/). pipx can also install from all other
sources pip can, such as a local directory, wheel, git url, etc.
Python and PyPI allow developers to distribute code with "console script entry points". These entry points let users
call into Python code from the command line, effectively acting like standalone applications.
pipx is a tool to install and run any of these thousands of application-containing packages in a safe, convenient, and
reliable way. **In a way, it turns Python Package Index (PyPI) into a big app store for Python applications.** Not all
Python packages have entry points, but many do.
If you would like to make your package compatible with pipx, all you need to do is add a
[console scripts](https://python-packaging.readthedocs.io/en/latest/command-line-scripts.html#the-console-scripts-entry-point)
entry point. If you're a poetry user, use [these instructions](https://python-poetry.org/docs/pyproject/#scripts). Or
you're using hatch, [try this](https://hatch.pypa.io/latest/config/metadata/#cli).
## Features
`pipx` enables you to
- Expose CLI entrypoints of packages ("apps") installed to isolated environments with the `install` command. This
guarantees no dependency conflicts and clean uninstalls!
- Easily list, upgrade, and uninstall packages that were installed with pipx
- Run the latest version of a Python application in a temporary environment with the `run` command
Best of all, pipx runs with regular user permissions, never calling `sudo pip install` (you aren't doing that, are you?
😄).
### Walkthrough: Installing a Package and its Applications With `pipx`
You can globally install an application by running
```
pipx install PACKAGE
```
This automatically creates a virtual environment, installs the package, and adds the package's associated applications
(entry points) to a location on your `PATH`. For example, `pipx install pycowsay` makes the `pycowsay` command available
globally, but sandboxes the pycowsay package in its own virtual environment. **pipx never needs to run as sudo to do
this.**
Example:
```
>> pipx install pycowsay
installed package pycowsay 2.0.3, Python 3.7.3
These apps are now globally available
- pycowsay
done! ✨ 🌟 ✨
>> pipx list
venvs are in /home/user/.local/share/pipx/venvs
apps are exposed on your $PATH at /home/user/.local/bin
package pycowsay 2.0.3, Python 3.7.3
- pycowsay
# Now you can run pycowsay from anywhere
>> pycowsay mooo
____
< mooo >
====
\
\
^__^
(oo)\_______
(__)\ )\/\
||----w |
|| ||
```
### Installing from Source Control
You can also install from a git repository. Here, `black` is used as an example.
```
pipx install git+https://github.com/psf/black.git
pipx install git+https://github.com/psf/black.git@branch # branch of your choice
pipx install git+https://github.com/psf/black.git@ce14fa8b497bae2b50ec48b3bd7022573a59cdb1 # git hash
pipx install https://github.com/psf/black/archive/18.9b0.zip # install a release
```
The pip syntax with `egg` must be used when installing extras:
```
pipx install "git+https://github.com/psf/black.git#egg=black[jupyter]"
```
### Inject a package
If an application installed by pipx requires additional packages, you can add them with pipx inject. For example, if you have ```ipython``` installed and want to add the ```matplotlib``` package to it, you would use:
```
pipx inject ipython matplotlib
```
### Walkthrough: Running an Application in a Temporary Virtual Environment
This is an alternative to `pipx install`.
`pipx run` downloads and runs the above mentioned Python "apps" in a one-time, temporary environment, leaving your
system untouched afterwards.
This can be handy when you need to run the latest version of an app, but don't necessarily want it installed on your
computer.
You may want to do this when you are initializing a new project and want to set up the right directory structure, when
you want to view the help text of an application, or if you simply want to run an app in a one-off case and leave your
system untouched afterwards.
For example, the blog post [How to set up a perfect Python project](https://sourcery.ai/blog/python-best-practices/)
uses `pipx run` to kickstart a new project with [cookiecutter](https://github.com/cookiecutter/cookiecutter), a tool
that creates projects from project templates.
A nice side benefit is that you don't have to remember to upgrade the app since `pipx run` will automatically run a
recent version for you.
Okay, let's see what this looks like in practice!
```
pipx run APP [ARGS...]
```
This will install the package in an isolated, temporary directory and invoke the app. Give it a try:
```
> pipx run pycowsay moo
---
< moo >
---
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
```
Notice that you **don't need to execute any install commands to run the app**.
Any arguments after the application name will be passed directly to the application:
```
> pipx run pycowsay these arguments are all passed to pycowsay!
-------------------------------------------
< these arguments are all passed to pycowsay! >
-------------------------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
```
### Ambiguous arguments
Sometimes pipx can consume arguments provided for the application:
```
> pipx run pycowsay --py
usage: pipx run [-h] [--no-cache] [--pypackages] [--spec SPEC] [--verbose] [--python PYTHON]
[--system-site-packages] [--index-url INDEX_URL] [--editable] [--pip-args PIP_ARGS]
app ...
pipx run: error: ambiguous option: --py could match --pypackages, --python
```
To prevent this put double dash `--` before APP. It will make pipx to forward the arguments to the right verbatim to the
application:
```
> pipx run -- pycowsay --py
----
< --py >
----
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
```
Re-running the same app is quick because pipx caches Virtual Environments on a per-app basis. The caches only last a few
days, and when they expire, pipx will again use the latest version of the package. This way you can be sure you're
always running a new version of the package without having to manually upgrade.
### Package with multiple apps, or the app name doesn't match the package name
If the app name does not match the package name, you can use the `--spec` argument to specify the `PACKAGE` name, and
provide the `APP` to run separately:
```
pipx run --spec PACKAGE APP
```
For example, the [esptool](https://github.com/espressif/esptool) package doesn't provide an executable with the same
name:
```
>> pipx run esptool
'esptool' executable script not found in package 'esptool'.
Available executable scripts:
esp_rfc2217_server.py - usage: 'pipx run --spec esptool esp_rfc2217_server.py [arguments?]'
espefuse.py - usage: 'pipx run --spec esptool espefuse.py [arguments?]'
espsecure.py - usage: 'pipx run --spec esptool espsecure.py [arguments?]'
esptool.py - usage: 'pipx run --spec esptool esptool.py [arguments?]'
```
You can instead run the executables that this package provides by using `--spec`:
```
pipx run --spec esptool esp_rfc2217_server.py
pipx run --spec esptool espefuse.py
pipx run --spec esptool espsecure.py
pipx run --spec esptool esptool.py
```
Note that the `.py` extension is not something you append to the executable name. It is part of the executable name, as
provided by the package. This can be anything. For example, when working with the
[pymodbus](https://github.com/pymodbus-dev/pymodbus) package:
```
>> pipx run pymodbus[repl]
'pymodbus' executable script not found in package 'pymodbus'.
Available executable scripts:
pymodbus.console - usage: 'pipx run --spec pymodbus pymodbus.console [arguments?]'
pymodbus.server - usage: 'pipx run --spec pymodbus pymodbus.server [arguments?]'
pymodbus.simulator - usage: 'pipx run --spec pymodbus pymodbus.simulator [arguments?]'
```
You can run the executables like this:
```
pipx run --spec pymodbus[repl] pymodbus.console
pipx run --spec pymodbus[repl] pymodbus.server
pipx run --spec pymodbus[repl] pymodbus.simulator
```
### Running a specific version of a package
The `PACKAGE` argument above is actually a
[requirement specifier](https://packaging.python.org/en/latest/glossary/#term-Requirement-Specifier). Therefore, you can
also specify specific versions, version ranges, or extras. For example:
```
pipx run mpremote==1.20.0
pipx run --spec esptool==4.6.2 esptool.py
pipx run --spec 'esptool>=4.5' esptool.py
pipx run --spec 'esptool >= 4.5' esptool.py
```
Notice that some requirement specifiers have to be enclosed in quotes or escaped.
### Running from Source Control
You can also run from a git repository. Here, `black` is used as an example.
```
pipx run --spec git+https://github.com/psf/black.git black
pipx run --spec git+https://github.com/psf/black.git@branch black # branch of your choice
pipx run --spec git+https://github.com/psf/black.git@ce14fa8b497bae2b50ec48b3bd7022573a59cdb1 black # git hash
pipx run --spec https://github.com/psf/black/archive/18.9b0.zip black # install a release
```
### Running from URL
You can run .py files directly, too.
```
pipx run https://gist.githubusercontent.com/cs01/fa721a17a326e551ede048c5088f9e0f/raw/6bdfbb6e9c1132b1c38fdd2f195d4a24c540c324/pipx-demo.py
pipx is working!
```
### Summary
That's it! Those are the most important commands `pipx` offers. To see all of pipx's documentation, run `pipx --help` or
see the [docs](https://pipx.pypa.io/stable/docs/).
## Testimonials
"Thanks for improving the workflow that pipsi has covered in the past. Nicely done!"
—Jannis Leidel, PSF fellow, former pip and Django core developer, and founder of the Python Packaging Authority (PyPA)
"My setup pieces together pyenv, poetry, and pipx. [...] For the things I need, it’s perfect."
## Credits
pipx was inspired by [pipsi](https://github.com/mitsuhiko/pipsi) and [npx](https://github.com/npm/npx). It was created
by [Chad Smith](https://github.com/cs01/) and has had lots of help from
[contributors](https://github.com/pypa/pipx/graphs/contributors). The logo was created by
[@IrishMorales](https://github.com/IrishMorales).
pipx is maintained by a team of volunteers (in alphabetical order)
- [Bernát Gábor](https://github.com/gaborbernat)
- [Chad Smith](https://github.com/cs01) - co-lead maintainer
- [Jason Lam](https://github.com/dukecat0)
- [Matthew Clapp](https://github.com/itsayellow) - co-lead maintainer
- [Tzu-ping Chung](https://github.com/uranusjr)
## Contributing
Issues and Pull Requests are definitely welcome! Check out [Contributing](https://pipx.pypa.io/stable/contributing/) to
get started. Everyone who interacts with the pipx project via codebase, issue tracker, chat rooms, or otherwise is
expected to follow the [PSF Code of Conduct](https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md).
pipx-1.4.3/changelog.d/ 0000775 0000000 0000000 00000000000 14551526321 0014654 5 ustar 00root root 0000000 0000000 pipx-1.4.3/changelog.d/.gitignore 0000664 0000000 0000000 00000000014 14551526321 0016637 0 ustar 00root root 0000000 0000000 !.gitignore
pipx-1.4.3/changelog.d/1150.bugfix.md 0000664 0000000 0000000 00000000127 14551526321 0017047 0 ustar 00root root 0000000 0000000 Autofix python version for pylauncher, when version is provided prefixed with `python`
pipx-1.4.3/changelog.d/1150.doc.md 0000664 0000000 0000000 00000000111 14551526321 0016321 0 ustar 00root root 0000000 0000000 Provide useful error messages when unresolvable python version is passed
pipx-1.4.3/changelog.d/1161.doc.md 0000664 0000000 0000000 00000000057 14551526321 0016334 0 ustar 00root root 0000000 0000000 Introduce towncrier for managing the changelog
pipx-1.4.3/changelog.d/1191.fix.md 0000664 0000000 0000000 00000000103 14551526321 0016350 0 ustar 00root root 0000000 0000000 Report correct filename in tracebacks with `pipx run `
pipx-1.4.3/changelog.d/1198.doc.md 0000664 0000000 0000000 00000000102 14551526321 0016335 0 ustar 00root root 0000000 0000000 Add workaround for using pipx applications in shebang under macOS
pipx-1.4.3/docs/ 0000775 0000000 0000000 00000000000 14551526321 0013433 5 ustar 00root root 0000000 0000000 pipx-1.4.3/docs/changelog.md 0000777 0000000 0000000 00000000000 14551526321 0017723 2../CHANGELOG.md ustar 00root root 0000000 0000000 pipx-1.4.3/docs/comparisons.md 0000664 0000000 0000000 00000012174 14551526321 0016317 0 ustar 00root root 0000000 0000000 ## pipx vs pip
- pip is a general Python package installer. It can be used to install libraries or cli applications with entrypoints.
- pipx is a specialized package installer. It can only be used to install packages with cli entrypoints.
- pipx and pip both install packages from PyPI (or locally)
- pipx relies on pip (and venv)
- pipx replaces a subset of pip's functionality; it lets you install cli applications but NOT libraries that you import
in your code.
- you can install pipx with pip
Example interaction: Install pipx with pip: `pip install --user pipx`
## pipx vs poetry and pipenv
- pipx is used solely for application consumption: you install cli apps with it
- pipenv and poetry are cli apps used to develop applications and libraries
- all three tools wrap pip and virtual environments for more convenient workflows
Example interaction: Install pipenv and poetry with pipx: `pipx install poetry` Run pipenv or poetry with pipx:
`pipx run poetry --help`
## pipx vs venv
- venv is part of Python's standard library in Python 3.2 and above
- venv creates "virtual environments" which are sandboxed python installations
- pipx heavily relies on the venv package
Example interaction: pipx installs packages to environments created with venv. `pipx install black --verbose`
## pipx vs pyenv
- pyenv manages python versions on your system. It helps you install versions like Python 3.6, 3.7, etc.
- pipx installs packages in virtual environments and exposes their entrypoints on your PATH
Example interaction: Install a Python interpreter with pyenv, then install a package using pipx and that new
interpreter: `pipx install black --python=python3.7` where python3.7 was installed on the system with pyenv
## pipx vs pipsi
- pipx and pipsi both install packages in a similar way
- pipx is under active development. pipsi is no longer maintained.
- pipx always makes sure you're using the latest version of pip
- pipx has the ability to run an app in one line, leaving your system unchanged after it finishes (`pipx run APP`) where
pipsi does not
- pipx has the ability to recursively install binaries from dependent packages
- pipx adds more useful information to its output
- pipx has more CLI options such as upgrade-all, reinstall-all, uninstall-all
- pipx is more modern. It uses Python 3.6+, and the `venv` package in the Python3 standard library instead of the python
2 package `virtualenv`.
- pipx works with Python homebrew installations while pipsi does not (at least on my machine)
- pipx defaults to less verbose output
- pipx allows you to see each command it runs by passing the --verbose flag
- pipx prints emojis 😀
Example interaction: None. Either one or the other should be used. These tools compete for a similar workflow.
### Migrating to pipx from pipsi
After you have installed pipx, run
[migrate_pipsi_to_pipx.py](https://raw.githubusercontent.com/pypa/pipx/main/scripts/migrate_pipsi_to_pipx.py). Why not
do this with your new pipx installation?
```
pipx run https://raw.githubusercontent.com/pypa/pipx/main/scripts/migrate_pipsi_to_pipx.py
```
## pipx vs brew
- Both brew and pipx install cli tools
- They install them from different sources. brew uses a curated repository specifically for brew, and pipx generally
uses PyPI.
Example interaction: brew can be used to install pipx, but they generally don't interact much.
## pipx vs npx
- Both can run cli tools (npx will search for them in node_modules, and if not found run in a temporary environment.
`pipx run` will search in `__pypackages__` and if not found run in a temporary environment)
- npx works with JavaScript and pipx works with Python
- Both tools attempt to make running executables written in a dynamic language (JS/Python) as easy as possible
- pipx can also install tools globally; npx cannot
Example interaction: None. These tools work for different languages.
## pipx vs pip-run
[pip-run](https://github.com/jaraco/pip-run) is focused on running **arbitrary Python code in ephemeral environments**
while pipx is focused on running **Python binaries in ephemeral and non-ephemeral environments**.
For example these two commands both install poetry to an ephemeral environment and invoke poetry with `--help`.
```
pipx run poetry --help
pip-run poetry -- -m poetry --help
```
Example interaction: None.
## pipx vs fades
[fades](https://github.com/PyAr/fades) is a tool to run **individual** Python scripts inside automatically provisioned
virtualenvs with their dependencies installed.
- Both [fades](https://github.com/PyAr/fades#how-to-mark-the-dependencies-to-be-installed) and
[pipx run](examples.md#pipx-run-examples) allow specifying a script's dependencies in specially formatted comments,
but the exact syntax differs. (pipx's syntax is standardized by a
[provisional specification](https://packaging.python.org/en/latest/specifications/inline-script-metadata/),
fades's syntax is not standardized.)
- Both tools automatically set up reusable virtualenvs containing the necessary dependencies.
- Both can download Python scripts/packages to execute from remote resources.
- fades can only run individual script files while pipx can also run packages.
Example interaction: None.
pipx-1.4.3/docs/contributing.md 0000777 0000000 0000000 00000000000 14551526321 0021123 2../CONTRIBUTING.md ustar 00root root 0000000 0000000 pipx-1.4.3/docs/examples.md 0000664 0000000 0000000 00000010044 14551526321 0015572 0 ustar 00root root 0000000 0000000 ## `pipx install` examples
```
pipx install pycowsay
pipx install --python python3.10 pycowsay
pipx install --python 3.12 pycowsay
pipx install git+https://github.com/psf/black
pipx install git+https://github.com/psf/black.git@branch-name
pipx install git+https://github.com/psf/black.git@git-hash
pipx install git+ssh://@/
pipx install https://github.com/psf/black/archive/18.9b0.zip
pipx install black[d]
pipx install 'black[d] @ git+https://github.com/psf/black.git@branch-name'
pipx install --suffix @branch-name 'black[d] @ git+https://github.com/psf/black.git@branch-name'
pipx install --include-deps jupyter
pipx install --pip-args='--pre' poetry
pipx install --pip-args='--index-url=: --trusted-host=:' private-repo-package
pipx install --index-url https://test.pypi.org/simple/ --pip-args='--extra-index-url https://pypi.org/simple/' some-package
```
## `pipx run` examples
pipx enables you to test various combinations of Python versions and package versions in ephemeral environments:
```
pipx run BINARY # latest version of binary is run with python3
pipx run --spec PACKAGE==2.0.0 BINARY # specific version of package is run
pipx run --python python3.7 BINARY # Installed and invoked with specific Python version
pipx run --python python3.9 --spec PACKAGE=1.7.3 BINARY
pipx run --spec git+https://url.git BINARY # latest version on default branch is run
pipx run --spec git+https://url.git@branch BINARY
pipx run --spec git+https://url.git@hash BINARY
pipx run pycowsay moo
pipx --version # prints pipx version
pipx run pycowsay --version # prints pycowsay version
pipx run --python pythonX pycowsay
pipx run pycowsay==2.0 --version
pipx run pycowsay[dev] --version
pipx run --spec git+https://github.com/psf/black.git black
pipx run --spec git+https://github.com/psf/black.git@branch-name black
pipx run --spec git+https://github.com/psf/black.git@git-hash black
pipx run --spec https://github.com/psf/black/archive/18.9b0.zip black --help
pipx run https://gist.githubusercontent.com/cs01/fa721a17a326e551ede048c5088f9e0f/raw/6bdfbb6e9c1132b1c38fdd2f195d4a24c540c324/pipx-demo.py
```
You can run local files, or scripts hosted on the internet, and you can run them with arguments:
```
pipx run test.py
pipx run test.py 1 2 3
pipx run https://example.com/test.py
pipx run https://example.com/test.py 1 2 3
```
A simple filename is ambiguous - it could be a file, or a package on PyPI. It will be treated as a filename if the file
exists, or as a package if not. To force interpretation as a local path, use `--path`, and to force interpretation as a
package name, use `--spec` (with the PyPI name of the package).
```
pipx run myscript.py # Local file, if myscript.py exists
pipx run doesnotexist.py # Package, because doesnotexist.py is not a local file
pipx run --path test.py # Always a local file
pipx run --spec test-py test.py # Always a package on PyPI
```
You can also run scripts that have dependencies:
If you have a script `test.py` that needs a 3rd party library like requests:
```
# test.py
# Requirements:
# requests
#
# The list of requirements is terminated by a blank line or an empty comment line.
import sys
import requests
project = sys.argv[1]
pipx_data = requests.get(f"https://pypi.org/pypi/{project}/json").json()
print(pipx_data["info"]["version"])
```
Then you can run it as follows:
```
> pipx run test.py pipx
1.1.0
```
## `pipx inject` example
One use of the inject command is setting up a REPL with some useful extra packages.
```
pipx install ptpython
pipx inject ptpython requests pendulum
```
After running the above commands, you will be able to import and use the `requests` and `pendulum` packages inside a
`ptpython` repl.
## `pipx list` example
```
> pipx list
venvs are in /Users/user/.local/pipx/venvs
binaries are exposed on your $PATH at /Users/user/.local/bin
package black 18.9b0, Python 3.7.0
- black
- blackd
package pipx 0.10.0, Python 3.7.0
- pipx
> pipx list --short
black 18.9b0
pipx 0.10.0
```
pipx-1.4.3/docs/getting-started.md 0000664 0000000 0000000 00000000526 14551526321 0017065 0 ustar 00root root 0000000 0000000 Now that you have pipx installed, you can install a program:
```
pipx install PACKAGE
```
for example
```
pipx install pycowsay
```
You can list programs installed:
```
pipx list
```
Or you can run a program without installing it:
```
pipx run pycowsay moooo!
```
You can view documentation for all commands by running `pipx --help`.
pipx-1.4.3/docs/how-pipx-works.md 0000664 0000000 0000000 00000006473 14551526321 0016705 0 ustar 00root root 0000000 0000000 ## How it Works
When installing a package and its binaries on linux (`pipx install package`) pipx will
- create directory `~/.local/share/pipx/venvs/PACKAGE`
- create or re-use a shared virtual environment that contains shared packaging library `pip` in
`~/.local/share/pipx/shared/`
- ensure the library is updated to its latest version
- create a Virtual Environment in `~/.local/share/pipx/venvs/PACKAGE` that uses the shared pip mentioned above but
otherwise is isolated (pipx uses a [.pth file](https://docs.python.org/3/library/site.html) to do this)
- install the desired package in the Virtual Environment
- expose binaries at `~/.local/bin` that point to new binaries in `~/.local/share/pipx/venvs/PACKAGE/bin` (such as
`~/.local/bin/black` -> `~/.local/share/pipx/venvs/black/bin/black`)
- expose manual pages at `~/.local/share/man/man[1-9]` that point to new manual pages in
`~/.local/pipx/venvs/PACKAGE/share/man/man[1-9]`
- as long as `~/.local/bin/` is on your PATH, you can now invoke the new binaries globally
- on operating systems which have the `man` command, as long as `~/.local/share/man` is a recognized search path of man,
you can now view the new manual pages globally
When running a binary (`pipx run BINARY`), pipx will
- create or re-use a shared virtual environment that contains the shared packaging library `pip`
- ensure the library is updated to its latest version
- create a temporary directory (or reuse a cached virtual environment for this package) with a name based on a hash of
the attributes that make the run reproducible. This includes things like the package name, spec, python version, and
pip arguments.
- create a Virtual Environment inside it with `python -m venv`
- install the desired package in the Virtual Environment
- invoke the binary
These are all things you can do yourself, but pipx automates them for you. If you are curious as to what pipx is doing
behind the scenes, you can always pass the `--verbose` flag to see every single command and argument being run.
## Developing for pipx
If you are a developer and want to be able to run
```
pipx install MY_PACKAGE
```
make sure you include an `entry_points` section in your `setup.py` file.
```
setup(
# other arguments here...
entry_points={
'console_scripts': [
'foo = my_package.some_module:main_func',
'bar = other_module:some_func',
],
'gui_scripts': [
'baz = my_package_gui:start_func',
]
}
)
```
In this case `main_func` and `some_func` would be available to pipx after installing the above example package.
To install manual pages, which can be viewed with the `man` command on operating systems which have this command,
include a
[`data_files` section](https://packaging.python.org/en/latest/guides/distributing-packages-using-setuptools/#data-files)
in your `setup.py` file.
```
setup(
# other arguments here...
data_files=[('share/man/man1', ['manpage.1'])]
)
```
In this case the manual page `manpage.1` would be available to pipx after installing the above example package.
For a real-world example, see [pycowsay](https://github.com/cs01/pycowsay/blob/master/setup.py)'s `setup.py` source
code.
You can read more about entry points
[here](https://setuptools.pypa.io/en/latest/userguide/quickstart.html#entry-points-and-automatic-script-creation).
pipx-1.4.3/docs/index.md 0000777 0000000 0000000 00000000000 14551526321 0016551 2../README.md ustar 00root root 0000000 0000000 pipx-1.4.3/docs/installation.md 0000664 0000000 0000000 00000014516 14551526321 0016465 0 ustar 00root root 0000000 0000000 ## System Requirements
python 3.7+ is required to install pipx. pipx can run binaries from packages with Python 3.3+. Don't have Python 3.7 or
later? See [Python 3 Installation & Setup Guide](https://realpython.com/installing-python/).
You also need to have `pip` installed on your machine for `python3`. Installing it varies from system to system. Consult
[pip's installation instructions](https://pip.pypa.io/en/stable/installing/). Installing on Linux works best with a
[Linux Package Manager](https://packaging.python.org/guides/installing-using-linux-tools/#installing-pip-setuptools-wheel-with-linux-package-managers).
pipx works on macOS, linux, and Windows.
## Installing pipx
### On macOS:
```
brew install pipx
pipx ensurepath
```
### On Linux:
- Ubuntu 23.04 or above
```
sudo apt update
sudo apt install pipx
pipx ensurepath
```
- Ubuntu 22.04 or below
```
python3 -m pip install --user pipx
python3 -m pipx ensurepath
```
### On Windows:
- Install via [Scoop](https://scoop.sh/):
```
scoop install pipx
pipx ensurepath
```
- Install via pip (requires pip 19.0 or later)
```
# If you installed python using Microsoft Store, replace `py` with `python3` in the next line.
py -m pip install --user pipx
```
It is possible (even most likely) the above finishes with a WARNING looking similar to this:
```
WARNING: The script pipx.exe is installed in `\AppData\Roaming\Python\Python3x\Scripts` which is not on PATH
```
If so, go to the mentioned folder, allowing you to run the pipx executable directly. Enter the following line (even if
you did not get the warning):
```
.\pipx.exe ensurepath
```
This will add both the above mentioned path and the `%USERPROFILE%\.local\bin` folder to your search path. Restart your
terminal session and verify `pipx` does run.
!!! warning
It is not recommended to install `pipx` via `pipx`. If you'd like to do this anyway, take a look at the
[`pipx-in-pipx`](https://github.com/mattsb42-meta/pipx-in-pipx) project and read about the limitations there.
### Using pipx without installing (via zipapp)
The zipapp can be downloaded from [Github releases](https://github.com/pypa/pipx/releases) and you can invoke it with a
Python 3.7+ interpreter:
```
python pipx.pyz ensurepath
```
### Using pipx with pre-commit
Pipx has [pre-commit](https://pre-commit.com/) support. This lets you run applications:
- That can be run using `pipx run` but don't have native pre-commit support.
- Using its prebuilt wheel from pypi.org instead of building it from source.
- Using pipx's `--spec` and `--index-url` flags.
Example configuration for use of the code linter [yapf](https://github.com/google/yapf/). This is to be added to your
`.pre-commit-config.yaml`.
```yaml
- repo: https://github.com/pypa/pipx
rev: 53e7f27
hooks:
- id: pipx
alias: yapf
name: yapf
args: ["yapf", "-i"]
types: ["python"]
```
## Installation Options
The default binary location for pipx-installed apps is `~/.local/bin`. This can be overridden with the environment
variable `PIPX_BIN_DIR`. The default manual page location for pipx-installed apps is `~/.local/share/man`. This can be
overridden with the environment variable `PIPX_MAN_DIR`.
pipx's default virtual environment location is typically `~/.local/share/pipx` on Linux/Unix,
`%USERPROFILE%\AppData\Local\pipx` on Windows and `~/Library/Application Support/pipx` on macOS, and for compatibility
reasons, if `~/.local/pipx` exists, it will be used as the default location instead. This can be overridden with the
`PIPX_HOME` environment variable.
As an example, you can install global apps accessible by all users on your system with the following command (on MacOS,
Linux, and Windows WSL):
```
sudo PIPX_HOME=/opt/pipx PIPX_BIN_DIR=/usr/local/bin PIPX_MAN_DIR=/usr/local/share/man pipx install PACKAGE
# Example: $ sudo PIPX_HOME=/opt/pipx PIPX_BIN_DIR=/usr/local/bin PIPX_MAN_DIR=/usr/local/share/man pipx install cowsay
```
!!! note
After version 1.2.0, the default pipx paths have been moved from `~/.local/pipx` to specific user data directories on each platform using [platformdirs](https://pypi.org/project/platformdirs/) library
| Old Path | New Path |
| ---------------------- | ------------------------------------------ |
| `~/.local/pipx/.trash` | `platformdirs.user_data_dir()/pipx/trash` |
| `~/.local/pipx/shared` | `platformdirs.user_data_dir()/pipx/shared` |
| `~/.local/pipx/venvs` | `platformdirs.user_data_dir()/pipx/venv` |
| `~/.local/pipx/.cache` | `platformdirs.user_cache_dir()/pipx` |
| `~/.local/pipx/logs` | `platformdirs.user_log_dir()/pipx/log` |
`user_data_dir()`, `user_cache_dir()` and `user_log_dir()` resolve to appropriate platform-specific user data, cache and log directories.
See the [platformdirs documentation](https://platformdirs.readthedocs.io/en/latest/api.html#platforms) for details.
## Upgrade pipx
On macOS:
```
brew update && brew upgrade pipx
```
On Linux:
```
sudo apt upgrade pipx
```
On Windows:
```
scoop update pipx
```
Otherwise, upgrade via pip:
```
python3 -m pip install --user -U pipx
```
### Note: Upgrading pipx from a pre-0.15.0.0 version to 0.15.0.0 or later
After upgrading to pipx 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 the 0.15.0.0 release. These metadata files store pip
specification values, injected packages, any custom pip arguments, and more in each main package's venv.
If you have no packages installed using the `--spec` option, and no venvs with injected packages, you can do this by
running `pipx reinstall-all`.
If you have any packages installed using the `--spec` option or venvs with injected packages, you should reinstall
packages manually using `pipx uninstall-all`, followed by `pipx install` and possibly `pipx inject`.
## Shell Completion
You can easily get your shell's tab completions working by following instructions printed with this command:
```
pipx completions
```
## Install pipx Development Versions
New versions of pipx are published as beta or release candidates. These versions look something like `0.13.0b1`, where
`b1` signifies the first beta release of version 0.13. These releases can be tested with
```
pip install --user --upgrade --pre pipx
```
pipx-1.4.3/docs/programs-to-try.md 0000664 0000000 0000000 00000003765 14551526321 0017056 0 ustar 00root root 0000000 0000000 ## Programs
Here are some programs you can try out. If you've never used the program before, make sure you add the `--help` flag so
it doesn't do something you don't expect. If you decide you want to install, you can run `pipx install PACKAGE` instead.
### ansible
IT automation
```
pipx install --include-deps ansible
```
### asciinema
Record and share your terminal sessions, the right way.
```
pipx run asciinema
```
### black
uncompromising Python code formatter
```
pipx run black
```
### pybabel
internationalizing and localizing Python applications
```
pipx run --spec=babel pybabel --help
```
### chardetect
detect file encoding
```
pipx run --spec=chardet chardetect --help
```
### cookiecutter
creates projects from project templates
```
pipx run cookiecutter
```
### create-python-package
easily create and publish new Python packages
```
pipx run create-python-package
```
### flake8
tool for style guide enforcement
```
pipx run flake8
```
### gdbgui
browser-based gdb debugger
```
pipx run gdbgui
```
### hatch
Python project manager that lets you build & publish packages, run tasks in environments and more
```
pipx run hatch
```
### hexsticker
create hexagon stickers automatically
```
pipx run hexsticker
```
### ipython
powerful interactive Python shell
```
pipx run ipython
```
### jupyter
web-based notebook environment for interactive computing
```
pipx run jupyter
```
### pipenv
python dependency/environment management
```
pipx run pipenv
```
### poetry
python dependency/environment/packaging management
```
pipx run poetry
```
### pylint
source code analyzer
```
pipx run pylint
```
### pyinstaller
bundles a Python application and all its dependencies into a single package
```
pipx run pyinstaller
```
### pyxtermjs
fully functional terminal in the browser
```
pipx run pyxtermjs
```
### ruff
An extremely fast Python linter
```
pipx run ruff
```
### shell-functools
Functional programming tools for the shell
```
pipx install shell-functools
```
pipx-1.4.3/docs/troubleshooting.md 0000664 0000000 0000000 00000012247 14551526321 0017212 0 ustar 00root root 0000000 0000000 ## `reinstall-all` fixes most issues
The following command should fix many problems you may encounter as a pipx user:
```
pipx reinstall-all
```
This is a good fix for the following problems:
- System python was upgraded and the python used with a pipx-installed package is no longer available
- pipx upgrade causes issues with old pipx-installed packages
pipx has been upgraded a lot over the years. If you are a long-standing pipx user (thanks, by the way!) then you may
have old pipx-installed packages that have internal data that is different than what pipx currently expects. By
executing `pipx reinstall-all`, pipx will re-write its internal data and this should fix many of issues you may
encounter.
**Note:** If your pipx-installed package was installed using a pipx version before 0.15.0.0 and you want to specify
particular options, then you may want to uninstall and install it manually:
```
pipx uninstall
pipx install
```
## Diagnosing problems using `list`
```
pipx list
```
will not only list all of your pipx-installed packages, but can also diagnose some problems with them, as well as
suggest solutions.
## Specifying pipx options
The most reliable method to specify command-line options that require an argument is to use an `=`-sign. An example:
```
pipx install pycowsay --pip-args="--no-cache-dir"
```
Another example for ignoring ssl/tls errors:
```
pipx install termpair --pip-args '--trusted-host files.pythonhosted.org --trusted-host pypi.org --trusted-host pypi.python.org --trusted-host github.com'"
```
## Check for `PIP_*` environment variables
pipx uses `pip` to install and manage packages. If you see pipx exhibiting strange behavior on install or upgrade, check
that you don't have special environment variables that affect `pip`'s behavior in your environment.
To check for `pip` environment variables, execute the following depending on your system:
### Unix or macOS
```
env | grep '^PIP_'
```
### Windows PowerShell
```
ls env:PIP_*
```
### Windows `cmd`
```
set PIP_
```
Reference: [pip Environment Variables](https://pip.pypa.io/en/stable/user_guide/#environment-variables)
## `pipx` log files
Pipx records a verbose log file for every `pipx` command invocation. The logs for the last 10 `pipx` commands can be
found in `$XDG_STATE_HOME/pipx/logs` or user's log path if the former is not writable by the user.
For most users this location is `~/.local/state/pipx/logs`, where `~` is your home directory.
## Debian, Ubuntu issues
If you have issues using pipx on Debian, Ubuntu, or other Debian-based linux distributions, make sure you have the
following packages installed on your system. (Debian systems do not install these by default with their python
installations.)
```
sudo apt install python3-venv python3-pip
```
Reference:
[Python Packaging User Guide: Installing pip/setuptools/wheel with Linux Package Managers](https://packaging.python.org/guides/installing-using-linux-tools)
## macOS issues
If you want to use a Pipx-installed package in a shebang (a common example is the AWS CLI),
you will likely not be able to, because the binary will be stored under `~/Library/Application Support/pipx/`.
The space in the path is not supported in a shebang. A simple solution is symlinking
`~/Library/Application Support/pipx` to `~/Library/ApplicationSupport/pipx`, and using that as the
path in the shebang instead.
```
mkdir $HOME/Library/ApplicationSupport
ln -s $HOME/Library/Application\ Support/pipx $HOME/Library/ApplicationSupport/pipx
```
## Does it work to install your package with `pip`?
This is a tip for advanced users. An easy way to check if pipx is the problem or a package you're trying to install is
the problem, is to try installing it using `pip`. For example:
### Unix or macOS
```
python3 -m venv test_venv
test_venv/bin/python3 -m pip install
```
### Windows
```
python -m venv test_venv
test_venv/Scripts/python -m pip install
```
If installation into this "virtual environment" using pip fails, then it's likely that the problem is with the package
or your host system.
To clean up after this experiment:
```
rm -rf test_venv
```
## Pipx files not in expected locations according to documentation
Pipx versions after 1.2.0 adopt the XDG base directory specification for the location of `PIPX_HOME` and the data,
cache, and log directories. Version 1.2.0 and earlier use `~/.local/pipx` as the default `PIPX_HOME` and install the
data, cache, and log directories under it. To maintain compatibility with older versions, pipx will automatically use
this old `PIPX_HOME` path if it exists. For a map of old and new paths, see
[Installation](installation.md#installation-options).
If you have a `pipx` version later than 1.2.0 and want to migrate from the old path to the new paths, you can move the
`~/.local/pipx` directory to the new location (after removing cache, log, and trash directories which will get recreated
automatically) and then reinstall all packages. For example, on Linux systems, `PIPX_HOME` moves from `~/.local/pipx` to
`~/.local/share/pipx` so you can do this:
```
rm -rf ~/.local/pipx/{.cache,logs,trash}
mkdir -p ~/.local/share && mv ~/.local/pipx ~/.local/share/
pipx reinstall-all
```
pipx-1.4.3/get-pipx.py 0000664 0000000 0000000 00000000527 14551526321 0014616 0 ustar 00root root 0000000 0000000 #!/usr/bin/env python3
import sys
def fail(msg):
sys.stderr.write(msg + "\n")
sys.stderr.flush()
sys.exit(1)
def main():
fail(
"This installation method has been deprecated. "
"See https://github.com/pypa/pipx for current installation "
"instructions."
)
if __name__ == "__main__":
main()
pipx-1.4.3/installation.md 0000777 0000000 0000000 00000000000 14551526321 0021474 2docs/installation.md ustar 00root root 0000000 0000000 pipx-1.4.3/logo.svg 0000664 0000000 0000000 00000200370 14551526321 0014166 0 ustar 00root root 0000000 0000000
pipx-1.4.3/mkdocs.yml 0000664 0000000 0000000 00000002302 14551526321 0014503 0 ustar 00root root 0000000 0000000 site_name: pipx
site_description: execute binaries from Python packages in isolated environments
theme:
name: "material"
palette:
- media: "(prefers-color-scheme: light)"
scheme: default
toggle:
icon: material/brightness-7
name: Switch to dark mode
- media: "(prefers-color-scheme: dark)"
scheme: slate
toggle:
icon: material/brightness-4
name: Switch to light mode
repo_name: pypa/pipx
repo_url: https://github.com/pypa/pipx
edit_uri: edit/main/docs/
extra:
analytics:
provider: 'google'
property: 'UA-90243909-2'
nav:
- Home: "index.md"
- Installation: "installation.md"
- Getting Started: "getting-started.md"
- Docs: "docs.md"
- Troubleshooting: "troubleshooting.md"
- Examples: "examples.md"
- Comparison to Other Tools: "comparisons.md"
- How pipx works: "how-pipx-works.md"
- Programs to Try: "programs-to-try.md"
- Contributing: "contributing.md"
- Changelog: "changelog.md"
markdown_extensions:
- admonition # note blocks, warning blocks -- https://github.com/mkdocs/mkdocs/issues/1659
plugins:
- search:
lang: en
- gen-files:
scripts:
- scripts/gen_doc_pages.py
- macros
pipx-1.4.3/noxfile.py 0000664 0000000 0000000 00000016510 14551526321 0014524 0 ustar 00root root 0000000 0000000 import shutil
import subprocess
import sys
from pathlib import Path
import nox
PYTHON_ALL_VERSIONS = ["3.12", "3.11", "3.10", "3.9", "3.8"]
PYTHON_DEFAULT_VERSION = "3.12"
DOC_DEPENDENCIES = ["jinja2", "mkdocs", "mkdocs-material", "mkdocs-gen-files", "mkdocs-macros-plugin", "towncrier"]
MAN_DEPENDENCIES = ["argparse-manpage[setuptools]"]
TEST_DEPENDENCIES = ["pytest", "pypiserver[passlib]", 'setuptools; python_version>="3.12"', "pytest-cov"]
# Packages whose dependencies need an intact system PATH to compile
# pytest setup clears PATH. So pre-build some wheels to the pip cache.
PREBUILD_PACKAGES = {"all": ["jupyter==1.0.0"], "macos": [], "unix": [], "win": []}
PIPX_TESTS_CACHE_DIR = Path("./.pipx_tests/package_cache")
PIPX_TESTS_PACKAGE_LIST_DIR = Path("testdata/tests_packages")
# Platform logic
PLATFORM = {"darwin": "macos", "win32": "win"}.get(sys.platform, "unix")
nox.options.sessions = ["tests", "lint", "build_docs", "zipapp"]
if PLATFORM != "win": # build_docs fail on Windows, even if `chcp.com 65001` is used
nox.options.sessions.append("build_man")
nox.options.reuse_existing_virtualenvs = True
def prebuild_wheels(session: nox.Session, prebuild_dict) -> None:
prebuild_list = prebuild_dict.get("all", []) + prebuild_dict.get(PLATFORM, [])
session.install("wheel")
wheel_dir = Path(session.virtualenv.location) / "prebuild_wheels"
wheel_dir.mkdir(exist_ok=True)
for prebuild in prebuild_list:
session.run("pip", "wheel", f"--wheel-dir={wheel_dir}", prebuild, silent=True)
def on_main_no_changes(session: nox.Session) -> None:
if len(subprocess.check_output(["git", "status", "--porcelain"], text=True).strip()) > 0: # has changes
session.error("All changes must be committed or removed before publishing")
branch = subprocess.check_output(["git", "rev-parse", "--abbrev-ref", "HEAD"], text=True).strip()
if branch != "main":
session.error(f"Must be on 'main' branch. Currently on {branch!r} branch")
def tests_with_options(session: nox.Session, *, net_pypiserver: bool) -> None:
prebuild_wheels(session, PREBUILD_PACKAGES)
session.install("-e", ".", *TEST_DEPENDENCIES)
test_dir = session.posargs or ["tests"]
if net_pypiserver:
pypiserver_option = ["--net-pypiserver"]
else:
refresh_packages_cache(session)
pypiserver_option = []
session.run("pytest", *pypiserver_option, "--cov=pipx", "--cov-report=", *test_dir)
session.notify("cover")
def create_upcoming_changelog(session: nox.Session) -> Path:
draft_changelog_content = session.run("towncrier", "build", "--version", "Upcoming", "--draft", silent=True)
draft_changelog = Path("docs", "_draft_changelog.md")
if draft_changelog_content and "No significant changes" not in draft_changelog_content:
lines_to_keep = draft_changelog_content.split("\n")
changelog_start = 0
for i, line in enumerate(lines_to_keep):
if line.startswith("##"):
changelog_start = i
break
lines_to_keep[changelog_start] = "## Planned for next release"
clean_changelog_content = "\n".join(lines_to_keep[changelog_start:])
draft_changelog.write_text(clean_changelog_content)
return draft_changelog
@nox.session(python=PYTHON_ALL_VERSIONS)
def tests(session: nox.Session) -> None:
"""Tests using local pypiserver only"""
tests_with_options(session, net_pypiserver=False)
@nox.session
def cover(session: nox.Session) -> None:
"""Coverage analysis"""
session.install("coverage")
session.run("coverage", "report", "--show-missing", "--fail-under=70")
session.run("coverage", "erase")
@nox.session
def zipapp(session: nox.Session) -> None:
"""Build a zipapp with shiv"""
session.install("shiv")
session.run("shiv", "-c", "pipx", "-o", "./pipx.pyz", ".")
session.run("./pipx.pyz", "--version", external=True)
@nox.session(python=PYTHON_DEFAULT_VERSION)
def lint(session):
session.run("python", "-m", "pip", "install", "pre-commit")
session.run("pre-commit", "run", "--all-files")
@nox.session(python=PYTHON_ALL_VERSIONS)
def develop(session: nox.Session) -> None:
"""Create a develop environment."""
session.run("python", "-m", "pip", "install", "--upgrade", "pip")
session.install(*DOC_DEPENDENCIES, *TEST_DEPENDENCIES, *MAN_DEPENDENCIES, "-e", ".", "nox")
@nox.session(python=PYTHON_DEFAULT_VERSION)
def build(session: nox.Session) -> None:
"""Build the wheel and source distribution for the project."""
session.install("build")
session.run("rm", "-rf", "dist", "build", external=True)
session.run("python", "-m", "build")
@nox.session(python=PYTHON_DEFAULT_VERSION)
def publish(session: nox.Session) -> None:
"""Publish the package to PyPI."""
on_main_no_changes(session)
session.install("twine")
build(session)
session.run("python", "-m", "twine", "upload", "dist/*")
@nox.session(python=PYTHON_DEFAULT_VERSION)
def build_docs(session: nox.Session) -> None:
site_dir = session.posargs or ["site/"]
session.install(*DOC_DEPENDENCIES, ".")
session.env["PIPX__DOC_DEFAULT_PYTHON"] = "typically the python used to execute pipx"
upcoming_changelog = create_upcoming_changelog(session)
session.run("mkdocs", "build", "--strict", "--site-dir", *site_dir)
upcoming_changelog.unlink(missing_ok=True)
for site in site_dir:
shutil.rmtree(Path(site, "_draft_changelog"))
@nox.session(python=PYTHON_DEFAULT_VERSION)
def watch_docs(session: nox.Session) -> None:
session.install(*DOC_DEPENDENCIES, ".")
upcoming_changelog = create_upcoming_changelog(session)
session.run("mkdocs", "serve", "--strict")
upcoming_changelog.unlink(missing_ok=True)
@nox.session(python=PYTHON_DEFAULT_VERSION)
def build_man(session: nox.Session) -> None:
session.install(*MAN_DEPENDENCIES, ".")
session.env["PIPX__DOC_DEFAULT_PYTHON"] = "typically the python used to execute pipx"
session.run("python", "scripts/generate_man.py")
@nox.session(python=PYTHON_ALL_VERSIONS)
def refresh_packages_cache(session: nox.Session) -> None:
"""Populate .pipx_tests/package_cache"""
print("Updating local tests package spec file cache...")
PIPX_TESTS_CACHE_DIR.mkdir(exist_ok=True, parents=True)
script = "scripts/update_package_cache.py"
session.run("python", script, str(PIPX_TESTS_PACKAGE_LIST_DIR), str(PIPX_TESTS_CACHE_DIR))
@nox.session(python=PYTHON_ALL_VERSIONS)
def create_test_package_list(session: nox.Session) -> None:
"""Update the list of packages needed for running the test suite."""
session.run("python", "-m", "pip", "install", "--upgrade", "pip")
output_dir = session.posargs[0] if session.posargs else str(PIPX_TESTS_PACKAGE_LIST_DIR)
primary = str(PIPX_TESTS_PACKAGE_LIST_DIR / "primary_packages.txt")
session.run("python", "scripts/list_test_packages.py", primary, output_dir)
@nox.session(python=PYTHON_ALL_VERSIONS)
def tests_internet(session: nox.Session) -> None:
"""Tests using internet pypi only"""
tests_with_options(session, net_pypiserver=True)
@nox.session(python=PYTHON_ALL_VERSIONS)
def test_all_packages(session: nox.Session) -> None:
"""A more in depth but slower test suite."""
session.install("-e", ".", *TEST_DEPENDENCIES)
test_dir = session.posargs or ["tests"]
session.run("pytest", "-v", "--tb=no", "--show-capture=no", "--net-pypiserver", "--all-packages", *test_dir)
pipx-1.4.3/pipx_demo.gif 0000664 0000000 0000000 00001007517 14551526321 0015171 0 ustar 00root root 0000000 0000000 GIF89a$ 1 H
IN
EEP=#E
6(771*T
$"0_#
$8$ ('.'%/)#)
)* +(+#,,&,B,:g- --1.1#H33>3O44 4,U5)8
8C`9 9:E;,_;Ar<3D=Pu>>5h>;R??F}A;B C&QFG.GVdH0EH1;JJ+#K(NWsOOH~ORP3P0ZQT*"T.7T4JT7VTBnV+WBYY*[f]1^Y_52`Gs`V_actd7CdQvephDUi3&mSEn:nJ`npW`s:1sRtouK.uL2uM6w~xzJUzTf{^u{`V|SA}SX}~bgq}qACpODQ|^eesj]Ô\Ui@ss]~xti@ٜqģt䦲秳i^wgdͰﳓٴtõsϸ@nÕo`<Ⱦ̖ηЪѰѼӥԛԬԱԿս֥fֺȶݹޟ8並欖8篡. Ti³9, /9ѷ0!NETSCAPE2.0 !
, $ -H*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜI͛8sɳϟ@
JѣH*]ʴӧPJJիXjʵׯ`ÊKٳh۷pE9s˷[uLIiE̸ǐG o˘3kL7MZ8L^ͺװc˞M۸sͻNȓ+_μУKNسkνËOӫ_Ͼ˟OϿ (h&6F(Vhfv ($h(,0(4h8<@)DiH&L6PF)TViXf\v`)dihlp)tix|矀*蠄j衈&袌6裐F*餔Vj饘f馜v駠*ꨤjꩨꪬ꫰*무j뭸뮼+k&6F+Vkfv+k覫+k ,l'7G,Wlgw ,$l(,0,4l8<@ ZJ2tX !R;<` hK.$"(DcL-d/@ "LMq7@D"v6:*N#ޠ8`0~7N*Dhc_9 wB.zW筿*fn[njJy宣.8+ȇ;^{Q`=7z:8} ~~Ooh |<`x1p?|`~
(
rpB(B0><{.B g6lsxCP=,!}(찈!%Nȝ RQ