Skip to content

Add pipx support for installing Python applications#250

Open
mvance wants to merge 3 commits into
geerlingguy:masterfrom
mvance:feature/add-pipx-support-v5
Open

Add pipx support for installing Python applications#250
mvance wants to merge 3 commits into
geerlingguy:masterfrom
mvance:feature/add-pipx-support-v5

Conversation

@mvance

@mvance mvance commented May 28, 2026

Copy link
Copy Markdown

In the interest of full disclosure, I leveraged AI assistance for this PR; I'd classify it as "Level 6: Bots coded, human understands mostly" on the VisiData scale. That said, I've put the changes through multiple rounds of code review using CodeRabbit, Gemini, cubic.dev, and Claude to achieve consensus.

With Python 3.12, Homebrew began following PEP 668 and recommends using pipx to install Python CLI applications in isolated virtual environments.

This PR adds pipx support, following the pattern used for npm, pip, gem, and composer packages. It adds:

  • pipx_packages: list of applications to install via pipx, supporting both simple strings (- ntfy) and dicts with per-item overrides (state, executable, backend)
  • pipx_ensurepath: opt-in flag to run pipx ensurepath and add the pipx bin directory to PATH (defaults to false)
  • pipx_executable and pipx_default_backend: playbook-wide defaults for the pipx binary and package backend (pip or uv)
  • pipx added to homebrew_installed_packages so it's present before the tasks run
  • community.general >= 5.5.0 added to requirements.yml (the pipx module was introduced in 3.8.0, but state: latest requires 5.5.0)

All new variables default to empty lists or false to avoid impacting existing users.

NOTE: existing tasks in extra-packages.yml use short module names (pip, gem, etc.); the new tasks use fully-qualified names (ansible.builtin.command, community.general.pipx). The FQCN is required for the community.general module and used on the command task for consistency, but I can align those to short names if you'd prefer uniformity.

mvance and others added 3 commits May 27, 2026 12:06
This PR adds native support for installing global Python applications via pipx, resolving PEP 668 ('externally-managed-environment') errors on modern macOS/Homebrew setups.

Key features:
- Integrated pipx into the default Homebrew package list.
- Added pipx_packages and backend configuration to default.config.yml.
- Implemented robust pipx tasks in tasks/extra-packages.yml with support for:
  - Custom executables and backends (e.g., uv).
  - Both simple string and dictionary-based package lists.
  - Safe handling of null or missing configuration keys.
- Added pipx_ensurepath option with accurate idempotency reporting.
- Updated documentation and requirements (community.general >= 5.5.0) to ensure compatibility.
- Expanded CI test coverage for both string and mapping input formats.
- Polished playbook output using loop_control labels.
Replace verbose `if item is mapping else` conditionals with the standard
`default()` filter pattern used by npm, pip, and gem tasks. These patterns
are functionally equivalent in Ansible/Jinja2 — `item.name | default(item)`
correctly handles both string and mapping inputs. Also remove the boolean
second argument to `default()` calls for consistency with existing tasks.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
refactor: simplify Jinja2 patterns in pipx task
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant