-
Notifications
You must be signed in to change notification settings - Fork 776
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
Declarative modules next steps #3900
Comments
Fantastic, thanks for creating this list! 👍 |
Possibly worth us remembering the discussion in #3919 (comment) to decide what is allowed to export before we declare stable and remove the feature gate. |
Some user feedback: I just upgraded to Of course you have all had a lot of discussion about this, and I don't understand most of the details. But from my perspective, the best course would be to bless declarative modules as the standard way of doing things and throw all that old It's not just that it's a nice feature. It's also that it might end up being on the migration path for a lot of users anyway. Moving from 20 to 21 raised several compiler warnings, and the only way I could figure out to silence all of them was to use a declarative module. |
Hey @nickdrozd, thanks for the feedback! I'm pleased you like these, I agree that imperative modules should be deprecated and replaced with these modules as soon as possible. This feature is probably the thing I've wanted most for PyO3 for the longest, except for the We could just call these stable in 0.21, but there are a couple of corner cases of unresolved design that I think could break people so I'd like to get these at least understood before we tell people it's stable. From the guide that we'll ship in 0.21:
|
Just to note against the alternative of 0.21 delaying until these design points are ready: so much is changing in 0.21 already that I'm quite keen to see the release finalised so that users can handle these. There's a lot of stuff beginning to pile up that I've asked to wait until 0.22 already, it would be good to unblock the development flow. If it turns out that lots of users need to update to declarative modules to solve compile issues, then I think probably we got something wrong with the design of the Bound API migration 😢. Hopefully the additional deprecation warnings we're shipping in 0.21 final compared to 0.21 beta will make the difference. |
I had a setup like this: #[pymodule]
fn rust_stuff(py: Python, m: &PyModule) -> PyResult<()> {
// ...
} After switching to
I don't know anything about (I am using PyO3 to rewrite a Python project in Rust using a bottom-up leaf-first approach. So Python calls into Rust, but the Rust code never interacts with Python except through |
Do you think it would have helped if these deprecation messages link you to the PyO3 migration guide? |
I check the migration guide, but it doesn't say anything about how to update |
#[pymodule]
mod submodule {
#[pyfunction] // ■■ consider importing one of these items: `use crate::pyfunction; `, `use pyo3::pyfunction; `
pub fn triple(x: usize) -> usize { // ■ failed to resolve: function `triple` is not a crate or module function `triple`
x * 3
}
} error: cannot find attribute `pyfunction` in this scope
--> src/lib.rs:24:11
|
24 | #[pyfunction]
| ^^^^^^^^^^
|
help: consider importing one of these items
|
24 + use crate::pyfunction;
|
24 + use pyo3::pyfunction;
|
error[E0433]: failed to resolve: function `triple` is not a crate or module
--> src/lib.rs:25:16
|
25 | pub fn triple(x: usize) -> usize {
| ^^^^^^ function `triple` is not a crate or module
Ok, nothing, this was at most a documentation issue, I was just missing a This works perfectly fine: #[pymodule]
mod submodule {
use pyo3::prelude::*;
#[pyfunction]
pub fn triple(x: usize) -> usize {
x * 3
}
} |
Moreover, something weird happens with classes. This is working as expected: use pyo3::prelude::*;
mod othermod {
use pyo3::prelude::*;
#[pyfunction]
pub fn triple(x: usize) -> usize {
x * 3
}
}
#[pymodule]
mod myext {
#[pymodule_export]
use super::othermod::triple;
} but this is not: use pyo3::prelude::*;
mod othermod {
use pyo3::prelude::*;
#[pyclass] // ■ private associated constant defined here
pub struct Unit;
}
#[pymodule] // ■■ associated constant `_PYO3_DEF` is private private associated constant
mod myext {
#[pymodule_export]
use super::othermod::Unit;
} error[E0624]: associated constant `_PYO3_DEF` is private
--> src/lib.rs:10:1
|
6 | #[pyclass]
| ---------- private associated constant defined here
...
10 | #[pymodule]
| ^^^^^^^^^^^ private associated constant
|
= note: this error originates in the attribute macro `pymodule` (in Nightly builds, run with -Z macro-backtrace for more info) |
@alecandido I think this bug is #4036. |
Oh, thanks. I actually searched for https://github.com/search?q=repo%3APyO3%2Fpyo3+PYO3_DEF&type=issues Sorry... |
Just a remark: exception created with |
With the current code, yes! I would tend to think the long term solution is #295 but it seems quite a bit of work. An other slighty hacky approach might be to make |
Documentation on the module are ignored: #[pymodule]
/// This is ignored
pub mod foo {
} |
@Stargateur Thank you for reporting this! It is weird, we have a test covering exactly this. May you share a bit more how you load the module and try to extract the documentation? |
my MCE is as follow: //! Foo
#![warn(missing_docs)]
use pyo3::pymodule;
#[pymodule]
/// This doesn't remove rustc warning about missing docs
pub mod foo {
} [package]
name = "foo"
version = "0.0.0"
edition = "2021"
[dependencies.pyo3]
version = "0.21.2"
features = [
"experimental-declarative-modules",
]
And |
@Stargateur Thank you! So, I guess the |
It may be possible that "imperative" module declarations will get deprecated, according to [1], so switch to declarative syntax even though it means more boilerplate due to missing `#[pymodule_export]` capability on glob `use`s. [1]: PyO3/pyo3#3900
declarative modules with the
#[pymodule] mod X {}
syntax is now merged behind theexperimental-declarative-modules
syntax (#3815).The next steps are:
Before v0.21:
#[pyclass]
,#[pyfunction]
and#[pymodule]
that are inlined in the modules (in progress in Allow inline struct, enum, fn and mod inside of declarative modules #3902)Before v0.22:
sys.modules
automatically i.e. fix ModuleNotFoundError: No module named 'supermodule.submodule'; 'supermodule' is not a package #759 by default#[pymodule_init]
function to return()
orPyResult<()>
PyAddToModule
trait is currently relying onPyTypeInfo::type_object_bound
. This function panics when module initialization fail. It would be better to throw an exception instead like inPyModuleMethods::add_class
(in progress in PyAddToModule: Properly propagate initialization error #3919)#[pymodule_data]
as a way to create a per-module data mechanism (might be postpone to later)#[pymodule_export] const FOO = ...;
to add constants to the modulesmodule
parameter of#[pyclass]
usages inside of decarative modules. Automated module= field creation in declarative modules #4213experimental-declarative-modules
feature flag to allow using declarative modules by defaultBefore v0.23 (or later?):
#[pyfn]
The text was updated successfully, but these errors were encountered: