From 12278956d5b4f6a08ce29043f04e2ff4e58572d4 Mon Sep 17 00:00:00 2001 From: Matt Davis Date: Sun, 5 Nov 2023 09:05:37 -0500 Subject: [PATCH 1/4] Use the extra pip args in the resolver. --- pipenv/routines/lock.py | 2 ++ pipenv/utils/resolver.py | 11 ++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/pipenv/routines/lock.py b/pipenv/routines/lock.py index 0a79cfc561..304094fc24 100644 --- a/pipenv/routines/lock.py +++ b/pipenv/routines/lock.py @@ -14,6 +14,7 @@ def do_lock( write=True, pypi_mirror=None, categories=None, + extra_pip_args=None, ): """Executes the freeze functionality.""" if not pre: @@ -74,6 +75,7 @@ def do_lock( pipfile=packages, lockfile=lockfile, old_lock_data=old_lock_data, + extra_pip_args=extra_pip_args, ) # Overwrite any category packages with default packages. diff --git a/pipenv/utils/resolver.py b/pipenv/utils/resolver.py index 858f7047c1..11e7053bef 100644 --- a/pipenv/utils/resolver.py +++ b/pipenv/utils/resolver.py @@ -261,6 +261,10 @@ def prepare_pip_args(self, use_pep517=None, build_isolation=True): if self.pre: pip_args.append("--pre") pip_args.extend(["--cache-dir", self.project.s.PIPENV_CACHE_DIR]) + extra_pip_args = os.environ.get("PIPENV_EXTRA_PIP_ARGS") + if extra_pip_args: + extra_pip_args = json.loads(extra_pip_args) + pip_args.extend(extra_pip_args) return pip_args @property # cached_property breaks authenticated private indexes @@ -733,6 +737,7 @@ def venv_resolve_deps( pipfile=None, lockfile=None, old_lock_data=None, + extra_pip_args=None, ): """ Resolve dependencies for a pipenv project, acts as a portal to the target environment. @@ -784,7 +789,11 @@ def venv_resolve_deps( os.environ["PIPENV_SITE_DIR"] = pipenv_site_dir else: os.environ.pop("PIPENV_SITE_DIR", None) - with console.status("Locking...", spinner=project.s.PIPENV_SPINNER) as st: + if extra_pip_args: + os.environ["PIPENV_EXTRA_PIP_ARGS"] = json.dumps(extra_pip_args) + with console.status( + f"Locking {category}...", spinner=project.s.PIPENV_SPINNER + ) as st: # This conversion is somewhat slow on local and file-type requirements since # we now download those requirements / make temporary folders to perform # dependency resolution on them, so we are including this step inside the From 8eb7cb0ab5543970a9abff7d2d30eb7b88d3dfcc Mon Sep 17 00:00:00 2001 From: Matt Davis Date: Tue, 14 Nov 2023 17:57:21 -0500 Subject: [PATCH 2/4] Expand to upgrade/update command as well --- pipenv/cli/command.py | 1 + pipenv/routines/update.py | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/pipenv/cli/command.py b/pipenv/cli/command.py index 57fe060451..0264c18705 100644 --- a/pipenv/cli/command.py +++ b/pipenv/cli/command.py @@ -258,6 +258,7 @@ def upgrade(state, **kwargs): dev=state.installstate.dev, system=state.system, lock_only=state.installstate.lock_only, + extra_pip_args=state.installstate.extra_pip_args, ) diff --git a/pipenv/routines/update.py b/pipenv/routines/update.py index 11897a6c20..3cfb65b611 100644 --- a/pipenv/routines/update.py +++ b/pipenv/routines/update.py @@ -1,3 +1,5 @@ +import json +import os import sys from collections import defaultdict @@ -62,6 +64,7 @@ def do_update( pre=pre, pypi_mirror=pypi_mirror, write=not outdated, + extra_pip_args=extra_pip_args, ) else: upgrade( @@ -75,6 +78,7 @@ def do_update( index_url=index_url, dev=dev, lock_only=lock_only, + extra_pip_args=extra_pip_args, ) if outdated: @@ -110,6 +114,7 @@ def upgrade( categories=None, dev=False, lock_only=False, + extra_pip_args=None, ): lockfile = project.lockfile() if not pre: @@ -123,6 +128,9 @@ def upgrade( if index_url: index_name = add_index_to_pipfile(project, index_url) + if extra_pip_args: + os.environ["PIPENV_EXTRA_PIP_ARGS"] = json.dumps(extra_pip_args) + package_args = list(packages) + [f"-e {pkg}" for pkg in editable_packages] requested_install_reqs = defaultdict(dict) From 2e115e2e88c1cdefa97aa87a56887d422217d6cf Mon Sep 17 00:00:00 2001 From: Matt Davis Date: Tue, 14 Nov 2023 17:58:20 -0500 Subject: [PATCH 3/4] add news fragment --- news/6006.feature.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 news/6006.feature.rst diff --git a/news/6006.feature.rst b/news/6006.feature.rst new file mode 100644 index 0000000000..ebdb4ecd84 --- /dev/null +++ b/news/6006.feature.rst @@ -0,0 +1 @@ +Supply any ``--extra-pip-args`` also in the resolver steps. From baf3f4a4d2a41214713db00b742d07341ff9816d Mon Sep 17 00:00:00 2001 From: Matt Davis Date: Tue, 28 May 2024 22:01:40 -0400 Subject: [PATCH 4/4] Add locking help to the docs. --- docs/locking.md | 86 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 docs/locking.md diff --git a/docs/locking.md b/docs/locking.md new file mode 100644 index 0000000000..f19b6660f8 --- /dev/null +++ b/docs/locking.md @@ -0,0 +1,86 @@ +# Locking Dependencies + +Locking dependencies in Pipenv ensures that your project's dependencies are consistent across different environments by creating a `Pipfile.lock` file. This file contains the exact versions of all dependencies, making your builds deterministic and reproducible. + +## Creating a Lock File + +Pipenv will automatically generate a `Pipfile.lock` file when you install dependencies using the `pipenv install` command. This file contains the specific versions of all installed packages and their dependencies. + +```bash +pipenv install requests +``` + +To completely update a `Pipfile.lock` file based on the currently available packages and your `Pipfile` specifiers, run the following command: + + pipenv lock + + +## Installing from a Lock File + +When you have a `Pipfile.lock` file in your project, you can install the exact dependencies specified in the lock file with: + + pipenv install + +## Updating Lock Files + +When you need to update your dependencies, you can update a subset of lock file with: + + pipenv upgrade mypackage==1.2.3 + +This command updates all dependencies to their latest compatible versions and regenerates the `Pipfile.lock`. + +Should you want `pipenv` to also install the upgraded packages, you can run the following command: + + pipenv update mypackage==1.2.3 + +## Viewing Locked Dependencies + +You can view the currently locked dependencies and their versions with: + + pipenv graph + +This command outputs a dependency graph, showing all locked packages and their dependencies. + +## Best Practices + +- **Commit Your `Pipfile.lock`:** Always commit your `Pipfile.lock` file to version control to ensure that your team members and CI/CD pipelines use the same dependencies. +- **Regularly Update Dependencies:** Periodically update your dependencies to include the latest patches and improvements while ensuring compatibility. +- **Review Dependency Changes:** When updating dependencies, review the changes in the `Pipfile.lock` to understand the impact on your project. + +## Troubleshooting + +### Common Issues + +- **Dependency Conflicts:** If you encounter dependency conflicts, you may need to adjust your `Pipfile` or manually resolve the conflicts before locking again. Run with the `--verbose` flag to get more information about the conflict. +- **Installation Errors:** Ensure that your `Pipfile.lock` is not corrupted and that you have the necessary permissions to install the dependencies. Check for common system dependencies when building sdist packages. + +### Helpful Commands + +- **Check for Dependency Issues:** + + ```bash + pipenv check + ``` + + This command checks for security vulnerabilities and other issues in your dependencies. + +- **Clear Caches:** + + ```bash + pipenv --clear + ``` + + This command clears Pipenv’s caches, which can resolve some installation issues. + +## Supplying additional arguments to the pipenv resolver + +You can supply additional arguments to the pipenv resolver by supplying `--extra-pip-arg` to the `install` command. For example, `pipenv install --extra-pip-args="--platform=win_amd64 --target /path/to/my/target`. + +```bash + +## Conclusion + +Locking in Pipenv is a powerful feature that ensures your Python project’s dependencies are consistent, secure, and reproducible. By understanding and utilizing Pipenv’s locking mechanism, you can avoid many common dependency management issues and ensure your projects run smoothly across different environments. + +```note +Locking ensures that all dependencies are resolved and installed in a consistent manner. This helps avoid issues where different versions of dependencies might introduce bugs or inconsistencies in your project.