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..261a367 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 @@ -50,9 +50,9 @@ 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) + python -m ty check -checks: check-dist +checks: check-dist check-types # Alias check: checks 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, 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]