diff --git a/hatch_rs/plugin.py b/hatch_rs/plugin.py index 97e1310..4f7dc77 100644 --- a/hatch_rs/plugin.py +++ b/hatch_rs/plugin.py @@ -98,7 +98,10 @@ def initialize(self, version: str, build_data: dict[str, Any]) -> None: os_name = "linux" else: os_name = "win" - build_data["tag"] = f"cp{version_major}{version_minor}-cp{version_major}{version_minor}-{os_name}_{machine}" + if config.abi3: + build_data["tag"] = f"cp{version_major}{version_minor}-abi3-{os_name}_{machine}" + else: + build_data["tag"] = f"cp{version_major}{version_minor}-cp{version_major}{version_minor}-{os_name}_{machine}" # force include libraries for path in Path(".").rglob("*"): diff --git a/hatch_rs/structs.py b/hatch_rs/structs.py index 0e00bde..e270ca7 100644 --- a/hatch_rs/structs.py +++ b/hatch_rs/structs.py @@ -30,6 +30,11 @@ class HatchRustBuildConfig(BaseModel): module: str = Field(description="Python module name for the Rust extension.") path: Optional[Path] = Field(default=None, description="Path to the project root directory.") + abi3: bool = Field( + default=False, + description="If True, build the extension with Python's ABI3 compatibility.", + ) + target: Optional[str] = Field( default=None, description="Target platform for the build. If not specified, it will be determined automatically.", @@ -147,13 +152,19 @@ def execute(self): # Copy each file to the current directory if sys_platform == "win32": - library_name = f"{self.module}\\{file_name}.pyd" + if self.abi3: + library_name = f"{self.module}\\{file_name}.abi3.pyd" + else: + library_name = f"{self.module}\\{file_name}.pyd" self._libraries.append(library_name) copy_command = f"copy {file} {cwd}\\{library_name}" else: if which("cp") is None: raise EnvironmentError("cp command not found. Ensure it is installed and available in PATH.") - library_name = f"{self.module}/{file_name}.so" + if self.abi3: + library_name = f"{self.module}/{file_name}.abi3.so" + else: + library_name = f"{self.module}/{file_name}.so" self._libraries.append(library_name) copy_command = f"cp -f {file} {cwd}/{library_name}" system_call(copy_command) diff --git a/hatch_rs/tests/test_project_basic/pyproject.toml b/hatch_rs/tests/test_project_basic/pyproject.toml index 62414f5..8f39c35 100644 --- a/hatch_rs/tests/test_project_basic/pyproject.toml +++ b/hatch_rs/tests/test_project_basic/pyproject.toml @@ -30,5 +30,6 @@ packages = ["project"] [tool.hatch.build.hooks.hatch-rs] verbose = true +abi3 = true path = "." module = "project" diff --git a/hatch_rs/tests/test_projects.py b/hatch_rs/tests/test_projects.py index 78bb8cb..399825d 100644 --- a/hatch_rs/tests/test_projects.py +++ b/hatch_rs/tests/test_projects.py @@ -35,9 +35,9 @@ def test_basic(self, project_folder): # assert built if platform == "win32": - assert "project.pyd" in listdir(f"hatch_rs/tests/{project_folder}/project") + assert "project.abi3.pyd" in listdir(f"hatch_rs/tests/{project_folder}/project") else: - assert "project.so" in listdir(f"hatch_rs/tests/{project_folder}/project") + assert "project.abi3.so" in listdir(f"hatch_rs/tests/{project_folder}/project") # dist check_call( @@ -51,7 +51,7 @@ def test_basic(self, project_folder): cwd=f"hatch_rs/tests/{project_folder}", ) - assert f"cp3{version_info.minor}-cp3{version_info.minor}" in listdir(f"hatch_rs/tests/{project_folder}/dist")[0] + assert f"cp3{version_info.minor}-abi3" in listdir(f"hatch_rs/tests/{project_folder}/dist")[0] # import here = Path(__file__).parent / project_folder