From e408ee35e2a5a68b0b74f1c7cb7290f64a978f2b Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Tue, 8 Jul 2025 12:26:20 -0400 Subject: [PATCH 1/4] feat: add uv backend Signed-off-by: Henry Schreiner --- .github/workflows/reusable-cookie.yml | 3 ++ README.md | 48 +++++++++++--------- cookiecutter.json | 4 +- copier.yml | 1 + docs/pages/guides/packaging_simple.md | 10 +++- {{cookiecutter.project_name}}/pyproject.toml | 5 +- 6 files changed, 46 insertions(+), 25 deletions(-) diff --git a/.github/workflows/reusable-cookie.yml b/.github/workflows/reusable-cookie.yml index 80093270..e352b629 100644 --- a/.github/workflows/reusable-cookie.yml +++ b/.github/workflows/reusable-cookie.yml @@ -60,6 +60,9 @@ jobs: - name: Test flit run: nox -s 'tests(flit, novcs)' -s 'tests(flit, vcs)' + - name: Test uv + run: nox -s 'tests(uv, novcs)' + - name: Test pdm run: nox -s 'tests(pdm, novcs)' -s 'tests(pdm, vcs)' diff --git a/README.md b/README.md index 46559144..70098a23 100644 --- a/README.md +++ b/README.md @@ -39,28 +39,32 @@ hand, from `{{cookiecutter.project_name}}/`). During generation you can select from the following backends for your package: -1. [hatch][]: This uses hatchling, a modern builder with nice file inclusion, - extendable via plugins, and good error messages. **(Recommended for pure - Python projects)** -2. [flit][]: A modern, lightweight [PEP 621][] build system for pure Python - projects. Replaces setuptools, no MANIFEST.in, setup.py, or setup.cfg. Low - learning curve. Easy to bootstrap into new distributions. Difficult to get - the right files included, little dynamic metadata support. -3. [pdm][]: A modern, less opinionated all-in-one solution to pure Python - projects supporting standards. Replaces setuptools, venv/pipenv, pip, wheel, - and twine. Supports [PEP 621][]. -4. [poetry][]: An all-in-one solution to pure Python projects. Replaces - setuptools, venv/pipenv, pip, wheel, and twine. Higher learning curve, but is - all-in-one. Makes some bad default assumptions for libraries. -5. [setuptools][]: The classic build system, but with the new standardized - configuration. -6. [pybind11][]: This is setuptools but with an C++ extension written in - [pybind11][] and wheels generated by [cibuildwheel][]. -7. [scikit-build][]: A scikit-build (CMake) project also using pybind11, using - scikit-build-core. **(Recommended for C++ projects)** -8. [meson-python][]: A Meson project also using pybind11. (No VCS versioning) -9. [maturin][]: A [PEP 621][] builder for Rust binary extensions. (No VCS - versioning) **(Recommended for Rust projects)** +1. [hatch][]: This uses hatchling, a modern builder with nice file inclusion, + extendable via plugins, and good error messages. **(Recommended for pure + Python projects)** +2. [uv][]: The `uv_build` backend is written in Rust and is integrated into' + `uv`, meaning it can build without downloading anything extra and can even + avoid running Python at all when building, making it the fastest backend for + simple packages. +3. [flit][]: A modern, lightweight [PEP 621][] build system for pure Python + projects. Replaces setuptools, no MANIFEST.in, setup.py, or setup.cfg. Low + learning curve. Easy to bootstrap into new distributions. Difficult to get + the right files included, little dynamic metadata support. +4. [pdm][]: A modern, less opinionated all-in-one solution to pure Python + projects supporting standards. Replaces setuptools, venv/pipenv, pip, wheel, + and twine. Supports [PEP 621][]. +5. [poetry][]: An all-in-one solution to pure Python projects. Replaces + setuptools, venv/pipenv, pip, wheel, and twine. Higher learning curve, but + is all-in-one. Makes some bad default assumptions for libraries. +6. [setuptools][]: The classic build system, but with the new standardized + configuration. +7. [pybind11][]: This is setuptools but with an C++ extension written in + [pybind11][] and wheels generated by [cibuildwheel][]. +8. [scikit-build][]: A scikit-build (CMake) project also using pybind11, using + scikit-build-core. **(Recommended for C++ projects)** +9. [meson-python][]: A Meson project also using pybind11. (No VCS versioning) +10. [maturin][]: A [PEP 621][] builder for Rust binary extensions. (No VCS + versioning) **(Recommended for Rust projects)** Currently, the best choice is probably hatch for pure Python projects, and scikit-build (such as the scikit-build-core + pybind11 choice) for binary diff --git a/cookiecutter.json b/cookiecutter.json index 89d31a1e..558ecc07 100644 --- a/cookiecutter.json +++ b/cookiecutter.json @@ -8,6 +8,7 @@ "license": ["BSD", "Apache", "MIT"], "backend": [ "hatch", + "uv", "flit", "pdm", "poetry", @@ -34,6 +35,7 @@ "backend": { "__prompt__": "Choose a build backend", "hatch": "Hatchling - Pure Python (recommended)", + "uv": "uv_build - Pure Python (fast)", "flit": "Flit-core - Pure Python (minimal)", "pdm": "PDM-backend - Pure Python", "poetry": "Poetry - Pure Python", @@ -41,7 +43,7 @@ "pybind11": "Setuptools and pybind11 - Compiled C++", "skbuild": "Scikit-build-core - Compiled C++ (recommended)", "mesonpy": "Meson-python - Compiled C++ (also good)", - "maturin": "Maturin - Compiled Rust (recommended)" + "maturin": "Maturin - Compiled Rust (recommended)" }, "vcs": "Use version control for versioning" } diff --git a/copier.yml b/copier.yml index fa6caa38..488cf8fa 100644 --- a/copier.yml +++ b/copier.yml @@ -71,6 +71,7 @@ backend: help: Choose a build backend choices: "Hatchling - Pure Python (recommended)": hatch + "uv_build - Pure Python (fast)": uv "Flit-core - Pure Python (minimal)": flit "PDM-backend - Pure Python": pdm "Poetry - Pure Python": poetry diff --git a/docs/pages/guides/packaging_simple.md b/docs/pages/guides/packaging_simple.md index ae2292ba..4d0bef36 100644 --- a/docs/pages/guides/packaging_simple.md +++ b/docs/pages/guides/packaging_simple.md @@ -54,11 +54,19 @@ requires = ["hatchling"] build-backend = "hatchling.build" ``` +{% endtab %} {% tab uv uv_build %} + +```toml +[build-system] +requires = ["uv_build>=0.7.19"] +build-backend = "uv_build" +``` + {% endtab %} {% tab flit Flit-core %} ```toml [build-system] -requires = ["flit_core>=3.3"] +requires = ["flit_core>=3.12"] build-backend = "flit_core.buildapi" ``` diff --git a/{{cookiecutter.project_name}}/pyproject.toml b/{{cookiecutter.project_name}}/pyproject.toml index 8d40ba3e..1617f948 100644 --- a/{{cookiecutter.project_name}}/pyproject.toml +++ b/{{cookiecutter.project_name}}/pyproject.toml @@ -2,6 +2,9 @@ {%- if cookiecutter.backend == "pdm" %} requires = ["pdm-backend>=2.4"] build-backend = "pdm.backend" +{%- elif cookiecutter.backend == "uv" %} +requires = ["uv_build~=0.7.19"] +build-backend = "uv_build" {%- elif cookiecutter.backend == "maturin" %} requires = ["maturin>=1.9,<2"] build-backend = "maturin" @@ -102,7 +105,7 @@ classifiers = [ "Topic :: Scientific/Engineering", "Typing :: Typed", ] -{%- if cookiecutter.backend not in ['maturin', 'mesonpy'] and cookiecutter.vcs or cookiecutter.backend in ['pdm', 'hatch', 'flit'] %} +{%- if cookiecutter.backend not in ['maturin', 'mesonpy', 'uv'] and cookiecutter.vcs or cookiecutter.backend in ['pdm', 'hatch', 'flit'] %} dynamic = ["version"] {%- endif %} dependencies = [] From 0f33b8a188cc0ae1d244efdceb711a2d7ecee202 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Fri, 18 Jul 2025 08:29:11 -0700 Subject: [PATCH 2/4] Update pyproject.toml --- {{cookiecutter.project_name}}/pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_name}}/pyproject.toml b/{{cookiecutter.project_name}}/pyproject.toml index 1617f948..24cf8b05 100644 --- a/{{cookiecutter.project_name}}/pyproject.toml +++ b/{{cookiecutter.project_name}}/pyproject.toml @@ -3,7 +3,7 @@ requires = ["pdm-backend>=2.4"] build-backend = "pdm.backend" {%- elif cookiecutter.backend == "uv" %} -requires = ["uv_build~=0.7.19"] +requires = ["uv_build>=0.7.19"] build-backend = "uv_build" {%- elif cookiecutter.backend == "maturin" %} requires = ["maturin>=1.9,<2"] From dc00973b52f88c8229fa067f80c3e67dc1205031 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Fri, 18 Jul 2025 09:29:27 -0700 Subject: [PATCH 3/4] fix: one more missing spot Signed-off-by: Henry Schreiner --- noxfile.py | 2 +- {{cookiecutter.project_name}}/pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/noxfile.py b/noxfile.py index e8e0bcfc..7125caef 100644 --- a/noxfile.py +++ b/noxfile.py @@ -55,7 +55,7 @@ def rmtree_ro(path: Path) -> None: def get_expected_version(backend: str, vcs: bool) -> str: - return "0.2.3" if vcs and backend not in {"maturin", "mesonpy"} else "0.1.0" + return "0.2.3" if vcs and backend not in {"maturin", "mesonpy", "uv"} else "0.1.0" def make_copier(session: nox.Session, backend: str, vcs: bool) -> None: diff --git a/{{cookiecutter.project_name}}/pyproject.toml b/{{cookiecutter.project_name}}/pyproject.toml index 24cf8b05..910bff36 100644 --- a/{{cookiecutter.project_name}}/pyproject.toml +++ b/{{cookiecutter.project_name}}/pyproject.toml @@ -56,7 +56,7 @@ build-backend = "poetry.core.masonry.api" [project] name = "{{ cookiecutter.project_name }}" -{%- if cookiecutter.backend in ['maturin', 'mesonpy'] or not cookiecutter.vcs and cookiecutter.backend in ['setuptools', 'pybind11', 'skbuild', 'poetry'] %} +{%- if cookiecutter.backend in ['maturin', 'mesonpy', 'uv'] or not cookiecutter.vcs and cookiecutter.backend in ['setuptools', 'pybind11', 'skbuild', 'poetry'] %} version = "0.1.0" {%- endif %} authors = [ From ee7a6903a4c99921075287dcf3c10a6ea39b3ad1 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Fri, 18 Jul 2025 10:51:58 -0700 Subject: [PATCH 4/4] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 70098a23..9cea9f65 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ During generation you can select from the following backends for your package: 2. [uv][]: The `uv_build` backend is written in Rust and is integrated into' `uv`, meaning it can build without downloading anything extra and can even avoid running Python at all when building, making it the fastest backend for - simple packages. + simple packages. No dynamic metadata support. 3. [flit][]: A modern, lightweight [PEP 621][] build system for pure Python projects. Replaces setuptools, no MANIFEST.in, setup.py, or setup.cfg. Low learning curve. Easy to bootstrap into new distributions. Difficult to get