astral-sh / uv

An extremely fast Python package installer and resolver, written in Rust.
https://astral.sh/
Apache License 2.0
15.15k stars 436 forks source link

Expose package metadata in a way that can be reused by other tools #2361

Open obi1kenobi opened 4 months ago

obi1kenobi commented 4 months ago

uv has done a lot of work to ensure it can read package metadata quickly and correctly: https://twitter.com/charliermarsh/status/1767251713134653641

This is a surprisingly tricky thing to get right, and it would be useful to a variety of tools in the Python ecosystem beyond just uv. It would be lovely to be able to reuse this fine work to power other tools as well. This could either be in the form of a Rust or Python API that other tools could hook into, or by introducing a uv CLI command or flag (e.g. uv metadata my_pkg==1.2.3) that other tools could run.

The current recommended workaround (per this tweet) is running echo "foo==1.2.3" | uv pip compile - and reading the output requirements file. This is reasonable as a workaround, but obviously not as elegant as either a dedicated CLI item or a direct Rust or Python API for this functionality.

I don't expect this feature request would be any kind of immediate priority, of course. My goal is to register interest in such a feature and provide a place where interested folks can coordinate, share experiences with workarounds, and have a dependable way to find out if/when an API or CLI extension for this gets added.

Thanks for all the awesome work you've been doing on uv!

konstin commented 4 months ago

Could you talk a bit more about what's your use case?

obi1kenobi commented 4 months ago

Sure! TL;DR: I'd love a cargo metadata but for Python.

Since I know you maintain maturin (thank you!), you might be familiar with my tool cargo-semver-checks, a linter for breaking changes in Rust. It uses cargo metadata as one of its sources of data to check.

I also build and maintain some linters for Python use cases: I recently built a linter called pepperlint that can catch breaking changes in Python packages, and I've built other linters that can catch cases like "your project's Kubernetes deployment uses a Docker image whose Python version is incompatible with your project's pyproject.toml Python version range."

A major challenge in linters like this is getting access to ground truth data about packages: info on dependencies and ranges, supported platforms, source code location, license, etc. In Rust, cargo metadata easily gives us the canonical copy of all this data. In Python, there's currently no equivalent command, and there's a wide variety of ways this metadata may be structured. uv faces the same problem, and appears to have solved it quite well.

This is why a uv metadata command analogous to cargo metadata would be lovely for downstream tools. Happy to chat more or answer any follow-up questions!