Skip to content

Commit

Permalink
add PyModule::new and PyModule::import_bound
Browse files Browse the repository at this point in the history
  • Loading branch information
davidhewitt committed Jan 29, 2024
1 parent c54d897 commit 575e0bf
Show file tree
Hide file tree
Showing 37 changed files with 249 additions and 149 deletions.
2 changes: 1 addition & 1 deletion guide/src/class.md
Original file line number Diff line number Diff line change
Expand Up @@ -911,7 +911,7 @@ 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 module = PyModule::new_bound(py, "my_module")?;
# module.add_class::<MyClass>()?;
# let class = module.getattr("MyClass")?;
#
Expand Down
6 changes: 3 additions & 3 deletions guide/src/module.md
Original file line number Diff line number Diff line change
Expand Up @@ -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())?)?;
parent_module.add_submodule(child_module.as_gil_ref())?;
Ok(())
}

Expand Down
2 changes: 1 addition & 1 deletion guide/src/python_from_rust.md
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ pub fn add_one(x: i64) -> i64 {
fn main() -> PyResult<()> {
Python::with_gil(|py| {
// Create new module
let foo_module = PyModule::new(py, "foo")?;
let foo_module = PyModule::new_bound(py, "foo")?;
foo_module.add_function(wrap_pyfunction!(add_one, foo_module)?)?;

// Import and get sys.modules
Expand Down
13 changes: 8 additions & 5 deletions pyo3-benches/benches/bench_call.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
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")
};
}

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();
}
});
})
Expand All @@ -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();
}
});
})
Expand Down
10 changes: 6 additions & 4 deletions pyo3-benches/benches/bench_intern.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::hint::black_box;

use codspeed_criterion_compat::{criterion_group, criterion_main, Bencher, Criterion};

use pyo3::prelude::*;
Expand All @@ -6,17 +8,17 @@ use pyo3::intern;

fn getattr_direct(b: &mut Bencher<'_>) {
Python::with_gil(|py| {
let sys = py.import("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("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());
});
}

