pub trait PyModuleMethods<'py>: Sealed {
// Required methods
fn dict(&self) -> Bound<'py, PyDict>;
fn index(&self) -> PyResult<Bound<'py, PyList>>;
fn name(&self) -> PyResult<Bound<'py, PyString>>;
fn filename(&self) -> PyResult<Bound<'py, PyString>>;
fn add<N, V>(&self, name: N, value: V) -> PyResult<()>
where N: IntoPyObject<'py, Target = PyString>,
V: IntoPyObject<'py>;
fn add_class<T>(&self) -> PyResult<()>
where T: PyClass;
fn add_wrapped<T>(
&self,
wrapper: &impl Fn(Python<'py>) -> T,
) -> PyResult<()>
where T: IntoPyCallbackOutput<'py, PyObject>;
fn add_submodule(&self, module: &Bound<'_, PyModule>) -> PyResult<()>;
fn add_function(&self, fun: Bound<'_, PyCFunction>) -> PyResult<()>;
fn gil_used(&self, gil_used: bool) -> PyResult<()>;
}
Expand description
Implementation of functionality for PyModule
.
These methods are defined for the Bound<'py, PyModule>
smart pointer, so to use method call
syntax these methods are separated into a trait, because stable Rust does not yet support
arbitrary_self_types
.
Required Methods§
Sourcefn dict(&self) -> Bound<'py, PyDict>
fn dict(&self) -> Bound<'py, PyDict>
Returns the module’s __dict__
attribute, which contains the module’s symbol table.
Sourcefn index(&self) -> PyResult<Bound<'py, PyList>>
fn index(&self) -> PyResult<Bound<'py, PyList>>
Returns the index (the __all__
attribute) of the module,
creating one if needed.
__all__
declares the items that will be imported with from my_module import *
.
Sourcefn name(&self) -> PyResult<Bound<'py, PyString>>
fn name(&self) -> PyResult<Bound<'py, PyString>>
Returns the name (the __name__
attribute) of the module.
May fail if the module does not have a __name__
attribute.
Sourcefn filename(&self) -> PyResult<Bound<'py, PyString>>
fn filename(&self) -> PyResult<Bound<'py, PyString>>
Returns the filename (the __file__
attribute) of the module.
May fail if the module does not have a __file__
attribute.
Sourcefn add<N, V>(&self, name: N, value: V) -> PyResult<()>
fn add<N, V>(&self, name: N, value: V) -> PyResult<()>
Adds an attribute to the module.
For adding classes, functions or modules, prefer to use PyModuleMethods::add_class
,
PyModuleMethods::add_function
or PyModuleMethods::add_submodule
instead,
respectively.
§Examples
use pyo3::prelude::*;
#[pymodule]
fn my_module(module: &Bound<'_, PyModule>) -> PyResult<()> {
module.add("c", 299_792_458)?;
Ok(())
}
Python code can then do the following:
from my_module import c
print("c is", c)
This will result in the following output:
c is 299792458
Sourcefn add_class<T>(&self) -> PyResult<()>where
T: PyClass,
fn add_class<T>(&self) -> PyResult<()>where
T: PyClass,
Adds a new class to the module.
Notice that this method does not take an argument. Instead, this method is generic, and requires us to use the “turbofish” syntax to specify the class we want to add.
§Examples
use pyo3::prelude::*;
#[pyclass]
struct Foo { /* fields omitted */ }
#[pymodule]
fn my_module(module: &Bound<'_, PyModule>) -> PyResult<()> {
module.add_class::<Foo>()?;
Ok(())
}
Python code can see this class as such:
from my_module import Foo
print("Foo is", Foo)
This will result in the following output:
Foo is <class 'builtins.Foo'>
Note that as we haven’t defined a constructor, Python code can’t actually
make an instance of Foo
(or get one for that matter, as we haven’t exported
anything that can return instances of Foo
).
Sourcefn add_wrapped<T>(&self, wrapper: &impl Fn(Python<'py>) -> T) -> PyResult<()>where
T: IntoPyCallbackOutput<'py, PyObject>,
fn add_wrapped<T>(&self, wrapper: &impl Fn(Python<'py>) -> T) -> PyResult<()>where
T: IntoPyCallbackOutput<'py, PyObject>,
Adds a function or a (sub)module to a module, using the functions name as name.
Prefer to use PyModuleMethods::add_function
and/or PyModuleMethods::add_submodule
instead.
Sourcefn add_submodule(&self, module: &Bound<'_, PyModule>) -> PyResult<()>
fn add_submodule(&self, module: &Bound<'_, PyModule>) -> PyResult<()>
Adds a submodule to a module.
This is especially useful for creating module hierarchies.
Note that this doesn’t define a package, so this won’t allow Python code
to directly import submodules by using
from my_module import submodule
.
For more information, see #759 and #1517.
§Examples
use pyo3::prelude::*;
#[pymodule]
fn my_module(py: Python<'_>, module: &Bound<'_, PyModule>) -> PyResult<()> {
let submodule = PyModule::new(py, "submodule")?;
submodule.add("super_useful_constant", "important")?;
module.add_submodule(&submodule)?;
Ok(())
}
Python code can then do the following:
import my_module
print("super_useful_constant is", my_module.submodule.super_useful_constant)
This will result in the following output:
super_useful_constant is important
Sourcefn add_function(&self, fun: Bound<'_, PyCFunction>) -> PyResult<()>
fn add_function(&self, fun: Bound<'_, PyCFunction>) -> PyResult<()>
Add a function to a module.
Note that this also requires the wrap_pyfunction!
macro
to wrap a function annotated with #[pyfunction]
.
use pyo3::prelude::*;
#[pyfunction]
fn say_hello() {
println!("Hello world!")
}
#[pymodule]
fn my_module(module: &Bound<'_, PyModule>) -> PyResult<()> {
module.add_function(wrap_pyfunction!(say_hello, module)?)
}
Python code can then do the following:
from my_module import say_hello
say_hello()
This will result in the following output:
Hello world!
Sourcefn gil_used(&self, gil_used: bool) -> PyResult<()>
fn gil_used(&self, gil_used: bool) -> PyResult<()>
Declare whether or not this module supports running with the GIL disabled
If the module does not rely on the GIL for thread safety, you can pass
false
to this function to indicate the module does not rely on the GIL
for thread-safety.
This function sets the Py_MOD_GIL
slot on the
module object. The default is Py_MOD_GIL_USED
, so passing true
to
this function is a no-op unless you have already set Py_MOD_GIL
to
Py_MOD_GIL_NOT_USED
elsewhere.
§Examples
use pyo3::prelude::*;
#[pymodule(gil_used = false)]
fn my_module(py: Python<'_>, module: &Bound<'_, PyModule>) -> PyResult<()> {
let submodule = PyModule::new(py, "submodule")?;
submodule.gil_used(false)?;
module.add_submodule(&submodule)?;
Ok(())
}
The resulting module will not print a RuntimeWarning
and re-enable the
GIL when Python imports it on the free-threaded build, since all module
objects defined in the extension have Py_MOD_GIL
set to
Py_MOD_GIL_NOT_USED
.
This is a no-op on the GIL-enabled build.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.