Skip to content

Commit

Permalink
pipenv 3000 install (behavioral refactor) (#6098)
Browse files Browse the repository at this point in the history
* Pipenv 3000 install refactor
* add news fragment.
* Factor out do_install_dependencies from do_init as it made no sense; reduce down unused arguments; no longer perform full lock resolution during install commands.
* Fix other issues affecting the CI
* Factor out validations to eliminate ruff branching factor error.
* provide documentation updates for this important pipenv 3000 behavioral change.
* PR Feedback.
* Further refinements to the docs.
  • Loading branch information
matteius authored Jun 3, 2024
1 parent 951c382 commit 0979912
Show file tree
Hide file tree
Showing 11 changed files with 272 additions and 234 deletions.
27 changes: 11 additions & 16 deletions docs/advanced.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,23 @@ argument `--extra-pip-args="--use-feature=truststore"`. It is possible to supply

You may want to use `pipenv` as part of a deployment process.

You can enforce that your `Pipfile.lock` is up to date using the `--deploy` flag:
You can enforce that your `Pipfile.lock` is in parity with your `Pipfile` by using the `--deploy` flag:

$ pipenv install --deploy

This will fail a build if the `Pipfile.lock` is out–of–date, instead of generating a new one.
This will fail a build if the `Pipfile.lock` `_meta` `hash` is out of date from the Pipfile contents.

Or you can install packages exactly as specified in `Pipfile.lock` using the `sync` command:
Or you can install packages exactly as specified in `Pipfile.lock` using the `install` or `sync` command:

$ pipenv sync
$ pipenv install

Note
or

$ pipenv install

Note: Legacy versions of pipenv (prior to pipenv 3000) would relock dependencies when running `pipenv install`. This behavior was changed in pipenv 3000 to only relock dependencies when supply package specifiers to the `install` command.

``pipenv install --ignore-pipfile`` is nearly equivalent to ``pipenv sync``, but ``pipenv sync`` will *never* attempt to re-lock your dependencies as it is considered an atomic operation. ``pipenv install`` by default does attempt to re-lock unless using the ``--deploy`` flag.
``pipenv sync`` is nearly equivalent to ``pipenv install`` at this point, except pipenv install provides more functionality for adding and upgrading packages.

You may only wish to verify your `Pipfile.lock` is up-to-date with dependencies specified in the `Pipfile`, without installing:

Expand Down Expand Up @@ -332,16 +336,7 @@ Here's an example `tox.ini` for both local and external testing:
pipenv run ruff .

Pipenv will automatically use the virtualenv provided by `tox`. If `pipenv install --dev` installs e.g. `pytest`, then installed command `pytest` will be present in given virtualenv and can be called directly by `pytest tests` instead of `pipenv run pytest tests`.

You might also want to add `--ignore-pipfile` to `pipenv install`, as to not accidentally modify the lock-file on each test run. This causes Pipenv
to ignore changes to the `Pipfile` and (more importantly) prevents it from adding the current environment to `Pipfile.lock`. This might be important as the current environment (i.e. the virtualenv provisioned by tox) will usually
contain the current project (which may or may not be desired) and additional dependencies from `tox`'s `deps` directive. The initial provisioning may
alternatively be disabled by adding `skip_install = True` to tox.ini.

This method requires you to be explicit about updating the lock-file, which is probably a good idea in any case.

A 3rd party plugin, [tox-pipenv](https://tox-pipenv.readthedocs.io/en/latest/) is also available to use Pipenv natively with tox.

W
✨🍰✨

## ☤ Working with Platform-Provided Python Components
Expand Down
2 changes: 1 addition & 1 deletion docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pipenv graph [OPTIONS]

## install

Installs provided packages and adds them to Pipfile, or (if no packages are given), installs all packages from Pipfile.
Installs provided packages and adds them to Pipfile, or (if no packages are given), installs all packages from Pipfile.lock

```bash
pipenv install [OPTIONS] [PACKAGES]...
Expand Down
13 changes: 6 additions & 7 deletions docs/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ The commands reference for pipenv (incomplete)
## install

``$ pipenv install`` is used for installing packages into the pipenv virtual environment
and updating your Pipfile and Pipfile.lock.
and updating your Pipfile and Pipfile.lock in the case of adding new packages.

Along with the basic installation command, which takes the form:

$ pipenv install <package_name>

Running the above will install the package `<package_name>` and add it to the default packages section in the `Pipfile.lock`
Running the above will install the package `<package_name>` and add it to the default packages section in the `Pipfile` and all of its dependencies to the `Pipfile.lock`.

The user can provide these additional parameters:

Expand All @@ -24,14 +24,13 @@ The user can provide these additional parameters:
--categories — Install packages to the category groups specified here.
--system — Install packages to the system site-packages rather than into your virtualenv.
--deploy — Verifies the _meta hash of the lock file is up to date with the ``Pipfile``, aborts install if not.
--ignore-pipfile — Install from the Pipfile.lock and completely ignore Pipfile information.
--ignore-pipfile — Install from the Pipfile.lock completely ignoring Pipfile information.

General Interface Note:
```{note}
It has been confusing to many users of pipenv that running install will completely relock the lock file.
Based on feedback in pipenv issue reports, we are considering changing install to only relock when adding or changing a package.
For now, to install lock file versions (without modification of the lock file) use: pipenv sync
To modify only specific packages and their subdependencies use: pipenv update <package_name>
It was confusing to users that prior to pipenv 3000, the install would relock the lock file every time it was run.
Based on feedback in pipenv issue reports, we changed the install command to only update lock when adding or changing a package.
If you wish to relock the entire set of Pipfile specifiers, please continue to utilize `pipenv lock`
```

## sync
Expand Down
42 changes: 25 additions & 17 deletions docs/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ from your command line. You can check this by simply running

$ python --version

You should get some output like `3.10.8`. If you do not have Python, please
You should get some output like `3.12.1`. If you do not have Python, please
install the latest 3.x version from [python.org](https://python.org)

Additionally, make sure you have [pip] available.
Additionally, make sure you have [pip] available, assuming you install via pip, our preferred method of installation.
Check this by running

$ pip --version
pip 22.3.1
pip 24.0

If you installed Python from source, with an installer from [python.org] or via [Homebrew], you likely already have pip.
If you're on Linux and installed using your OS package manager, you may have to [install pip](https://pip.pypa.io/en/stable/installing/) manually.
Expand Down Expand Up @@ -114,24 +114,32 @@ For example when installing the `requests` library, you should get output simila

$ pipenv install requests
Creating a virtualenv for this project...
Pipfile: C:\Users\matte\Projects\pipenv-triage\example\Pipfile
Using C:/Users/matte/AppData/Local/Programs/Python/Python311/python.exe (3.11.2) to create virtualenv...
[ ] Creating virtual environment...created virtual environment CPython3.11.2.final.0-64 in 488ms
creator CPython3Windows(dest=C:\Users\matte\.virtualenvs\example-7V6BFyzL, clear=False, no_vcs_ignore=False, global=False)
seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=C:\Users\matte\AppData\Local\pypa\virtualenv)
added seed packages: pip==23.0, setuptools==67.1.0, wheel==0.38.4
activators BashActivator,BatchActivator,FishActivator,NushellActivator,PowerShellActivator,PythonActivator

Successfully created virtual environment!
Virtualenv location: C:\Users\matte\.virtualenvs\example-7V6BFyzL
Pipfile: /home/matteius/pipenv-triage/test_install2/Pipfile
Using default python from /mnt/extra/miniconda3/bin/python (3.12.1) to create virtualenv...
⠹ Creating virtual environment...created virtual environment CPython3.12.1.final.0-64 in 139ms
creator CPython3Posix(dest=/home/matteius/Envs/test_install2-DMnDbAT9, clear=False, no_vcs_ignore=False, global=False)
seeder FromAppData(download=False, pip=bundle, via=copy, app_data_dir=/home/matteius/.local/share/virtualenv)
added seed packages: pip==24.0
activators BashActivator,CShellActivator,FishActivator,NushellActivator,PowerShellActivator,PythonActivator

✔ Successfully created virtual environment!
Virtualenv location: /home/matteius/Envs/test_install2-DMnDbAT9
Creating a Pipfile for this project...
Installing requests...
Resolving requests...
Installing...
Adding requests to Pipfile's [packages] ...
Installation Succeeded
Installing dependencies from Pipfile.lock (3b5a71)...
Added requests to Pipfile's [packages] ...
✔ Installation Succeeded
Pipfile.lock not found, creating...
Locking [packages] dependencies...
Building requirements...
Resolving dependencies...
✔ Success!
Locking [dev-packages] dependencies...
Updated Pipfile.lock (1977acb1ba9778abb66054090e2618a0a1f1759b1b3b32afd8a7d404ba18b4fb)!
To activate this project's virtualenv, run pipenv shell.
Alternatively, run a command inside the virtualenv with pipenv run.
Installing dependencies from Pipfile.lock (18b4fb)...


## Using installed packages

Expand Down
11 changes: 5 additions & 6 deletions docs/pipfile.md
Original file line number Diff line number Diff line change
Expand Up @@ -238,11 +238,10 @@ This guarantees you're installing the same exact packages on any network as the
where the lock file was last updated, even on untrusted networks.

We recommend designing CI/CD deployments whereby the build does not alter the lock file as a side effect.
In other words, you can use `pipenv lock` or `pipenv upgrade` to adjust your lockfile through local development,
the PR process and approve those lock changes before deploying to production that version of the lockfile.
In other words avoid having your CI issue `lock`, `update`, `upgrade` `uninstall` or `install` commands that will relock.
Note: It is counterintuitive that `pipenv install` re-locks and `pipenv sync` or `pipenv install --deploy` does not.
Based on feedback, we may change this behavior of `pipenv install` to not re-lock in the future but be mindful of this when designing CI pipelines today.
In other words, you can use `pipenv lock` or `pipenv upgrade` to adjust your lockfile through local development.
The PR process of reviewing and approving those lock changes before deploying to production that version of the lockfile
is a recommended best practice.
In other words: always avoid having your CI issue `lock`, `update`, `upgrade` `uninstall` or any commands that will relock.

```{admonition} Generate requirements.txt output from lock file
$ pipenv requirements
Expand All @@ -267,7 +266,7 @@ All named categories (other than the special default/develop) will use the categ
## General Notes and Recommendations

- Keep both `Pipfile` and `Pipfile.lock` in version control.
- `pipenv install` adds specifiers to `Pipfile` and rebuilds the lock file based on the Pipfile specs, by utilizing the internal resolver of `pip`.
- `pipenv install package-name` adds specifiers to `Pipfile` and rebuilds the lock file based on the Pipfile specs, by utilizing the internal resolver of `pip`.
- Not all the required sub-dependencies need be specified in `Pipfile`, instead only add specifiers that make sense for the stability of your project.
Example: `requests` requires `cryptography` but (for reasons) you want to ensure `cryptography` is pinned to a particular version set.
- Consider specifying your target Python version in your `Pipfile`'s `[requires]` section.
Expand Down
4 changes: 2 additions & 2 deletions docs/workflows.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ Clone / create project repository:

Install from `Pipfile.lock`, if there is one:

$ pipenv sync
$ pipenv install

Add a package to your project, recalibrating entire lock file using the Pipfile specifiers:
Add a package to your project, recalibrating subset of lock file using the Pipfile specifiers:

$ pipenv install <package>

Expand Down
4 changes: 4 additions & 0 deletions news/6098.behavior.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
``pipenv==3000.0.0`` denotes the first major release of our semver strategy.
As much requested, the ``install`` no longer does a complete lock operation. Instead ``install`` follows the same code path as pipenv update (which is upgrade + sync).
This is what most new users expect the behavior to be; it is a behavioral change, a necessary one to make the tool more usable.
Remember that complete lock resolution can be invoked with ``pipenv lock`` just as before.
4 changes: 1 addition & 3 deletions pipenv/cli/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -646,16 +646,14 @@ def run_open(state, module, *args, **kwargs):
@pass_context
def sync(ctx, state, bare=False, user=False, unused=False, **kwargs):
"""Installs all packages specified in Pipfile.lock."""
from pipenv.routines.install import do_sync
from pipenv.routines.sync import do_sync

retcode = do_sync(
state.project,
dev=state.installstate.dev,
python=state.python,
bare=bare,
user=user,
clear=state.clear,
unused=unused,
pypi_mirror=state.pypi_mirror,
system=state.system,
extra_pip_args=state.installstate.extra_pip_args,
Expand Down
Loading

0 comments on commit 0979912

Please sign in to comment.