Skip to content

Switch from requirements files to pyproject.toml and uv lock file #12298

@agjohnson

Description

@agjohnson

In #12164 we tried installing ext-theme through an easier pattern, but hit some trouble due to our
rel/relcorp pattern on all our repositories.

Overall, requirements files are an old pattern and I'd feel better about spending time working
towards a modern solution. I find the pip tools solution is mush better than what we had previously but do find
it to also be confusing to figure out what is being installed and from where.

We use uv to install dependencies, but consolidating this all to pyproject.toml and uv could be a next step.
In this, the pip compile input file becomes our dependency specification, the uv lock file becomes
what our requirements files are -- a snapshot of the exact versions/commits installed. Tox doesn't
handle uv well just yet, but there is a uv extension at least.

The main quesiton, and we hit this in #12264, is how to handle our release branches (rel/relcorp).
There seem two paths here:

Reduce complexity, stop using them on dependencies

There is a fair amount of complexity in the rel/relcorp release branches, it would be worth
exploring if we really need them for at least our own dependencies (ext, ext-theme, etc). These libraries
rarely have splits in code between rel/relcorp, the release branches are mostly to snapshot the
release and to allow for hotfixing.

We may need to keep rel/relcorp at the application at least, we should decide on this separately.

For the other repositories we could determine if:

  • We want a single release branch
  • We don't want a release branch at all, treat main as release and rely mostly on the lock file.

In both we rely on the lock file to snapshot what went into the release 1.
Also in both, our pyproject.toml is easier to manage and it just specifies a single dependency.

Without a release branch, hotfixing an ext/ext-theme change might be installing the repository
commit sha and commiting the lock file change. This would be new.

Keep our release branch pattern

In this, we kick our past design down the road again and just reimplement it in pyproject.toml. We
still get a reduction in complexity between multiple requirements files and pip compile inputs, and
we still get a lock file that snapshots the exact release versions/commits.

There might be multiple options:

  • We use optional dependencies to specify a rel, relcorp, dev optional dependencies
  • We use conditional dependencies2 to install rel, relcorp, main branches -- I believe this looks a lot like optional dependencies though.

Optional dependencies might be like:

[project.optional-dependencies]
dev = [
  "http://github.com/readthedocs/ext@main",
]
rel = [
  "http://github.com/readthedocs/ext@rel",
]
relcorp = [
  "http://github.com/readthedocs/ext@relcorp",
]

Footnotes

  1. uv should do what we want here, it pins a commit SHA in the lock file: "uv applies similar
    logic to Git dependencies. For example, if a Git dependency references the main branch, uv will
    prefer the locked commit SHA in an existing uv.lock file over the latest commit on the main
    branch"

  2. https://peps.python.org/pep-0508/

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions