Mercurial > public > mercurial-scm > hg
annotate rust/hg-pyo3/src/util.rs @ 52407:c5128c541021
rust-pyo3: facility for submodule registration, using it for dagop
It turns out that PyO3 has the exact same problem that we encountered
long ago with rust-cpython. The only difference is that the value
of `__name__` is not within the `mercurial` package at this point of
registration.
We reimplement the solution (equivalent to the suggestions in PyO3
issue tracker anyway), this time in a generic module to limit the
amount of boilerplate in subsequent applications.
author | Georges Racinet <georges.racinet@cloudcrane.io> |
---|---|
date | Fri, 29 Nov 2024 23:47:37 +0100 |
parents | |
children | 42b219a1404a |
rev | line source |
---|---|
52407
c5128c541021
rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
1 use pyo3::prelude::*; |
c5128c541021
rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
2 use pyo3::types::PyDict; |
c5128c541021
rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
3 /// Create the module, with `__package__` given from parent |
c5128c541021
rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
4 /// |
c5128c541021
rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
5 /// According to PyO3 documentation, which links to |
c5128c541021
rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
6 /// <https://github.com/PyO3/pyo3/issues/1517>, the same convoluted |
c5128c541021
rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
7 /// write to sys.modules has to be made as with the `cpython` crate. |
c5128c541021
rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
8 pub(crate) fn new_submodule<'py>( |
c5128c541021
rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
9 py: Python<'py>, |
c5128c541021
rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
10 package_name: &str, |
c5128c541021
rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
11 name: &str, |
c5128c541021
rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
12 ) -> PyResult<Bound<'py, PyModule>> { |
c5128c541021
rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
13 let dotted_name = &format!("{}.{}", package_name, name); |
c5128c541021
rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
14 let m = PyModule::new(py, name)?; |
c5128c541021
rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
15 m.add("__package__", package_name)?; |
c5128c541021
rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
16 m.add("__doc__", "DAG operations - Rust implementation")?; |
c5128c541021
rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
17 |
c5128c541021
rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
18 let sys = PyModule::import(py, "sys")?; |
c5128c541021
rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
19 // according to the doc, we could make a static PyString out of |
c5128c541021
rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
20 // "modules" with the `intern!` macro, but this is used only at |
c5128c541021
rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
21 // registration so it may not be worth the effort. |
c5128c541021
rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
22 let sys_modules: Bound<'_, PyDict> = sys.getattr("modules")?.extract()?; |
c5128c541021
rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
23 sys_modules.set_item(dotted_name, &m)?; |
c5128c541021
rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
24 // Example C code (see pyexpat.c and import.c) will "give away the |
c5128c541021
rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
25 // reference", but we won't because it will be consumed once the |
c5128c541021
rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
26 // Rust PyObject is dropped. |
c5128c541021
rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
27 Ok(m) |
c5128c541021
rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
28 } |