Trying to build modules hierarchy with pyo3 and this code
pub mod types;
pub mod sources;
use pyo3::prelude::*;
use pyo3::wrap_pymodule;
use sources::file::{find_days, read_many, read_one};
#[pymodule]
fn file(_py: Python, m: &PyModule) -> PyResult<()> {
#[pyfn(m, "find_days")]
fn find_days_py(_py: Python, dir: String) -> PyResult<Vec<String>> {
let out = find_days(&dir)?;
Ok(out.iter().map(|x| String::from(x.to_str().unwrap())).collect())
}
Ok(())
}
#[pymodule]
fn sources(_py: Python, m: &PyModule) -> PyResult<()> {
m.add_wrapped(wrap_pymodule!(file))?;
Ok(())
}
#[pymodule]
fn cstuff(_py: Python, m: &PyModule) -> PyResult<()> {
m.add_wrapped(wrap_pymodule!(sources))?;
// m.add("__path__", vec![""])?;
Ok(())
}
Code builds and works fine, except that when I try to import it, I'm getting this error
In [1]: import cstuff.sources.file
---------------------------------------------------------------------------
ModuleNotFoundError Traceback (most recent call last)
<ipython-input-1-97430c5317d9> in <module>
----> 1 import cstuff.sources.file
ModuleNotFoundError: No module named 'cstuff.sources'; 'cstuff' is not a package
From what I understand from python documentation, module is a package if it have __path__
attribute.
I can add that with m.add("__path__", vec![""])?;
, after this import
works as expected but only when python is launched from the dir with .so
file, which is expected.
The problem is that I don't know __path__
in advance. How to fix that, is there any way to force python to set __path__
?