Skip to content

Commit

Permalink
Reintroduces Python::import and Python::get_type (#4436)
Browse files Browse the repository at this point in the history
* reintroduce `Python::import`

* reintroduce `Python::get_type`
  • Loading branch information
Icxolu authored Aug 12, 2024
1 parent 0791562 commit b520bc1
Show file tree
Hide file tree
Showing 52 changed files with 215 additions and 208 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,10 +149,10 @@ use pyo3::types::IntoPyDict;

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

let locals = [("os", py.import_bound("os")?)].into_py_dict(py);
let locals = [("os", py.import("os")?)].into_py_dict(py);
let code = "os.getenv('USER') or os.getenv('USERNAME') or 'Unknown'";
let user: String = py.eval_bound(code, None, Some(&locals))?.extract()?;

Expand Down
26 changes: 13 additions & 13 deletions guide/src/class.md
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ impl SubSubClass {
# pyo3::py_run!(py, subsub, "assert subsub.get_values() == (20, 30, 40)");
# let subsub = SubSubClass::factory_method(py, 2).unwrap();
# let subsubsub = SubSubClass::factory_method(py, 3).unwrap();
# let cls = py.get_type_bound::<SubSubClass>();
# let cls = py.get_type::<SubSubClass>();
# pyo3::py_run!(py, subsub cls, "assert not isinstance(subsub, cls)");
# pyo3::py_run!(py, subsubsub cls, "assert isinstance(subsubsub, cls)");
# });
Expand Down Expand Up @@ -526,7 +526,7 @@ impl MyDict {
// some custom methods that use `private` here...
}
# Python::with_gil(|py| {
# let cls = py.get_type_bound::<MyDict>();
# let cls = py.get_type::<MyDict>();
# pyo3::py_run!(py, cls, "cls(a=1, b=2)")
# });
# }
Expand Down Expand Up @@ -797,7 +797,7 @@ impl MyClass {
}

Python::with_gil(|py| {
let my_class = py.get_type_bound::<MyClass>();
let my_class = py.get_type::<MyClass>();
pyo3::py_run!(py, my_class, "assert my_class.my_attribute == 'hello'")
});
```
Expand Down Expand Up @@ -1093,7 +1093,7 @@ enum MyEnum {
Python::with_gil(|py| {
let x = Py::new(py, MyEnum::Variant).unwrap();
let y = Py::new(py, MyEnum::OtherVariant).unwrap();
let cls = py.get_type_bound::<MyEnum>();
let cls = py.get_type::<MyEnum>();
pyo3::py_run!(py, x y cls, r#"
assert x == cls.Variant
assert y == cls.OtherVariant
Expand All @@ -1114,7 +1114,7 @@ enum MyEnum {
}

Python::with_gil(|py| {
let cls = py.get_type_bound::<MyEnum>();
let cls = py.get_type::<MyEnum>();
let x = MyEnum::Variant as i32; // The exact value is assigned by the compiler.
pyo3::py_run!(py, cls x, r#"
assert int(cls.Variant) == x
Expand All @@ -1135,7 +1135,7 @@ enum MyEnum{
}

Python::with_gil(|py| {
let cls = py.get_type_bound::<MyEnum>();
let cls = py.get_type::<MyEnum>();
let x = Py::new(py, MyEnum::Variant).unwrap();
pyo3::py_run!(py, cls x, r#"
assert repr(x) == 'MyEnum.Variant'
Expand All @@ -1162,7 +1162,7 @@ impl MyEnum {
}

Python::with_gil(|py| {
let cls = py.get_type_bound::<MyEnum>();
let cls = py.get_type::<MyEnum>();
pyo3::py_run!(py, cls, "assert repr(cls.Answer) == '42'")
})
```
Expand All @@ -1180,7 +1180,7 @@ enum MyEnum {

Python::with_gil(|py| {
let x = Py::new(py, MyEnum::Variant).unwrap();
let cls = py.get_type_bound::<MyEnum>();
let cls = py.get_type::<MyEnum>();
pyo3::py_run!(py, x cls, r#"
assert repr(x) == 'RenamedEnum.UPPERCASE'
assert x == cls.UPPERCASE
Expand All @@ -1202,7 +1202,7 @@ enum MyEnum{
}

Python::with_gil(|py| {
let cls = py.get_type_bound::<MyEnum>();
let cls = py.get_type::<MyEnum>();
let a = Py::new(py, MyEnum::A).unwrap();
let b = Py::new(py, MyEnum::B).unwrap();
let c = Py::new(py, MyEnum::C).unwrap();
Expand Down Expand Up @@ -1260,7 +1260,7 @@ enum Shape {
Python::with_gil(|py| {
let circle = Shape::Circle { radius: 10.0 }.into_py(py);
let square = Shape::RegularPolygon(4, 10.0).into_py(py);
let cls = py.get_type_bound::<Shape>();
let cls = py.get_type::<Shape>();
pyo3::py_run!(py, circle square cls, r#"
assert isinstance(circle, cls)
assert isinstance(circle, cls.Circle)
Expand Down Expand Up @@ -1299,7 +1299,7 @@ enum MyEnum {

Python::with_gil(|py| {
let x = Py::new(py, MyEnum::Variant { i: 42 }).unwrap();
let cls = py.get_type_bound::<MyEnum>();
let cls = py.get_type::<MyEnum>();
pyo3::py_run!(py, x cls, r#"
assert isinstance(x, cls)
assert not isinstance(x, cls.Variant)
Expand All @@ -1325,7 +1325,7 @@ enum Shape {

# #[cfg(Py_3_10)]
Python::with_gil(|py| {
let cls = py.get_type_bound::<Shape>();
let cls = py.get_type::<Shape>();
pyo3::py_run!(py, cls, r#"
circle = cls.Circle()
assert isinstance(circle, cls)
Expand Down Expand Up @@ -1446,7 +1446,7 @@ impl pyo3::impl_::pyclass::PyClassImpl for MyClass {
}

# Python::with_gil(|py| {
# let cls = py.get_type_bound::<MyClass>();
# let cls = py.get_type::<MyClass>();
# pyo3::py_run!(py, cls, "assert cls.__name__ == 'MyClass'")
# });
# }
Expand Down
4 changes: 2 additions & 2 deletions guide/src/exception.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use pyo3::exceptions::PyException;
create_exception!(mymodule, CustomError, PyException);

Python::with_gil(|py| {
let ctx = [("CustomError", py.get_type_bound::<CustomError>())].into_py_dict(py);
let ctx = [("CustomError", py.get_type::<CustomError>())].into_py_dict(py);
pyo3::py_run!(
py,
*ctx,
Expand All @@ -46,7 +46,7 @@ pyo3::create_exception!(mymodule, CustomError, PyException);
#[pymodule]
fn mymodule(py: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()> {
// ... other elements added to module ...
m.add("CustomError", py.get_type_bound::<CustomError>())?;
m.add("CustomError", py.get_type::<CustomError>())?;

Ok(())
}
Expand Down
6 changes: 3 additions & 3 deletions guide/src/migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ Python::with_gil(|py| {

After:

```rust
```rust,ignore
# #![allow(dead_code)]
# use pyo3::prelude::*;
# use pyo3::types::{PyBool};
Expand Down Expand Up @@ -593,7 +593,7 @@ assert_eq!(name, "list");

After:

```rust
```rust,ignore
# #[cfg(any(not(Py_LIMITED_API), Py_3_10))] {
# use pyo3::prelude::*;
# use pyo3::types::{PyList, PyType};
Expand All @@ -614,7 +614,7 @@ To avoid needing to worry about lifetimes at all, it is also possible to use the

The following example uses the same snippet as those just above, but this time the final extracted type is `PyBackedStr`:

```rust
```rust,ignore
# use pyo3::prelude::*;
# use pyo3::types::{PyList, PyType};
# fn example<'py>(py: Python<'py>) -> PyResult<()> {
Expand Down
4 changes: 2 additions & 2 deletions guide/src/python-from-rust/calling-existing-code.md
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ fn main() -> PyResult<()> {
let py_app = fs::read_to_string(path.join("app.py"))?;
let from_python = Python::with_gil(|py| -> PyResult<Py<PyAny>> {
let syspath = py
.import_bound("sys")?
.import("sys")?
.getattr("path")?
.downcast_into::<PyList>()?;
syspath.insert(0, &path)?;
Expand Down Expand Up @@ -383,7 +383,7 @@ use pyo3::prelude::*;

# fn main() -> PyResult<()> {
Python::with_gil(|py| -> PyResult<()> {
let signal = py.import_bound("signal")?;
let signal = py.import("signal")?;
// Set SIGINT to have the default action
signal
.getattr("signal")?
Expand Down
2 changes: 1 addition & 1 deletion pyo3-macros-backend/src/pyclass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1535,7 +1535,7 @@ pub fn gen_complex_enum_variant_attr(
let variant_cls = format_ident!("{}_{}", cls, member);
let associated_method = quote! {
fn #wrapper_ident(py: #pyo3_path::Python<'_>) -> #pyo3_path::PyResult<#pyo3_path::PyObject> {
::std::result::Result::Ok(py.get_type_bound::<#variant_cls>().into_any().unbind())
::std::result::Result::Ok(py.get_type::<#variant_cls>().into_any().unbind())
}
};

Expand Down
2 changes: 1 addition & 1 deletion src/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -880,7 +880,7 @@ mod tests {
fn test_array_buffer() {
Python::with_gil(|py| {
let array = py
.import_bound("array")
.import("array")
.unwrap()
.call_method("array", ("f", (1.0, 1.5, 2.0, 2.5)), None)
.unwrap();
Expand Down
10 changes: 5 additions & 5 deletions src/conversions/chrono.rs
Original file line number Diff line number Diff line change
Expand Up @@ -678,7 +678,7 @@ fn warn_truncated_leap_second(obj: &Bound<'_, PyAny>) {
let py = obj.py();
if let Err(e) = PyErr::warn_bound(
py,
&py.get_type_bound::<PyUserWarning>(),
&py.get_type::<PyUserWarning>(),
"ignored leap-second, `datetime` does not support leap-seconds",
0,
) {
Expand Down Expand Up @@ -762,7 +762,7 @@ impl DatetimeTypes {
fn try_get(py: Python<'_>) -> PyResult<&Self> {
static TYPES: GILOnceCell<DatetimeTypes> = GILOnceCell::new();
TYPES.get_or_try_init(py, || {
let datetime = py.import_bound("datetime")?;
let datetime = py.import("datetime")?;
let timezone = datetime.getattr("timezone")?;
Ok::<_, PyErr>(Self {
date: datetime.getattr("date")?.into(),
Expand Down Expand Up @@ -1297,7 +1297,7 @@ mod tests {
name: &str,
args: impl IntoPy<Py<PyTuple>>,
) -> Bound<'py, PyAny> {
py.import_bound("datetime")
py.import("datetime")
.unwrap()
.getattr(name)
.unwrap()
Expand All @@ -1306,7 +1306,7 @@ mod tests {
}

fn python_utc(py: Python<'_>) -> Bound<'_, PyAny> {
py.import_bound("datetime")
py.import("datetime")
.unwrap()
.getattr("timezone")
.unwrap()
Expand All @@ -1328,7 +1328,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_bound("datetime").unwrap())].into_py_dict(py);
let globals = [("datetime", py.import("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_bound(&code, Some(&globals), None).unwrap();

Expand Down
5 changes: 1 addition & 4 deletions src/conversions/chrono_tz.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,6 @@ mod tests {
}

fn zoneinfo_class(py: Python<'_>) -> Bound<'_, PyAny> {
py.import_bound("zoneinfo")
.unwrap()
.getattr("ZoneInfo")
.unwrap()
py.import("zoneinfo").unwrap().getattr("ZoneInfo").unwrap()
}
}
4 changes: 2 additions & 2 deletions src/conversions/num_bigint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ macro_rules! bigint_conversion {
} else {
None
};
py.get_type_bound::<PyInt>()
py.get_type::<PyInt>()
.call_method("from_bytes", (bytes_obj, "little"), kwargs.as_ref())
.expect("int.from_bytes() failed during to_object()") // FIXME: #1813 or similar
.into()
Expand Down Expand Up @@ -170,7 +170,7 @@ macro_rules! bigint_conversion {
None
};
unsafe {
py.get_type_bound::<PyInt>()
py.get_type::<PyInt>()
.call_method("from_bytes", (bytes_obj, "little"), kwargs.as_ref())
.downcast_into_unchecked()
}
Expand Down
14 changes: 4 additions & 10 deletions src/conversions/std/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ fn unix_epoch_py(py: Python<'_>) -> &PyObject {
}
#[cfg(Py_LIMITED_API)]
{
let datetime = py.import_bound("datetime")?;
let datetime = py.import("datetime")?;
let utc = datetime.getattr("timezone")?.getattr("utc")?;
Ok::<_, PyErr>(
datetime
Expand Down Expand Up @@ -412,7 +412,7 @@ mod tests {
}

fn tz_utc(py: Python<'_>) -> Bound<'_, PyAny> {
py.import_bound("datetime")
py.import("datetime")
.unwrap()
.getattr("timezone")
.unwrap()
Expand All @@ -432,16 +432,10 @@ mod tests {
}

fn datetime_class(py: Python<'_>) -> Bound<'_, PyAny> {
py.import_bound("datetime")
.unwrap()
.getattr("datetime")
.unwrap()
py.import("datetime").unwrap().getattr("datetime").unwrap()
}

fn timedelta_class(py: Python<'_>) -> Bound<'_, PyAny> {
py.import_bound("datetime")
.unwrap()
.getattr("timedelta")
.unwrap()
py.import("datetime").unwrap().getattr("timedelta").unwrap()
}
}
2 changes: 1 addition & 1 deletion src/coroutine/waker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ impl LoopAndFuture {
fn new(py: Python<'_>) -> PyResult<Self> {
static GET_RUNNING_LOOP: GILOnceCell<PyObject> = GILOnceCell::new();
let import = || -> PyResult<_> {
let module = py.import_bound("asyncio")?;
let module = py.import("asyncio")?;
Ok(module.getattr("get_running_loop")?.into())
};
let event_loop = GET_RUNNING_LOOP.get_or_try_init(py, import)?.call0(py)?;
Expand Down
6 changes: 3 additions & 3 deletions src/err/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -596,7 +596,7 @@ impl PyErr {
/// # use pyo3::prelude::*;
/// # fn main() -> PyResult<()> {
/// Python::with_gil(|py| {
/// let user_warning = py.get_type_bound::<pyo3::exceptions::PyUserWarning>();
/// let user_warning = py.get_type::<pyo3::exceptions::PyUserWarning>();
/// PyErr::warn_bound(py, &user_warning, "I am warning you", 0)?;
/// Ok(())
/// })
Expand Down Expand Up @@ -1125,10 +1125,10 @@ mod tests {
// GIL locked should prevent effects to be visible to other testing
// threads.
Python::with_gil(|py| {
let cls = py.get_type_bound::<exceptions::PyUserWarning>();
let cls = py.get_type::<exceptions::PyUserWarning>();

// Reset warning filter to default state
let warnings = py.import_bound("warnings").unwrap();
let warnings = py.import("warnings").unwrap();
warnings.call_method0("resetwarnings").unwrap();

// First, test the warning is emitted
Expand Down
Loading

0 comments on commit b520bc1

Please sign in to comment.