From f1c5ca0010178899e083d9cdc1a06d6d6d60c3b9 Mon Sep 17 00:00:00 2001 From: "python-templates-copier-update[bot]" Date: Sun, 11 Oct 2026 11:26:41 +0000 Subject: [PATCH 1/4] Update from Copier (2026-10-11T11-26-39Z) Signed-off-by: python-templates-copier-update[bot] --- .copier-answers.yaml | 2 +- .github/workflows/build.yaml | 2 +- Makefile | 10 +++++----- pyproject.toml | 3 ++- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/.copier-answers.yaml b/.copier-answers.yaml index 6edb06c..e9155f7 100644 --- a/.copier-answers.yaml +++ b/.copier-answers.yaml @@ -1,5 +1,5 @@ # Changes here will be overwritten by Copier -_commit: ebb6e1c +_commit: '4372075' _src_path: https://github.com/python-project-templates/base.git add_docs: false add_extension: python diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 0583a17..2cba429 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -15,7 +15,7 @@ on: workflow_dispatch: concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true permissions: diff --git a/Makefile b/Makefile index 2d00fe7..62d3fbb 100644 --- a/Makefile +++ b/Makefile @@ -25,16 +25,16 @@ lint-py: ## lint python with ruff python -m ruff format --check hatch_rs lint-docs: ## lint docs with mdformat and codespell - python -m mdformat --check README.md - python -m codespell_lib README.md + python -m mdformat --check README.md $(wildcard docs/src) + python -m codespell_lib README.md $(wildcard docs/src) fix-py: ## autoformat python code with ruff python -m ruff check --fix hatch_rs python -m ruff format hatch_rs fix-docs: ## autoformat docs with mdformat and codespell - python -m mdformat README.md - python -m codespell_lib --write README.md + python -m mdformat README.md $(wildcard docs/src) + python -m codespell_lib --write README.md $(wildcard docs/src) lint: lint-py lint-docs ## run all linters lints: lint @@ -52,7 +52,7 @@ check-dist: ## check python sdist and wheel with check-dist check-types: ## check python types with ty ty check --python $$(which python) -checks: check-dist +checks: check-dist check-types # Alias check: checks diff --git a/pyproject.toml b/pyproject.toml index de55eda..c94b924 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -48,6 +48,7 @@ develop = [ "editables", "hatchling", "mdformat", + "mdformat-frontmatter", "mdformat-tables>=1", "pip", "pytest", @@ -88,7 +89,7 @@ replace = 'version = "{new_version}"' [tool.coverage.run] branch = false omit = [ - "hatch_rs/tests/integration/", + "hatch_rs/tests/integration/*", ] [tool.coverage.report] From 8e63f09cecaa05bb2330d0595b1b0cbdc6dd51be Mon Sep 17 00:00:00 2001 From: Tim Paine <3105306+timkpaine@users.noreply.github.com> Date: Sun, 11 Oct 2026 10:58:07 -0400 Subject: [PATCH 2/4] Resolve build paths and correct test types Signed-off-by: Tim Paine <3105306+timkpaine@users.noreply.github.com> --- Makefile | 8 ++++---- hatch_rs/structs.py | 2 +- hatch_rs/tests/test_hook_registration.py | 3 ++- hatch_rs/tests/test_plugin.py | 8 +++----- hatch_rs/tests/test_projects.py | 15 ++++++++------- hatch_rs/tests/test_structs.py | 14 ++++++++++++-- 6 files changed, 30 insertions(+), 20 deletions(-) diff --git a/Makefile b/Makefile index 62d3fbb..29b0177 100644 --- a/Makefile +++ b/Makefile @@ -25,16 +25,16 @@ lint-py: ## lint python with ruff python -m ruff format --check hatch_rs lint-docs: ## lint docs with mdformat and codespell - python -m mdformat --check README.md $(wildcard docs/src) - python -m codespell_lib README.md $(wildcard docs/src) + python -m mdformat --check README.md $(wildcard docs/src) + python -m codespell_lib README.md $(wildcard docs/src) fix-py: ## autoformat python code with ruff python -m ruff check --fix hatch_rs python -m ruff format hatch_rs fix-docs: ## autoformat docs with mdformat and codespell - python -m mdformat README.md $(wildcard docs/src) - python -m codespell_lib --write README.md $(wildcard docs/src) + python -m mdformat README.md $(wildcard docs/src) + python -m codespell_lib --write README.md $(wildcard docs/src) lint: lint-py lint-docs ## run all linters lints: lint diff --git a/hatch_rs/structs.py b/hatch_rs/structs.py index e65f2c1..d71fab3 100644 --- a/hatch_rs/structs.py +++ b/hatch_rs/structs.py @@ -683,7 +683,7 @@ class HatchRustBuildConfig(BaseModel): name: str | None = Field(default=None) module: str = Field(description="Python module name for the Rust extension.") - path: Path | None = Field(default=None, description="Path to the project root directory.") + path: Path = Field(default_factory=Path.cwd, description="Path to the project root directory.") manifest: Path | None = Field(default=None, description="Path to Cargo.toml, relative to path unless absolute.") build_type: BuildType = Field(default="release", alias="build-type") profile: str | None = Field(default=None, description="Cargo profile to build. Overrides build_type when set.") diff --git a/hatch_rs/tests/test_hook_registration.py b/hatch_rs/tests/test_hook_registration.py index 29585a0..3cc1ae8 100644 --- a/hatch_rs/tests/test_hook_registration.py +++ b/hatch_rs/tests/test_hook_registration.py @@ -1,4 +1,5 @@ from hatchling.builders.hooks.plugin.interface import BuildHookInterface +from hatchling.metadata.core import ProjectMetadata from hatch_rs.hooks import hatch_register_build_hook @@ -10,7 +11,7 @@ def test_registered_build_hook_accepts_hatchling_configuration(tmp_path): root=str(tmp_path), config=config, build_config=None, - metadata=None, + metadata=ProjectMetadata(str(tmp_path), None, {"project": {"name": "project", "version": "0.1.0"}}), directory=str(tmp_path), target_name="wheel", ) diff --git a/hatch_rs/tests/test_plugin.py b/hatch_rs/tests/test_plugin.py index acd9251..0b3866c 100644 --- a/hatch_rs/tests/test_plugin.py +++ b/hatch_rs/tests/test_plugin.py @@ -1,3 +1,5 @@ +from hatchling.metadata.core import ProjectMetadata + from hatch_rs.plugin import HatchRustBuildHook @@ -21,16 +23,12 @@ def execute(self): def cleanup(self): pass - class Metadata: - def __init__(self): - self.config = {"project": {"name": "project"}} - monkeypatch.setattr("hatch_rs.plugin.import_string", lambda path: CustomBuildPlan) hook = HatchRustBuildHook( root=str(tmp_path), config={"module": "project", "path": str(tmp_path), "build-plan-class": "tests.CustomBuildPlan"}, build_config=None, - metadata=Metadata(), + metadata=ProjectMetadata(str(tmp_path), None, {"project": {"name": "project", "version": "0.1.0"}}), directory=str(tmp_path), target_name="wheel", ) diff --git a/hatch_rs/tests/test_projects.py b/hatch_rs/tests/test_projects.py index e7179ad..2e54568 100644 --- a/hatch_rs/tests/test_projects.py +++ b/hatch_rs/tests/test_projects.py @@ -1,3 +1,4 @@ +from importlib import import_module from json import loads from os import environ, listdir, pathsep from os.path import dirname @@ -77,9 +78,9 @@ def test_basic(self, project_folder): # import here = Path(__file__).parent / project_folder path.insert(0, str(here)) - import project.project + project = import_module("project.project") - assert project.project.hello() == "A string" + assert project.hello() == "A string" def test_cargo_controls_manifest_rustc_args_and_isolated_target_dir(self): project_folder = "test_project_cargo_controls" @@ -141,7 +142,7 @@ def test_cargo_controls_manifest_rustc_args_and_isolated_target_dir(self): # import here = Path(__file__).parent / project_folder path.insert(0, str(here)) - import cargo_controls_project + cargo_controls_project = import_module("cargo_controls_project") assert cargo_controls_project.hello() == "Cargo controls 1" assert cargo_controls_project.compile_env() == "enabled" @@ -217,7 +218,7 @@ def test_python_extension_and_c_abi_shared_library_artifacts(self): # import here = Path(__file__).parent / project_folder path.insert(0, str(here)) - import c_abi_bundle_project + c_abi_bundle_project = import_module("c_abi_bundle_project") assert c_abi_bundle_project.extension_answer() == 42 assert c_abi_bundle_project.shared_answer() == 7 @@ -274,7 +275,7 @@ def test_generated_file_and_header_artifacts(self): # import here = Path(__file__).parent / project_folder path.insert(0, str(here)) - import generated_files_project + generated_files_project = import_module("generated_files_project") assert generated_files_project.generated_text() == "generated package data" @@ -340,6 +341,6 @@ def test_editable_debug(self): # import here = Path(__file__).parent / project_folder path.insert(0, str(here)) - import project.extension + extension = import_module("project.extension") - assert project.extension.hello() == "A string" + assert extension.hello() == "A string" diff --git a/hatch_rs/tests/test_structs.py b/hatch_rs/tests/test_structs.py index b3e2570..346ed46 100644 --- a/hatch_rs/tests/test_structs.py +++ b/hatch_rs/tests/test_structs.py @@ -3,10 +3,12 @@ from json import loads from pathlib import Path, PureWindowsPath from sys import version_info +from typing import Any import pytest from hatch_rs.structs import ( + CargoTargetKind, HatchRustBuildPlan, RustArtifactConfig, executable_name, @@ -119,7 +121,7 @@ def test_resolve_target_triple_rejects_macos_universal2_as_rust_target(): ), ], ) -def test_wheel_tag_uses_packaging_tags(monkeypatch: pytest.MonkeyPatch, kwargs: dict[str, object], expected: str): +def test_wheel_tag_uses_packaging_tags(monkeypatch: pytest.MonkeyPatch, kwargs: dict[str, Any], expected: str): monkeypatch.delenv("AUDITWHEEL_PLAT", raising=False) kwargs_copy = dict(kwargs) python_version = kwargs_copy.pop("python_version", (3, 11)) @@ -228,6 +230,14 @@ def test_python_extension_name_rejects_abi3_free_threaded_before_python_315(pyth ) +@pytest.mark.parametrize("config", [{"module": "project"}, {"module": "project", "path": None}]) +def test_build_plan_defaults_to_working_directory(tmp_path, monkeypatch, config): + monkeypatch.chdir(tmp_path) + plan = HatchRustBuildPlan(**config) + plan.generate() + assert plan.cargo_invocations[0].cwd == tmp_path + + def test_build_plan_copies_emscripten_python_extension(tmp_path): plan = HatchRustBuildPlan( module="project", @@ -386,7 +396,7 @@ def test_build_plan_does_not_disable_crt_static_for_musl_executable(tmp_path): @pytest.mark.parametrize("cargo_target_kind", ["test", "bench"]) -def test_build_plan_handles_test_and_bench_as_executables(tmp_path, cargo_target_kind: str): +def test_build_plan_handles_test_and_bench_as_executables(tmp_path, cargo_target_kind: CargoTargetKind): plan = HatchRustBuildPlan( module="project", path=tmp_path, From 8ca4cde9663ce69ec7347a4c996c424c8fa332c0 Mon Sep 17 00:00:00 2001 From: Tim Paine <3105306+timkpaine@users.noreply.github.com> Date: Sun, 11 Oct 2026 11:00:45 -0400 Subject: [PATCH 3/4] Use Python executable path for Windows type checks Signed-off-by: Tim Paine <3105306+timkpaine@users.noreply.github.com> --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 29b0177..19428b6 100644 --- a/Makefile +++ b/Makefile @@ -50,7 +50,7 @@ check-dist: ## check python sdist and wheel with check-dist check-dist -v check-types: ## check python types with ty - ty check --python $$(which python) + ty check --python "$$(python -c 'import sys; print(sys.executable)')" checks: check-dist check-types From 1ee19350f14cac244fc3ff9a66c6fc698a707663 Mon Sep 17 00:00:00 2001 From: Tim Paine <3105306+timkpaine@users.noreply.github.com> Date: Sun, 11 Oct 2026 11:35:26 -0400 Subject: [PATCH 4/4] Simplify type check command Signed-off-by: Tim Paine <3105306+timkpaine@users.noreply.github.com> --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 19428b6..261a367 100644 --- a/Makefile +++ b/Makefile @@ -50,7 +50,7 @@ check-dist: ## check python sdist and wheel with check-dist check-dist -v check-types: ## check python types with ty - ty check --python "$$(python -c 'import sys; print(sys.executable)')" + python -m ty check checks: check-dist check-types