Skip to content

Commit

Permalink
Add a Python import hook
Browse files Browse the repository at this point in the history
  • Loading branch information
messense committed Dec 3, 2021
1 parent b1d11a5 commit cc4c0fd
Showing 1 changed file with 79 additions and 0 deletions.
79 changes: 79 additions & 0 deletions maturin/import_hook.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import importlib
import importlib.util
from importlib import abc
import os
import pathlib
import sys
import subprocess

import toml


class Importer(abc.MetaPathFinder):
"""A meta-path importer for the maturin based packages"""

def find_spec(self, fullname, path, target=None):
if fullname in sys.modules:
return
mod_parts = fullname.split(".")
module_name = mod_parts[-1]
cargo_toml = pathlib.Path(os.getcwd()) / "Cargo.toml"
if os.path.exists(cargo_toml):
with open(cargo_toml) as f:
cargo = toml.load(f)
package_name = cargo.get("package", {}).get("name")
if (
package_name == module_name
or package_name.replace("-", "_") == module_name
):
build_module(cargo_toml)
loader = Loader(fullname)
return importlib.util.spec_from_loader(fullname, loader)


class Loader(abc.Loader):
def __init__(self, fullname):
self.fullname = fullname

def load_module(self, fullname):
return importlib.import_module(self.fullname)


def build_module(manifest_path):
command = ["maturin", "develop", "-m", manifest_path]
result = subprocess.run(command, stdout=subprocess.PIPE)
sys.stdout.buffer.write(result.stdout)
sys.stdout.flush()
if result.returncode != 0:
sys.stderr.write(
f"Error: command {command} returned non-zero exit status {result.returncode}\n"
)
raise ImportError("Failed to build module with maturin")


def _have_importer():
for importer in sys.meta_path:
if isinstance(importer, Importer):
return True
return False


def install():
"""
Install the import hook.
"""
if _have_importer():
return
importer = Importer()
sys.meta_path.append(importer)
return importer


def uninstall(importer):
"""
Uninstall the import hook.
"""
try:
sys.meta_path.remove(importer)
except ValueError:
pass

0 comments on commit cc4c0fd

Please sign in to comment.