Best practice to modify editable wheel
See original GitHub issueHi all, thanks for the fantastic work here.
Disclaimer: I feel like I might be pushing the limits of what hatchling
can reasonably be expected to support, but I’ll ask anyway!
I’m building a build hook plugin to support transpiling Jupyter notebooks into Python modules on build. This is done by generating some gitignore’d assets, and including them with force-include
.
I’d also like to support editable builds, where instead of generating any assets, the user is given an import hook.
Currently, this looks like:
def initialize(self, version, build_data):
if self.target_name == "wheel":
# For editable wheels, we don't want to build anything for Literary
# Instead, we just want to patch the final wheel to support the import hook
if version == "editable":
# Patch metadata constructor to inject dependency
wheel_config = self._BuildHookInterface__build_config
wheel_metadata_constructor = wheel_config.core_metadata_constructor
def core_metadata_constructor(metadata, extra_dependencies=()):
extra_dependencies += ("literary>=3.0.2",)
return wheel_metadata_constructor(metadata, extra_dependencies)
assert wheel_config.core_metadata_constructor is core_metadata_constructor
# We only want to generate files for standard wheels
elif version == "standard":
self._builder.build()
# Ensure generated files are included in wheel
build_data["force-include"] = {self._builder.generated_path: "/"}
def finalize(self, version, build_data, artifact):
# We can inject our editable support to wheels
if version != "editable":
return
# As we cannot edit the wheel, we'll create a temporary file
dst_fd, dst_path = tempfile.mkstemp()
# To patch-in support for Literary, we'll augment the existing editables
# support by appending to the first `.pth` created.
has_import_hook = False
with zipfile.ZipFile(artifact, "r") as src, zipfile.ZipFile(
dst_path, "w"
) as dst:
for info in src.infolist():
# If we've found a .pth file
if not has_import_hook and fnmatch.fnmatch(info.filename, "*.pth"):
# Patch-in Literary support
new_pth_contents = self._patch_editable_pth_support(
src.read(info).decode()
)
dst.writestr(info, new_pth_contents)
has_import_hook = True
else:
dst.writestr(info, src.read(info))
# Move new archive to replace existing artifact
shutil.move(dst_path, artifact)
As you can see, this is pretty bad. On the one hand, it’s hidden from the user, but it’s also using several name manged variables that I’m less fond of.
I think ideally I’d like for the ability to add custom lines / paths to the generated .pth
, and also to propose a set of additional dependencies for editable hooks. Do you think that this is within scope?
Issue Analytics
- State:
- Created a year ago
- Comments:14
Hi @ofek,
Thanks for the hard work here! #242 ended up being what I needed for my solution - I managed to move the
.pth
file to the dependency that gets installed for editable installs. However, I imagine that #245 would still be useful for people!I can close this issue now, I think, as you’ve added two very useful configuration points.
Cheers
part 2 https://github.com/pypa/hatch/pull/245
would your use case be satisfied now?