1use crate::callback::IntoPyCallbackOutput;
2use crate::err::{PyErr, PyResult};
3use crate::exceptions;
4use crate::ffi;
5use crate::pyclass::PyClass;
6use crate::types::{PyAny, PyCFunction, PyDict, PyList, PyString};
7use crate::{IntoPy, Py, PyObject, Python};
8use std::ffi::{CStr, CString};
9use std::str;
10
11/// Represents a Python [`module`][1] object.
12///
13/// As with all other Python objects, modules are first class citizens.
14/// This means they can be passed to or returned from functions,
15/// created dynamically, assigned to variables and so forth.
16///
17/// [1]: https://docs.python.org/3/tutorial/modules.html
18#[repr(transparent)]
19pub struct PyModule(PyAny);
20
21pyobject_native_type_core!(PyModule, pyobject_native_static_type_object!(ffi::PyModule_Type), #checkfunction=ffi::PyModule_Check);
22
23impl PyModule {
24 /// Creates a new module object with the `__name__` attribute set to `name`.
25 ///
26 /// # Examples
27 ///
28 /// ``` rust
29 /// use pyo3::prelude::*;
30 ///
31 /// # fn main() -> PyResult<()> {
32 /// Python::with_gil(|py| -> PyResult<()> {
33 /// let module = PyModule::new(py, "my_module")?;
34 ///
35 /// assert_eq!(module.name()?, "my_module");
36 /// Ok(())
37 /// })?;
38 /// # Ok(())}
39 /// ```
40 pub fn new<'p>(py: Python<'p>, name: &str) -> PyResult<&'p PyModule> {
41 // Could use PyModule_NewObject, but it doesn't exist on PyPy.
42 let name = CString::new(name)?;
43 unsafe { py.from_owned_ptr_or_err(ffi::PyModule_New(name.as_ptr())) }
44 }
45
46 /// Imports the Python module with the specified name.
47 ///
48 /// # Examples
49 ///
50 /// ```no_run
51 /// # fn main() {
52 /// use pyo3::prelude::*;
53 ///
54 /// Python::with_gil(|py| {
55 /// let module = PyModule::import(py, "antigravity").expect("No flying for you.");
56 /// });
57 /// # }
58 /// ```
59 ///
60 /// This is equivalent to the following Python expression:
61 /// ```python
62 /// import antigravity
63 /// ```
64 pub fn import<N>(py: Python<'_>, name: N) -> PyResult<&PyModule>
65 where
66 N: IntoPy<Py<PyString>>,
67 {
68 let name: Py<PyString> = name.into_py(py);
69 unsafe { py.from_owned_ptr_or_err(ffi::PyImport_Import(name.as_ptr())) }
70 }
71
72 /// Creates and loads a module named `module_name`,
73 /// containing the Python code passed to `code`
74 /// and pretending to live at `file_name`.
75 ///
76 /// <div class="information">
77 /// <div class="tooltip compile_fail" style="">&#x26a0; &#xfe0f;</div>
78 /// </div><div class="example-wrap" style="display:inline-block"><pre class="compile_fail" style="white-space:normal;font:inherit;">
79 //
80 /// <strong>Warning</strong>: This will compile and execute code. <strong>Never</strong> pass untrusted code to this function!
81 ///
82 /// </pre></div>
83 ///
84 /// # Errors
85 ///
86 /// Returns `PyErr` if:
87 /// - `code` is not syntactically correct Python.
88 /// - Any Python exceptions are raised while initializing the module.
89 /// - Any of the arguments cannot be converted to [`CString`]s.
90 ///
91 /// # Example: bundle in a file at compile time with [`include_str!`][std::include_str]:
92 ///
93 /// ```rust
94 /// use pyo3::prelude::*;
95 ///
96 /// # fn main() -> PyResult<()> {
97 /// // This path is resolved relative to this file.
98 /// let code = include_str!("../../assets/script.py");
99 ///
100 /// Python::with_gil(|py| -> PyResult<()> {
101 /// PyModule::from_code(py, code, "example.py", "example")?;
102 /// Ok(())
103 /// })?;
104 /// # Ok(())
105 /// # }
106 /// ```
107 ///
108 /// # Example: Load a file at runtime with [`std::fs::read_to_string`].
109 ///
110 /// ```rust
111 /// use pyo3::prelude::*;
112 ///
113 /// # fn main() -> PyResult<()> {
114 /// // This path is resolved by however the platform resolves paths,
115 /// // which also makes this less portable. Consider using `include_str`
116 /// // if you just want to bundle a script with your module.
117 /// let code = std::fs::read_to_string("assets/script.py")?;
118 ///
119 /// Python::with_gil(|py| -> PyResult<()> {
120 /// PyModule::from_code(py, &code, "example.py", "example")?;
121 /// Ok(())
122 /// })?;
123 /// Ok(())
124 /// # }
125 /// ```
126 pub fn from_code<'p>(
127 py: Python<'p>,
128 code: &str,
129 file_name: &str,
130 module_name: &str,
131 ) -> PyResult<&'p PyModule> {
132 let data = CString::new(code)?;
133 let filename = CString::new(file_name)?;
134 let module = CString::new(module_name)?;
135
136 unsafe {
137 let cptr = ffi::Py_CompileString(data.as_ptr(), filename.as_ptr(), ffi::Py_file_input);
138 if cptr.is_null() {
139 return Err(PyErr::fetch(py));
140 }
141
142 let mptr = ffi::PyImport_ExecCodeModuleEx(module.as_ptr(), cptr, filename.as_ptr());
143 ffi::Py_DECREF(cptr);
144 if mptr.is_null() {
145 return Err(PyErr::fetch(py));
146 }
147
148 <&PyModule as crate::FromPyObject>::extract(py.from_owned_ptr_or_err(mptr)?)
149 }
150 }
151
152 /// Returns the module's `__dict__` attribute, which contains the module's symbol table.
153 pub fn dict(&self) -> &PyDict {
154 unsafe {
155 // PyModule_GetDict returns borrowed ptr; must make owned for safety (see #890).
156 let ptr = ffi::PyModule_GetDict(self.as_ptr());
157 self.py().from_owned_ptr(ffi::_Py_NewRef(ptr))
158 }
159 }
160
161 /// Returns the index (the `__all__` attribute) of the module,
162 /// creating one if needed.
163 ///
164 /// `__all__` declares the items that will be imported with `from my_module import *`.
165 pub fn index(&self) -> PyResult<&PyList> {
166 let __all__ = __all__(self.py());
167 match self.getattr(__all__) {
168 Ok(idx) => idx.downcast().map_err(PyErr::from),
169 Err(err) => {
170 if err.is_instance_of::<exceptions::PyAttributeError>(self.py()) {
171 let l = PyList::empty(self.py());
172 self.setattr(__all__, l).map_err(PyErr::from)?;
173 Ok(l)
174 } else {
175 Err(err)
176 }
177 }
178 }
179 }
180
181 /// Returns the name (the `__name__` attribute) of the module.
182 ///
183 /// May fail if the module does not have a `__name__` attribute.
184 pub fn name(&self) -> PyResult<&str> {
185 let ptr = unsafe { ffi::PyModule_GetName(self.as_ptr()) };
186 if ptr.is_null() {
187 Err(PyErr::fetch(self.py()))
188 } else {
189 let name = unsafe { CStr::from_ptr(ptr) }
190 .to_str()
191 .expect("PyModule_GetName expected to return utf8");
192 Ok(name)
193 }
194 }
195
196 /// Returns the filename (the `__file__` attribute) of the module.
197 ///
198 /// May fail if the module does not have a `__file__` attribute.
199 #[cfg(not(PyPy))]
200 pub fn filename(&self) -> PyResult<&str> {
201 unsafe {
202 self.py()
203 .from_owned_ptr_or_err::<PyString>(ffi::PyModule_GetFilenameObject(self.as_ptr()))?
204 .to_str()
205 }
206 }
207
208 /// Adds an attribute to the module.
209 ///
210 /// For adding classes, functions or modules, prefer to use [`PyModule::add_class`],
211 /// [`PyModule::add_function`] or [`PyModule::add_submodule`] instead, respectively.
212 ///
213 /// # Examples
214 ///
215 /// ```rust
216 /// use pyo3::prelude::*;
217 ///
218 /// #[pymodule]
219 /// fn my_module(_py: Python<'_>, module: &PyModule) -> PyResult<()> {
220 /// module.add("c", 299_792_458)?;
221 /// Ok(())
222 /// }
223 /// ```
224 ///
225 /// Python code can then do the following:
226 ///
227 /// ```python
228 /// from my_module import c
229 ///
230 /// print("c is", c)
231 /// ```
232 ///
233 /// This will result in the following output:
234 ///
235 /// ```text
236 /// c is 299792458
237 /// ```
238 pub fn add<V>(&self, name: &str, value: V) -> PyResult<()>
239 where
240 V: IntoPy<PyObject>,
241 {
242 self.index()?
243 .append(name)
244 .expect("could not append __name__ to __all__");
245 self.setattr(name, value.into_py(self.py()))
246 }
247
248 /// Adds a new class to the module.
249 ///
250 /// Notice that this method does not take an argument.
251 /// Instead, this method is *generic*, and requires us to use the
252 /// "turbofish" syntax to specify the class we want to add.
253 ///
254 /// # Examples
255 ///
256 /// ```rust
257 /// use pyo3::prelude::*;
258 ///
259 /// #[pyclass]
260 /// struct Foo { /* fields omitted */ }
261 ///
262 /// #[pymodule]
263 /// fn my_module(_py: Python<'_>, module: &PyModule) -> PyResult<()> {
264 /// module.add_class::<Foo>()?;
265 /// Ok(())
266 /// }
267 /// ```
268 ///
269 /// Python code can see this class as such:
270 /// ```python
271 /// from my_module import Foo
272 ///
273 /// print("Foo is", Foo)
274 /// ```
275 ///
276 /// This will result in the following output:
277 /// ```text
278 /// Foo is <class 'builtins.Foo'>
279 /// ```
280 ///
281 /// Note that as we haven't defined a [constructor][1], Python code can't actually
282 /// make an *instance* of `Foo` (or *get* one for that matter, as we haven't exported
283 /// anything that can return instances of `Foo`).
284 ///
285 /// [1]: https://pyo3.rs/latest/class.html#constructor
286 pub fn add_class<T>(&self) -> PyResult<()>
287 where
288 T: PyClass,
289 {
290 let py = self.py();
291 self.add(T::NAME, T::lazy_type_object().get_or_try_init(py)?)
292 }
293
294 /// Adds a function or a (sub)module to a module, using the functions name as name.
295 ///
296 /// Prefer to use [`PyModule::add_function`] and/or [`PyModule::add_submodule`] instead.
297 pub fn add_wrapped<'a, T>(&'a self, wrapper: &impl Fn(Python<'a>) -> T) -> PyResult<()>
298 where
299 T: IntoPyCallbackOutput<PyObject>,
300 {
301 self._add_wrapped(wrapper(self.py()).convert(self.py())?)
302 }
303
304 fn _add_wrapped(&self, object: PyObject) -> PyResult<()> {
305 let py = self.py();
306 let name = object.getattr(py, __name__(py))?;
307 let name = name.extract(py)?;
308 self.add(name, object)
309 }
310
311 /// Adds a submodule to a module.
312 ///
313 /// This is especially useful for creating module hierarchies.
314 ///
315 /// Note that this doesn't define a *package*, so this won't allow Python code
316 /// to directly import submodules by using
317 /// <span style="white-space: pre">`from my_module import submodule`</span>.
318 /// For more information, see [#759][1] and [#1517][2].
319 ///
320 /// # Examples
321 ///
322 /// ```rust
323 /// use pyo3::prelude::*;
324 ///
325 /// #[pymodule]
326 /// fn my_module(py: Python<'_>, module: &PyModule) -> PyResult<()> {
327 /// let submodule = PyModule::new(py, "submodule")?;
328 /// submodule.add("super_useful_constant", "important")?;
329 ///
330 /// module.add_submodule(submodule)?;
331 /// Ok(())
332 /// }
333 /// ```
334 ///
335 /// Python code can then do the following:
336 ///
337 /// ```python
338 /// import my_module
339 ///
340 /// print("super_useful_constant is", my_module.submodule.super_useful_constant)
341 /// ```
342 ///
343 /// This will result in the following output:
344 ///
345 /// ```text
346 /// super_useful_constant is important
347 /// ```
348 ///
349 /// [1]: https://github.com/PyO3/pyo3/issues/759
350 /// [2]: https://github.com/PyO3/pyo3/issues/1517#issuecomment-808664021
351 pub fn add_submodule(&self, module: &PyModule) -> PyResult<()> {
352 let name = module.name()?;
353 self.add(name, module)
354 }
355
356 /// Add a function to a module.
357 ///
358 /// Note that this also requires the [`wrap_pyfunction!`][2] macro
359 /// to wrap a function annotated with [`#[pyfunction]`][1].
360 ///
361 /// ```rust
362 /// use pyo3::prelude::*;
363 ///
364 /// #[pyfunction]
365 /// fn say_hello() {
366 /// println!("Hello world!")
367 /// }
368 /// #[pymodule]
369 /// fn my_module(_py: Python<'_>, module: &PyModule) -> PyResult<()> {
370 /// module.add_function(wrap_pyfunction!(say_hello, module)?)
371 /// }
372 /// ```
373 ///
374 /// Python code can then do the following:
375 ///
376 /// ```python
377 /// from my_module import say_hello
378 ///
379 /// say_hello()
380 /// ```
381 ///
382 /// This will result in the following output:
383 ///
384 /// ```text
385 /// Hello world!
386 /// ```
387 ///
388 /// [1]: crate::prelude::pyfunction
389 /// [2]: crate::wrap_pyfunction
390 pub fn add_function<'a>(&'a self, fun: &'a PyCFunction) -> PyResult<()> {
391 let name = fun.getattr(__name__(self.py()))?.extract()?;
392 self.add(name, fun)
393 }
394}
395
396fn __all__(py: Python<'_>) -> &PyString {
397 intern!(py, "__all__")
398}
399
400fn __name__(py: Python<'_>) -> &PyString {
401 intern!(py, "__name__")
402}
403
404#[cfg(test)]
405mod tests {
406 use crate::{types::PyModule, Python};
407
408 #[test]
409 fn module_import_and_name() {
410 Python::with_gil(|py| {
411 let builtins = PyModule::import(py, "builtins").unwrap();
412 assert_eq!(builtins.name().unwrap(), "builtins");
413 })
414 }
415}
416