diff --git a/content/posts/2022-02-18-dependency-protection-with-python-and-github-actions.md b/content/posts/2022-02-18-dependency-protection-with-python-and-github-actions.md index e39a1d0..f6ddd2c 100644 --- a/content/posts/2022-02-18-dependency-protection-with-python-and-github-actions.md +++ b/content/posts/2022-02-18-dependency-protection-with-python-and-github-actions.md @@ -7,7 +7,7 @@ aliases = [ ] [taxonomies] -tags = ["python", "github", "github-actions", "out-of-date"] +tags = ["python", "github", "github-actions", "out-of-date", "dependency-protection"] categories = ["how-to"] +++ @@ -18,7 +18,7 @@ Or, as the dude would say > New s*** has come to light -See ["Dependency protection with pyproject.toml"](@/posts/2023-05-10-pyproject-toml.md) for my latest thinking on this topic. +See [Dependency protection with pyproject.toml](@/posts/2023-05-10-pyproject-toml.md) for my latest thinking on this topic. --- diff --git a/content/posts/2023-05-10-pyproject-toml.md b/content/posts/2023-05-10-pyproject-toml.md index b719ed7..6d93122 100644 --- a/content/posts/2023-05-10-pyproject-toml.md +++ b/content/posts/2023-05-10-pyproject-toml.md @@ -4,10 +4,21 @@ slug = "dependency-protection-pyproject-toml" date = 2023-05-10 [taxonomies] -tags = ["python", "github", "github-actions"] +tags = ["python", "github", "github-actions", "dependency-protection", "out-of-date"] categories = ["how-to"] +++ +![Iceberg](/img/iceberg.jpg) + +**NOTE: This post is out-of-date.** +Or, as the dude would say + +> New s*** has come to light + +See [Just use uv](@/posts/2023-05-10-pyproject-toml.md) for my latest thinking on this topic (spoiler: you should just use [uv](https://docs.astral.sh/uv)). + +--- + This is a follow up post to ["Dependency protection with Python and Github actions"](@/posts/2022-02-18-dependency-protection-with-python-and-github-actions.md), where I describe a relatively complex setup that uses `setup.cfg` and external requirement files to test against our minimum set of dependencies. With the rise of `pyproject.toml` as the standard way of specifying project metadata, and [**setuptools'** support for the standard](https://setuptools.pypa.io/en/latest/userguide/pyproject_config.html), we can simplify our CI system quite a bit. See [the original post](@/posts/2022-02-18-dependency-protection-with-python-and-github-actions.md) for background and the rationale on why we want to test against our minimum dependencies. diff --git a/content/posts/2024-10-12-use-uv.md b/content/posts/2024-10-12-use-uv.md new file mode 100644 index 0000000..98f2ead --- /dev/null +++ b/content/posts/2024-10-12-use-uv.md @@ -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 +``` \ No newline at end of file