-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Closes #22
- Loading branch information
Showing
3 changed files
with
65 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
+++ | ||
title = "Just use uv" | ||
slug = "use-uv" | ||
date = 2024-10-12 | ||
description = "Hopefully the final installment in our 'Dependency protection in Python' series" | ||
|
||
[taxonomies] | ||
tags = ["python", "dependency-protection"] | ||
categories = ["how-to"] | ||
+++ | ||
|
||
When you're building a Python library, take care with your dependency specifiers. | ||
Overly-specific or overly-restrictive dependencies can quickly lead to dependency hell for your dependents. | ||
I've written two articles on the topic, the first one in 2022: | ||
|
||
- In [Dependency protection with Python and Github actions](@/posts/2022-02-18-dependency-protection-with-python-and-github-actions.md), I outlined a scheme to test minimum versions against a manually-maintained `requirements-min.txt`. | ||
- The follow-on [Dependency protection with pyproject.toml](@/posts/2023-05-10-pyproject-toml.md) "simplified" the workflow with a utility script to calculate and install the minimum versions of dependencies. | ||
|
||
All these backflips were required because [pip doesn't support resolving to minimum versions](https://github.com/pypa/pip/issues/8085). | ||
Various utilities and package management systems did, but none of them felt like the right solution to me — until now. | ||
|
||
## Just use **uv** | ||
|
||
[uv](https://docs.astral.sh/uv/) is a Python package and project manager from [Astral](https://astral.sh/), the folks who brought us [ruff](https://astral.sh/ruff). | ||
Astral, in my opinion, are those rare folks whose tools actually live up to their hype. | ||
**uv** does a lot of stuff, including solving our minimum dependency problem. | ||
|
||
```sh | ||
uv pip install . --resolution lowest # or --resolution lowest-direct | ||
``` | ||
|
||
If you're using [**uv** projects](https://docs.astral.sh/uv/concepts/projects/) (which I would recommend) you can `sync` to your lowest versions as well: | ||
|
||
```sh | ||
uv sync --resolution lowest | ||
``` | ||
|
||
This makes things pretty darn simple, especially compared to the mess that was the solutions I wrote about above. | ||
To see this in action, I just updated [antimeridian](https://github.com/gadomski/antimeridian/pull/139) to use **uv** in its CI to [test against minimum versions](https://github.com/gadomski/antimeridian/pull/139/files#diff-944291df2c9c06359d37cc8833d182d705c9e8c3108e7cfe132d61a06e9133ddR44-R52): | ||
|
||
```yaml | ||
- uses: astral-sh/setup-uv@v3 | ||
- name: Sync | ||
run: uv sync --resolution lowest-direct | ||
- name: pytest | ||
run: uv run pytest | ||
- name: Sync w/ all extras | ||
run: uv sync --resolution lowest-direct --all-extras | ||
- name: pytest | ||
run: uv run pytest | ||
``` |