Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/reference/configs.md
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ print(mk_skbuild_docs())

```{eval-rst}
.. confval:: editable.mode
:type: ``"redirect" | "inplace"``
:type: ``"redirect" | "inplace" | "build-dir"``
:default: "redirect"

Select the editable mode to use. Can be "redirect" (default) or "inplace".
Expand Down
33 changes: 32 additions & 1 deletion src/scikit_build_core/build/_editable.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,44 @@
if typing.TYPE_CHECKING:
from collections.abc import Sequence

__all__ = ["editable_redirect", "libdir_to_installed", "mapping_to_modules"]
__all__ = [
"editable_build_dir",
"editable_redirect",
"libdir_to_installed",
"mapping_to_modules",
]


def __dir__() -> list[str]:
return __all__


def editable_build_dir(
*,
source_files: dict[str, str],
) -> str:
"""
Prepare the contents of the _editable_redirect.py file as build-dir mode.
"""

# We can reuse the `_editable_redirect.py` file without the rebuild/install
# feature and providing only source files to map.
editable_py = resources / "_editable_redirect.py"
editable_txt: str = editable_py.read_text(encoding="utf-8")

# Wheel_files are always empty here.
wheel_files: dict[str, str] = {}

arguments = (
source_files, # known_source_files
wheel_files, # known_wheel_files
None, # path
)
arguments_str = ", ".join(repr(x) for x in arguments)
editable_txt += f"\n\ninstall({arguments_str})\n"
return editable_txt


def editable_redirect(
*,
modules: dict[str, str],
Expand Down
44 changes: 32 additions & 12 deletions src/scikit_build_core/build/wheel.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,12 @@
from ..errors import FailedLiveProcessError
from ..format import pyproject_format
from ..settings.skbuild_read_settings import SettingsReader
from ._editable import editable_redirect, libdir_to_installed, mapping_to_modules
from ._editable import (
editable_build_dir,
editable_redirect,
libdir_to_installed,
mapping_to_modules,
)
from ._init import setup_logging
from ._pathutil import (
packages_to_file_mapping,
Expand Down Expand Up @@ -56,22 +61,36 @@ def _make_editable(
settings: ScikitBuildSettings,
wheel: WheelWriter,
packages: Iterable[str],
mode: Literal["redirect", "inplace", "build-dir"],
) -> None:
modules = mapping_to_modules(mapping, libdir)
installed = libdir_to_installed(libdir)
if settings.wheel.install_dir.startswith("/"):
msg = "Editable installs cannot rebuild an absolute wheel.install-dir. Use an override to change if needed."
raise AssertionError(msg)
editable_txt = editable_redirect(
modules=modules,
installed=installed,
reload_dir=reload_dir,
rebuild=settings.editable.rebuild,
verbose=settings.editable.verbose,
build_options=build_options,
install_options=install_options,
install_dir=settings.wheel.install_dir,
)
if mode == "redirect":
editable_txt = editable_redirect(
modules=modules,
installed=installed,
reload_dir=reload_dir,
rebuild=settings.editable.rebuild,
verbose=settings.editable.verbose,
build_options=build_options,
install_options=install_options,
install_dir=settings.wheel.install_dir,
)
elif mode == "build-dir":
if not settings.build_dir:
msg = "Editable mode build-dir must have the build-dir option set."
raise ValueError(msg)
source_files = modules
# TODO: get the source files from the build-dir
editable_txt = editable_build_dir(
source_files=source_files,
)
else:
msg = f"Unexpected editable mode used: {mode}"
raise NotImplementedError(msg)

wheel.writestr(
f"_{name}_editable.py",
Expand Down Expand Up @@ -500,7 +519,7 @@ def _build_wheel_impl_impl(
str_pkgs = (
str(Path.cwd().joinpath(p).parent.resolve()) for p in packages.values()
)
if editable and settings.editable.mode == "redirect":
if editable and settings.editable.mode in ("redirect", "build-dir"):
reload_dir = build_dir.resolve() if settings.build_dir else None

_make_editable(
Expand All @@ -513,6 +532,7 @@ def _build_wheel_impl_impl(
wheel=wheel,
name=normalized_name,
packages=str_pkgs,
mode=settings.editable.mode,
)
elif editable and settings.editable.mode == "inplace":
if not packages:
Expand Down
3 changes: 2 additions & 1 deletion src/scikit_build_core/resources/scikit-build.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,8 @@
"mode": {
"enum": [
"redirect",
"inplace"
"inplace",
"build-dir"
],
"default": "redirect",
"description": "Select the editable mode to use. Can be \"redirect\" (default) or \"inplace\"."
Expand Down
2 changes: 1 addition & 1 deletion src/scikit_build_core/settings/skbuild_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ class BackportSettings:

@dataclasses.dataclass
class EditableSettings:
mode: Literal["redirect", "inplace"] = "redirect"
mode: Literal["redirect", "inplace", "build-dir"] = "redirect"
"""
Select the editable mode to use. Can be "redirect" (default) or "inplace".
"""
Expand Down
Loading