-
-
Notifications
You must be signed in to change notification settings - Fork 278
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
Complex Python + Rust layout #1372
Comments
I tried to carefully look for issues and discussions, sorry if I missed something already existing... |
IMO maturin is designed specified for bridging Rust and Python, so we didn't try to support packaging multi-package Python project.
We can certainly support this, but I wonder if it's better to just keep extension modules simple and package pure Python module separately? It'd simplify the whole setup. And IMO
You can use the |
Ok, thank you, this is enough to solve this part :)
That I accept as a useful advice, but at the moment I can't choose. The package is already existing this way, so, in order to minimize the migration cost, I need to support current layout. However, I guess it does not hurt to In any case, I modified the |
I will take a look after recovering from covid soon. |
Thank you! |
+1, rest well and hope you have a swift recovery @messense! |
I think we can start with a conservative approach by providing a [tool.maturin]
python-packages = ["foo", "bar"] What do you think? @alecandido Implemented in #1378 |
personally, i'd strongly favor a one top level package per wheel rule, where the package has the same name as the wheel. the main problem is that we have otherwise no control and no introspection which packages get installed through a wheel, and there might even be silent overwrites (this is already a problem currently, as with the bson example). i know it's cumbersome to manage multiple local wheels, but i think that's better solved by make/nox/etc combining multiple tools. |
I would say that the conservative approach is perfect also in the long-run: as you said, and @konstin remarked, the same-named single package per wheel is a simpler layout with less surprises, and it should be favored (it is already enough counter-intuitive to Consider that, in some cases, the overwriting might also be explicit, e.g. with drop-in replacements (consider the example of |
I think a |
For me, |
1378: Add support for packaging multiple pure Python packages r=messense a=messense Implements #1372 (comment) Co-authored-by: messense <messense@icloud.com>
Somehow they are still undetected, but maybe I'm doing something wrong:
https://github.com/AleCandido/atuin/tree/6b54b627ea367ebc54729a4f388e7c0779235737/full E.g. should I specify the whole path in the |
src layout requires mixed Rust/Python project(for the main Rust extension module), so you'll need to add a |
The problem is not |
Please, do give it a try instead of making false assumptions. $ RUST_LOG=maturin=debug maturin build -o dist
2022-12-29T22:36:45.462662Z DEBUG maturin::project_layout: Found pyproject.toml in working directory at "/Users/messense/Projects/atuin/full/pyproject.toml"
2022-12-29T22:36:45.473200Z DEBUG maturin::project_layout: Using cargo manifest path from pyproject.toml "rust/tphon/Cargo.toml"
2022-12-29T22:36:45.475894Z DEBUG maturin::project_layout: Resolving cargo metadata from "/Users/messense/Projects/atuin/full/rust/tphon/Cargo.toml"
2022-12-29T22:36:45.535189Z DEBUG maturin::project_layout: Project layout resolved project_root=/Users/messense/Projects/atuin/full python_dir=/Users/messense/Projects/atuin/full/src rust_module=/Users/messense/Projects/atuin/full/src/tphon python_module=/Users/messense/Projects/atuin/full/src/tphon extension_name=tphon
🍹 Building a mixed python/rust project
🔗 Found pyo3 bindings
🐍 Found CPython 3.11 at /Users/messense/.pyenv/versions/3.11.0/bin/python3
2022-12-29T22:36:45.688591Z DEBUG maturin::compile: Setting additional linker args for macOS: ["-C", "link-arg=-undefined", "-C", "link-arg=dynamic_lookup", "-C", "link-args=-Wl,-install_name,@rpath/tphon.cpython-311-darwin.so"]
2022-12-29T22:36:45.718421Z DEBUG maturin::compile: Running "cargo" "rustc" "--manifest-path" "/Users/messense/Projects/atuin/full/rust/tphon/Cargo.toml" "--message-format" "json" "--lib" "--" "-C" "link-arg=-undefined" "-C" "link-arg=dynamic_lookup" "-C" "link-args=-Wl,-install_name,@rpath/tphon.cpython-311-darwin.so"
Finished dev [unoptimized + debuginfo] target(s) in 0.03s
⚠️ Warning: Couldn't find the symbol `PyInit_tphon` in the native library. Python will fail to import this module. If you're using pyo3, check that `#[pymodule]` uses `tphon` as module name
2022-12-29T22:36:45.881313Z DEBUG maturin::module_writer: Adding tphon-0.1.0.dist-info/METADATA
2022-12-29T22:36:45.882770Z DEBUG maturin::module_writer: Adding tphon-0.1.0.dist-info/WHEEL
2022-12-29T22:36:45.886970Z DEBUG maturin::module_writer: Adding tphon/__init__.py from /Users/messense/Projects/atuin/full/src/tphon/__init__.py
2022-12-29T22:36:45.888885Z DEBUG maturin::module_writer: Adding jerakeen/__init__.py from /Users/messense/Projects/atuin/full/src/jerakeen/__init__.py
2022-12-29T22:36:45.890923Z DEBUG maturin::module_writer: Adding tubul/__init__.py from /Users/messense/Projects/atuin/full/src/tubul/__init__.py
2022-12-29T22:36:45.891180Z DEBUG maturin::module_writer: Adding tphon/tphon.cpython-311-darwin.so from /Users/messense/Projects/atuin/full/rust/target/debug/maturin/libtphon.dylib
2022-12-29T22:36:45.982344Z DEBUG maturin::module_writer: Adding tphon-0.1.0.dist-info/RECORD
📦 Built wheel for CPython 3.11 to dist/tphon-0.1.0-cp311-cp311-macosx_11_0_arm64.whl |
Anyway, I've opened #1380 to allow detecting src-layout when the main Rust extension module is a pure Rust project. |
I'm sorry if I missed something, but I actually gave a try. I didn't try to run with
Same output without To complete the report:
and the logs
For convenience, I added the commit to the demo project alecandido/atuin@fb8073d. |
Moreover, you were definitely using an old commit, since in alecandido/atuin@6b54b62 I also changed the name of the module function in Can you give me the commit you used, and the |
Ok, so it's a misunderstanding, I mean this by mkdir src/tphon
touch src/tphon/__init__.py
|
Ok, I managed to see it working :D But there was even one extra step required (I inferred from your logs): the project name should be the same of the Rust module, implemented in alecandido/atuin@d2fdec8 In any case, this is not really a limitation for myself: if I want a crate with a different name I can always put a "bridge" crate for the bindings with the same name of the project. |
Now this isn't required anymore in 0.14.8b2, a pure Rust project should just work. |
Thank you, it works perfectly! |
v0.14.8 is out. |
At the moment, I have a Python distribution package managed by Poetry, and I'd like to implement one of its modules in Rust.
On one side, I already had successful and pleasant experience using
maturin
, but I also like Poetry environment management, development dependencies, and lock files.I already had a look into issues and discussions, and found out that the two things are not incompatible: what I like of Poetry is not the build backend (i.e.
poetry-core
), but everything else.Following #1246, I'm willing to switch build backend from
poetry-core
tomaturin
, while retaining Poetry for development.Unfortunately, my package is already more complex than the proposed layouts, and I'd like to also introduce an extended Rust layout.
In the following, I will outline the two levels of support I'm looking for: the first consist in better integration with pretty standard Python layout (and possibly Poetry, but I believe this not to be
maturin
's responsibility), the second is an extended Rust layout, yet not departing from standard practices.In order to clarify, I tried to collect the two layouts in a dedicated repo:
https://github.com/AleCandido/atuin
Multi-package Python
At the moment, my current repository contains a single Python distribution package, but multiple import packages.
I tried to follow the advice in #1246, retaining
[tool.poetry]
, but implementing the src layout.In the repo, this is done in the
alternate
folder.With this layout, most of the expected workflow works smoothly, i.e.:
[tools.poetry]
section)poetry run maturin develop
to recompile the Rust part and install in developmentpoetry run maturin build
The few places in which this is falling short are:
maturin
is currently not packaging the extra Python import packagespoetry build
to work similar topip wheel ...
, but it isn't, since it is not invoking the build backend)It seems like nor PEP 517 neither PEP 621 define any way to specify multiple import packages, so I'd suggest to detect multiple folders in the
src
directory, and check they contain a top-level__init__.py
file.Rust workspace
One of the reasons to switch to Rust was to release this part with API for a different language (i.e. make a Rust crate), and possibly provide C bindings as well.
This is more comfortably developed in distinct crates, and multiple crates might be useful for further use cases.
I do not ant all of them to be packaged by
maturin
, since a single one will contain the Python package in the end, but I'd like to develop them altogether in as single workspace.So, what I'd like from
maturin
, and it doesn't seem to be currently possible, is to locate the crate inside a workspace contained in the samerust
directory specified in the alternate layout.In the repo, this is attempted in the
workspace
folder.In particular, the one presented in this folder is the full layout with two import packages and two crates:
tubul
, depending ontphon
package resulting from the corresponding cratejerakeen
, providing some further utilities, and depending ontubul
maturin
istphon
, as said before, then on its turn depends onberilia
, that is the crate expected to do the heavy lift, and it has no dependence on any other code contained in the packageberilia
in particular does not have to be known tomaturin
, but it is just used as a path dependency oftphon
, that will be resolved by Cargo during compilation.I'd like to release
berilia
as a stand-alone crate on https://crates.io, with no trace of Python packaging.I know I wrote a lengthy issue, and it might be not so straightforward to implement. However, I expect this not to be incredibly complex: it essentially boils down to add further import packages on the Python side, and recognize a nested crate.
If the project makes sense, I'd be happy to provide some help (even a full proposal in a PR) to implement this, if possible with little guidance.
The text was updated successfully, but these errors were encountered: