Suggestion: Add release submodule for import_hook
I would like a better way of requesting release builds of Rust code directly within Python. I know I can import rustimport.settings, then set compile_release_binaries to True, and import rustimport.import_hook, but that's annoying. Could a new submodule be added so that I can simply run import rustimport.release.import_hook and it would set compile_release_binaries for me? I can write the PR and change add it to the README if you agree, but I realise this may be somewhat unorthodox.
That's a cool idea. However, it might be confusing if a user (maybe in separate files) imports both, the normal import hook and the release mode import hook. This could lead to ambiguities that might be hard to spot/debug.
So we need some good way to handle this :thinking: – maybe by raising an exception in this case?
True, hadn't thought of that. I feel an exception is a little extreme: if I use the import hook in multiple places, having it raise an exception when I try to import the release import_hook somewhat defeats the purpose of having a quick way of switching to release mode, as I would have to modify all files using the import hook in order to use it.
As I don't think this is aimed at using release mode in production (your existing build command does that perfectly, and I don't see myself even keeping the rustimport import in production, only the final binary), we could log a warning whenever this import is used, something like "All rustimport binaries will be compiled in release mode across all files from now on".
I could also add an equivalent submodule to force debug mode (import rustimport.debug.import_hook) and raise an exception if both are imported. This would allow me to quickly force debug mode if I suspect something else is forcing release, and if I don't care, just use the normal import_hook.
All of this still leaves a situation in which a Rust file is imported in debug mode in one file (using the normal import_hook), then another file is imported in which the release hook is used, so the file is recompiled in release mode. It would then be compiled twice every time the program is run (as I understand it). I don't see any obvious way around this, but I think the same would happen if someone manually set compile_release_binaries in the other file, so does that matter?
Basically, we could have three states for compile_release_binaries: by default it's None (which would continue to work with existing logic), but it can be forced to True or False, in which case forcing it to the other state would raise an exception.
The way it works at the moment is this:
import rustimport.settings, rustimport.import_hook
import some_rust_extension # compiled in debug mode
rustimport.settings.compile_release_binaries = True
import some_rust_extension # not recompiled, as this module is already cached by python in sys.modules
import some_other_rust_extension # compiled in release mode
rustimport.settings.compile_release_binaries = False
import some_third_rust_module # compiled in debug mode again
This follows the standard python importing semantics, in which no module is ever imported twice. This would be the same way if we had a separate release import hook – i.e. once you import that import hook, all already imported extensions would not be recompiled in release mode, and all extensions you import afterwards would be in release mode. Basically, you could swap the 3rd line above with importing the release import hook and it would behave the exact same way for now.
Basically, we could have three states for compile_release_binaries: by default it's None (which would continue to work with existing logic), but it can be forced to True or False, in which case forcing it to the other state would raise an exception.
I'd prefer not to do so, as I like the opportunity we have at the moment, to import only a single module in release mode by toggling the setting on and off again (as in the example above).
we could log a warning whenever this import is used, something like "All rustimport binaries will be compiled in release mode across all files from now on".
That sounds good to me – you're right, a warning is definitely better than an exeption. However, I'd only log the warning if both import hooks (normal and release) are imported, if only the release import hook is imported, I don't see a point in the warning.
Also, structure wise, I'd prefer import rustimport.import_hook.release_mode to import rustimport.release.import_hook since this way we have all import hooks living within a single import_hook directory.
I'd be happy if you submit a PR for this :)