pyo3/types/
module.rs

1use crate::err::{PyErr, PyResult};
2use crate::ffi_ptr_ext::FfiPtrExt;
3use crate::impl_::callback::IntoPyCallbackOutput;
4use crate::py_result_ext::PyResultExt;
5use crate::pyclass::PyClass;
6use crate::types::{
7    any::PyAnyMethods, list::PyListMethods, PyAny, PyCFunction, PyDict, PyList, PyString,
8};
9use crate::{
10    exceptions, ffi, Borrowed, Bound, BoundObject, IntoPyObject, IntoPyObjectExt, Py, PyObject,
11    Python,
12};
13use std::ffi::{CStr, CString};
14#[cfg(all(not(Py_LIMITED_API), Py_GIL_DISABLED))]
15use std::os::raw::c_int;
16use std::str;
17
18/// Represents a Python [`module`][1] object.
19///
20/// Values of this type are accessed via PyO3's smart pointers, e.g. as
21/// [`Py<PyModule>`][crate::Py] or [`Bound<'py, PyModule>`][Bound].
22///
23/// For APIs available on `module` objects, see the [`PyModuleMethods`] trait which is implemented for
24/// [`Bound<'py, PyModule>`][Bound].
25///
26/// As with all other Python objects, modules are first class citizens.
27/// This means they can be passed to or returned from functions,
28/// created dynamically, assigned to variables and so forth.
29///
30/// [1]: https://docs.python.org/3/tutorial/modules.html
31#[repr(transparent)]
32pub struct PyModule(PyAny);
33
34pyobject_native_type_core!(PyModule, pyobject_native_static_type_object!(ffi::PyModule_Type), #checkfunction=ffi::PyModule_Check);
35
36impl PyModule {
37    /// Creates a new module object with the `__name__` attribute set to `name`.
38    ///
39    /// # Examples
40    ///
41    /// ``` rust
42    /// use pyo3::prelude::*;
43    ///
44    /// # fn main() -> PyResult<()> {
45    /// Python::with_gil(|py| -> PyResult<()> {
46    ///     let module = PyModule::new(py, "my_module")?;
47    ///
48    ///     assert_eq!(module.name()?, "my_module");
49    ///     Ok(())
50    /// })?;
51    /// # Ok(())}
52    ///  ```
53    pub fn new<'py>(py: Python<'py>, name: &str) -> PyResult<Bound<'py, PyModule>> {
54        let name = PyString::new(py, name);
55        unsafe {
56            ffi::PyModule_NewObject(name.as_ptr())
57                .assume_owned_or_err(py)
58                .downcast_into_unchecked()
59        }
60    }
61
62    /// Deprecated name for [`PyModule::new`].
63    #[deprecated(since = "0.23.0", note = "renamed to `PyModule::new`")]
64    #[inline]
65    pub fn new_bound<'py>(py: Python<'py>, name: &str) -> PyResult<Bound<'py, PyModule>> {
66        Self::new(py, name)
67    }
68
69    /// Imports the Python module with the specified name.
70    ///
71    /// # Examples
72    ///
73    /// ```no_run
74    /// # fn main() {
75    /// use pyo3::prelude::*;
76    ///
77    /// Python::with_gil(|py| {
78    ///     let module = PyModule::import(py, "antigravity").expect("No flying for you.");
79    /// });
80    /// # }
81    ///  ```
82    ///
83    /// This is equivalent to the following Python expression:
84    /// ```python
85    /// import antigravity
86    /// ```
87    ///
88    /// If you want to import a class, you can store a reference to it with
89    /// [`GILOnceCell::import`][crate::sync::GILOnceCell#method.import].
90    pub fn import<'py, N>(py: Python<'py>, name: N) -> PyResult<Bound<'py, PyModule>>
91    where
92        N: IntoPyObject<'py, Target = PyString>,
93    {
94        let name = name.into_pyobject_or_pyerr(py)?;
95        unsafe {
96            ffi::PyImport_Import(name.as_ptr())
97                .assume_owned_or_err(py)
98                .downcast_into_unchecked()
99        }
100    }
101
102    /// Deprecated name for [`PyModule::import`].
103    #[deprecated(since = "0.23.0", note = "renamed to `PyModule::import`")]
104    #[allow(deprecated)]
105    #[inline]
106    pub fn import_bound<N>(py: Python<'_>, name: N) -> PyResult<Bound<'_, PyModule>>
107    where
108        N: crate::IntoPy<Py<PyString>>,
109    {
110        Self::import(py, name.into_py(py))
111    }
112
113    /// Creates and loads a module named `module_name`,
114    /// containing the Python code passed to `code`
115    /// and pretending to live at `file_name`.
116    ///
117    /// <div class="information">
118    ///     <div class="tooltip compile_fail" style="">&#x26a0; &#xfe0f;</div>
119    /// </div><div class="example-wrap" style="display:inline-block"><pre class="compile_fail" style="white-space:normal;font:inherit;">
120    //
121    ///  <strong>Warning</strong>: This will compile and execute code. <strong>Never</strong> pass untrusted code to this function!
122    ///
123    /// </pre></div>
124    ///
125    /// # Errors
126    ///
127    /// Returns `PyErr` if:
128    /// - `code` is not syntactically correct Python.
129    /// - Any Python exceptions are raised while initializing the module.
130    /// - Any of the arguments cannot be converted to [`CString`]s.
131    ///
132    /// # Example: bundle in a file at compile time with [`include_str!`][std::include_str]:
133    ///
134    /// ```rust
135    /// use pyo3::prelude::*;
136    /// use pyo3::ffi::c_str;
137    ///
138    /// # fn main() -> PyResult<()> {
139    /// // This path is resolved relative to this file.
140    /// let code = c_str!(include_str!("../../assets/script.py"));
141    ///
142    /// Python::with_gil(|py| -> PyResult<()> {
143    ///     PyModule::from_code(py, code, c_str!("example.py"), c_str!("example"))?;
144    ///     Ok(())
145    /// })?;
146    /// # Ok(())
147    /// # }
148    /// ```
149    ///
150    /// # Example: Load a file at runtime with [`std::fs::read_to_string`].
151    ///
152    /// ```rust
153    /// use pyo3::prelude::*;
154    /// use pyo3::ffi::c_str;
155    /// use std::ffi::CString;
156    ///
157    /// # fn main() -> PyResult<()> {
158    /// // This path is resolved by however the platform resolves paths,
159    /// // which also makes this less portable. Consider using `include_str`
160    /// // if you just want to bundle a script with your module.
161    /// let code = std::fs::read_to_string("assets/script.py")?;
162    ///
163    /// Python::with_gil(|py| -> PyResult<()> {
164    ///     PyModule::from_code(py, CString::new(code)?.as_c_str(), c_str!("example.py"), c_str!("example"))?;
165    ///     Ok(())
166    /// })?;
167    /// Ok(())
168    /// # }
169    /// ```
170    pub fn from_code<'py>(
171        py: Python<'py>,
172        code: &CStr,
173        file_name: &CStr,
174        module_name: &CStr,
175    ) -> PyResult<Bound<'py, PyModule>> {
176        unsafe {
177            let code = ffi::Py_CompileString(code.as_ptr(), file_name.as_ptr(), ffi::Py_file_input)
178                .assume_owned_or_err(py)?;
179
180            ffi::PyImport_ExecCodeModuleEx(module_name.as_ptr(), code.as_ptr(), file_name.as_ptr())
181                .assume_owned_or_err(py)
182                .downcast_into()
183        }
184    }
185
186    /// Deprecated name for [`PyModule::from_code`].
187    #[deprecated(since = "0.23.0", note = "renamed to `PyModule::from_code`")]
188    #[inline]
189    pub fn from_code_bound<'py>(
190        py: Python<'py>,
191        code: &str,
192        file_name: &str,
193        module_name: &str,
194    ) -> PyResult<Bound<'py, PyModule>> {
195        let data = CString::new(code)?;
196        let filename = CString::new(file_name)?;
197        let module = CString::new(module_name)?;
198
199        Self::from_code(py, data.as_c_str(), filename.as_c_str(), module.as_c_str())
200    }
201}
202
203/// Implementation of functionality for [`PyModule`].
204///
205/// These methods are defined for the `Bound<'py, PyModule>` smart pointer, so to use method call
206/// syntax these methods are separated into a trait, because stable Rust does not yet support
207/// `arbitrary_self_types`.
208#[doc(alias = "PyModule")]
209pub trait PyModuleMethods<'py>: crate::sealed::Sealed {
210    /// Returns the module's `__dict__` attribute, which contains the module's symbol table.
211    fn dict(&self) -> Bound<'py, PyDict>;
212
213    /// Returns the index (the `__all__` attribute) of the module,
214    /// creating one if needed.
215    ///
216    /// `__all__` declares the items that will be imported with `from my_module import *`.
217    fn index(&self) -> PyResult<Bound<'py, PyList>>;
218
219    /// Returns the name (the `__name__` attribute) of the module.
220    ///
221    /// May fail if the module does not have a `__name__` attribute.
222    fn name(&self) -> PyResult<Bound<'py, PyString>>;
223
224    /// Returns the filename (the `__file__` attribute) of the module.
225    ///
226    /// May fail if the module does not have a `__file__` attribute.
227    fn filename(&self) -> PyResult<Bound<'py, PyString>>;
228
229    /// Adds an attribute to the module.
230    ///
231    /// For adding classes, functions or modules, prefer to use [`PyModuleMethods::add_class`],
232    /// [`PyModuleMethods::add_function`] or [`PyModuleMethods::add_submodule`] instead,
233    /// respectively.
234    ///
235    /// # Examples
236    ///
237    /// ```rust
238    /// use pyo3::prelude::*;
239    ///
240    /// #[pymodule]
241    /// fn my_module(module: &Bound<'_, PyModule>) -> PyResult<()> {
242    ///     module.add("c", 299_792_458)?;
243    ///     Ok(())
244    /// }
245    /// ```
246    ///
247    /// Python code can then do the following:
248    ///
249    /// ```python
250    /// from my_module import c
251    ///
252    /// print("c is", c)
253    /// ```
254    ///
255    /// This will result in the following output:
256    ///
257    /// ```text
258    /// c is 299792458
259    /// ```
260    fn add<N, V>(&self, name: N, value: V) -> PyResult<()>
261    where
262        N: IntoPyObject<'py, Target = PyString>,
263        V: IntoPyObject<'py>;
264
265    /// Adds a new class to the module.
266    ///
267    /// Notice that this method does not take an argument.
268    /// Instead, this method is *generic*, and requires us to use the
269    /// "turbofish" syntax to specify the class we want to add.
270    ///
271    /// # Examples
272    ///
273    /// ```rust
274    /// use pyo3::prelude::*;
275    ///
276    /// #[pyclass]
277    /// struct Foo { /* fields omitted */ }
278    ///
279    /// #[pymodule]
280    /// fn my_module(module: &Bound<'_, PyModule>) -> PyResult<()> {
281    ///     module.add_class::<Foo>()?;
282    ///     Ok(())
283    /// }
284    ///  ```
285    ///
286    /// Python code can see this class as such:
287    /// ```python
288    /// from my_module import Foo
289    ///
290    /// print("Foo is", Foo)
291    /// ```
292    ///
293    /// This will result in the following output:
294    /// ```text
295    /// Foo is <class 'builtins.Foo'>
296    /// ```
297    ///
298    /// Note that as we haven't defined a [constructor][1], Python code can't actually
299    /// make an *instance* of `Foo` (or *get* one for that matter, as we haven't exported
300    /// anything that can return instances of `Foo`).
301    ///
302    #[doc = concat!("[1]: https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/class.html#constructor")]
303    fn add_class<T>(&self) -> PyResult<()>
304    where
305        T: PyClass;
306
307    /// Adds a function or a (sub)module to a module, using the functions name as name.
308    ///
309    /// Prefer to use [`PyModuleMethods::add_function`] and/or [`PyModuleMethods::add_submodule`]
310    /// instead.
311    fn add_wrapped<T>(&self, wrapper: &impl Fn(Python<'py>) -> T) -> PyResult<()>
312    where
313        T: IntoPyCallbackOutput<'py, PyObject>;
314
315    /// Adds a submodule to a module.
316    ///
317    /// This is especially useful for creating module hierarchies.
318    ///
319    /// Note that this doesn't define a *package*, so this won't allow Python code
320    /// to directly import submodules by using
321    /// <span style="white-space: pre">`from my_module import submodule`</span>.
322    /// For more information, see [#759][1] and [#1517][2].
323    ///
324    /// # Examples
325    ///
326    /// ```rust
327    /// use pyo3::prelude::*;
328    ///
329    /// #[pymodule]
330    /// fn my_module(py: Python<'_>, module: &Bound<'_, PyModule>) -> PyResult<()> {
331    ///     let submodule = PyModule::new(py, "submodule")?;
332    ///     submodule.add("super_useful_constant", "important")?;
333    ///
334    ///     module.add_submodule(&submodule)?;
335    ///     Ok(())
336    /// }
337    /// ```
338    ///
339    /// Python code can then do the following:
340    ///
341    /// ```python
342    /// import my_module
343    ///
344    /// print("super_useful_constant is", my_module.submodule.super_useful_constant)
345    /// ```
346    ///
347    /// This will result in the following output:
348    ///
349    /// ```text
350    /// super_useful_constant is important
351    /// ```
352    ///
353    /// [1]: https://github.com/PyO3/pyo3/issues/759
354    /// [2]: https://github.com/PyO3/pyo3/issues/1517#issuecomment-808664021
355    fn add_submodule(&self, module: &Bound<'_, PyModule>) -> PyResult<()>;
356
357    /// Add a function to a module.
358    ///
359    /// Note that this also requires the [`wrap_pyfunction!`][2] macro
360    /// to wrap a function annotated with [`#[pyfunction]`][1].
361    ///
362    /// ```rust
363    /// use pyo3::prelude::*;
364    ///
365    /// #[pyfunction]
366    /// fn say_hello() {
367    ///     println!("Hello world!")
368    /// }
369    /// #[pymodule]
370    /// fn my_module(module: &Bound<'_, PyModule>) -> PyResult<()> {
371    ///     module.add_function(wrap_pyfunction!(say_hello, module)?)
372    /// }
373    /// ```
374    ///
375    /// Python code can then do the following:
376    ///
377    /// ```python
378    /// from my_module import say_hello
379    ///
380    /// say_hello()
381    /// ```
382    ///
383    /// This will result in the following output:
384    ///
385    /// ```text
386    /// Hello world!
387    /// ```
388    ///
389    /// [1]: crate::prelude::pyfunction
390    /// [2]: crate::wrap_pyfunction
391    fn add_function(&self, fun: Bound<'_, PyCFunction>) -> PyResult<()>;
392
393    /// Declare whether or not this module supports running with the GIL disabled
394    ///
395    /// If the module does not rely on the GIL for thread safety, you can pass
396    /// `false` to this function to indicate the module does not rely on the GIL
397    /// for thread-safety.
398    ///
399    /// This function sets the [`Py_MOD_GIL`
400    /// slot](https://docs.python.org/3/c-api/module.html#c.Py_mod_gil) on the
401    /// module object. The default is `Py_MOD_GIL_USED`, so passing `true` to
402    /// this function is a no-op unless you have already set `Py_MOD_GIL` to
403    /// `Py_MOD_GIL_NOT_USED` elsewhere.
404    ///
405    /// # Examples
406    ///
407    /// ```rust
408    /// use pyo3::prelude::*;
409    ///
410    /// #[pymodule(gil_used = false)]
411    /// fn my_module(py: Python<'_>, module: &Bound<'_, PyModule>) -> PyResult<()> {
412    ///     let submodule = PyModule::new(py, "submodule")?;
413    ///     submodule.gil_used(false)?;
414    ///     module.add_submodule(&submodule)?;
415    ///     Ok(())
416    /// }
417    /// ```
418    ///
419    /// The resulting module will not print a `RuntimeWarning` and re-enable the
420    /// GIL when Python imports it on the free-threaded build, since all module
421    /// objects defined in the extension have `Py_MOD_GIL` set to
422    /// `Py_MOD_GIL_NOT_USED`.
423    ///
424    /// This is a no-op on the GIL-enabled build.
425    fn gil_used(&self, gil_used: bool) -> PyResult<()>;
426}
427
428impl<'py> PyModuleMethods<'py> for Bound<'py, PyModule> {
429    fn dict(&self) -> Bound<'py, PyDict> {
430        unsafe {
431            // PyModule_GetDict returns borrowed ptr; must make owned for safety (see #890).
432            ffi::PyModule_GetDict(self.as_ptr())
433                .assume_borrowed(self.py())
434                .to_owned()
435                .downcast_into_unchecked()
436        }
437    }
438
439    fn index(&self) -> PyResult<Bound<'py, PyList>> {
440        let __all__ = __all__(self.py());
441        match self.getattr(__all__) {
442            Ok(idx) => idx.downcast_into().map_err(PyErr::from),
443            Err(err) => {
444                if err.is_instance_of::<exceptions::PyAttributeError>(self.py()) {
445                    let l = PyList::empty(self.py());
446                    self.setattr(__all__, &l)?;
447                    Ok(l)
448                } else {
449                    Err(err)
450                }
451            }
452        }
453    }
454
455    fn name(&self) -> PyResult<Bound<'py, PyString>> {
456        #[cfg(not(PyPy))]
457        {
458            unsafe {
459                ffi::PyModule_GetNameObject(self.as_ptr())
460                    .assume_owned_or_err(self.py())
461                    .downcast_into_unchecked()
462            }
463        }
464
465        #[cfg(PyPy)]
466        {
467            self.dict()
468                .get_item("__name__")
469                .map_err(|_| exceptions::PyAttributeError::new_err("__name__"))?
470                .downcast_into()
471                .map_err(PyErr::from)
472        }
473    }
474
475    fn filename(&self) -> PyResult<Bound<'py, PyString>> {
476        #[cfg(not(PyPy))]
477        unsafe {
478            ffi::PyModule_GetFilenameObject(self.as_ptr())
479                .assume_owned_or_err(self.py())
480                .downcast_into_unchecked()
481        }
482
483        #[cfg(PyPy)]
484        {
485            self.dict()
486                .get_item("__file__")
487                .map_err(|_| exceptions::PyAttributeError::new_err("__file__"))?
488                .downcast_into()
489                .map_err(PyErr::from)
490        }
491    }
492
493    fn add<N, V>(&self, name: N, value: V) -> PyResult<()>
494    where
495        N: IntoPyObject<'py, Target = PyString>,
496        V: IntoPyObject<'py>,
497    {
498        fn inner(
499            module: &Bound<'_, PyModule>,
500            name: Borrowed<'_, '_, PyString>,
501            value: Borrowed<'_, '_, PyAny>,
502        ) -> PyResult<()> {
503            module
504                .index()?
505                .append(name)
506                .expect("could not append __name__ to __all__");
507            module.setattr(name, value)
508        }
509
510        let py = self.py();
511        inner(
512            self,
513            name.into_pyobject_or_pyerr(py)?.as_borrowed(),
514            value.into_pyobject_or_pyerr(py)?.into_any().as_borrowed(),
515        )
516    }
517
518    fn add_class<T>(&self) -> PyResult<()>
519    where
520        T: PyClass,
521    {
522        let py = self.py();
523        self.add(T::NAME, T::lazy_type_object().get_or_try_init(py)?)
524    }
525
526    fn add_wrapped<T>(&self, wrapper: &impl Fn(Python<'py>) -> T) -> PyResult<()>
527    where
528        T: IntoPyCallbackOutput<'py, PyObject>,
529    {
530        fn inner(module: &Bound<'_, PyModule>, object: Bound<'_, PyAny>) -> PyResult<()> {
531            let name = object.getattr(__name__(module.py()))?;
532            module.add(name.downcast_into::<PyString>()?, object)
533        }
534
535        let py = self.py();
536        inner(self, wrapper(py).convert(py)?.into_bound(py))
537    }
538
539    fn add_submodule(&self, module: &Bound<'_, PyModule>) -> PyResult<()> {
540        let name = module.name()?;
541        self.add(name, module)
542    }
543
544    fn add_function(&self, fun: Bound<'_, PyCFunction>) -> PyResult<()> {
545        let name = fun.getattr(__name__(self.py()))?;
546        self.add(name.downcast_into::<PyString>()?, fun)
547    }
548
549    #[cfg_attr(any(Py_LIMITED_API, not(Py_GIL_DISABLED)), allow(unused_variables))]
550    fn gil_used(&self, gil_used: bool) -> PyResult<()> {
551        #[cfg(all(not(Py_LIMITED_API), Py_GIL_DISABLED))]
552        {
553            let gil_used = match gil_used {
554                true => ffi::Py_MOD_GIL_USED,
555                false => ffi::Py_MOD_GIL_NOT_USED,
556            };
557            match unsafe { ffi::PyUnstable_Module_SetGIL(self.as_ptr(), gil_used) } {
558                c_int::MIN..=-1 => Err(PyErr::fetch(self.py())),
559                0..=c_int::MAX => Ok(()),
560            }
561        }
562        #[cfg(any(Py_LIMITED_API, not(Py_GIL_DISABLED)))]
563        Ok(())
564    }
565}
566
567fn __all__(py: Python<'_>) -> &Bound<'_, PyString> {
568    intern!(py, "__all__")
569}
570
571fn __name__(py: Python<'_>) -> &Bound<'_, PyString> {
572    intern!(py, "__name__")
573}
574
575#[cfg(test)]
576mod tests {
577    use crate::{
578        types::{module::PyModuleMethods, PyModule},
579        Python,
580    };
581
582    #[test]
583    fn module_import_and_name() {
584        Python::with_gil(|py| {
585            let builtins = PyModule::import(py, "builtins").unwrap();
586            assert_eq!(builtins.name().unwrap(), "builtins");
587        })
588    }
589
590    #[test]
591    fn module_filename() {
592        use crate::types::string::PyStringMethods;
593        Python::with_gil(|py| {
594            let site = PyModule::import(py, "site").unwrap();
595            assert!(site
596                .filename()
597                .unwrap()
598                .to_cow()
599                .unwrap()
600                .ends_with("site.py"));
601        })
602    }
603}