Anki/pylib/hatch_build.py
Damien Elmes 9b287dc51a Python dependency/wheel tweaks
- Use --locked to assert that the lockfile won't change, so we need
to explicitly 'uv lock' when making changes. Still trying to get to
the bottom of why the lockfile sometimes has editable entries, which
break things when switching between platforms.
- Exclude __pycache__ from wheels
- Move the typing stubs to our dev deps
(https://github.com/ankitects/anki/pull/4074#pullrequestreview-2948088436)
2025-06-27 16:10:12 +07:00

50 lines
1.9 KiB
Python

# Copyright: Ankitects Pty Ltd and contributors
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import os
import platform
import sys
from pathlib import Path
from typing import Any, Dict
from hatchling.builders.hooks.plugin.interface import BuildHookInterface
class CustomBuildHook(BuildHookInterface):
"""Build hook to include compiled rsbridge from out/pylib."""
PLUGIN_NAME = "custom"
def initialize(self, version: str, build_data: Dict[str, Any]) -> None:
"""Initialize the build hook."""
force_include = build_data.setdefault("force_include", {})
# Set platform-specific wheel tag
if not (platform_tag := os.environ.get("ANKI_WHEEL_TAG")):
# On Windows, uv invokes this build hook during the initial uv sync,
# when the tag has not been declared by our build script.
return
build_data.setdefault("tag", platform_tag)
# Mark as non-pure Python since we include compiled extension
build_data["pure_python"] = False
# Look for generated files in out/pylib/anki
project_root = Path(self.root).parent
generated_root = project_root / "out" / "pylib" / "anki"
assert generated_root.exists(), "you should build with --wheel"
for path in generated_root.rglob("*"):
if path.is_file() and not self._should_exclude(path):
relative_path = path.relative_to(generated_root)
# Place files under anki/ in the distribution
dist_path = "anki" / relative_path
force_include[str(path)] = str(dist_path)
def _should_exclude(self, path: Path) -> bool:
"""Check if a file should be excluded from the wheel."""
# Exclude __pycache__
path_str = str(path)
if "/__pycache__/" in path_str:
return True
return False