Skip to content

🐛 fix(install): keyring auth and URL constraint handling#1759

Merged
gaborbernat merged 3 commits intopypa:mainfrom
gaborbernat:fix/keyring-subprocess-provider
Mar 21, 2026
Merged

🐛 fix(install): keyring auth and URL constraint handling#1759
gaborbernat merged 3 commits intopypa:mainfrom
gaborbernat:fix/keyring-subprocess-provider

Conversation

@gaborbernat
Copy link
Copy Markdown
Contributor

pipx install from private indexes silently failed keyring-based authentication because pip defaults --keyring-provider to disabled. Setting PIP_KEYRING_PROVIDER=subprocess in the subprocess environment enables pip to call out to the system keyring for credentials, matching how pip behaves when invoked directly. The env var uses setdefault so users who explicitly configure a different provider are not overridden.

Separately, since 1.7.0 parse_specifier_for_install() calls Path.resolve() on -c/--constraint arguments unconditionally, turning URLs like https://example.com/constraints.txt into bogus local paths. 🔗 The fix checks for a URL scheme via urlsplit() before resolving, so URLs pass through untouched while local paths still get resolved.

Also removes stale type: ignore[import-not-found] comments on pytest imports across test files, now that pytest is declared as a mypy dependency in pre-commit config.

Fixes #1582, fixes #1603

pipx passes --no-input to pip, which implicitly disables keyring.
The venv also lacks keyring as a library, so pip can't import it.
This breaks users who authenticate to private package indexes
(Azure Artifacts, Artifactory) via keyring.

Setting PIP_KEYRING_PROVIDER=subprocess tells pip to invoke the
system-installed keyring CLI instead of importing it. The subprocess
provider works with --no-input and gracefully no-ops when keyring
isn't installed. Uses setdefault so users can override.

Closes pypa#1603
Add pytest to mypy's additional_dependencies in pre-commit
config and add future annotations import for 3.9 support.
Now that pytest is in mypy's additional_dependencies,
the import-not-found ignores are unnecessary. Also
convert skip() to skipif marker to fix unreachable error.
@gaborbernat gaborbernat force-pushed the fix/keyring-subprocess-provider branch from 2b7207d to 919298c Compare March 21, 2026 00:47
@gaborbernat gaborbernat enabled auto-merge (squash) March 21, 2026 00:47
@gaborbernat gaborbernat merged commit 1b9edc7 into pypa:main Mar 21, 2026
20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant