-
-
Notifications
You must be signed in to change notification settings - Fork 277
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improved import hook #1748
Improved import hook #1748
Conversation
✅ Deploy Preview for maturin-guide ready!Built without sensitive environment variables
To edit notification comments on pull requests, go to your Netlify site configuration. |
35872a1
to
0770262
Compare
0770262
to
e4cc108
Compare
e4cc108
to
ca62147
Compare
tests/common/import_hook.rs
Outdated
|
||
let (venv_dir, python) = create_virtualenv(virtualenv_name, Some(python)).unwrap(); | ||
|
||
println!("installing maturin binary into virtualenv"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if this is the best way of making the maturin
binary available to the python tests on the CI but currently they fail without this.
I tried installing with pip install .
but that seems to install a release binary from pypi or something because maturin new
was not available
Thanks for the PR and detailed write-up, this is a large PR so review may take a while. |
369ab21
to
1fa2b38
Compare
1fa2b38
to
1be2370
Compare
I have fixed the CI tests that fail because of issues with the import hook and I now clear up the temporary I have reviewed my own PR and made some changes based on that. There are more options |
I'm worried the new test case takes too much time to run.
|
I knew the tests would take a while but each one was very necessary during development to get the logic just right. I think they will be very useful during maintenance to catch any regressions but I agree that they aren't fast. These are the options I can think of:
|
|
I fixed the main test failure and discovered and fixed some more. Setting up github actions on my fork was useful as it allowed me to iterate faster with this. The issue that neither of us could replicate on our machines turned out to simply be the lock timing out if compilation of the project takes too long. This only happened on the CI when running many tests in parallel and without a populated sccache. The old timeout was 2 minutes. I kept this default (with a more informative message so the user can raise it if they need to) but raised the timeout to 10 minutes for the tests that are supposed to wait on the lock (so the parallel import tests). Perhaps the default timeout should be raised to something like 10 minutes? I'm not sure what the best default would be but I don't think an infinite timeout as the default is a good idea. The Cirrus CI tests are all failing and I think the machine is just getting overloaded so I'm skipping the import hook tests on that CI for now. The tests on my fork now all pass (including on MacOS): https://github.com/mbway/maturin/actions/runs/7402918125 Summary of other things fixed/changed
|
The remaining issues have been fixed. The remaining CI failures seem to just be overloaded machines or something else unrelated to the import hook. So I suppose the PR is ready for review now :) The outstanding improvements/changes I can think of are:
|
I'm fine with extracting the import hook out to a separate package, I'd also want to put it in a separate repository so the slow CI run time won't be an issue for |
Ok, so what do you think are the next steps? It sounds like you are happy to have the import hook associated with maturin, so would the pypi package and repo be called My email is on my profile if it would be better to continue the conversation there |
Sorry for the late reply, I've created https://github.com/PyO3/maturin-import-hook, let's move the import hook code there. |
superseded by PyO3/maturin-import-hook#1 |
I am working towards integrating rust into a python codebase and one of the main blockers is the lack of a comprehensive
import hook for automatically recompiling rust projects that have been installed in editable / unpacked mode.
To that end I have created a new import hook for maturin that I hope should cover most reasonable use cases and be
robust to many edge cases. I have written a fairly comprehensive test suite to ensure that the import hook is working
in many situations. I hope to upstream this new hook if possible.
Overview
The new import hook is mostly compatible with the old one (see the comparison section below) but is also usable in
many more situations:
.rs
files and import themforce_rebuild
optioninstall_new_packages
optionvery confusing as well as being quite limiting
pytest-xdist
.rs
importer separatelyLimitations and Future Improvements
I wrote this new hook in python because that is what was used previously but implementing in rust may have some
advantages. Namely, re-using the project resolving code instead of re-implementing it in python and probably being
able to detect changed projects more accurately and quickly. Although I find the performance to be reasonable in
the 'unchanged' case already.
The import hook works around an issue where I am usingproject_name-0.0.0.dist-info/direct_url.json
tofollow editable installed packages back to the project source code in the 'pure' package case. When projects are
installed with
pip install -e
afile://
URL is written todirect_url.json
that points to the project directorybut when installed with
maturin develop
thedirect_url.json
file points to the temporary wheel that was createdduring installation. I would be willing to look into fixing this issue by having
maturin
write the required valuesdirectly instead of applying a fix afterward. This also means existing pure packages installed with
maturin develop
won't rebuild with the import hook until this is fixed.
edit: this has now been fixed in this PR and
maturin develop
now creates editable installs.The project change detection probably isn't perfect. A potential improvement might be to load
.gitignore
and excludeignored files when deciding whether to rebuild. There are probably also edge cases of packages relying on data outside
the project directory which I have not considered yet.
The single
.rs
file import is currently missing some features offered by alternatives such asrustimport but similar features could be added in future if there is demand.
If maturin was able to create an 'unpacked' wheel or just write the extension module binary somewhere that may be
more efficient than creating a wheel then unzipping it.
Background and comparison
The old import hook supports the following scenarios:
maturin develop
to build and install or re-install the projectinto the active environment
name as the project it contains
maturin develop
to build and install or re-install the projectinto the active environment
.rs
file$PWD/build
and installs or re-installs theproject into the active environment
The old import hook is much more limited in the situations it can be used for. It isn't a fair comparison but the old
import hook only passes 4/84 of the tests (and not usually because they fail on the assertions that are looking for log
outputs specific to the new hook)
Old scenario 1 is expanded upon with the new import hook because it detects the project from any subdirectory within
the project instead of just at the root and works regardless of what the current working directory is (which fits
with how imports of regular packages takes place).
Old Scenario 2 is not supported by the new hook because I decided the added complexity of being able to support
this feature well outweighs the usefulness. I would suggest that installing the project in editable mode before
using the hook is a reasonable compromise.
Old scenario 3 is supported by the new rust file import hook but again is improved to not rely on the current
working directory. The old hook also had limitations like not being able to support multiple
.rs
files with the samename but in different packages.