add `PyModule::new_bound` and `PyModule::import_bound` (#3775)
* add `PyModule::new` and `PyModule::import_bound` * review: Icxolu feedback
This commit is contained in:
parent
c4f66657c5
commit
9e74c858c2
|
@ -27,8 +27,8 @@ fn maturin_starter(py: Python<'_>, m: &PyModule) -> PyResult<()> {
|
|||
// Inserting to sys.modules allows importing submodules nicely from Python
|
||||
// e.g. from maturin_starter.submodule import SubmoduleClass
|
||||
|
||||
let sys = PyModule::import(py, "sys")?;
|
||||
let sys_modules: &PyDict = sys.getattr("modules")?.downcast()?;
|
||||
let sys = PyModule::import_bound(py, "sys")?;
|
||||
let sys_modules: Bound<'_, PyDict> = sys.getattr("modules")?.downcast_into()?;
|
||||
sys_modules.set_item("maturin_starter.submodule", m.getattr("submodule")?)?;
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -19,7 +19,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
|
||||
// Now we can load our python_plugin/gadget_init_plugin.py file.
|
||||
// It can in turn import other stuff as it deems appropriate
|
||||
let plugin = PyModule::import(py, "gadget_init_plugin")?;
|
||||
let plugin = PyModule::import_bound(py, "gadget_init_plugin")?;
|
||||
// and call start function there, which will return a python reference to Gadget.
|
||||
// Gadget here is a "pyclass" object reference
|
||||
let gadget = plugin.getattr("start")?.call0()?;
|
||||
|
|
|
@ -27,8 +27,8 @@ fn _setuptools_rust_starter(py: Python<'_>, m: &PyModule) -> PyResult<()> {
|
|||
// Inserting to sys.modules allows importing submodules nicely from Python
|
||||
// e.g. from setuptools_rust_starter.submodule import SubmoduleClass
|
||||
|
||||
let sys = PyModule::import(py, "sys")?;
|
||||
let sys_modules: &PyDict = sys.getattr("modules")?.downcast()?;
|
||||
let sys = PyModule::import_bound(py, "sys")?;
|
||||
let sys_modules: Bound<'_, PyDict> = sys.getattr("modules")?.downcast_into()?;
|
||||
sys_modules.set_item("setuptools_rust_starter.submodule", m.getattr("submodule")?)?;
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -941,8 +941,8 @@ impl MyClass {
|
|||
#
|
||||
# fn main() -> PyResult<()> {
|
||||
# Python::with_gil(|py| {
|
||||
# let inspect = PyModule::import(py, "inspect")?.getattr("signature")?;
|
||||
# let module = PyModule::new(py, "my_module")?;
|
||||
# let inspect = PyModule::import_bound(py, "inspect")?.getattr("signature")?;
|
||||
# let module = PyModule::new_bound(py, "my_module")?;
|
||||
# module.add_class::<MyClass>()?;
|
||||
# let class = module.getattr("MyClass")?;
|
||||
#
|
||||
|
@ -951,7 +951,7 @@ impl MyClass {
|
|||
# assert_eq!(doc, "");
|
||||
#
|
||||
# let sig: String = inspect
|
||||
# .call1((class,))?
|
||||
# .call1((&class,))?
|
||||
# .call_method0("__str__")?
|
||||
# .extract()?;
|
||||
# assert_eq!(sig, "(c, d)");
|
||||
|
@ -959,7 +959,7 @@ impl MyClass {
|
|||
# let doc: String = class.getattr("__doc__")?.extract()?;
|
||||
# assert_eq!(doc, "");
|
||||
#
|
||||
# inspect.call1((class,)).expect_err("`text_signature` on classes is not compatible with compilation in `abi3` mode until Python 3.10 or greater");
|
||||
# inspect.call1((&class,)).expect_err("`text_signature` on classes is not compatible with compilation in `abi3` mode until Python 3.10 or greater");
|
||||
# }
|
||||
#
|
||||
# {
|
||||
|
|
|
@ -386,7 +386,7 @@ fn my_module(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
|
|||
#
|
||||
# fn main() -> PyResult<()> {
|
||||
# Python::with_gil(|py| -> PyResult<()> {
|
||||
# let globals = PyModule::import(py, "__main__")?.dict().as_borrowed();
|
||||
# let globals = PyModule::import_bound(py, "__main__")?.dict();
|
||||
# globals.set_item("Number", Number::type_object_bound(py))?;
|
||||
#
|
||||
# py.run_bound(SCRIPT, Some(&globals), None)?;
|
||||
|
|
|
@ -54,7 +54,7 @@ struct RustyStruct {
|
|||
#
|
||||
# fn main() -> PyResult<()> {
|
||||
# Python::with_gil(|py| -> PyResult<()> {
|
||||
# let module = PyModule::from_code(
|
||||
# let module = PyModule::from_code_bound(
|
||||
# py,
|
||||
# "class Foo:
|
||||
# def __init__(self):
|
||||
|
@ -111,7 +111,7 @@ struct RustyStruct {
|
|||
#
|
||||
# fn main() -> PyResult<()> {
|
||||
# Python::with_gil(|py| -> PyResult<()> {
|
||||
# let module = PyModule::from_code(
|
||||
# let module = PyModule::from_code_bound(
|
||||
# py,
|
||||
# "class Foo(dict):
|
||||
# def __init__(self):
|
||||
|
@ -339,7 +339,7 @@ enum RustyEnum<'a> {
|
|||
# );
|
||||
# }
|
||||
# {
|
||||
# let module = PyModule::from_code(
|
||||
# let module = PyModule::from_code_bound(
|
||||
# py,
|
||||
# "class Foo(dict):
|
||||
# def __init__(self):
|
||||
|
@ -364,7 +364,7 @@ enum RustyEnum<'a> {
|
|||
# }
|
||||
#
|
||||
# {
|
||||
# let module = PyModule::from_code(
|
||||
# let module = PyModule::from_code_bound(
|
||||
# py,
|
||||
# "class Foo(dict):
|
||||
# def __init__(self):
|
||||
|
|
|
@ -138,7 +138,7 @@ fn increment(x: u64, amount: Option<u64>) -> u64 {
|
|||
# Python::with_gil(|py| {
|
||||
# let fun = pyo3::wrap_pyfunction!(increment, py)?;
|
||||
#
|
||||
# let inspect = PyModule::import(py, "inspect")?.getattr("signature")?;
|
||||
# let inspect = PyModule::import_bound(py, "inspect")?.getattr("signature")?;
|
||||
# let sig: String = inspect
|
||||
# .call1((fun,))?
|
||||
# .call_method0("__str__")?
|
||||
|
@ -166,7 +166,7 @@ fn increment(x: u64, amount: Option<u64>) -> u64 {
|
|||
# Python::with_gil(|py| {
|
||||
# let fun = pyo3::wrap_pyfunction!(increment, py)?;
|
||||
#
|
||||
# let inspect = PyModule::import(py, "inspect")?.getattr("signature")?;
|
||||
# let inspect = PyModule::import_bound(py, "inspect")?.getattr("signature")?;
|
||||
# let sig: String = inspect
|
||||
# .call1((fun,))?
|
||||
# .call_method0("__str__")?
|
||||
|
@ -209,7 +209,7 @@ fn add(a: u64, b: u64) -> u64 {
|
|||
# let doc: String = fun.getattr("__doc__")?.extract()?;
|
||||
# assert_eq!(doc, "This function adds two unsigned 64-bit integers.");
|
||||
#
|
||||
# let inspect = PyModule::import(py, "inspect")?.getattr("signature")?;
|
||||
# let inspect = PyModule::import_bound(py, "inspect")?.getattr("signature")?;
|
||||
# let sig: String = inspect
|
||||
# .call1((fun,))?
|
||||
# .call_method0("__str__")?
|
||||
|
@ -257,7 +257,7 @@ fn add(a: u64, b: u64) -> u64 {
|
|||
# let doc: String = fun.getattr("__doc__")?.extract()?;
|
||||
# assert_eq!(doc, "This function adds two unsigned 64-bit integers.");
|
||||
#
|
||||
# let inspect = PyModule::import(py, "inspect")?.getattr("signature")?;
|
||||
# let inspect = PyModule::import_bound(py, "inspect")?.getattr("signature")?;
|
||||
# let sig: String = inspect
|
||||
# .call1((fun,))?
|
||||
# .call_method0("__str__")?
|
||||
|
|
|
@ -78,9 +78,9 @@ fn parent_module(py: Python<'_>, m: &PyModule) -> PyResult<()> {
|
|||
}
|
||||
|
||||
fn register_child_module(py: Python<'_>, parent_module: &PyModule) -> PyResult<()> {
|
||||
let child_module = PyModule::new(py, "child_module")?;
|
||||
child_module.add_function(wrap_pyfunction!(func, child_module)?)?;
|
||||
parent_module.add_submodule(child_module)?;
|
||||
let child_module = PyModule::new_bound(py, "child_module")?;
|
||||
child_module.add_function(&wrap_pyfunction!(func, child_module.as_gil_ref())?.as_borrowed())?;
|
||||
parent_module.add_submodule(child_module.as_gil_ref())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ fn main() -> PyResult<()> {
|
|||
let arg3 = "arg3";
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let fun: Py<PyAny> = PyModule::from_code(
|
||||
let fun: Py<PyAny> = PyModule::from_code_bound(
|
||||
py,
|
||||
"def example(*args, **kwargs):
|
||||
if args != ():
|
||||
|
@ -78,7 +78,7 @@ fn main() -> PyResult<()> {
|
|||
let val2 = 2;
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let fun: Py<PyAny> = PyModule::from_code(
|
||||
let fun: Py<PyAny> = PyModule::from_code_bound(
|
||||
py,
|
||||
"def example(*args, **kwargs):
|
||||
if args != ():
|
||||
|
@ -134,7 +134,7 @@ use pyo3::prelude::*;
|
|||
|
||||
fn main() -> PyResult<()> {
|
||||
Python::with_gil(|py| {
|
||||
let builtins = PyModule::import(py, "builtins")?;
|
||||
let builtins = PyModule::import_bound(py, "builtins")?;
|
||||
let total: i32 = builtins
|
||||
.getattr("sum")?
|
||||
.call1((vec![1, 2, 3],))?
|
||||
|
@ -233,7 +233,7 @@ use pyo3::{
|
|||
|
||||
# fn main() -> PyResult<()> {
|
||||
Python::with_gil(|py| {
|
||||
let activators = PyModule::from_code(
|
||||
let activators = PyModule::from_code_bound(
|
||||
py,
|
||||
r#"
|
||||
def relu(x):
|
||||
|
@ -253,7 +253,7 @@ def leaky_relu(x, slope=0.01):
|
|||
let kwargs = [("slope", 0.2)].into_py_dict_bound(py);
|
||||
let lrelu_result: f64 = activators
|
||||
.getattr("leaky_relu")?
|
||||
.call((-1.0,), Some(kwargs.as_gil_ref()))?
|
||||
.call((-1.0,), Some(&kwargs))?
|
||||
.extract()?;
|
||||
assert_eq!(lrelu_result, -0.2);
|
||||
# Ok(())
|
||||
|
@ -310,12 +310,12 @@ pub fn add_one(x: i64) -> i64 {
|
|||
fn main() -> PyResult<()> {
|
||||
Python::with_gil(|py| {
|
||||
// Create new module
|
||||
let foo_module = PyModule::new(py, "foo")?;
|
||||
foo_module.add_function(wrap_pyfunction!(add_one, foo_module)?)?;
|
||||
let foo_module = PyModule::new_bound(py, "foo")?;
|
||||
foo_module.add_function(&wrap_pyfunction!(add_one, foo_module.as_gil_ref())?.as_borrowed())?;
|
||||
|
||||
// Import and get sys.modules
|
||||
let sys = PyModule::import(py, "sys")?;
|
||||
let py_modules: &PyDict = sys.getattr("modules")?.downcast()?;
|
||||
let sys = PyModule::import_bound(py, "sys")?;
|
||||
let py_modules: Bound<'_, PyDict> = sys.getattr("modules")?.downcast_into()?;
|
||||
|
||||
// Insert foo into sys.modules
|
||||
py_modules.set_item("foo", foo_module)?;
|
||||
|
@ -381,8 +381,8 @@ fn main() -> PyResult<()> {
|
|||
));
|
||||
let py_app = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/python_app/app.py"));
|
||||
let from_python = Python::with_gil(|py| -> PyResult<Py<PyAny>> {
|
||||
PyModule::from_code(py, py_foo, "utils.foo", "utils.foo")?;
|
||||
let app: Py<PyAny> = PyModule::from_code(py, py_app, "", "")?
|
||||
PyModule::from_code_bound(py, py_foo, "utils.foo", "utils.foo")?;
|
||||
let app: Py<PyAny> = PyModule::from_code_bound(py, py_app, "", "")?
|
||||
.getattr("run")?
|
||||
.into();
|
||||
app.call0(py)
|
||||
|
@ -416,7 +416,7 @@ fn main() -> PyResult<()> {
|
|||
let from_python = Python::with_gil(|py| -> PyResult<Py<PyAny>> {
|
||||
let syspath = py.import_bound("sys")?.getattr("path")?.downcast_into::<PyList>()?;
|
||||
syspath.insert(0, &path)?;
|
||||
let app: Py<PyAny> = PyModule::from_code(py, &py_app, "", "")?
|
||||
let app: Py<PyAny> = PyModule::from_code_bound(py, &py_app, "", "")?
|
||||
.getattr("run")?
|
||||
.into();
|
||||
app.call0(py)
|
||||
|
@ -440,7 +440,7 @@ use pyo3::prelude::*;
|
|||
|
||||
fn main() {
|
||||
Python::with_gil(|py| {
|
||||
let custom_manager = PyModule::from_code(
|
||||
let custom_manager = PyModule::from_code_bound(
|
||||
py,
|
||||
r#"
|
||||
class House(object):
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
use std::hint::black_box;
|
||||
|
||||
use codspeed_criterion_compat::{criterion_group, criterion_main, Bencher, Criterion};
|
||||
|
||||
use pyo3::prelude::*;
|
||||
|
||||
macro_rules! test_module {
|
||||
($py:ident, $code:literal) => {
|
||||
PyModule::from_code($py, $code, file!(), "test_module").expect("module creation failed")
|
||||
PyModule::from_code_bound($py, $code, file!(), "test_module")
|
||||
.expect("module creation failed")
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -12,11 +15,11 @@ fn bench_call_0(b: &mut Bencher<'_>) {
|
|||
Python::with_gil(|py| {
|
||||
let module = test_module!(py, "def foo(): pass");
|
||||
|
||||
let foo_module = module.getattr("foo").unwrap();
|
||||
let foo_module = &module.getattr("foo").unwrap();
|
||||
|
||||
b.iter(|| {
|
||||
for _ in 0..1000 {
|
||||
foo_module.call0().unwrap();
|
||||
black_box(foo_module).call0().unwrap();
|
||||
}
|
||||
});
|
||||
})
|
||||
|
@ -33,11 +36,11 @@ class Foo:
|
|||
"
|
||||
);
|
||||
|
||||
let foo_module = module.getattr("Foo").unwrap().call0().unwrap();
|
||||
let foo_module = &module.getattr("Foo").unwrap().call0().unwrap();
|
||||
|
||||
b.iter(|| {
|
||||
for _ in 0..1000 {
|
||||
foo_module.call_method0("foo").unwrap();
|
||||
black_box(foo_module).call_method0("foo").unwrap();
|
||||
}
|
||||
});
|
||||
})
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use std::hint::black_box;
|
||||
|
||||
use codspeed_criterion_compat::{criterion_group, criterion_main, Bencher, Criterion};
|
||||
|
||||
use pyo3::prelude::*;
|
||||
|
@ -6,17 +8,17 @@ use pyo3::intern;
|
|||
|
||||
fn getattr_direct(b: &mut Bencher<'_>) {
|
||||
Python::with_gil(|py| {
|
||||
let sys = py.import_bound("sys").unwrap();
|
||||
let sys = &py.import_bound("sys").unwrap();
|
||||
|
||||
b.iter(|| sys.getattr("version").unwrap());
|
||||
b.iter(|| black_box(sys).getattr("version").unwrap());
|
||||
});
|
||||
}
|
||||
|
||||
fn getattr_intern(b: &mut Bencher<'_>) {
|
||||
Python::with_gil(|py| {
|
||||
let sys = py.import_bound("sys").unwrap();
|
||||
let sys = &py.import_bound("sys").unwrap();
|
||||
|
||||
b.iter(|| sys.getattr(intern!(py, "version")).unwrap());
|
||||
b.iter(|| black_box(sys).getattr(intern!(py, "version")).unwrap());
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -39,8 +39,8 @@ fn pyo3_pytests(py: Python<'_>, m: &PyModule) -> PyResult<()> {
|
|||
// Inserting to sys.modules allows importing submodules nicely from Python
|
||||
// e.g. import pyo3_pytests.buf_and_str as bas
|
||||
|
||||
let sys = PyModule::import(py, "sys")?;
|
||||
let sys_modules: &PyDict = sys.getattr("modules")?.downcast()?;
|
||||
let sys = PyModule::import_bound(py, "sys")?;
|
||||
let sys_modules = sys.getattr("modules")?.downcast_into::<PyDict>()?;
|
||||
sys_modules.set_item("pyo3_pytests.awaitable", m.getattr("awaitable")?)?;
|
||||
sys_modules.set_item("pyo3_pytests.buf_and_str", m.getattr("buf_and_str")?)?;
|
||||
sys_modules.set_item("pyo3_pytests.comparisons", m.getattr("comparisons")?)?;
|
||||
|
|
|
@ -75,7 +75,7 @@
|
|||
//! // could call inside an application...
|
||||
//! // This might return a `PyErr`.
|
||||
//! let res = Python::with_gil(|py| {
|
||||
//! let zlib = PyModule::import(py, "zlib")?;
|
||||
//! let zlib = PyModule::import_bound(py, "zlib")?;
|
||||
//! let decompress = zlib.getattr("decompress")?;
|
||||
//! let bytes = PyBytes::new_bound(py, bytes);
|
||||
//! let value = decompress.call1((bytes,))?;
|
||||
|
|
|
@ -564,7 +564,7 @@ fn timezone_utc_bound(py: Python<'_>) -> Bound<'_, PyAny> {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{types::PyTuple, Py};
|
||||
use crate::{types::PyTuple, Bound, Py};
|
||||
use std::{cmp::Ordering, panic};
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -69,6 +69,8 @@ impl FromPyObject<'_> for Tz {
|
|||
|
||||
#[cfg(all(test, not(windows)))] // Troubles loading timezones on Windows
|
||||
mod tests {
|
||||
use crate::{types::any::PyAnyMethods, Bound};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -74,7 +74,7 @@
|
|||
//! // could call inside an application...
|
||||
//! // This might return a `PyErr`.
|
||||
//! let res = Python::with_gil(|py| {
|
||||
//! let zlib = PyModule::import(py, "zlib")?;
|
||||
//! let zlib = PyModule::import_bound(py, "zlib")?;
|
||||
//! let decompress = zlib.getattr("decompress")?;
|
||||
//! let bytes = PyBytes::new_bound(py, bytes);
|
||||
//! let value = decompress.call1((bytes,))?;
|
||||
|
|
|
@ -262,7 +262,10 @@ fn int_n_bits(long: &Bound<'_, PyLong>) -> PyResult<usize> {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::types::{PyDict, PyModule};
|
||||
use crate::{
|
||||
types::{PyDict, PyModule},
|
||||
Bound,
|
||||
};
|
||||
use indoc::indoc;
|
||||
|
||||
fn rust_fib<T>() -> impl Iterator<Item = T>
|
||||
|
@ -323,7 +326,7 @@ mod tests {
|
|||
});
|
||||
}
|
||||
|
||||
fn python_index_class(py: Python<'_>) -> &PyModule {
|
||||
fn python_index_class(py: Python<'_>) -> Bound<'_, PyModule> {
|
||||
let index_code = indoc!(
|
||||
r#"
|
||||
class C:
|
||||
|
@ -333,7 +336,7 @@ mod tests {
|
|||
return self.x
|
||||
"#
|
||||
);
|
||||
PyModule::from_code(py, index_code, "index.py", "index").unwrap()
|
||||
PyModule::from_code_bound(py, index_code, "index.py", "index").unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
//! ```ignore
|
||||
//! # // not tested because nalgebra isn't supported on msrv
|
||||
//! # // please file an issue if it breaks!
|
||||
//! use nalgebra::base::{dimension::Const, storage::Storage, Matrix};
|
||||
//! use nalgebra::base::{dimension::Const, Matrix};
|
||||
//! use num_complex::Complex;
|
||||
//! use pyo3::prelude::*;
|
||||
//!
|
||||
|
@ -55,9 +55,9 @@
|
|||
//! #
|
||||
//! # fn main() -> PyResult<()> {
|
||||
//! # Python::with_gil(|py| -> PyResult<()> {
|
||||
//! # let module = PyModule::new(py, "my_module")?;
|
||||
//! # let module = PyModule::new_bound(py, "my_module")?;
|
||||
//! #
|
||||
//! # module.add_function(wrap_pyfunction!(get_eigenvalues, module)?)?;
|
||||
//! # module.add_function(&wrap_pyfunction!(get_eigenvalues, module.as_gil_ref())?.as_borrowed())?;
|
||||
//! #
|
||||
//! # let m11 = PyComplex::from_doubles_bound(py, 0_f64, -1_f64);
|
||||
//! # let m12 = PyComplex::from_doubles_bound(py, 1_f64, 0_f64);
|
||||
|
@ -199,8 +199,7 @@ complex_conversion!(f64);
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::types::complex::PyComplexMethods;
|
||||
use crate::types::PyModule;
|
||||
use crate::types::{any::PyAnyMethods, complex::PyComplexMethods, PyModule};
|
||||
|
||||
#[test]
|
||||
fn from_complex() {
|
||||
|
@ -229,7 +228,7 @@ mod tests {
|
|||
#[test]
|
||||
fn from_python_magic() {
|
||||
Python::with_gil(|py| {
|
||||
let module = PyModule::from_code(
|
||||
let module = PyModule::from_code_bound(
|
||||
py,
|
||||
r#"
|
||||
class A:
|
||||
|
@ -267,7 +266,7 @@ class C:
|
|||
#[test]
|
||||
fn from_python_inherited_magic() {
|
||||
Python::with_gil(|py| {
|
||||
let module = PyModule::from_code(
|
||||
let module = PyModule::from_code_bound(
|
||||
py,
|
||||
r#"
|
||||
class First: pass
|
||||
|
@ -311,7 +310,7 @@ class C(First, IndexMixin): pass
|
|||
// `type(inst).attr(inst)` equivalent to `inst.attr()` for methods, but this isn't the only
|
||||
// way the descriptor protocol might be implemented.
|
||||
Python::with_gil(|py| {
|
||||
let module = PyModule::from_code(
|
||||
let module = PyModule::from_code_bound(
|
||||
py,
|
||||
r#"
|
||||
class A:
|
||||
|
@ -334,7 +333,7 @@ class A:
|
|||
fn from_python_nondescriptor_magic() {
|
||||
// Magic methods don't need to implement the descriptor protocol, if they're callable.
|
||||
Python::with_gil(|py| {
|
||||
let module = PyModule::from_code(
|
||||
let module = PyModule::from_code_bound(
|
||||
py,
|
||||
r#"
|
||||
class MyComplex:
|
||||
|
|
|
@ -722,12 +722,12 @@ impl<T> IntoPy<PyObject> for Borrowed<'_, '_, T> {
|
|||
/// #
|
||||
/// # fn main() -> PyResult<()> {
|
||||
/// # Python::with_gil(|py| {
|
||||
/// # let m = pyo3::types::PyModule::new(py, "test")?;
|
||||
/// # let m = pyo3::types::PyModule::new_bound(py, "test")?;
|
||||
/// # m.add_class::<Foo>()?;
|
||||
/// #
|
||||
/// # let foo: &PyCell<Foo> = m.getattr("Foo")?.call0()?.downcast()?;
|
||||
/// # let foo: Bound<'_, Foo> = m.getattr("Foo")?.call0()?.downcast_into()?;
|
||||
/// # let dict = &foo.borrow().inner;
|
||||
/// # let dict: &PyDict = dict.as_ref(py);
|
||||
/// # let dict: &Bound<'_, PyDict> = dict.bind(py);
|
||||
/// #
|
||||
/// # Ok(())
|
||||
/// # })
|
||||
|
@ -759,10 +759,10 @@ impl<T> IntoPy<PyObject> for Borrowed<'_, '_, T> {
|
|||
/// #
|
||||
/// # fn main() -> PyResult<()> {
|
||||
/// # Python::with_gil(|py| {
|
||||
/// # let m = pyo3::types::PyModule::new(py, "test")?;
|
||||
/// # let m = pyo3::types::PyModule::new_bound(py, "test")?;
|
||||
/// # m.add_class::<Foo>()?;
|
||||
/// #
|
||||
/// # let foo: &PyCell<Foo> = m.getattr("Foo")?.call0()?.downcast()?;
|
||||
/// # let foo: Bound<'_, Foo> = m.getattr("Foo")?.call0()?.downcast_into()?;
|
||||
/// # let bar = &foo.borrow().inner;
|
||||
/// # let bar: &Bar = &*bar.borrow(py);
|
||||
/// #
|
||||
|
@ -1357,7 +1357,7 @@ impl<T> Py<T> {
|
|||
/// }
|
||||
/// #
|
||||
/// # Python::with_gil(|py| {
|
||||
/// # let ob = PyModule::new(py, "empty").unwrap().into_py(py);
|
||||
/// # let ob = PyModule::new_bound(py, "empty").unwrap().into_py(py);
|
||||
/// # set_answer(ob, py).unwrap();
|
||||
/// # });
|
||||
/// ```
|
||||
|
@ -1905,6 +1905,7 @@ impl PyObject {
|
|||
#[cfg_attr(not(feature = "gil-refs"), allow(deprecated))]
|
||||
mod tests {
|
||||
use super::{Bound, Py, PyObject};
|
||||
use crate::types::any::PyAnyMethods;
|
||||
use crate::types::PyCapsule;
|
||||
use crate::types::{dict::IntoPyDict, PyDict, PyString};
|
||||
use crate::{ffi, Borrowed, PyAny, PyNativeType, PyResult, Python, ToPyObject};
|
||||
|
@ -1978,7 +1979,7 @@ class A:
|
|||
pass
|
||||
a = A()
|
||||
"#;
|
||||
let module = PyModule::from_code(py, CODE, "", "")?;
|
||||
let module = PyModule::from_code_bound(py, CODE, "", "")?;
|
||||
let instance: Py<PyAny> = module.getattr("a")?.into();
|
||||
|
||||
instance.getattr(py, "foo").unwrap_err();
|
||||
|
@ -2005,7 +2006,7 @@ class A:
|
|||
pass
|
||||
a = A()
|
||||
"#;
|
||||
let module = PyModule::from_code(py, CODE, "", "")?;
|
||||
let module = PyModule::from_code_bound(py, CODE, "", "")?;
|
||||
let instance: Py<PyAny> = module.getattr("a")?.into();
|
||||
|
||||
let foo = crate::intern!(py, "foo");
|
||||
|
|
|
@ -764,7 +764,7 @@ impl<'py> Python<'py> {
|
|||
where
|
||||
N: IntoPy<Py<PyString>>,
|
||||
{
|
||||
PyModule::import(self, name)
|
||||
Self::import_bound(self, name).map(Bound::into_gil_ref)
|
||||
}
|
||||
|
||||
/// Imports the Python module with the specified name.
|
||||
|
@ -772,11 +772,7 @@ impl<'py> Python<'py> {
|
|||
where
|
||||
N: IntoPy<Py<PyString>>,
|
||||
{
|
||||
// FIXME: This should be replaced by `PyModule::import_bound` once thats
|
||||
// implemented.
|
||||
PyModule::import(self, name)
|
||||
.map(PyNativeType::as_borrowed)
|
||||
.map(crate::Borrowed::to_owned)
|
||||
PyModule::import_bound(self, name)
|
||||
}
|
||||
|
||||
/// Gets the Python builtin value `None`.
|
||||
|
|
|
@ -184,7 +184,7 @@ impl<T: PyClass> PyClassInitializer<T> {
|
|||
///
|
||||
/// fn main() -> PyResult<()> {
|
||||
/// Python::with_gil(|py| {
|
||||
/// let m = PyModule::new(py, "example")?;
|
||||
/// let m = PyModule::new_bound(py, "example")?;
|
||||
/// m.add_class::<SubClass>()?;
|
||||
/// m.add_class::<BaseClass>()?;
|
||||
///
|
||||
|
|
|
@ -146,16 +146,16 @@ impl PyAny {
|
|||
/// # Example: `intern!`ing the attribute name
|
||||
///
|
||||
/// ```
|
||||
/// # use pyo3::{intern, pyfunction, types::PyModule, PyAny, Python, PyResult};
|
||||
/// # use pyo3::{prelude::*, intern};
|
||||
/// #
|
||||
/// #[pyfunction]
|
||||
/// fn set_answer(ob: &PyAny) -> PyResult<()> {
|
||||
/// fn set_answer(ob: &Bound<'_, PyAny>) -> PyResult<()> {
|
||||
/// ob.setattr(intern!(ob.py(), "answer"), 42)
|
||||
/// }
|
||||
/// #
|
||||
/// # Python::with_gil(|py| {
|
||||
/// # let ob = PyModule::new(py, "empty").unwrap();
|
||||
/// # set_answer(ob).unwrap();
|
||||
/// # let ob = PyModule::new_bound(py, "empty").unwrap();
|
||||
/// # set_answer(&ob).unwrap();
|
||||
/// # });
|
||||
/// ```
|
||||
pub fn setattr<N, V>(&self, attr_name: N, value: V) -> PyResult<()>
|
||||
|
@ -346,7 +346,7 @@ impl PyAny {
|
|||
///
|
||||
/// # fn main() -> PyResult<()> {
|
||||
/// Python::with_gil(|py| -> PyResult<()> {
|
||||
/// let builtins = PyModule::import(py, "builtins")?;
|
||||
/// let builtins = PyModule::import_bound(py, "builtins")?;
|
||||
/// let print = builtins.getattr("print")?;
|
||||
/// assert!(print.is_callable());
|
||||
/// Ok(())
|
||||
|
@ -385,12 +385,12 @@ impl PyAny {
|
|||
///
|
||||
/// # fn main() -> PyResult<()> {
|
||||
/// Python::with_gil(|py| {
|
||||
/// let module = PyModule::from_code(py, CODE, "", "")?;
|
||||
/// let module = PyModule::from_code_bound(py, CODE, "", "")?;
|
||||
/// let fun = module.getattr("function")?;
|
||||
/// let args = ("hello",);
|
||||
/// let kwargs = PyDict::new_bound(py);
|
||||
/// kwargs.set_item("cruel", "world")?;
|
||||
/// let result = fun.call(args, Some(kwargs.as_gil_ref()))?;
|
||||
/// let result = fun.call(args, Some(&kwargs))?;
|
||||
/// assert_eq!(result.extract::<&str>()?, "called with args and kwargs");
|
||||
/// Ok(())
|
||||
/// })
|
||||
|
@ -417,7 +417,7 @@ impl PyAny {
|
|||
///
|
||||
/// # fn main() -> PyResult<()> {
|
||||
/// Python::with_gil(|py| -> PyResult<()> {
|
||||
/// let module = PyModule::import(py, "builtins")?;
|
||||
/// let module = PyModule::import_bound(py, "builtins")?;
|
||||
/// let help = module.getattr("help")?;
|
||||
/// help.call0()?;
|
||||
/// Ok(())
|
||||
|
@ -448,7 +448,7 @@ impl PyAny {
|
|||
///
|
||||
/// # fn main() -> PyResult<()> {
|
||||
/// Python::with_gil(|py| {
|
||||
/// let module = PyModule::from_code(py, CODE, "", "")?;
|
||||
/// let module = PyModule::from_code_bound(py, CODE, "", "")?;
|
||||
/// let fun = module.getattr("function")?;
|
||||
/// let args = ("hello",);
|
||||
/// let result = fun.call1(args)?;
|
||||
|
@ -485,12 +485,12 @@ impl PyAny {
|
|||
///
|
||||
/// # fn main() -> PyResult<()> {
|
||||
/// Python::with_gil(|py| {
|
||||
/// let module = PyModule::from_code(py, CODE, "", "")?;
|
||||
/// let module = PyModule::from_code_bound(py, CODE, "", "")?;
|
||||
/// let instance = module.getattr("a")?;
|
||||
/// let args = ("hello",);
|
||||
/// let kwargs = PyDict::new_bound(py);
|
||||
/// kwargs.set_item("cruel", "world")?;
|
||||
/// let result = instance.call_method("method", args, Some(kwargs.as_gil_ref()))?;
|
||||
/// let result = instance.call_method("method", args, Some(&kwargs))?;
|
||||
/// assert_eq!(result.extract::<&str>()?, "called with args and kwargs");
|
||||
/// Ok(())
|
||||
/// })
|
||||
|
@ -529,7 +529,7 @@ impl PyAny {
|
|||
///
|
||||
/// # fn main() -> PyResult<()> {
|
||||
/// Python::with_gil(|py| {
|
||||
/// let module = PyModule::from_code(py, CODE, "", "")?;
|
||||
/// let module = PyModule::from_code_bound(py, CODE, "", "")?;
|
||||
/// let instance = module.getattr("a")?;
|
||||
/// let result = instance.call_method0("method")?;
|
||||
/// assert_eq!(result.extract::<&str>()?, "called with no arguments");
|
||||
|
@ -569,7 +569,7 @@ impl PyAny {
|
|||
///
|
||||
/// # fn main() -> PyResult<()> {
|
||||
/// Python::with_gil(|py| {
|
||||
/// let module = PyModule::from_code(py, CODE, "", "")?;
|
||||
/// let module = PyModule::from_code_bound(py, CODE, "", "")?;
|
||||
/// let instance = module.getattr("a")?;
|
||||
/// let args = ("hello",);
|
||||
/// let result = instance.call_method1("method", args)?;
|
||||
|
@ -1008,16 +1008,16 @@ pub trait PyAnyMethods<'py> {
|
|||
/// # Example: `intern!`ing the attribute name
|
||||
///
|
||||
/// ```
|
||||
/// # use pyo3::{intern, pyfunction, types::PyModule, PyAny, Python, PyResult};
|
||||
/// # use pyo3::{prelude::*, intern};
|
||||
/// #
|
||||
/// #[pyfunction]
|
||||
/// fn set_answer(ob: &PyAny) -> PyResult<()> {
|
||||
/// fn set_answer(ob: &Bound<'_, PyAny>) -> PyResult<()> {
|
||||
/// ob.setattr(intern!(ob.py(), "answer"), 42)
|
||||
/// }
|
||||
/// #
|
||||
/// # Python::with_gil(|py| {
|
||||
/// # let ob = PyModule::new(py, "empty").unwrap();
|
||||
/// # set_answer(ob).unwrap();
|
||||
/// # let ob = PyModule::new_bound(py, "empty").unwrap();
|
||||
/// # set_answer(&ob).unwrap();
|
||||
/// # });
|
||||
/// ```
|
||||
fn setattr<N, V>(&self, attr_name: N, value: V) -> PyResult<()>
|
||||
|
@ -1228,7 +1228,7 @@ pub trait PyAnyMethods<'py> {
|
|||
///
|
||||
/// # fn main() -> PyResult<()> {
|
||||
/// Python::with_gil(|py| -> PyResult<()> {
|
||||
/// let builtins = PyModule::import(py, "builtins")?;
|
||||
/// let builtins = PyModule::import_bound(py, "builtins")?;
|
||||
/// let print = builtins.getattr("print")?;
|
||||
/// assert!(print.is_callable());
|
||||
/// Ok(())
|
||||
|
@ -1265,12 +1265,12 @@ pub trait PyAnyMethods<'py> {
|
|||
///
|
||||
/// # fn main() -> PyResult<()> {
|
||||
/// Python::with_gil(|py| {
|
||||
/// let module = PyModule::from_code(py, CODE, "", "")?;
|
||||
/// let module = PyModule::from_code_bound(py, CODE, "", "")?;
|
||||
/// let fun = module.getattr("function")?;
|
||||
/// let args = ("hello",);
|
||||
/// let kwargs = PyDict::new_bound(py);
|
||||
/// kwargs.set_item("cruel", "world")?;
|
||||
/// let result = fun.call(args, Some(kwargs.as_gil_ref()))?;
|
||||
/// let result = fun.call(args, Some(&kwargs))?;
|
||||
/// assert_eq!(result.extract::<&str>()?, "called with args and kwargs");
|
||||
/// Ok(())
|
||||
/// })
|
||||
|
@ -1293,7 +1293,7 @@ pub trait PyAnyMethods<'py> {
|
|||
///
|
||||
/// # fn main() -> PyResult<()> {
|
||||
/// Python::with_gil(|py| -> PyResult<()> {
|
||||
/// let module = PyModule::import(py, "builtins")?;
|
||||
/// let module = PyModule::import_bound(py, "builtins")?;
|
||||
/// let help = module.getattr("help")?;
|
||||
/// help.call0()?;
|
||||
/// Ok(())
|
||||
|
@ -1322,7 +1322,7 @@ pub trait PyAnyMethods<'py> {
|
|||
///
|
||||
/// # fn main() -> PyResult<()> {
|
||||
/// Python::with_gil(|py| {
|
||||
/// let module = PyModule::from_code(py, CODE, "", "")?;
|
||||
/// let module = PyModule::from_code_bound(py, CODE, "", "")?;
|
||||
/// let fun = module.getattr("function")?;
|
||||
/// let args = ("hello",);
|
||||
/// let result = fun.call1(args)?;
|
||||
|
@ -1357,12 +1357,12 @@ pub trait PyAnyMethods<'py> {
|
|||
///
|
||||
/// # fn main() -> PyResult<()> {
|
||||
/// Python::with_gil(|py| {
|
||||
/// let module = PyModule::from_code(py, CODE, "", "")?;
|
||||
/// let module = PyModule::from_code_bound(py, CODE, "", "")?;
|
||||
/// let instance = module.getattr("a")?;
|
||||
/// let args = ("hello",);
|
||||
/// let kwargs = PyDict::new_bound(py);
|
||||
/// kwargs.set_item("cruel", "world")?;
|
||||
/// let result = instance.call_method("method", args, Some(kwargs.as_gil_ref()))?;
|
||||
/// let result = instance.call_method("method", args, Some(&kwargs))?;
|
||||
/// assert_eq!(result.extract::<&str>()?, "called with args and kwargs");
|
||||
/// Ok(())
|
||||
/// })
|
||||
|
@ -1401,7 +1401,7 @@ pub trait PyAnyMethods<'py> {
|
|||
///
|
||||
/// # fn main() -> PyResult<()> {
|
||||
/// Python::with_gil(|py| {
|
||||
/// let module = PyModule::from_code(py, CODE, "", "")?;
|
||||
/// let module = PyModule::from_code_bound(py, CODE, "", "")?;
|
||||
/// let instance = module.getattr("a")?;
|
||||
/// let result = instance.call_method0("method")?;
|
||||
/// assert_eq!(result.extract::<&str>()?, "called with no arguments");
|
||||
|
@ -1436,7 +1436,7 @@ pub trait PyAnyMethods<'py> {
|
|||
///
|
||||
/// # fn main() -> PyResult<()> {
|
||||
/// Python::with_gil(|py| {
|
||||
/// let module = PyModule::from_code(py, CODE, "", "")?;
|
||||
/// let module = PyModule::from_code_bound(py, CODE, "", "")?;
|
||||
/// let instance = module.getattr("a")?;
|
||||
/// let args = ("hello",);
|
||||
/// let result = instance.call_method1("method", args)?;
|
||||
|
@ -2326,13 +2326,13 @@ mod tests {
|
|||
use crate::{
|
||||
basic::CompareOp,
|
||||
types::{any::PyAnyMethods, IntoPyDict, PyAny, PyBool, PyList, PyLong, PyModule},
|
||||
PyNativeType, PyTypeInfo, Python, ToPyObject,
|
||||
Bound, PyNativeType, PyTypeInfo, Python, ToPyObject,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn test_lookup_special() {
|
||||
Python::with_gil(|py| {
|
||||
let module = PyModule::from_code(
|
||||
let module = PyModule::from_code_bound(
|
||||
py,
|
||||
r#"
|
||||
class CustomCallable:
|
||||
|
@ -2371,13 +2371,8 @@ class NonHeapNonDescriptorInt:
|
|||
.unwrap();
|
||||
|
||||
let int = crate::intern!(py, "__int__");
|
||||
let eval_int = |obj: &PyAny| {
|
||||
obj.as_borrowed()
|
||||
.lookup_special(int)?
|
||||
.unwrap()
|
||||
.call0()?
|
||||
.extract::<u32>()
|
||||
};
|
||||
let eval_int =
|
||||
|obj: Bound<'_, PyAny>| obj.lookup_special(int)?.unwrap().call0()?.extract::<u32>();
|
||||
|
||||
let simple = module.getattr("SimpleInt").unwrap().call0().unwrap();
|
||||
assert_eq!(eval_int(simple).unwrap(), 1);
|
||||
|
@ -2430,7 +2425,7 @@ class NonHeapNonDescriptorInt:
|
|||
#[test]
|
||||
fn test_call_method0() {
|
||||
Python::with_gil(|py| {
|
||||
let module = PyModule::from_code(
|
||||
let module = PyModule::from_code_bound(
|
||||
py,
|
||||
r#"
|
||||
class SimpleClass:
|
||||
|
|
|
@ -31,7 +31,7 @@ use std::os::raw::{c_char, c_int, c_void};
|
|||
///
|
||||
/// let capsule = PyCapsule::new_bound(py, foo, Some(name.clone()))?;
|
||||
///
|
||||
/// let module = PyModule::import(py, "builtins")?;
|
||||
/// let module = PyModule::import_bound(py, "builtins")?;
|
||||
/// module.add("capsule", capsule)?;
|
||||
///
|
||||
/// let cap: &Foo = unsafe { PyCapsule::import(py, name.as_ref())? };
|
||||
|
@ -441,11 +441,13 @@ fn name_ptr_ignore_error(slf: &Bound<'_, PyCapsule>) -> *const c_char {
|
|||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[cfg_attr(not(feature = "gil-refs"), allow(deprecated))]
|
||||
mod tests {
|
||||
use libc::c_void;
|
||||
|
||||
use crate::prelude::PyModule;
|
||||
use crate::types::capsule::PyCapsuleMethods;
|
||||
use crate::types::module::PyModuleMethods;
|
||||
use crate::{types::PyCapsule, Py, PyResult, Python};
|
||||
use std::ffi::CString;
|
||||
use std::sync::mpsc::{channel, Sender};
|
||||
|
@ -528,7 +530,7 @@ mod tests {
|
|||
|
||||
let capsule = PyCapsule::new_bound(py, foo, Some(name.clone()))?;
|
||||
|
||||
let module = PyModule::import(py, "builtins")?;
|
||||
let module = PyModule::import_bound(py, "builtins")?;
|
||||
module.add("capsule", capsule)?;
|
||||
|
||||
// check error when wrong named passed for capsule.
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
use crate::callback::IntoPyCallbackOutput;
|
||||
use crate::err::{PyErr, PyResult};
|
||||
use crate::ffi_ptr_ext::FfiPtrExt;
|
||||
use crate::py_result_ext::PyResultExt;
|
||||
use crate::pyclass::PyClass;
|
||||
use crate::types::{
|
||||
any::PyAnyMethods, list::PyListMethods, PyAny, PyCFunction, PyDict, PyList, PyString,
|
||||
};
|
||||
use crate::{exceptions, ffi, Bound, FromPyObject, IntoPy, Py, PyNativeType, PyObject, Python};
|
||||
use crate::{exceptions, ffi, Bound, IntoPy, Py, PyNativeType, PyObject, Python};
|
||||
use std::ffi::CString;
|
||||
use std::str;
|
||||
|
||||
|
@ -22,6 +23,19 @@ pub struct PyModule(PyAny);
|
|||
pyobject_native_type_core!(PyModule, pyobject_native_static_type_object!(ffi::PyModule_Type), #checkfunction=ffi::PyModule_Check);
|
||||
|
||||
impl PyModule {
|
||||
/// Deprecated form of [`PyModule::new_bound`].
|
||||
#[inline]
|
||||
#[cfg_attr(
|
||||
not(feature = "gil-refs"),
|
||||
deprecated(
|
||||
since = "0.21.0",
|
||||
note = "`PyModule::new` will be replaced by `PyModule::new_bound` in a future PyO3 version"
|
||||
)
|
||||
)]
|
||||
pub fn new<'py>(py: Python<'py>, name: &str) -> PyResult<&'py PyModule> {
|
||||
Self::new_bound(py, name).map(Bound::into_gil_ref)
|
||||
}
|
||||
|
||||
/// Creates a new module object with the `__name__` attribute set to `name`.
|
||||
///
|
||||
/// # Examples
|
||||
|
@ -31,22 +45,39 @@ impl PyModule {
|
|||
///
|
||||
/// # fn main() -> PyResult<()> {
|
||||
/// Python::with_gil(|py| -> PyResult<()> {
|
||||
/// let module = PyModule::new(py, "my_module")?;
|
||||
/// let module = PyModule::new_bound(py, "my_module")?;
|
||||
///
|
||||
/// assert_eq!(module.name()?, "my_module");
|
||||
/// assert_eq!(module.name()?.to_cow()?, "my_module");
|
||||
/// Ok(())
|
||||
/// })?;
|
||||
/// # Ok(())}
|
||||
/// ```
|
||||
pub fn new<'p>(py: Python<'p>, name: &str) -> PyResult<&'p PyModule> {
|
||||
pub fn new_bound<'py>(py: Python<'py>, name: &str) -> PyResult<Bound<'py, PyModule>> {
|
||||
// Could use PyModule_NewObject, but it doesn't exist on PyPy.
|
||||
let name = CString::new(name)?;
|
||||
#[allow(deprecated)]
|
||||
unsafe {
|
||||
py.from_owned_ptr_or_err(ffi::PyModule_New(name.as_ptr()))
|
||||
ffi::PyModule_New(name.as_ptr())
|
||||
.assume_owned_or_err(py)
|
||||
.downcast_into_unchecked()
|
||||
}
|
||||
}
|
||||
|
||||
/// Deprecated form of [`PyModule::import_bound`].
|
||||
#[inline]
|
||||
#[cfg_attr(
|
||||
not(feature = "gil-refs"),
|
||||
deprecated(
|
||||
since = "0.21.0",
|
||||
note = "`PyModule::import` will be replaced by `PyModule::import_bound` in a future PyO3 version"
|
||||
)
|
||||
)]
|
||||
pub fn import<N>(py: Python<'_>, name: N) -> PyResult<&PyModule>
|
||||
where
|
||||
N: IntoPy<Py<PyString>>,
|
||||
{
|
||||
Self::import_bound(py, name).map(Bound::into_gil_ref)
|
||||
}
|
||||
|
||||
/// Imports the Python module with the specified name.
|
||||
///
|
||||
/// # Examples
|
||||
|
@ -56,7 +87,7 @@ impl PyModule {
|
|||
/// use pyo3::prelude::*;
|
||||
///
|
||||
/// Python::with_gil(|py| {
|
||||
/// let module = PyModule::import(py, "antigravity").expect("No flying for you.");
|
||||
/// let module = PyModule::import_bound(py, "antigravity").expect("No flying for you.");
|
||||
/// });
|
||||
/// # }
|
||||
/// ```
|
||||
|
@ -65,17 +96,36 @@ impl PyModule {
|
|||
/// ```python
|
||||
/// import antigravity
|
||||
/// ```
|
||||
pub fn import<N>(py: Python<'_>, name: N) -> PyResult<&PyModule>
|
||||
pub fn import_bound<N>(py: Python<'_>, name: N) -> PyResult<Bound<'_, PyModule>>
|
||||
where
|
||||
N: IntoPy<Py<PyString>>,
|
||||
{
|
||||
let name: Py<PyString> = name.into_py(py);
|
||||
#[allow(deprecated)]
|
||||
unsafe {
|
||||
py.from_owned_ptr_or_err(ffi::PyImport_Import(name.as_ptr()))
|
||||
ffi::PyImport_Import(name.as_ptr())
|
||||
.assume_owned_or_err(py)
|
||||
.downcast_into_unchecked()
|
||||
}
|
||||
}
|
||||
|
||||
/// Deprecated form of [`PyModule::from_code_bound`].
|
||||
#[inline]
|
||||
#[cfg_attr(
|
||||
not(feature = "gil-refs"),
|
||||
deprecated(
|
||||
since = "0.21.0",
|
||||
note = "`PyModule::from_code` will be replaced by `PyModule::from_code_bound` in a future PyO3 version"
|
||||
)
|
||||
)]
|
||||
pub fn from_code<'py>(
|
||||
py: Python<'py>,
|
||||
code: &str,
|
||||
file_name: &str,
|
||||
module_name: &str,
|
||||
) -> PyResult<&'py PyModule> {
|
||||
Self::from_code_bound(py, code, file_name, module_name).map(Bound::into_gil_ref)
|
||||
}
|
||||
|
||||
/// Creates and loads a module named `module_name`,
|
||||
/// containing the Python code passed to `code`
|
||||
/// and pretending to live at `file_name`.
|
||||
|
@ -105,7 +155,7 @@ impl PyModule {
|
|||
/// let code = include_str!("../../assets/script.py");
|
||||
///
|
||||
/// Python::with_gil(|py| -> PyResult<()> {
|
||||
/// PyModule::from_code(py, code, "example.py", "example")?;
|
||||
/// PyModule::from_code_bound(py, code, "example.py", "example")?;
|
||||
/// Ok(())
|
||||
/// })?;
|
||||
/// # Ok(())
|
||||
|
@ -124,36 +174,29 @@ impl PyModule {
|
|||
/// let code = std::fs::read_to_string("assets/script.py")?;
|
||||
///
|
||||
/// Python::with_gil(|py| -> PyResult<()> {
|
||||
/// PyModule::from_code(py, &code, "example.py", "example")?;
|
||||
/// PyModule::from_code_bound(py, &code, "example.py", "example")?;
|
||||
/// Ok(())
|
||||
/// })?;
|
||||
/// Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn from_code<'p>(
|
||||
py: Python<'p>,
|
||||
pub fn from_code_bound<'py>(
|
||||
py: Python<'py>,
|
||||
code: &str,
|
||||
file_name: &str,
|
||||
module_name: &str,
|
||||
) -> PyResult<&'p PyModule> {
|
||||
) -> PyResult<Bound<'py, PyModule>> {
|
||||
let data = CString::new(code)?;
|
||||
let filename = CString::new(file_name)?;
|
||||
let module = CString::new(module_name)?;
|
||||
|
||||
unsafe {
|
||||
let cptr = ffi::Py_CompileString(data.as_ptr(), filename.as_ptr(), ffi::Py_file_input);
|
||||
if cptr.is_null() {
|
||||
return Err(PyErr::fetch(py));
|
||||
}
|
||||
let code = ffi::Py_CompileString(data.as_ptr(), filename.as_ptr(), ffi::Py_file_input)
|
||||
.assume_owned_or_err(py)?;
|
||||
|
||||
let mptr = ffi::PyImport_ExecCodeModuleEx(module.as_ptr(), cptr, filename.as_ptr());
|
||||
ffi::Py_DECREF(cptr);
|
||||
if mptr.is_null() {
|
||||
return Err(PyErr::fetch(py));
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
<&PyModule as FromPyObject>::extract(py.from_owned_ptr_or_err(mptr)?)
|
||||
ffi::PyImport_ExecCodeModuleEx(module.as_ptr(), code.as_ptr(), filename.as_ptr())
|
||||
.assume_owned_or_err(py)
|
||||
.downcast_into()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -293,10 +336,10 @@ impl PyModule {
|
|||
///
|
||||
/// #[pymodule]
|
||||
/// fn my_module(py: Python<'_>, module: &PyModule) -> PyResult<()> {
|
||||
/// let submodule = PyModule::new(py, "submodule")?;
|
||||
/// let submodule = PyModule::new_bound(py, "submodule")?;
|
||||
/// submodule.add("super_useful_constant", "important")?;
|
||||
///
|
||||
/// module.add_submodule(submodule)?;
|
||||
/// module.add_submodule(submodule.as_gil_ref())?;
|
||||
/// Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
|
@ -487,10 +530,10 @@ pub trait PyModuleMethods<'py> {
|
|||
///
|
||||
/// #[pymodule]
|
||||
/// fn my_module(py: Python<'_>, module: &PyModule) -> PyResult<()> {
|
||||
/// let submodule = PyModule::new(py, "submodule")?;
|
||||
/// let submodule = PyModule::new_bound(py, "submodule")?;
|
||||
/// submodule.add("super_useful_constant", "important")?;
|
||||
///
|
||||
/// module.add_submodule(submodule)?;
|
||||
/// module.add_submodule(submodule.as_gil_ref())?;
|
||||
/// Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
|
@ -580,8 +623,6 @@ impl<'py> PyModuleMethods<'py> for Bound<'py, PyModule> {
|
|||
fn name(&self) -> PyResult<Bound<'py, PyString>> {
|
||||
#[cfg(not(PyPy))]
|
||||
{
|
||||
use crate::py_result_ext::PyResultExt;
|
||||
|
||||
unsafe {
|
||||
ffi::PyModule_GetNameObject(self.as_ptr())
|
||||
.assume_owned_or_err(self.py())
|
||||
|
@ -601,8 +642,6 @@ impl<'py> PyModuleMethods<'py> for Bound<'py, PyModule> {
|
|||
|
||||
#[cfg(not(PyPy))]
|
||||
fn filename(&self) -> PyResult<Bound<'py, PyString>> {
|
||||
use crate::py_result_ext::PyResultExt;
|
||||
|
||||
unsafe {
|
||||
ffi::PyModule_GetFilenameObject(self.as_ptr())
|
||||
.assume_owned_or_err(self.py())
|
||||
|
@ -676,14 +715,21 @@ fn __name__(py: Python<'_>) -> &Bound<'_, PyString> {
|
|||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[cfg_attr(not(feature = "gil-refs"), allow(deprecated))]
|
||||
mod tests {
|
||||
use crate::{types::PyModule, Python};
|
||||
use crate::{
|
||||
types::{module::PyModuleMethods, string::PyStringMethods, PyModule},
|
||||
Python,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn module_import_and_name() {
|
||||
Python::with_gil(|py| {
|
||||
let builtins = PyModule::import(py, "builtins").unwrap();
|
||||
assert_eq!(builtins.name().unwrap(), "builtins");
|
||||
let builtins = PyModule::import_bound(py, "builtins").unwrap();
|
||||
assert_eq!(
|
||||
builtins.name().unwrap().to_cow().unwrap().as_ref(),
|
||||
"builtins"
|
||||
);
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -691,8 +737,13 @@ mod tests {
|
|||
#[cfg(not(PyPy))]
|
||||
fn module_filename() {
|
||||
Python::with_gil(|py| {
|
||||
let site = PyModule::import(py, "site").unwrap();
|
||||
assert!(site.filename().unwrap().ends_with("site.py"));
|
||||
let site = PyModule::import_bound(py, "site").unwrap();
|
||||
assert!(site
|
||||
.filename()
|
||||
.unwrap()
|
||||
.to_cow()
|
||||
.unwrap()
|
||||
.ends_with("site.py"));
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
use crate::err::{error_on_minusone, PyResult};
|
||||
use crate::types::PyString;
|
||||
use crate::types::{any::PyAnyMethods, string::PyStringMethods, PyString};
|
||||
use crate::{ffi, Bound};
|
||||
use crate::{PyAny, PyNativeType};
|
||||
|
||||
use super::any::PyAnyMethods;
|
||||
use super::string::PyStringMethods;
|
||||
|
||||
/// Represents a Python traceback.
|
||||
#[repr(transparent)]
|
||||
pub struct PyTraceback(PyAny);
|
||||
|
|
|
@ -154,7 +154,7 @@ struct EmptyClassInModule {}
|
|||
#[ignore]
|
||||
fn empty_class_in_module() {
|
||||
Python::with_gil(|py| {
|
||||
let module = PyModule::new(py, "test_module.nested").unwrap();
|
||||
let module = PyModule::new_bound(py, "test_module.nested").unwrap();
|
||||
module.add_class::<EmptyClassInModule>().unwrap();
|
||||
|
||||
let ty = module.getattr("EmptyClassInModule").unwrap();
|
||||
|
|
|
@ -169,10 +169,7 @@ c = Class()
|
|||
assert c.from_rust is False
|
||||
"#
|
||||
);
|
||||
let globals = PyModule::import(py, "__main__")
|
||||
.unwrap()
|
||||
.dict()
|
||||
.as_borrowed();
|
||||
let globals = PyModule::import_bound(py, "__main__").unwrap().dict();
|
||||
globals.set_item("SuperClass", super_cls).unwrap();
|
||||
py.run_bound(source, Some(&globals), None)
|
||||
.map_err(|e| e.display(py))
|
||||
|
|
|
@ -354,7 +354,7 @@ fn module_add_class_inherit_bool_fails() {
|
|||
struct ExtendsBool;
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let m = PyModule::new(py, "test_module").unwrap();
|
||||
let m = PyModule::new_bound(py, "test_module").unwrap();
|
||||
|
||||
let err = m.add_class::<ExtendsBool>().unwrap_err();
|
||||
assert_eq!(
|
||||
|
|
|
@ -135,9 +135,9 @@ fn test_module_renaming() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn test_module_from_code() {
|
||||
fn test_module_from_code_bound() {
|
||||
Python::with_gil(|py| {
|
||||
let adder_mod = PyModule::from_code(
|
||||
let adder_mod = PyModule::from_code_bound(
|
||||
py,
|
||||
"def add(a,b):\n\treturn a+b",
|
||||
"adder_mod.py",
|
||||
|
@ -239,8 +239,8 @@ fn subfunction() -> String {
|
|||
"Subfunction".to_string()
|
||||
}
|
||||
|
||||
fn submodule(module: &PyModule) -> PyResult<()> {
|
||||
module.add_function(wrap_pyfunction!(subfunction, module)?)?;
|
||||
fn submodule(module: &Bound<'_, PyModule>) -> PyResult<()> {
|
||||
module.add_function(&wrap_pyfunction!(subfunction, module.as_gil_ref())?.as_borrowed())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -258,12 +258,12 @@ fn superfunction() -> String {
|
|||
#[pymodule]
|
||||
fn supermodule(py: Python<'_>, module: &PyModule) -> PyResult<()> {
|
||||
module.add_function(wrap_pyfunction!(superfunction, module)?)?;
|
||||
let module_to_add = PyModule::new(py, "submodule")?;
|
||||
submodule(module_to_add)?;
|
||||
module.add_submodule(module_to_add)?;
|
||||
let module_to_add = PyModule::new(py, "submodule_with_init_fn")?;
|
||||
submodule_with_init_fn(py, module_to_add)?;
|
||||
module.add_submodule(module_to_add)?;
|
||||
let module_to_add = PyModule::new_bound(py, "submodule")?;
|
||||
submodule(&module_to_add)?;
|
||||
module.add_submodule(module_to_add.as_gil_ref())?;
|
||||
let module_to_add = PyModule::new_bound(py, "submodule_with_init_fn")?;
|
||||
submodule_with_init_fn(py, module_to_add.as_gil_ref())?;
|
||||
module.add_submodule(module_to_add.as_gil_ref())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -697,10 +697,7 @@ if sys.platform == "win32" and sys.version_info >= (3, 8, 0):
|
|||
|
||||
asyncio.run(main())
|
||||
"#;
|
||||
let globals = PyModule::import(py, "__main__")
|
||||
.unwrap()
|
||||
.dict()
|
||||
.as_borrowed();
|
||||
let globals = PyModule::import_bound(py, "__main__").unwrap().dict();
|
||||
globals.set_item("Once", once).unwrap();
|
||||
py.run_bound(source, Some(&globals), None)
|
||||
.map_err(|e| e.display(py))
|
||||
|
@ -754,10 +751,7 @@ if sys.platform == "win32" and sys.version_info >= (3, 8, 0):
|
|||
|
||||
asyncio.run(main())
|
||||
"#;
|
||||
let globals = PyModule::import(py, "__main__")
|
||||
.unwrap()
|
||||
.dict()
|
||||
.as_borrowed();
|
||||
let globals = PyModule::import_bound(py, "__main__").unwrap().dict();
|
||||
globals.set_item("Once", once).unwrap();
|
||||
globals
|
||||
.set_item("AsyncIterator", py.get_type_bound::<AsyncIterator>())
|
||||
|
@ -829,10 +823,7 @@ del c.counter
|
|||
assert c.counter.count == 1
|
||||
"#
|
||||
);
|
||||
let globals = PyModule::import(py, "__main__")
|
||||
.unwrap()
|
||||
.dict()
|
||||
.as_borrowed();
|
||||
let globals = PyModule::import_bound(py, "__main__").unwrap().dict();
|
||||
globals.set_item("Counter", counter).unwrap();
|
||||
py.run_bound(source, Some(&globals), None)
|
||||
.map_err(|e| e.display(py))
|
||||
|
|
|
@ -133,8 +133,8 @@ impl PickleSupport {
|
|||
}
|
||||
}
|
||||
|
||||
fn add_module(py: Python<'_>, module: &PyModule) -> PyResult<()> {
|
||||
py.import_bound("sys")?
|
||||
fn add_module(module: Bound<'_, PyModule>) -> PyResult<()> {
|
||||
PyModule::import_bound(module.py(), "sys")?
|
||||
.dict()
|
||||
.get_item("modules")
|
||||
.unwrap()
|
||||
|
@ -147,9 +147,9 @@ fn add_module(py: Python<'_>, module: &PyModule) -> PyResult<()> {
|
|||
#[cfg_attr(all(Py_LIMITED_API, not(Py_3_10)), ignore)]
|
||||
fn test_pickle() {
|
||||
Python::with_gil(|py| {
|
||||
let module = PyModule::new(py, "test_module").unwrap();
|
||||
let module = PyModule::new_bound(py, "test_module").unwrap();
|
||||
module.add_class::<PickleSupport>().unwrap();
|
||||
add_module(py, module).unwrap();
|
||||
add_module(module).unwrap();
|
||||
let inst = Py::new(py, PickleSupport {}).unwrap();
|
||||
py_run!(
|
||||
py,
|
||||
|
|
Loading…
Reference in New Issue