* fix: use target Python filtering instead of ignore_requires_python=True
Previously the resolver set ignore_requires_python=True which disabled
all Requires-Python filtering in both the PackageFinder (link evaluator)
and the resolver factory. This caused the resolver to consider every
published version of every package — including ancient Python 2.x-era
releases — massively inflating the search space and triggering
ResolutionTooDeepError on large dependency trees (e.g. 101 Sentry
requirements).
Instead, extract the target Python version from the Pipfile's
python_version/python_full_version and pass it as py_version_info to
both the PackageFinder (for link filtering) and make_resolver (for
RequiresPythonRequirement constraint creation). This lets the resolver
properly prune incompatible candidates while still supporting
cross-version locking (e.g. locking for Python 3.12 while running 3.11).
* fix benchmark
* Improve resolver conflict prioritization and hash warnings
* check pt
* Check pt
Fixes#4398: Add --exclude-index flag to 'pipenv requirements' to allow
users to exclude index URLs (-i and --extra-index-url) from the output.
Fixes#4085: 'pipenv --where' now exits with code 1 when no Pipfile is
found, making it suitable for scripting and CI pipelines.
Closes#4053 - Added a dedicated 'Installing on Windows' section to
docs/installation.md with the recommended pipx-based approach and
PATH setup instructions.
Closes#4577 - Added an 'Upgrading the Python Version' workflow to
docs/workflows.md with step-by-step instructions for migrating a
project to a new Python interpreter.
Closes#4636 - Documented that python_version in [requires] only
accepts an exact version string (e.g. '3.10'), not range specifiers
like '>= 3.6', and added a warning with the misleading error message.
Closes#5129 - Enhanced the 'Moving or Renaming Projects' section in
docs/virtualenv.md with a recovery workflow for users who already
moved their project without running 'pipenv --rm', plus a tip about
PIPENV_VENV_IN_PROJECT.
Closes#5130 - Added a 'Multi-Platform Considerations' section to
docs/locking.md explaining that Pipfile.lock is platform-specific,
with workarounds for cross-platform teams (Docker locking, CI, etc.).
Closes#5324 - Added a 'News Fragments' section to
docs/dev/contributing.md covering all towncrier fragment types and
explaining why 'trivial' entries are intentionally omitted from the
CHANGELOG.
Closes#5528 - Documented the behavior when a package pinned in
[dev-packages] conflicts with the version resolved through [packages]
dependencies, and how to enforce a specific version.
Closes#6028 - Added a 'Platform Markers and Locking' note to
docs/specifiers.md explaining that pip resolves all packages at lock
time regardless of sys_platform markers, and providing workarounds.
When using fish shell and typing `pipenv run <command> <tab>`, file
path completion was not working because:
1. The fish completion script uses --no-files globally, preventing
fallback file completion from the shell.
2. The `args` argument (nargs=-1) in the `run` command uses click's
STRING type, whose shell_complete method returns [] (no completions).
Fix by adding a _complete_run_args shell completion callback to the
`args` argument of the `run` command that returns CompletionItem
with type='file'. The fish completion script already handles 'file'
type items via __fish_complete_path, which triggers proper file path
completion in fish.
Fixes: https://github.com/pypa/pipenv/issues/3478
When the Pipfile specifies only python_version (e.g. '3.11') without an
explicit python_full_version, _get_pipfile_python_override() was hardcoding
python_full_version to '{major}.{minor}.0' (e.g. '3.11.0'). This caused
markers like 'python_full_version >= "3.11.4"' to evaluate incorrectly
during resolution, excluding necessary dependencies and triggering excessive
backtracking that hit the 200,000 round limit (ResolutionTooDeepError).
Now uses the running interpreter's actual patch version when it matches the
Pipfile's major.minor, falling back to .0 only when they differ.
Also fixes a Rich markup bug in do_create_virtualenv where an unclosed
[green] tag and missing space caused the Python path and version to render
concatenated (e.g. 'python3.11.15' instead of 'python3.11 3.11.15').
- Add pipfile_build_requires property to Project
- Add install_build_system_packages() to install build deps before resolving
- Add build-system to NON_CATEGORY_SECTIONS
- Update lock routine to include build-system in lockfile
- Add unit tests for build-system functionality
- Add --system flag to 'pipenv update' command (was hardcoded to False)
- Add PIPENV_BREAK_SYSTEM_PACKAGES env var for PEP 668 environments
- Fix ensure_virtualenv aborting when --system is used with existing venv
- Pass PIP_IGNORE_INSTALLED and PIP_USER through to pip with --system
- Support --system --python to target specific Python site-packages
Fixes#3593, #4453, #5052, #5584, #5631, #5660
Related: #5086, #5089, #5115
Path(python).absolute() on Windows prepends the current drive letter
(e.g. D:) to Unix-style absolute paths, corrupting the interpreter
path. Use the python string directly since it is already provided as
an absolute path by the caller.
When Pipfile specifies python_version = '3' (major-only), the override
produced python_full_version = '3.0' and python_version = '3'. This
caused markers like 'python_version < "3.10"' to evaluate as True
(since '3' < '3.10' in PEP 440), activating stale dependency
constraints and causing resolver conflicts (e.g. urllib3>=2 vs
urllib3<1.27 from botocore).
Now major-only versions are skipped — the running interpreter's actual
version is used for marker evaluation instead.
Install SIGTSTP and SIGCONT handlers around pexpect's interact() loop
so that when the child shell is suspended, the pipenv process stops
itself too, and resumes the child when continued. Without this, the
pexpect loop keeps pipenv in the foreground and the parent shell
never regains control.
Closes#5359
When PIPENV_PYENV_ONLY=1 is set, pipenv will only search for Python
interpreters installed via pyenv, ignoring system, Homebrew, asdf,
and other Python installations.
Closes#3855
The 300ms timeout was too aggressive, causing ReadTimeoutError failures
when resolving large requirements files (e.g. pipenv install -r with 100+
packages). Each package triggers a sequential HTTP request to pypi.org for
proper casing, and under load or from CI the requests frequently exceeded
the timeout, leading to silent failures and 'Locking Failed' errors.
pipenv shell uses pexpect to spawn a subshell and send the virtualenv
activate script. Previously, the activate command was sent immediately
after spawning, before the shell had finished its startup. If an
interactive prompt appeared during startup (e.g. oh-my-zsh asking to
update), the activate command was consumed by that prompt instead of
being executed as a shell command.
Fix: send a startup sentinel (echo __PIPENV_STARTUP_READY__) and wait
for it to appear before sending the activate script. This ensures the
shell has fully initialised and any interactive prompts have been
resolved by the user. The timeout is set to 30 seconds to give ample
time for user interaction.
Shorthand marker keys in Pipfile entries (e.g. sys_platform, platform_machine)
were not translated to PEP 508 markers when building the pip requirement line.
This caused pip to resolve and download sub-dependencies on all platforms,
even though the top-level package was platform-restricted.
Call translate_markers() in dependency_as_pip_install_line() so shorthand
keys are folded into the canonical 'markers' key before the pip line is
assembled.
Add a new PIPENV_KEYRING_PROVIDER environment variable that allows users
to explicitly configure the keyring provider used for credential lookup
during both dependency resolution and package installation.
By default, pipenv disables pip's interactive input (no_input=True), which
causes pip to skip keyring-based credential lookup when the provider is
set to 'auto'. This means system credential managers like Windows
Credential Manager are never consulted, even though they don't require
user interaction.
Setting PIPENV_KEYRING_PROVIDER to 'import' or 'subprocess' overrides
this behavior, enabling non-interactive keyring credential lookup.
Changes:
- Add PIPENV_KEYRING_PROVIDER setting in environments.py
- Pass keyring_provider through to pip_options in the resolver
- Pass PIP_KEYRING_PROVIDER to the resolver subprocess environment
- Pass PIP_KEYRING_PROVIDER to the pip install subprocess environment
- Pass keyring_provider in environment.py's get_finder session
- Update docs: configuration.md, credentials.md, indexes.md
- Fix mock _Settings in test_install_error_context.py
Fixes#5715
Click's auto_envvar_prefix='PIPENV' automatically maps --version to the
PIPENV_VERSION environment variable. When users set PIPENV_VERSION for
other purposes (e.g., CI parametrization), Click tries to parse it as a
boolean and fails with a confusing error message.
Fix by setting allow_from_autoenv=False on the version_option decorator,
which prevents Click from reading PIPENV_VERSION as a value for --version.
The --all flag was already defined and working for sync and install commands
but update and upgrade commands did not check state.installstate.all_categories,
so the flag was silently ignored.
- Fix update command to check all_categories before falling back to default
- Fix upgrade command to check all_categories before falling back to default
- Document --all flag for sync, update, and upgrade in CLI docs
- Add integration tests for --all flag on update and upgrade
Capture direct pip modifications as proper _post patch files so they
survive re-vendoring. These patches are applied after import rewriting.
- _post-pip_distutils_fallback.patch: Handle missing distutils on
Python 3.12+ by falling back to sysconfig (fixes#5674)
- _post-pip_editable_extras.patch: Fix extras handling in editable
VCS requirements
- _post-pip_wheel_name_casing.patch: Preserve wheel dist name casing
for headers install directory (fixes#5717)
- _post-pip_resolution_log_level.patch: Use logger.critical for
dependency resolution conflict messages
When locking a non-default package category (e.g. [dev-packages] or a
custom group), Resolver.create() only built index_lookup from the packages
explicitly listed in that category. With index_restricted=True in pip's
SearchScope, any package *not* in index_lookup was looked up exclusively on
the first configured index (typically PyPI).
This caused resolution to fail when:
- [packages] declares private_lib = {version="*", index="private"}
- [dev-packages] declares dev_tool = {version="*", index="private"}
- dev_tool has private_lib as a transitive dependency
pip could not find private_lib during the [dev-packages] resolution pass
because private_lib was absent from index_lookup, so pip only searched PyPI.
Fix: after building index_lookup from the current category, inject index
entries from all *other* Pipfile sections for packages not already present.
Entries set by the current category are never overridden, preserving the
existing behaviour for packages that appear in multiple sections with
different indexes.
Fixes: https://github.com/pypa/pipenv/issues/5782
Two bugs caused `pipenv install` (from a Pipfile with python_full_version)
and `pipenv --python 3.11.9` to fail on Windows even when the requested
Python version was installed and discoverable via `py --list-paths`:
1. find_python_from_py_launcher() required split(None, 2) to produce three
tokens per line, but non-default py-launcher entries (those without the
`*` marker) only produce two tokens. Non-default versions were therefore
silently skipped. Fix: require len(parts) >= 2 and take parts[-1] as the
path in all cases.
2. PyLauncherFinder stored only the major.minor version that `py --list-paths`
reports (e.g. "3.11"), leaving patch=None. Searches requiring a specific
patch level (patch=9) therefore never matched. Fix: query each discovered
executable for its real version string (e.g. "3.11.9") via get_python_version()
so that full-version lookups succeed.
Fixes#5893
Fixes two remaining issues from #5914:
1. Pipfile whitespace / blank-line stripping
- cleanup_toml() previously removed ALL empty lines then re-added a
single blank line between section headers only. This destroyed any
blank lines the user placed within a [packages] / [dev-packages]
section for visual grouping.
- New behaviour: consecutive blank lines are collapsed to one (so
accidental duplication is still normalised), but a single blank line
within a section is preserved.
- convert_tomlkit_table() now passes through tomlkit whitespace items
(key=None) instead of silently dropping them, so tomlkit's own
whitespace-preservation round-trips cleanly through write_toml().
2. Cross-category Pipfile corruption (missing --dev flag)
- When a user runs `pipenv upgrade mypy==1.5.1` without --dev,
_find_additional_categories() correctly detects that mypy lives in
[dev-packages] and ensures the lockfile is updated in both sections.
However, _process_package_args() was also writing the updated entry
to [packages] (the category derived from the absent --dev flag),
resulting in mypy appearing in both Pipfile sections.
- Fix: before calling add_pipfile_entry_to_pipfile(), check whether the
package already exists in a *different* Pipfile category. If so,
skip the Pipfile write for the current category and emit a helpful
warning pointing the user at --dev / --categories.
Tests added:
- test_cleanup_toml_preserves_single_blank_lines_within_sections
- test_cleanup_toml_collapses_multiple_blank_lines
- test_cleanup_toml_adds_blank_line_before_section_header
- test_process_package_args_does_not_cross_contaminate_categories
- test_process_package_args_writes_to_pipfile_when_package_in_correct_category
When 'python -m virtualenv --python=<interp>' exits non-zero and the user
has not explicitly set PIPENV_VIRTUALENV_CREATOR, pipenv now automatically
retries using the target interpreter's own built-in venv module
('python -m venv'). This gives alternative Python implementations such as
RustPython, GraalPy, and Jython a real chance to work, because those
interpreters are more likely to ship a functional venv module than to
support all the C-extension hooks that virtualenv probes for.
If the venv fallback also fails, both error messages are surfaced so the
user has full context. When PIPENV_VIRTUALENV_CREATOR is set explicitly
the fallback is skipped, respecting the user's intent.
A new helper, _create_builtin_venv_cmd(), builds the 'python -m venv'
command using the *target* interpreter (not sys.executable), which is the
key difference from the primary virtualenv invocation.
Closes#5601