Skip to content

Commit

Permalink
Upgrade maturin (#9)
Browse files Browse the repository at this point in the history
  • Loading branch information
mbway authored Dec 7, 2024
1 parent 49f973b commit dddccd1
Show file tree
Hide file tree
Showing 31 changed files with 1,174 additions and 742 deletions.
8 changes: 4 additions & 4 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
rev: v5.0.0
hooks:
- id: check-yaml
- id: check-toml
- id: end-of-file-fixer
- id: trailing-whitespace
- id: mixed-line-ending
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.4.9
rev: v0.7.4
hooks:
- id: ruff-format
- id: ruff
args: [ --fix ]
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.10.0
rev: v1.13.0
hooks:
# note: mypy runs in an isolated environment and so has no access to third party packages
- id: mypy
Expand All @@ -26,6 +26,6 @@ repos:
hooks:
- id: codespell
- repo: https://github.com/igorshubovych/markdownlint-cli
rev: v0.41.0
rev: v0.42.0
hooks:
- id: markdownlint-fix
10 changes: 6 additions & 4 deletions src/maturin_import_hook/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,10 +191,12 @@ def _main() -> None:
install.add_argument(
"--user",
action="store_true",
help="whether to install into usercustomize.py instead of sitecustomize.py. "
"Note that usercustomize.py is shared between virtualenvs of the same interpreter version and is not loaded "
"unless the virtualenv is created with the `--system-site-packages` argument. Use `site info` to check "
"whether usercustomize.py is loaded the current interpreter.",
help=(
"whether to install into usercustomize.py instead of sitecustomize.py. "
"Note that usercustomize.py is shared between virtualenvs of the same interpreter version and is "
"not loaded unless the virtualenv is created with the `--system-site-packages` argument. "
"Use `site info` to check whether usercustomize.py is loaded the current interpreter."
),
)

uninstall = site_sub_actions.add_parser(
Expand Down
2 changes: 1 addition & 1 deletion src/maturin_import_hook/_building.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ def get_maturin_version(maturin_path: Path) -> tuple[int, int, int]:
if not success:
msg = f'running "{maturin_path} --version" failed'
raise MaturinError(msg)
match = re.fullmatch(r"maturin ([0-9]+)\.([0-9]+)\.([0-9]+)\n", output)
match = re.fullmatch(r"maturin ([0-9]+)\.([0-9]+)\.([0-9]+)(-.*)?\n", output)
if match is None:
msg = f'unexpected version string: "{output}"'
raise MaturinError(msg)
Expand Down
28 changes: 19 additions & 9 deletions src/maturin_import_hook/_resolve_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def get_value(self, keys: list[str], required_type: type[_T]) -> Optional[_T]:

def find_cargo_manifest(project_dir: Path) -> Optional[Path]:
pyproject_path = project_dir / "pyproject.toml"
if pyproject_path.exists():
if pyproject_path.is_file():
pyproject_data = pyproject_path.read_text()
if "manifest-path" in pyproject_data:
pyproject = _TomlFile.from_string(pyproject_path, pyproject_data)
Expand All @@ -69,17 +69,17 @@ def find_cargo_manifest(project_dir: Path) -> Optional[Path]:
return project_dir / relative_manifest_path

manifest_path = project_dir / "Cargo.toml"
if manifest_path.exists():
if manifest_path.is_file():
return manifest_path
manifest_path = project_dir / "rust/Cargo.toml"
if manifest_path.exists():
if manifest_path.is_file():
return manifest_path
return None


def is_maybe_maturin_project(project_dir: Path) -> bool:
def is_maybe_maturin_project(directory: Path) -> bool:
"""note: this function does not check if this really is a maturin project for simplicity."""
return (project_dir / "pyproject.toml").exists() and find_cargo_manifest(project_dir) is not None
return (directory / "pyproject.toml").is_file() and find_cargo_manifest(directory) is not None


class ProjectResolver:
Expand Down Expand Up @@ -142,7 +142,7 @@ def all_path_dependencies(self) -> list[Path]:
def _find_all_path_dependencies(immediate_path_dependencies: list[Path]) -> list[Path]:
if not immediate_path_dependencies:
return []
all_path_dependencies = set()
all_path_dependencies: set[Path] = set()
to_search = immediate_path_dependencies.copy()
while to_search:
dependency_project_dir = to_search.pop()
Expand Down Expand Up @@ -170,6 +170,9 @@ def _resolve_project(project_dir: Path) -> MaturinProject:
msg = "no pyproject.toml found"
raise _ProjectResolveError(msg)
pyproject = _TomlFile.load(pyproject_path)
if not _is_valid_pyproject(pyproject):
msg = "pyproject.toml is invalid (does not have required fields)"
raise _ProjectResolveError(msg)

manifest_path = find_cargo_manifest(project_dir)
if manifest_path is None:
Expand Down Expand Up @@ -203,6 +206,13 @@ def _resolve_project(project_dir: Path) -> MaturinProject:
)


def _is_valid_pyproject(pyproject: _TomlFile) -> bool:
"""in maturin serde is used to load into a `PyProjectToml` struct.
This function should match whether the toml would parse correctly"""
# it should be sufficient to check the required fields rather than match the serde parsing logic exactly
return pyproject.get_value(["build-system", "requires"], list) is not None


def _resolve_rust_module(python_dir: Path, module_name: str) -> tuple[Path, Path, str]:
"""This follows the same logic as project_layout.rs (ProjectLayout::determine).
Expand Down Expand Up @@ -244,11 +254,11 @@ def _resolve_module_name(pyproject: _TomlFile, cargo: _TomlFile) -> Optional[str


def _get_immediate_path_dependencies(manifest_dir_path: Path, cargo: _TomlFile) -> list[Path]:
path_dependencies = []
path_dependencies: list[Path] = []
for dependency in cargo.get_value_or_default(["dependencies"], dict, {}).values():
if isinstance(dependency, dict):
relative_path = dependency.get("path", None)
if relative_path is not None:
relative_path: Any = dependency.get("path", None)
if relative_path is not None and isinstance(relative_path, str):
path_dependencies.append((manifest_dir_path / relative_path).resolve())
return path_dependencies

Expand Down
4 changes: 3 additions & 1 deletion src/maturin_import_hook/project_importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ def find_maturin(self) -> Path:
return self._maturin_path

def invalidate_caches(self) -> None:
"""called by importlib.invalidate_caches()"""
"""called by `importlib.invalidate_caches()`"""
logger.info("clearing cache")
self._resolver.clear_cache()
_find_maturin_project_above.cache_clear()
Expand Down Expand Up @@ -172,6 +172,8 @@ def find_spec(
logger.info('rebuilt and loaded package "%s" in %.3fs', package_name, duration)
else:
logger.debug('loaded package "%s" in %.3fs', package_name, duration)
elif logger.isEnabledFor(logging.DEBUG):
logger.debug('%s did not find "%s"', type(self).__name__, package_name)
return spec

def _handle_reload(self, package_name: str, spec: ModuleSpec) -> ModuleSpec:
Expand Down
2 changes: 2 additions & 0 deletions src/maturin_import_hook/rust_file_importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,8 @@ def find_spec(
logger.info('rebuilt and loaded module "%s" in %.3fs', fullname, duration)
else:
logger.debug('loaded module "%s" in %.3fs', fullname, duration)
elif logger.isEnabledFor(logging.DEBUG):
logger.debug('%s did not find "%s"', type(self).__name__, fullname)

return spec

Expand Down
7 changes: 4 additions & 3 deletions src/maturin_import_hook/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ def to_args(self) -> list[str]:
class MaturinBuildSettings(MaturinSettings):
"""settings for `maturin build`."""

skip_auditwheel: bool = False
auditwheel: Optional[str] = None
zig: bool = False

@staticmethod
Expand All @@ -108,8 +108,9 @@ def supported_commands() -> set[str]:

def to_args(self) -> list[str]:
args = []
if self.skip_auditwheel:
args.append("--skip-auditwheel")
if self.auditwheel is not None:
args.append("--auditwheel")
args.append(self.auditwheel)
if self.zig:
args.append("--zig")
args.extend(super().to_args())
Expand Down
17 changes: 16 additions & 1 deletion tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,27 @@ To update maturin:

- update the submodule to the maturin commit you want to update to
- re-run the `package_resolver` to update `resolved.json` (see `package_resolver/README.md` for instructions)
- update `requirements.txt` to match the packages and versions used by the maturin ci (`.github/workflows.test.yml`)
- update `requirements.txt` to match the packages and versions installed by the maturin ci
(see `pip` and `uv` commands in `maturin/.github/workflows/test.yml`)
- check the `uniffi` package version listed in the `Cargo.toml` of any of the `uniffi-*`
test crates and update `uniffi-bindgen` in `requirements.txt` to match.
- check that no crates have been added to `test-crates` that should be excluded from the import hook tests.
If so, add them to `IGNORED_TEST_CRATES` in `common.py`
- upgrade the test packages in `test_import_hook/*_helpers`
- check what version of `pyo3` is used by the command: `maturin new --bindings pyo3`
- update the version check in the import hook to ensure it allows using the new version
- run the tests to ensure everything still works

Released versions of the import hook should use a tagged version of maturin, but during development, in order
to use a specific maturin commit:

- use `maturin @ git+https://github.com/PyO3/maturin@xxxxxxx` in `requirements.txt`
- where `xxxxxxx` is a git commit hash
- `export MATURIN_SETUP_ARGS="--features=scaffolding"` before running `runner.py`
- the `setup.py` of `maturin` uses this environment variable when building from source. the `scaffolding` feature
is required for `maturin new`.
- Make sure a cached built version of this commit is not available because `uv` doesn't know about the
environment variable. run `uv cache clean maturin` to remove any cached versions.

## Notes

Expand Down
2 changes: 1 addition & 1 deletion tests/maturin
Submodule maturin updated 158 files
Loading

0 comments on commit dddccd1

Please sign in to comment.