![]() This PR adds a mechanism by which we can ensure that we _always_ try to refresh Git dependencies when resolving; further, we now write the fully resolved SHA to the "lockfile". However, nothing in the code _assumes_ we do this, so the installer will remain agnostic to this behavior. The specific approach taken here is minimally invasive. Specifically, when we try to fetch a source distribution, we check if it's a Git dependency; if it is, we fetch, and return the exact SHA, which we then map back to a new URL. In the resolver, we keep track of URL "redirects", and then we use the redirect (1) for the actual source distribution building, and (2) when writing back out to the lockfile. As such, none of the types outside of the resolver change at all, since we're just mapping `RemoteDistribution` to `RemoteDistribution`, but swapping out the internal URLs. There are some inefficiencies here since, e.g., we do the Git fetch, send back the "precise" URL, then a moment later, do a Git checkout of that URL (which will be _mostly_ a no-op -- since we have a full SHA, we don't have to fetch anything, but we _do_ check back on disk to see if the SHA is still checked out). A more efficient approach would be to return the path to the checked-out revision when we do this conversion to a "precise" URL, since we'd then only interact with the Git repo exactly once. But this runs the risk that the checked-out SHA changes between the time we make the "precise" URL and the time we build the source distribution. Closes #286. |
||
---|---|---|
.cargo | ||
.github/workflows | ||
crates | ||
scripts | ||
vendor/pubgrub | ||
workers/pypi-metadata | ||
.dockerignore | ||
.gitignore | ||
builder.dockerfile | ||
Cargo.lock | ||
Cargo.toml | ||
CONTRIBUTING.md | ||
LICENSE-APACHE | ||
LICENSE-MIT | ||
README.md | ||
ruff.toml | ||
rust-toolchain.toml |
puffin
An experimental Python packaging tool.
Motivation
Puffin is an extremely fast (experimental) Python package resolver and installer, intended to
replace pip
and pip-tools
(pip-compile
and pip-sync
).
Puffin itself is not a complete "package manager", but rather a tool for locking dependencies
(similar to pip-compile
) and installing them (similar to pip-sync
). Puffin can be used to
generate a set of locked dependencies from a requirements.txt
file, and then install those
locked dependencies into a virtual environment.
Puffin represents an intermediary goal in our pursuit of building a "Cargo for Python": a Python
package manager that is extremely fast, reliable, and easy to use -- capable of replacing not only
pip
, but also pipx
, pip-tools
, virtualenv
, tox
, setuptools
, and even pyenv
, by way of
managing the Python installation itself.
Puffin's limited scope allows us to solve many of the low-level problems that are required to
build such a package manager (like package installation) while shipping an immediately useful tool
with a minimal barrier to adoption. Try it today in lieu of pip
and pip-tools
.
Features
- Extremely fast dependency resolution and installation: install dependencies in sub-second time.
- Disk-space efficient: Puffin uses a global cache to deduplicate dependencies, and uses Copy-on-Write on supported filesystems to reduce disk usage.
Limitations
Puffin does not yet support:
- Source distributions
- VCS dependencies
- URL dependencies
- Windows
- ...
Like pip-compile
, Puffin generates a platform-specific requirements.txt
file (unlike, e.g.,
poetry
, which generates a platform-agnostic poetry.lock
file). As such, Puffin's
requirements.txt
files are not portable across platforms and Python versions.
Usage
To resolve a requirements.in
file:
cargo run -p puffin-cli -- pip-compile requirements.in
To install from a resolved requirements.txt
file:
cargo run -p puffin-cli -- pip-sync requirements.txt
For more, see cargo run -p puffin-cli -- --help
:
Usage: puffin-cli <COMMAND>
Commands:
compile Compile a `requirements.in` file to a `requirements.txt` file
sync Sync dependencies from a `requirements.txt` file
clean Clear the cache
freeze Enumerate the installed packages in the current environment
help Print this message or the help of the given subcommand(s)
Options:
-h, --help Print help
-V, --version Print version
License
Puffin is licensed under either of
- Apache License, Version 2.0, (LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or https://opensource.org/licenses/MIT)
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in Puffin by you, as defined in the Apache-2.0 license, shall be dually licensed as above, without any additional terms or conditions.