Skip to content

Commit 9c72a44

Browse files
committed
port Python::import to Bound API
1 parent e308c8d commit 9c72a44

26 files changed

+150
-106
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,10 +149,10 @@ use pyo3::types::IntoPyDict;
149149

150150
fn main() -> PyResult<()> {
151151
Python::with_gil(|py| {
152-
let sys = py.import("sys")?;
152+
let sys = py.import_bound("sys")?;
153153
let version: String = sys.getattr("version")?.extract()?;
154154

155-
let locals = [("os", py.import("os")?)].into_py_dict_bound(py);
155+
let locals = [("os", py.import_bound("os")?)].into_py_dict_bound(py);
156156
let code = "os.getenv('USER') or os.getenv('USERNAME') or 'Unknown'";
157157
let user: String = py.eval_bound(code, None, Some(&locals))?.extract()?;
158158

guide/src/python_from_rust.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,7 @@ fn main() -> PyResult<()> {
414414
let path = Path::new("/usr/share/python_app");
415415
let py_app = fs::read_to_string(path.join("app.py"))?;
416416
let from_python = Python::with_gil(|py| -> PyResult<Py<PyAny>> {
417-
let syspath: &PyList = py.import("sys")?.getattr("path")?.downcast()?;
417+
let syspath = py.import_bound("sys")?.getattr("path")?.downcast_into::<PyList>()?;
418418
syspath.insert(0, &path)?;
419419
let app: Py<PyAny> = PyModule::from_code(py, &py_app, "", "")?
420420
.getattr("run")?
@@ -498,7 +498,7 @@ use pyo3::prelude::*;
498498

499499
# fn main() -> PyResult<()> {
500500
Python::with_gil(|py| -> PyResult<()> {
501-
let signal = py.import("signal")?;
501+
let signal = py.import_bound("signal")?;
502502
// Set SIGINT to have the default action
503503
signal
504504
.getattr("signal")?

src/buffer.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -689,6 +689,7 @@ impl_element!(f64, Float);
689689
mod tests {
690690
use super::PyBuffer;
691691
use crate::ffi;
692+
use crate::types::any::PyAnyMethods;
692693
use crate::Python;
693694

694695
#[test]
@@ -890,11 +891,11 @@ mod tests {
890891
fn test_array_buffer() {
891892
Python::with_gil(|py| {
892893
let array = py
893-
.import("array")
894+
.import_bound("array")
894895
.unwrap()
895896
.call_method("array", ("f", (1.0, 1.5, 2.0, 2.5)), None)
896897
.unwrap();
897-
let buffer = PyBuffer::get(array).unwrap();
898+
let buffer = PyBuffer::get(array.as_gil_ref()).unwrap();
898899
assert_eq!(buffer.dimensions(), 1);
899900
assert_eq!(buffer.item_count(), 4);
900901
assert_eq!(buffer.format().to_str().unwrap(), "f");
@@ -924,7 +925,7 @@ mod tests {
924925
assert_eq!(buffer.to_vec(py).unwrap(), [10.0, 11.0, 12.0, 13.0]);
925926

926927
// F-contiguous fns
927-
let buffer = PyBuffer::get(array).unwrap();
928+
let buffer = PyBuffer::get(array.as_gil_ref()).unwrap();
928929
let slice = buffer.as_fortran_slice(py).unwrap();
929930
assert_eq!(slice.len(), 4);
930931
assert_eq!(slice[1].get(), 11.0);

src/conversions/chrono.rs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -540,15 +540,15 @@ impl DatetimeTypes {
540540
static TYPES: GILOnceCell<DatetimeTypes> = GILOnceCell::new();
541541
TYPES
542542
.get_or_try_init(py, || {
543-
let datetime = py.import("datetime")?;
543+
let datetime = py.import_bound("datetime")?;
544544
let timezone = datetime.getattr("timezone")?;
545545
Ok::<_, PyErr>(Self {
546546
date: datetime.getattr("date")?.into(),
547547
datetime: datetime.getattr("datetime")?.into(),
548548
time: datetime.getattr("time")?.into(),
549549
timedelta: datetime.getattr("timedelta")?.into(),
550-
timezone: timezone.into(),
551550
timezone_utc: timezone.getattr("utc")?.into(),
551+
timezone: timezone.into(),
552552
tzinfo: datetime.getattr("tzinfo")?.into(),
553553
})
554554
})
@@ -683,7 +683,7 @@ mod tests {
683683
let delta = delta.to_object(py);
684684
let py_delta = new_py_datetime_ob(py, "timedelta", (py_days, py_seconds, py_ms));
685685
assert!(
686-
delta.as_ref(py).eq(py_delta).unwrap(),
686+
delta.bind(py).eq(&py_delta).unwrap(),
687687
"{}: {} != {}",
688688
name,
689689
delta,
@@ -779,7 +779,7 @@ mod tests {
779779
.to_object(py);
780780
let py_date = new_py_datetime_ob(py, "date", (year, month, day));
781781
assert_eq!(
782-
date.as_ref(py).compare(py_date).unwrap(),
782+
date.bind(py).compare(&py_date).unwrap(),
783783
Ordering::Equal,
784784
"{}: {} != {}",
785785
name,
@@ -838,7 +838,7 @@ mod tests {
838838
),
839839
);
840840
assert_eq!(
841-
datetime.as_ref(py).compare(py_datetime).unwrap(),
841+
datetime.bind(py).compare(&py_datetime).unwrap(),
842842
Ordering::Equal,
843843
"{}: {} != {}",
844844
name,
@@ -880,7 +880,7 @@ mod tests {
880880
(year, month, day, hour, minute, second, py_ms, py_tz),
881881
);
882882
assert_eq!(
883-
datetime.as_ref(py).compare(py_datetime).unwrap(),
883+
datetime.bind(py).compare(&py_datetime).unwrap(),
884884
Ordering::Equal,
885885
"{}: {} != {}",
886886
name,
@@ -1005,7 +1005,7 @@ mod tests {
10051005
Python::with_gil(|py| {
10061006
let utc = Utc.to_object(py);
10071007
let py_utc = python_utc(py);
1008-
assert!(utc.as_ref(py).is(py_utc));
1008+
assert!(utc.bind(py).is(&py_utc));
10091009
})
10101010
}
10111011

@@ -1036,7 +1036,7 @@ mod tests {
10361036
.to_object(py);
10371037
let py_time = new_py_datetime_ob(py, "time", (hour, minute, second, py_ms));
10381038
assert!(
1039-
time.as_ref(py).eq(py_time).unwrap(),
1039+
time.bind(py).eq(&py_time).unwrap(),
10401040
"{}: {} != {}",
10411041
name,
10421042
time,
@@ -1071,21 +1071,21 @@ mod tests {
10711071
})
10721072
}
10731073

1074-
fn new_py_datetime_ob<'a>(
1075-
py: Python<'a>,
1074+
fn new_py_datetime_ob<'py>(
1075+
py: Python<'py>,
10761076
name: &str,
10771077
args: impl IntoPy<Py<PyTuple>>,
1078-
) -> &'a PyAny {
1079-
py.import("datetime")
1078+
) -> Bound<'py, PyAny> {
1079+
py.import_bound("datetime")
10801080
.unwrap()
10811081
.getattr(name)
10821082
.unwrap()
10831083
.call1(args)
10841084
.unwrap()
10851085
}
10861086

1087-
fn python_utc(py: Python<'_>) -> &PyAny {
1088-
py.import("datetime")
1087+
fn python_utc(py: Python<'_>) -> Bound<'_, PyAny> {
1088+
py.import_bound("datetime")
10891089
.unwrap()
10901090
.getattr("timezone")
10911091
.unwrap()
@@ -1108,7 +1108,7 @@ mod tests {
11081108
fn test_pyo3_offset_fixed_frompyobject_created_in_python(timestamp in 0..(i32::MAX as i64), timedelta in -86399i32..=86399i32) {
11091109
Python::with_gil(|py| {
11101110

1111-
let globals = [("datetime", py.import("datetime").unwrap())].into_py_dict_bound(py);
1111+
let globals = [("datetime", py.import_bound("datetime").unwrap())].into_py_dict_bound(py);
11121112
let code = format!("datetime.datetime.fromtimestamp({}).replace(tzinfo=datetime.timezone(datetime.timedelta(seconds={})))", timestamp, timedelta);
11131113
let t = py.eval_bound(&code, Some(&globals), None).unwrap();
11141114

src/conversions/chrono_tz.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,8 @@ mod tests {
8989
#[test]
9090
fn test_topyobject() {
9191
Python::with_gil(|py| {
92-
let assert_eq = |l: PyObject, r: &PyAny| {
93-
assert!(l.as_ref(py).eq(r).unwrap());
92+
let assert_eq = |l: PyObject, r: Bound<'_, PyAny>| {
93+
assert!(l.bind(py).eq(r).unwrap());
9494
};
9595

9696
assert_eq(
@@ -105,11 +105,14 @@ mod tests {
105105
});
106106
}
107107

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

112-
fn zoneinfo_class(py: Python<'_>) -> &PyAny {
113-
py.import("zoneinfo").unwrap().getattr("ZoneInfo").unwrap()
112+
fn zoneinfo_class(py: Python<'_>) -> Bound<'_, PyAny> {
113+
py.import_bound("zoneinfo")
114+
.unwrap()
115+
.getattr("ZoneInfo")
116+
.unwrap()
114117
}
115118
}

src/conversions/rust_decimal.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ static DECIMAL_CLS: GILOnceCell<Py<PyType>> = GILOnceCell::new();
7777
fn get_decimal_cls(py: Python<'_>) -> PyResult<&PyType> {
7878
DECIMAL_CLS
7979
.get_or_try_init(py, || {
80-
py.import(intern!(py, "decimal"))?
80+
py.import_bound(intern!(py, "decimal"))?
8181
.getattr(intern!(py, "Decimal"))?
8282
.extract()
8383
})

src/conversions/std/time.rs

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ fn unix_epoch_py(py: Python<'_>) -> &PyObject {
146146
}
147147
#[cfg(Py_LIMITED_API)]
148148
{
149-
let datetime = py.import("datetime")?;
149+
let datetime = py.import_bound("datetime")?;
150150
let utc = datetime.getattr("timezone")?.getattr("utc")?;
151151
Ok::<_, PyErr>(
152152
datetime
@@ -216,8 +216,8 @@ mod tests {
216216
#[test]
217217
fn test_duration_topyobject() {
218218
Python::with_gil(|py| {
219-
let assert_eq = |l: PyObject, r: &PyAny| {
220-
assert!(l.as_ref(py).eq(r).unwrap());
219+
let assert_eq = |l: PyObject, r: Bound<'_, PyAny>| {
220+
assert!(l.bind(py).eq(r).unwrap());
221221
};
222222

223223
assert_eq(
@@ -300,8 +300,8 @@ mod tests {
300300
#[test]
301301
fn test_time_topyobject() {
302302
Python::with_gil(|py| {
303-
let assert_eq = |l: PyObject, r: &PyAny| {
304-
assert!(l.as_ref(py).eq(r).unwrap());
303+
let assert_eq = |l: PyObject, r: Bound<'_, PyAny>| {
304+
assert!(l.bind(py).eq(r).unwrap());
305305
};
306306

307307
assert_eq(
@@ -331,7 +331,7 @@ mod tests {
331331
minute: u8,
332332
second: u8,
333333
microsecond: u32,
334-
) -> &PyAny {
334+
) -> Bound<'_, PyAny> {
335335
datetime_class(py)
336336
.call1((
337337
year,
@@ -346,13 +346,11 @@ mod tests {
346346
.unwrap()
347347
}
348348

349-
fn max_datetime(py: Python<'_>) -> &PyAny {
349+
fn max_datetime(py: Python<'_>) -> Bound<'_, PyAny> {
350350
let naive_max = datetime_class(py).getattr("max").unwrap();
351351
let kargs = PyDict::new_bound(py);
352352
kargs.set_item("tzinfo", tz_utc(py)).unwrap();
353-
naive_max
354-
.call_method("replace", (), Some(kargs.as_gil_ref()))
355-
.unwrap()
353+
naive_max.call_method("replace", (), Some(&kargs)).unwrap()
356354
}
357355

358356
#[test]
@@ -365,26 +363,37 @@ mod tests {
365363
})
366364
}
367365

368-
fn tz_utc(py: Python<'_>) -> &PyAny {
369-
py.import("datetime")
366+
fn tz_utc(py: Python<'_>) -> Bound<'_, PyAny> {
367+
py.import_bound("datetime")
370368
.unwrap()
371369
.getattr("timezone")
372370
.unwrap()
373371
.getattr("utc")
374372
.unwrap()
375373
}
376374

377-
fn new_timedelta(py: Python<'_>, days: i32, seconds: i32, microseconds: i32) -> &PyAny {
375+
fn new_timedelta(
376+
py: Python<'_>,
377+
days: i32,
378+
seconds: i32,
379+
microseconds: i32,
380+
) -> Bound<'_, PyAny> {
378381
timedelta_class(py)
379382
.call1((days, seconds, microseconds))
380383
.unwrap()
381384
}
382385

383-
fn datetime_class(py: Python<'_>) -> &PyAny {
384-
py.import("datetime").unwrap().getattr("datetime").unwrap()
386+
fn datetime_class(py: Python<'_>) -> Bound<'_, PyAny> {
387+
py.import_bound("datetime")
388+
.unwrap()
389+
.getattr("datetime")
390+
.unwrap()
385391
}
386392

387-
fn timedelta_class(py: Python<'_>) -> &PyAny {
388-
py.import("datetime").unwrap().getattr("timedelta").unwrap()
393+
fn timedelta_class(py: Python<'_>) -> Bound<'_, PyAny> {
394+
py.import_bound("datetime")
395+
.unwrap()
396+
.getattr("timedelta")
397+
.unwrap()
389398
}
390399
}

src/coroutine/waker.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::sync::GILOnceCell;
2+
use crate::types::any::PyAnyMethods;
23
use crate::types::PyCFunction;
34
use crate::{intern, wrap_pyfunction, Py, PyAny, PyObject, PyResult, Python};
45
use pyo3_macros::pyfunction;
@@ -56,7 +57,7 @@ impl LoopAndFuture {
5657
fn new(py: Python<'_>) -> PyResult<Self> {
5758
static GET_RUNNING_LOOP: GILOnceCell<PyObject> = GILOnceCell::new();
5859
let import = || -> PyResult<_> {
59-
let module = py.import("asyncio")?;
60+
let module = py.import_bound("asyncio")?;
6061
Ok(module.getattr("get_running_loop")?.into())
6162
};
6263
let event_loop = GET_RUNNING_LOOP.get_or_try_init(py, import)?.call0(py)?;

src/err/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -974,6 +974,7 @@ impl_signed_integer!(isize);
974974
mod tests {
975975
use super::PyErrState;
976976
use crate::exceptions::{self, PyTypeError, PyValueError};
977+
use crate::types::any::PyAnyMethods;
977978
use crate::{PyErr, PyTypeInfo, Python};
978979

979980
#[test]
@@ -1174,7 +1175,7 @@ mod tests {
11741175
let cls = py.get_type::<exceptions::PyUserWarning>();
11751176

11761177
// Reset warning filter to default state
1177-
let warnings = py.import("warnings").unwrap();
1178+
let warnings = py.import_bound("warnings").unwrap();
11781179
warnings.call_method0("resetwarnings").unwrap();
11791180

11801181
// First, test the warning is emitted

src/exceptions.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,13 +101,14 @@ macro_rules! import_exception {
101101
fn type_object_raw(py: $crate::Python<'_>) -> *mut $crate::ffi::PyTypeObject {
102102
use $crate::sync::GILOnceCell;
103103
use $crate::prelude::PyTracebackMethods;
104+
use $crate::prelude::PyAnyMethods;
104105
static TYPE_OBJECT: GILOnceCell<$crate::Py<$crate::types::PyType>> =
105106
GILOnceCell::new();
106107

107108
TYPE_OBJECT
108109
.get_or_init(py, || {
109110
let imp = py
110-
.import(stringify!($module))
111+
.import_bound(stringify!($module))
111112
.unwrap_or_else(|err| {
112113
let traceback = err
113114
.traceback_bound(py)
@@ -812,7 +813,7 @@ mod tests {
812813
Python::with_gil(|py| {
813814
let err: PyErr = gaierror::new_err(());
814815
let socket = py
815-
.import("socket")
816+
.import_bound("socket")
816817
.map_err(|e| e.display(py))
817818
.expect("could not import socket");
818819

@@ -836,7 +837,7 @@ mod tests {
836837
Python::with_gil(|py| {
837838
let err: PyErr = MessageError::new_err(());
838839
let email = py
839-
.import("email")
840+
.import_bound("email")
840841
.map_err(|e| e.display(py))
841842
.expect("could not import email");
842843

src/gil.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ where
143143

144144
// Import the threading module - this ensures that it will associate this thread as the "main"
145145
// thread, which is important to avoid an `AssertionError` at finalization.
146-
pool.python().import("threading").unwrap();
146+
pool.python().import_bound("threading").unwrap();
147147

148148
// Execute the closure.
149149
let result = f(pool.python());

src/impl_/pymodule.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,8 @@ mod tests {
202202
assert_eq!((*module_def.ffi_def.get()).m_doc, DOC.as_ptr() as _);
203203

204204
Python::with_gil(|py| {
205-
module_def.initializer.0(py, py.import("builtins").unwrap()).unwrap();
205+
module_def.initializer.0(py, py.import_bound("builtins").unwrap().into_gil_ref())
206+
.unwrap();
206207
assert!(INIT_CALLED.load(Ordering::SeqCst));
207208
})
208209
}

0 commit comments

Comments
 (0)