Expand Down
7 changes: 4 additions & 3 deletions src/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,7 @@ impl_element!(f64, Float);
mod tests {
use super::PyBuffer;
use crate::ffi;
use crate::types::any::PyAnyMethods;
use crate::Python;

#[test]
Expand Down Expand Up @@ -889,11 +890,11 @@ mod tests {
fn test_array_buffer() {
Python::with_gil(|py| {
let array = py
.import("array")
.import_bound("array")
.unwrap()
.call_method("array", ("f", (1.0, 1.5, 2.0, 2.5)), None)
.unwrap();
let buffer = PyBuffer::get(array).unwrap();
let buffer = PyBuffer::get(array.as_gil_ref()).unwrap();
assert_eq!(buffer.dimensions(), 1);
assert_eq!(buffer.item_count(), 4);
assert_eq!(buffer.format().to_str().unwrap(), "f");
Expand Down Expand Up @@ -923,7 +924,7 @@ mod tests {
assert_eq!(buffer.to_vec(py).unwrap(), [10.0, 11.0, 12.0, 13.0]);

// F-contiguous fns
let buffer = PyBuffer::get(array).unwrap();
let buffer = PyBuffer::get(array.as_gil_ref()).unwrap();
let slice = buffer.as_fortran_slice(py).unwrap();
assert_eq!(slice.len(), 4);
assert_eq!(slice[1].get(), 11.0);
Expand Down
28 changes: 14 additions & 14 deletions src/conversions/chrono.rs
Original file line number Diff line number Diff line change
Expand Up @@ -566,7 +566,7 @@ fn timezone_utc(py: Python<'_>) -> &PyAny {
#[cfg(test)]
mod tests {
use super::*;
use crate::{types::PyTuple, Py};
use crate::{types::PyTuple, Bound, Py};
use std::{cmp::Ordering, panic};

#[test]
Expand Down Expand Up @@ -682,7 +682,7 @@ mod tests {
let delta = delta.to_object(py);
let py_delta = new_py_datetime_ob(py, "timedelta", (py_days, py_seconds, py_ms));
assert!(
delta.as_ref(py).eq(py_delta).unwrap(),
delta.as_ref(py).eq(&py_delta).unwrap(),
"{}: {} != {}",
name,
delta,
Expand Down Expand Up @@ -778,7 +778,7 @@ mod tests {
.to_object(py);
let py_date = new_py_datetime_ob(py, "date", (year, month, day));
assert_eq!(
date.as_ref(py).compare(py_date).unwrap(),
date.as_ref(py).compare(&py_date).unwrap(),
Ordering::Equal,
"{}: {} != {}",
name,
Expand Down Expand Up @@ -837,7 +837,7 @@ mod tests {
),
);
assert_eq!(
datetime.as_ref(py).compare(py_datetime).unwrap(),
datetime.as_ref(py).compare(&py_datetime).unwrap(),
Ordering::Equal,
"{}: {} != {}",
name,
Expand Down Expand Up @@ -879,7 +879,7 @@ mod tests {
(year, month, day, hour, minute, second, py_ms, py_tz),
);
assert_eq!(
datetime.as_ref(py).compare(py_datetime).unwrap(),
datetime.as_ref(py).compare(&py_datetime).unwrap(),
Ordering::Equal,
"{}: {} != {}",
name,
Expand Down Expand Up @@ -1004,7 +1004,7 @@ mod tests {
Python::with_gil(|py| {
let utc = Utc.to_object(py);
let py_utc = python_utc(py);
assert!(utc.as_ref(py).is(py_utc));
assert!(utc.as_ref(py).is(&py_utc));
})
}

Expand Down Expand Up @@ -1035,7 +1035,7 @@ mod tests {
.to_object(py);
let py_time = new_py_datetime_ob(py, "time", (hour, minute, second, py_ms));
assert!(
time.as_ref(py).eq(py_time).unwrap(),
time.as_ref(py).eq(&py_time).unwrap(),
"{}: {} != {}",
name,
time,
Expand Down Expand Up @@ -1070,21 +1070,21 @@ mod tests {
})
}

fn new_py_datetime_ob<'a>(
py: Python<'a>,
fn new_py_datetime_ob<'py>(
py: Python<'py>,
name: &str,
args: impl IntoPy<Py<PyTuple>>,
) -> &'a PyAny {
py.import("datetime")
) -> Bound<'py, PyAny> {
py.import_bound("datetime")
.unwrap()
.getattr(name)
.unwrap()
.call1(args)
.unwrap()
}

fn python_utc(py: Python<'_>) -> &PyAny {
py.import("datetime")
fn python_utc(py: Python<'_>) -> Bound<'_, PyAny> {
py.import_bound("datetime")
.unwrap()
.getattr("timezone")
.unwrap()
Expand All @@ -1106,7 +1106,7 @@ mod tests {
fn test_pyo3_offset_fixed_frompyobject_created_in_python(timestamp in 0..(i32::MAX as i64), timedelta in -86399i32..=86399i32) {
Python::with_gil(|py| {

let globals = [("datetime", py.import("datetime").unwrap())].into_py_dict(py);
let globals = [("datetime", py.import_bound("datetime").unwrap())].into_py_dict(py);
let code = format!("datetime.datetime.fromtimestamp({}).replace(tzinfo=datetime.timezone(datetime.timedelta(seconds={})))", timestamp, timedelta);
let t = py.eval(&code, Some(globals), None).unwrap();

Expand Down
13 changes: 9 additions & 4 deletions src/conversions/chrono_tz.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,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]
Expand All @@ -87,7 +89,7 @@ mod tests {
#[test]
fn test_topyobject() {
Python::with_gil(|py| {
let assert_eq = |l: PyObject, r: &PyAny| {
let assert_eq = |l: PyObject, r: Bound<'_, PyAny>| {
assert!(l.as_ref(py).eq(r).unwrap());
};

Expand All @@ -103,11 +105,14 @@ mod tests {
});
}

fn new_zoneinfo<'a>(py: Python<'a>, name: &str) -> &'a PyAny {
fn new_zoneinfo<'py>(py: Python<'py>, name: &str) -> Bound<'py, PyAny> {
zoneinfo_class(py).call1((name,)).unwrap()
}

fn zoneinfo_class(py: Python<'_>) -> &PyAny {
py.import("zoneinfo").unwrap().getattr("ZoneInfo").unwrap()
fn zoneinfo_class(py: Python<'_>) -> Bound<'_, PyAny> {
py.import_bound("zoneinfo")
.unwrap()
.getattr("ZoneInfo")
.unwrap()
}
}
9 changes: 6 additions & 3 deletions src/conversions/num_bigint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,10 @@ fn int_n_bits(long: &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>
Expand Down Expand Up @@ -310,7 +313,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:
Expand All @@ -320,7 +323,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]
Expand Down
12 changes: 6 additions & 6 deletions src/conversions/num_complex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
//! #
//! # 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)?)?;
//! #
Expand Down Expand Up @@ -183,7 +183,7 @@ complex_conversion!(f64);
#[cfg(test)]
mod tests {
use super::*;
use crate::types::PyModule;
use crate::types::{any::PyAnyMethods, PyModule};

#[test]
fn from_complex() {
Expand Down Expand Up @@ -212,7 +212,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:
Expand Down Expand Up @@ -250,7 +250,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
Expand Down Expand Up @@ -294,7 +294,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:
Expand All @@ -317,7 +317,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:
Expand Down
3 changes: 2 additions & 1 deletion src/conversions/rust_decimal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
use crate::exceptions::PyValueError;
use crate::sync::GILOnceCell;
use crate::types::any::PyAnyMethods;
use crate::types::PyType;
use crate::{intern, FromPyObject, IntoPy, Py, PyAny, PyObject, PyResult, Python, ToPyObject};
use rust_decimal::Decimal;
Expand All @@ -73,7 +74,7 @@ static DECIMAL_CLS: GILOnceCell<Py<PyType>> = GILOnceCell::new();
fn get_decimal_cls(py: Python<'_>) -> PyResult<&PyType> {
DECIMAL_CLS
.get_or_try_init(py, || {
py.import(intern!(py, "decimal"))?
py.import_bound(intern!(py, "decimal"))?
.getattr(intern!(py, "Decimal"))?
.extract()
})
Expand Down
Loading

0 comments on commit 575e0bf

Please sign in to comment.