diff --git a/README.md b/README.md index 98eeeb80242..bdb4c3ef196 100644 --- a/README.md +++ b/README.md @@ -152,9 +152,9 @@ fn main() -> PyResult<()> { let sys = py.import("sys")?; let version: String = sys.getattr("version")?.extract()?; - let locals = [("os", py.import("os")?)].into_py_dict(py); + let locals = [("os", py.import("os")?)].into_py_dict_bound(py); let code = "os.getenv('USER') or os.getenv('USERNAME') or 'Unknown'"; - let user: String = py.eval(code, None, Some(&locals))?.extract()?; + let user: String = py.eval_bound(code, None, Some(&locals))?.extract()?; println!("Hello {}, I'm Python {}", user, version); Ok(()) diff --git a/guide/src/class.md b/guide/src/class.md index 37265aaa2bc..05c4350af61 100644 --- a/guide/src/class.md +++ b/guide/src/class.md @@ -202,7 +202,7 @@ Python::with_gil(|py| { } // You can convert `&PyCell` to a Python object - pyo3::py_run!(py, obj, "assert obj.num == 5"); + pyo3::py_run_bound!(py, obj, "assert obj.num == 5"); }); ``` @@ -368,12 +368,12 @@ impl SubSubClass { } # Python::with_gil(|py| { # let subsub = pyo3::PyCell::new(py, SubSubClass::new()).unwrap(); -# pyo3::py_run!(py, subsub, "assert subsub.method3() == 3000"); +# pyo3::py_run_bound!(py, subsub, "assert subsub.method3() == 3000"); # let subsub = SubSubClass::factory_method(py, 2).unwrap(); # let subsubsub = SubSubClass::factory_method(py, 3).unwrap(); # let cls = py.get_type::(); -# pyo3::py_run!(py, subsub cls, "assert not isinstance(subsub, cls)"); -# pyo3::py_run!(py, subsubsub cls, "assert isinstance(subsubsub, cls)"); +# pyo3::py_run_bound!(py, subsub cls, "assert not isinstance(subsub, cls)"); +# pyo3::py_run_bound!(py, subsubsub cls, "assert isinstance(subsubsub, cls)"); # }); ``` @@ -412,7 +412,7 @@ impl DictWithCounter { } # Python::with_gil(|py| { # let cnt = pyo3::PyCell::new(py, DictWithCounter::new()).unwrap(); -# pyo3::py_run!(py, cnt, "cnt.set('abc', 10); assert cnt['abc'] == 10") +# pyo3::py_run_bound!(py, cnt, "cnt.set('abc', 10); assert cnt['abc'] == 10") # }); # } ``` @@ -468,7 +468,7 @@ impl MyDict { } # Python::with_gil(|py| { # let cls = py.get_type::(); -# pyo3::py_run!(py, cls, "cls(a=1, b=2)") +# pyo3::py_run_bound!(py, cls, "cls(a=1, b=2)") # }); # } ``` @@ -738,7 +738,7 @@ impl MyClass { Python::with_gil(|py| { let my_class = py.get_type::(); - pyo3::py_run!(py, my_class, "assert my_class.my_attribute == 'hello'") + pyo3::py_run_bound!(py, my_class, "assert my_class.my_attribute == 'hello'") }); ``` @@ -997,7 +997,7 @@ 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::(); - pyo3::py_run!(py, x y cls, r#" + pyo3::py_run_bound!(py, x y cls, r#" assert x == cls.Variant assert y == cls.OtherVariant assert x != y @@ -1018,7 +1018,7 @@ enum MyEnum { Python::with_gil(|py| { let cls = py.get_type::(); let x = MyEnum::Variant as i32; // The exact value is assigned by the compiler. - pyo3::py_run!(py, cls x, r#" + pyo3::py_run_bound!(py, cls x, r#" assert int(cls.Variant) == x assert int(cls.OtherVariant) == 10 assert cls.OtherVariant == 10 # You can also compare against int. @@ -1040,7 +1040,7 @@ enum MyEnum{ Python::with_gil(|py| { let cls = py.get_type::(); let x = Py::new(py, MyEnum::Variant).unwrap(); - pyo3::py_run!(py, cls x, r#" + pyo3::py_run_bound!(py, cls x, r#" assert repr(x) == 'MyEnum.Variant' assert repr(cls.OtherVariant) == 'MyEnum.OtherVariant' "#) @@ -1065,7 +1065,7 @@ impl MyEnum { Python::with_gil(|py| { let cls = py.get_type::(); - pyo3::py_run!(py, cls, "assert repr(cls.Answer) == '42'") + pyo3::py_run_bound!(py, cls, "assert repr(cls.Answer) == '42'") }) ``` @@ -1082,7 +1082,7 @@ enum MyEnum { Python::with_gil(|py| { let x = Py::new(py, MyEnum::Variant).unwrap(); let cls = py.get_type::(); - pyo3::py_run!(py, x cls, r#" + pyo3::py_run_bound!(py, x cls, r#" assert repr(x) == 'RenamedEnum.UPPERCASE' assert x == cls.UPPERCASE "#) @@ -1136,7 +1136,7 @@ Python::with_gil(|py| { let circle = Shape::Circle { radius: 10.0 }.into_py(py); let square = Shape::RegularPolygon { side_count: 4, radius: 10.0 }.into_py(py); let cls = py.get_type::(); - pyo3::py_run!(py, circle square cls, r#" + pyo3::py_run_bound!(py, circle square cls, r#" assert isinstance(circle, cls) assert isinstance(circle, cls.Circle) assert circle.radius == 10.0 @@ -1175,7 +1175,7 @@ enum MyEnum { Python::with_gil(|py| { let x = Py::new(py, MyEnum::Variant { i: 42 }).unwrap(); let cls = py.get_type::(); - pyo3::py_run!(py, x cls, r#" + pyo3::py_run_bound!(py, x cls, r#" assert isinstance(x, cls) assert not isinstance(x, cls.Variant) "#) @@ -1279,7 +1279,7 @@ impl pyo3::impl_::pyclass::PyClassImpl for MyClass { # Python::with_gil(|py| { # let cls = py.get_type::(); -# pyo3::py_run!(py, cls, "assert cls.__name__ == 'MyClass'") +# pyo3::py_run_bound!(py, cls, "assert cls.__name__ == 'MyClass'") # }); # } ``` diff --git a/guide/src/class/numeric.md b/guide/src/class/numeric.md index ee17ea10bd9..0bf663bae87 100644 --- a/guide/src/class/numeric.md +++ b/guide/src/class/numeric.md @@ -390,7 +390,7 @@ fn my_module(_py: Python<'_>, m: &PyModule) -> PyResult<()> { # let globals = PyModule::import(py, "__main__")?.dict(); # globals.set_item("Number", Number::type_object(py))?; # -# py.run(SCRIPT, Some(globals), None)?; +# py.run_bound(SCRIPT, Some(&globals.as_borrowed()), None)?; # Ok(()) # }) # } diff --git a/guide/src/class/protocols.md b/guide/src/class/protocols.md index 411978f0567..b684e4e6669 100644 --- a/guide/src/class/protocols.md +++ b/guide/src/class/protocols.md @@ -208,8 +208,8 @@ impl Container { # Python::with_gil(|py| { # let container = Container { iter: vec![1, 2, 3, 4] }; # let inst = pyo3::PyCell::new(py, container).unwrap(); -# pyo3::py_run!(py, inst, "assert list(inst) == [1, 2, 3, 4]"); -# pyo3::py_run!(py, inst, "assert list(iter(iter(inst))) == [1, 2, 3, 4]"); +# pyo3::py_run_bound!(py, inst, "assert list(inst) == [1, 2, 3, 4]"); +# pyo3::py_run_bound!(py, inst, "assert list(iter(iter(inst))) == [1, 2, 3, 4]"); # }); ``` diff --git a/guide/src/conversions/traits.md b/guide/src/conversions/traits.md index 4f3342f2ccc..b46e5c02f4c 100644 --- a/guide/src/conversions/traits.md +++ b/guide/src/conversions/traits.md @@ -86,7 +86,7 @@ struct RustyStruct { # use pyo3::types::PyDict; # fn main() -> PyResult<()> { # Python::with_gil(|py| -> PyResult<()> { -# let dict = PyDict::new(py); +# let dict = PyDict::new_bound(py); # dict.set_item("my_string", "test")?; # # let rustystruct: RustyStruct = dict.extract()?; @@ -155,7 +155,7 @@ struct RustyStruct { # # fn main() -> PyResult<()> { # Python::with_gil(|py| -> PyResult<()> { -# let py_dict = py.eval("{'foo': 'foo', 'bar': 'bar', 'foobar': 'foobar'}", None, None)?; +# let py_dict = py.eval_bound("{'foo': 'foo', 'bar': 'bar', 'foobar': 'foobar'}", None, None)?; # let rustystruct: RustyStruct = py_dict.extract()?; # assert_eq!(rustystruct.foo, "foo"); # assert_eq!(rustystruct.bar, "bar"); diff --git a/guide/src/ecosystem/logging.md b/guide/src/ecosystem/logging.md index 2e7d4a087c6..caed60e9974 100644 --- a/guide/src/ecosystem/logging.md +++ b/guide/src/ecosystem/logging.md @@ -79,7 +79,7 @@ fn main() -> PyResult<()> { // Log some messages from Python Python::with_gil(|py| { - py.run( + py.run_bound( " import logging logging.error('Something bad happened') diff --git a/guide/src/exception.md b/guide/src/exception.md index e1ce24980d3..0af1ca90a35 100644 --- a/guide/src/exception.md +++ b/guide/src/exception.md @@ -24,13 +24,13 @@ use pyo3::exceptions::PyException; create_exception!(mymodule, CustomError, PyException); Python::with_gil(|py| { - let ctx = [("CustomError", py.get_type::())].into_py_dict(py); - pyo3::py_run!( + let ctx = [("CustomError", py.get_type::())].into_py_dict_bound(py); + pyo3::py_run_bound!( py, *ctx, "assert str(CustomError) == \"\"" ); - pyo3::py_run!(py, *ctx, "assert CustomError('oops').args == ('oops',)"); + pyo3::py_run_bound!(py, *ctx, "assert CustomError('oops').args == ('oops',)"); }); ``` diff --git a/guide/src/features.md b/guide/src/features.md index 43124e0076e..710b9d86cc8 100644 --- a/guide/src/features.md +++ b/guide/src/features.md @@ -73,7 +73,7 @@ This feature enables a dependency on the `pyo3-macros` crate, which provides the - `#[pymethods]` - `#[derive(FromPyObject)]` -It also provides the `py_run!` macro. +It also provides the `py_run_bound!` macro. These macros require a number of dependencies which may not be needed by users who just need PyO3 for Python FFI. Disabling this feature enables faster builds for those users, as these dependencies will not be built if this feature is disabled. diff --git a/guide/src/memory.md b/guide/src/memory.md index f9201e3f003..d089be4e152 100644 --- a/guide/src/memory.md +++ b/guide/src/memory.md @@ -27,7 +27,7 @@ very simple and easy-to-understand programs like this: # use pyo3::types::PyString; # fn main() -> PyResult<()> { Python::with_gil(|py| -> PyResult<()> { - let hello: &PyString = py.eval("\"Hello World!\"", None, None)?.extract()?; + let hello: Bound<'_, PyString> = py.eval_bound("\"Hello World!\"", None, None)?.downcast_into()?; println!("Python says: {}", hello); Ok(()) })?; @@ -48,7 +48,7 @@ of the time we don't have to think about this, but consider the following: # fn main() -> PyResult<()> { Python::with_gil(|py| -> PyResult<()> { for _ in 0..10 { - let hello: &PyString = py.eval("\"Hello World!\"", None, None)?.extract()?; + let hello: Bound<'_, PyString> = py.eval_bound("\"Hello World!\"", None, None)?.downcast_into()?; println!("Python says: {}", hello); } // There are 10 copies of `hello` on Python's heap here. @@ -76,7 +76,7 @@ is to acquire and release the GIL with each iteration of the loop. # fn main() -> PyResult<()> { for _ in 0..10 { Python::with_gil(|py| -> PyResult<()> { - let hello: &PyString = py.eval("\"Hello World!\"", None, None)?.extract()?; + let hello: Bound<'_, PyString> = py.eval_bound("\"Hello World!\"", None, None)?.downcast_into()?; println!("Python says: {}", hello); Ok(()) })?; // only one copy of `hello` at a time @@ -97,7 +97,7 @@ Python::with_gil(|py| -> PyResult<()> { for _ in 0..10 { let pool = unsafe { py.new_pool() }; let py = pool.python(); - let hello: &PyString = py.eval("\"Hello World!\"", None, None)?.extract()?; + let hello: Bound<'_, PyString> = py.eval_bound("\"Hello World!\"", None, None)?.downcast_into()?; println!("Python says: {}", hello); } Ok(()) @@ -144,7 +144,7 @@ reference count reaches zero? It depends whether or not we are holding the GIL. # use pyo3::types::PyString; # fn main() -> PyResult<()> { Python::with_gil(|py| -> PyResult<()> { - let hello: Py = py.eval("\"Hello World!\"", None, None)?.extract()?; + let hello: Py = py.eval_bound("\"Hello World!\"", None, None)?.extract()?; println!("Python says: {}", hello.as_ref(py)); Ok(()) })?; @@ -166,7 +166,7 @@ we are *not* holding the GIL? # use pyo3::types::PyString; # fn main() -> PyResult<()> { let hello: Py = Python::with_gil(|py| { - py.eval("\"Hello World!\"", None, None)?.extract() + py.eval_bound("\"Hello World!\"", None, None)?.extract() })?; // Do some stuff... // Now sometime later in the program we want to access `hello`. @@ -197,7 +197,7 @@ We can avoid the delay in releasing memory if we are careful to drop the # use pyo3::types::PyString; # fn main() -> PyResult<()> { let hello: Py = - Python::with_gil(|py| py.eval("\"Hello World!\"", None, None)?.extract())?; + Python::with_gil(|py| py.eval_bound("\"Hello World!\"", None, None)?.extract())?; // Do some stuff... // Now sometime later in the program: Python::with_gil(|py| { @@ -219,7 +219,7 @@ until the GIL is dropped. # use pyo3::types::PyString; # fn main() -> PyResult<()> { let hello: Py = - Python::with_gil(|py| py.eval("\"Hello World!\"", None, None)?.extract())?; + Python::with_gil(|py| py.eval_bound("\"Hello World!\"", None, None)?.extract())?; // Do some stuff... // Now sometime later in the program: Python::with_gil(|py| { diff --git a/guide/src/migration.md b/guide/src/migration.md index 6a151b99164..2f9b3cd6f25 100644 --- a/guide/src/migration.md +++ b/guide/src/migration.md @@ -280,7 +280,7 @@ Python::with_gil(|py| { After: -```rust +```rust,ignore use pyo3::prelude::*; use pyo3::exceptions::PyTypeError; use pyo3::types::{PyDict, IntoPyDict}; @@ -403,7 +403,7 @@ fn raise_err() -> anyhow::Result<()> { fn main() { Python::with_gil(|py| { let rs_func = wrap_pyfunction!(raise_err, py).unwrap(); - pyo3::py_run!( + pyo3::py_run_bound!( py, rs_func, r" @@ -1201,7 +1201,7 @@ all you need to do is remove `ObjectProtocol` from your code. Or if you use `ObjectProtocol` by `use pyo3::prelude::*`, you have to do nothing. Before: -```rust,compile_fail +```rust,ignore use pyo3::ObjectProtocol; # pyo3::Python::with_gil(|py| { @@ -1212,7 +1212,7 @@ assert_eq!(hi.len().unwrap(), 5); ``` After: -```rust +```rust,ignore # pyo3::Python::with_gil(|py| { let obj = py.eval("lambda: 'Hi :)'", None, None).unwrap(); let hi: &pyo3::types::PyString = obj.call0().unwrap().downcast().unwrap(); @@ -1293,7 +1293,7 @@ impl Names { } # Python::with_gil(|py| { # let names = PyCell::new(py, Names::new()).unwrap(); -# pyo3::py_run!(py, names, r" +# pyo3::py_run_bound!(py, names, r" # try: # names.merge(names) # assert False, 'Unreachable' @@ -1358,8 +1358,8 @@ After: # #[pymethods] impl MyClass { #[new]fn new() -> Self { MyClass {} }} # Python::with_gil(|py| { # let typeobj = py.get_type::(); -# let d = [("c", typeobj)].into_py_dict(py); -# let create_obj = || py.eval("c()", None, Some(d)).unwrap(); +# let d = [("c", typeobj)].into_py_dict_bound(py); +# let create_obj = || py.eval_bound("c()", None, Some(&d)).unwrap().into_gil_ref(); let obj: &PyAny = create_obj(); let obj_cell: &PyCell = obj.extract().unwrap(); let obj_cloned: MyClass = obj.extract().unwrap(); // extracted by cloning the object diff --git a/guide/src/module.md b/guide/src/module.md index 9e52ab93e2b..3d984f60d39 100644 --- a/guide/src/module.md +++ b/guide/src/module.md @@ -93,9 +93,9 @@ fn func() -> String { # use pyo3::wrap_pymodule; # use pyo3::types::IntoPyDict; # let parent_module = wrap_pymodule!(parent_module)(py); -# let ctx = [("parent_module", parent_module)].into_py_dict(py); +# let ctx = [("parent_module", parent_module)].into_py_dict_bound(py); # -# py.run("assert parent_module.child_module.func() == 'func'", None, Some(&ctx)).unwrap(); +# py.run_bound("assert parent_module.child_module.func() == 'func'", None, Some(&ctx)).unwrap(); # }) ``` diff --git a/guide/src/python_from_rust.md b/guide/src/python_from_rust.md index 99da2e15434..0e4844bff25 100644 --- a/guide/src/python_from_rust.md +++ b/guide/src/python_from_rust.md @@ -94,17 +94,17 @@ fn main() -> PyResult<()> { .into(); // call object with PyDict - let kwargs = [(key1, val1)].into_py_dict(py); - fun.call_bound(py, (), Some(&kwargs.as_borrowed()))?; + let kwargs = [(key1, val1)].into_py_dict_bound(py); + fun.call_bound(py, (), Some(&kwargs))?; // pass arguments as Vec let kwargs = vec![(key1, val1), (key2, val2)]; - fun.call_bound(py, (), Some(&kwargs.into_py_dict(py).as_borrowed()))?; + fun.call_bound(py, (), Some(&kwargs.into_py_dict_bound(py)))?; // pass arguments as HashMap let mut kwargs = HashMap::<&str, i32>::new(); kwargs.insert(key1, 1); - fun.call_bound(py, (), Some(&kwargs.into_py_dict(py).as_borrowed()))?; + fun.call_bound(py, (), Some(&kwargs.into_py_dict_bound(py)))?; Ok(()) }) @@ -157,7 +157,7 @@ use pyo3::prelude::*; # fn main() -> Result<(), ()> { Python::with_gil(|py| { let result = py - .eval("[i * 10 for i in range(5)]", None, None) + .eval_bound("[i * 10 for i in range(5)]", None, None) .map_err(|e| { e.print_and_set_sys_last_vars(py); })?; @@ -175,13 +175,13 @@ Python::with_gil(|py| { This method returns nothing (like any Python statement), but you can get access to manipulated objects via the `locals` dict. -You can also use the [`py_run!`] macro, which is a shorthand for [`Python::run`]. -Since [`py_run!`] panics on exceptions, we recommend you use this macro only for +You can also use the [`py_run_bound!`] macro, which is a shorthand for [`Python::run`]. +Since [`py_run_bound!`] panics on exceptions, we recommend you use this macro only for quickly testing your Python extensions. ```rust use pyo3::prelude::*; -use pyo3::{PyCell, py_run}; +use pyo3::{PyCell, py_run_bound}; # fn main() { #[pyclass] @@ -208,7 +208,7 @@ Python::with_gil(|py| { }; let userdata = PyCell::new(py, userdata).unwrap(); let userdata_as_tuple = (34, "Yu"); - py_run!(py, userdata userdata_as_tuple, r#" + py_run_bound!(py, userdata userdata_as_tuple, r#" assert repr(userdata) == "User Yu(id: 34)" assert userdata.as_tuple() == userdata_as_tuple "#); @@ -250,10 +250,10 @@ def leaky_relu(x, slope=0.01): let relu_result: f64 = activators.getattr("relu")?.call1((-1.0,))?.extract()?; assert_eq!(relu_result, 0.0); - let kwargs = [("slope", 0.2)].into_py_dict(py); + let kwargs = [("slope", 0.2)].into_py_dict_bound(py); let lrelu_result: f64 = activators .getattr("leaky_relu")? - .call((-1.0,), Some(kwargs))? + .call((-1.0,), Some(kwargs.as_gil_ref()))? .extract()?; assert_eq!(lrelu_result, -0.2); # Ok(()) @@ -290,7 +290,7 @@ fn foo(_py: Python<'_>, foo_module: &PyModule) -> PyResult<()> { fn main() -> PyResult<()> { pyo3::append_to_inittab!(foo); - Python::with_gil(|py| Python::run(py, "import foo; foo.add_one(6)", None, None)) + Python::with_gil(|py| py.run_bound("import foo; foo.add_one(6)", None, None)) } ``` @@ -321,7 +321,7 @@ fn main() -> PyResult<()> { py_modules.set_item("foo", foo_module)?; // Now we can import + run our python code - Python::run(py, "import foo; foo.add_one(6)", None, None) + py.run_bound("import foo; foo.add_one(6)", None, None) }) } ``` @@ -429,7 +429,7 @@ fn main() -> PyResult<()> { [`Python::run`]: {{#PYO3_DOCS_URL}}/pyo3/struct.Python.html#method.run -[`py_run!`]: {{#PYO3_DOCS_URL}}/pyo3/macro.py_run.html +[`py_run_bound!`]: {{#PYO3_DOCS_URL}}/pyo3/macro.py_run.html ## Need to use a context manager from Rust? @@ -466,7 +466,7 @@ class House(object): house.call_method0("__enter__").unwrap(); - let result = py.eval("undefined_variable + 1", None, None); + let result = py.eval_bound("undefined_variable + 1", None, None); // If the eval threw an exception we'll pass it through to the context manager. // Otherwise, __exit__ is called with empty arguments (Python "None"). diff --git a/pyo3-benches/benches/bench_any.rs b/pyo3-benches/benches/bench_any.rs index bfd010efd19..e3c919e55f7 100644 --- a/pyo3-benches/benches/bench_any.rs +++ b/pyo3-benches/benches/bench_any.rs @@ -1,6 +1,7 @@ use codspeed_criterion_compat::{criterion_group, criterion_main, Bencher, Criterion}; use pyo3::{ + prelude::*, types::{ PyBool, PyByteArray, PyBytes, PyDict, PyFloat, PyFrozenSet, PyInt, PyList, PyMapping, PySequence, PySet, PyString, PyTuple, @@ -27,7 +28,7 @@ enum ObjectType { Unknown, } -fn find_object_type(obj: &PyAny) -> ObjectType { +fn find_object_type(obj: &Bound<'_, PyAny>) -> ObjectType { if obj.is_none() { ObjectType::None } else if obj.is_instance_of::() { @@ -63,17 +64,17 @@ fn find_object_type(obj: &PyAny) -> ObjectType { fn bench_identify_object_type(b: &mut Bencher<'_>) { Python::with_gil(|py| { - let obj = py.eval("object()", None, None).unwrap(); + let obj = py.eval_bound("object()", None, None).unwrap(); - b.iter(|| find_object_type(obj)); + b.iter(|| find_object_type(&obj)); - assert_eq!(find_object_type(obj), ObjectType::Unknown); + assert_eq!(find_object_type(&obj), ObjectType::Unknown); }); } fn bench_collect_generic_iterator(b: &mut Bencher<'_>) { Python::with_gil(|py| { - let collection = py.eval("list(range(1 << 20))", None, None).unwrap(); + let collection = py.eval_bound("list(range(1 << 20))", None, None).unwrap(); b.iter(|| { collection diff --git a/pyo3-benches/benches/bench_bigint.rs b/pyo3-benches/benches/bench_bigint.rs index d3c71629ba4..7eff183e457 100644 --- a/pyo3-benches/benches/bench_bigint.rs +++ b/pyo3-benches/benches/bench_bigint.rs @@ -1,14 +1,15 @@ use codspeed_criterion_compat::{black_box, criterion_group, criterion_main, Bencher, Criterion}; -use pyo3::{types::PyDict, PyAny, Python}; +use pyo3::prelude::*; +use pyo3::{types::PyDict, Python}; use num_bigint::BigInt; fn extract_bigint_extract_fail(bench: &mut Bencher<'_>) { Python::with_gil(|py| { - let d = PyDict::new(py) as &PyAny; + let d = PyDict::new_bound(py); - bench.iter(|| match black_box(d).extract::() { + bench.iter(|| match black_box(&d).extract::() { Ok(v) => panic!("should err {}", v), Err(e) => black_box(e), }); @@ -17,10 +18,10 @@ fn extract_bigint_extract_fail(bench: &mut Bencher<'_>) { fn extract_bigint_small(bench: &mut Bencher<'_>) { Python::with_gil(|py| { - let int = py.eval("-42", None, None).unwrap(); + let int = py.eval_bound("-42", None, None).unwrap(); bench.iter(|| { - let v = black_box(int).extract::().unwrap(); + let v = black_box(&int).extract::().unwrap(); black_box(v); }); }); @@ -28,10 +29,10 @@ fn extract_bigint_small(bench: &mut Bencher<'_>) { fn extract_bigint_big_negative(bench: &mut Bencher<'_>) { Python::with_gil(|py| { - let int = py.eval("-10**300", None, None).unwrap(); + let int = py.eval_bound("-10**300", None, None).unwrap(); bench.iter(|| { - let v = black_box(int).extract::().unwrap(); + let v = black_box(&int).extract::().unwrap(); black_box(v); }); }); @@ -39,10 +40,10 @@ fn extract_bigint_big_negative(bench: &mut Bencher<'_>) { fn extract_bigint_big_positive(bench: &mut Bencher<'_>) { Python::with_gil(|py| { - let int = py.eval("10**300", None, None).unwrap(); + let int = py.eval_bound("10**300", None, None).unwrap(); bench.iter(|| { - let v = black_box(int).extract::().unwrap(); + let v = black_box(&int).extract::().unwrap(); black_box(v); }); }); @@ -50,10 +51,10 @@ fn extract_bigint_big_positive(bench: &mut Bencher<'_>) { fn extract_bigint_huge_negative(bench: &mut Bencher<'_>) { Python::with_gil(|py| { - let int = py.eval("-10**3000", None, None).unwrap(); + let int = py.eval_bound("-10**3000", None, None).unwrap(); bench.iter(|| { - let v = black_box(int).extract::().unwrap(); + let v = black_box(&int).extract::().unwrap(); black_box(v); }); }); @@ -61,10 +62,10 @@ fn extract_bigint_huge_negative(bench: &mut Bencher<'_>) { fn extract_bigint_huge_positive(bench: &mut Bencher<'_>) { Python::with_gil(|py| { - let int = py.eval("10**3000", None, None).unwrap(); + let int = py.eval_bound("10**3000", None, None).unwrap(); bench.iter(|| { - let v = black_box(int).extract::().unwrap(); + let v = black_box(&int).extract::().unwrap(); black_box(v); }); }); diff --git a/pyo3-benches/benches/bench_decimal.rs b/pyo3-benches/benches/bench_decimal.rs index 203756b54cc..6db6704bf8e 100644 --- a/pyo3-benches/benches/bench_decimal.rs +++ b/pyo3-benches/benches/bench_decimal.rs @@ -6,20 +6,20 @@ use rust_decimal::Decimal; fn decimal_via_extract(b: &mut Bencher<'_>) { Python::with_gil(|py| { - let locals = PyDict::new(py); - py.run( + let locals = PyDict::new_bound(py); + py.run_bound( r#" import decimal py_dec = decimal.Decimal("0.0") "#, None, - Some(locals), + Some(&locals), ) .unwrap(); let py_dec = locals.get_item("py_dec").unwrap().unwrap(); b.iter(|| { - let _: Decimal = black_box(py_dec).extract().unwrap(); + let _: Decimal = black_box(&py_dec).extract().unwrap(); }); }) } diff --git a/pyo3-benches/benches/bench_dict.rs b/pyo3-benches/benches/bench_dict.rs index 06559519e7e..9e3ea0d4fce 100644 --- a/pyo3-benches/benches/bench_dict.rs +++ b/pyo3-benches/benches/bench_dict.rs @@ -8,10 +8,10 @@ use std::hint::black_box; fn iter_dict(b: &mut Bencher<'_>) { Python::with_gil(|py| { const LEN: usize = 100_000; - let dict = (0..LEN as u64).map(|i| (i, i * 2)).into_py_dict(py); + let dict = (0..LEN as u64).map(|i| (i, i * 2)).into_py_dict_bound(py); let mut sum = 0; b.iter(|| { - for (k, _v) in dict { + for (k, _v) in dict.iter() { let i: u64 = k.extract().unwrap(); sum += i; } @@ -22,14 +22,14 @@ fn iter_dict(b: &mut Bencher<'_>) { fn dict_new(b: &mut Bencher<'_>) { Python::with_gil(|py| { const LEN: usize = 50_000; - b.iter(|| (0..LEN as u64).map(|i| (i, i * 2)).into_py_dict(py)); + b.iter_with_large_drop(|| (0..LEN as u64).map(|i| (i, i * 2)).into_py_dict_bound(py)); }); } fn dict_get_item(b: &mut Bencher<'_>) { Python::with_gil(|py| { const LEN: usize = 50_000; - let dict = (0..LEN as u64).map(|i| (i, i * 2)).into_py_dict(py); + let dict = (0..LEN as u64).map(|i| (i, i * 2)).into_py_dict_bound(py); let mut sum = 0; b.iter(|| { for i in 0..LEN { @@ -47,16 +47,16 @@ fn dict_get_item(b: &mut Bencher<'_>) { fn extract_hashmap(b: &mut Bencher<'_>) { Python::with_gil(|py| { const LEN: usize = 100_000; - let dict = (0..LEN as u64).map(|i| (i, i * 2)).into_py_dict(py); - b.iter(|| HashMap::::extract(dict)); + let dict = (0..LEN as u64).map(|i| (i, i * 2)).into_py_dict_bound(py); + b.iter(|| HashMap::::extract(dict.as_gil_ref())); }); } fn extract_btreemap(b: &mut Bencher<'_>) { Python::with_gil(|py| { const LEN: usize = 100_000; - let dict = (0..LEN as u64).map(|i| (i, i * 2)).into_py_dict(py); - b.iter(|| BTreeMap::::extract(dict)); + let dict = (0..LEN as u64).map(|i| (i, i * 2)).into_py_dict_bound(py); + b.iter(|| BTreeMap::::extract(dict.as_gil_ref())); }); } @@ -64,8 +64,8 @@ fn extract_btreemap(b: &mut Bencher<'_>) { fn extract_hashbrown_map(b: &mut Bencher<'_>) { Python::with_gil(|py| { const LEN: usize = 100_000; - let dict = (0..LEN as u64).map(|i| (i, i * 2)).into_py_dict(py); - b.iter(|| hashbrown::HashMap::::extract(dict)); + let dict = (0..LEN as u64).map(|i| (i, i * 2)).into_py_dict_bound(py); + b.iter(|| hashbrown::HashMap::::extract(dict.as_gil_ref())); }); } @@ -74,10 +74,9 @@ fn mapping_from_dict(b: &mut Bencher<'_>) { const LEN: usize = 100_000; let dict = &(0..LEN as u64) .map(|i| (i, i * 2)) - .into_py_dict(py) - .to_object(py) - .into_bound(py); - b.iter(|| black_box(dict).downcast::().unwrap()); + .into_py_dict_bound(py) + .into_any(); + b.iter(|| dict.downcast::().unwrap()); }); } diff --git a/pyo3-benches/benches/bench_extract.rs b/pyo3-benches/benches/bench_extract.rs index 479bd0fd547..a116214d545 100644 --- a/pyo3-benches/benches/bench_extract.rs +++ b/pyo3-benches/benches/bench_extract.rs @@ -3,7 +3,7 @@ use codspeed_criterion_compat::{black_box, criterion_group, criterion_main, Benc use pyo3::{ prelude::*, types::{PyDict, PyFloat, PyInt, PyString}, - IntoPy, PyAny, PyObject, Python, + IntoPy, PyObject, Python, }; fn extract_str_extract_success(bench: &mut Bencher<'_>) { @@ -16,11 +16,11 @@ fn extract_str_extract_success(bench: &mut Bencher<'_>) { fn extract_str_extract_fail(bench: &mut Bencher<'_>) { Python::with_gil(|py| { - let d = PyDict::new(py) as &PyAny; + let d = &PyDict::new_bound(py); bench.iter(|| match black_box(d).extract::<&str>() { Ok(v) => panic!("should err {}", v), - Err(e) => black_box(e), + Err(e) => e, }); }); } @@ -39,11 +39,11 @@ fn extract_str_downcast_success(bench: &mut Bencher<'_>) { fn extract_str_downcast_fail(bench: &mut Bencher<'_>) { Python::with_gil(|py| { - let d = PyDict::new(py) as &PyAny; + let d = &PyDict::new_bound(py); bench.iter(|| match black_box(d).downcast::() { Ok(v) => panic!("should err {}", v), - Err(e) => black_box(e), + Err(e) => e, }); }); } @@ -62,11 +62,11 @@ fn extract_int_extract_success(bench: &mut Bencher<'_>) { fn extract_int_extract_fail(bench: &mut Bencher<'_>) { Python::with_gil(|py| { - let d = PyDict::new(py) as &PyAny; + let d = &PyDict::new_bound(py); bench.iter(|| match black_box(d).extract::() { Ok(v) => panic!("should err {}", v), - Err(e) => black_box(e), + Err(e) => e, }); }); } @@ -86,11 +86,11 @@ fn extract_int_downcast_success(bench: &mut Bencher<'_>) { fn extract_int_downcast_fail(bench: &mut Bencher<'_>) { Python::with_gil(|py| { - let d = PyDict::new(py) as &PyAny; + let d = &PyDict::new_bound(py); bench.iter(|| match black_box(d).downcast::() { Ok(v) => panic!("should err {}", v), - Err(e) => black_box(e), + Err(e) => e, }); }); } @@ -100,20 +100,17 @@ fn extract_float_extract_success(bench: &mut Bencher<'_>) { let float_obj: PyObject = 23.42.into_py(py); let float = float_obj.as_ref(py); - bench.iter(|| { - let v = black_box(float).extract::().unwrap(); - black_box(v); - }); + bench.iter(|| black_box(float).extract::().unwrap()); }); } fn extract_float_extract_fail(bench: &mut Bencher<'_>) { Python::with_gil(|py| { - let d = PyDict::new(py) as &PyAny; + let d = &PyDict::new_bound(py); bench.iter(|| match black_box(d).extract::() { Ok(v) => panic!("should err {}", v), - Err(e) => black_box(e), + Err(e) => e, }); }); } @@ -133,11 +130,11 @@ fn extract_float_downcast_success(bench: &mut Bencher<'_>) { fn extract_float_downcast_fail(bench: &mut Bencher<'_>) { Python::with_gil(|py| { - let d = PyDict::new(py) as &PyAny; + let d = &PyDict::new_bound(py); bench.iter(|| match black_box(d).downcast::() { Ok(v) => panic!("should err {}", v), - Err(e) => black_box(e), + Err(e) => e, }); }); } diff --git a/src/buffer.rs b/src/buffer.rs index d18f05e289d..0db18a65d26 100644 --- a/src/buffer.rs +++ b/src/buffer.rs @@ -686,6 +686,7 @@ impl_element!(f32, Float); impl_element!(f64, Float); #[cfg(test)] +#[cfg_attr(not(feature = "gil-refs"), allow(deprecated))] mod tests { use super::PyBuffer; use crate::ffi; diff --git a/src/conversions/anyhow.rs b/src/conversions/anyhow.rs index 3b5aa053e84..453799c6e8b 100644 --- a/src/conversions/anyhow.rs +++ b/src/conversions/anyhow.rs @@ -147,8 +147,8 @@ mod test_anyhow { let pyerr = PyErr::from(err); Python::with_gil(|py| { - let locals = [("err", pyerr)].into_py_dict(py); - let pyerr = py.run("raise err", None, Some(locals)).unwrap_err(); + let locals = [("err", pyerr)].into_py_dict_bound(py); + let pyerr = py.run_bound("raise err", None, Some(&locals)).unwrap_err(); assert_eq!(pyerr.value(py).to_string(), expected_contents); }) } @@ -164,8 +164,8 @@ mod test_anyhow { let pyerr = PyErr::from(err); Python::with_gil(|py| { - let locals = [("err", pyerr)].into_py_dict(py); - let pyerr = py.run("raise err", None, Some(locals)).unwrap_err(); + let locals = [("err", pyerr)].into_py_dict_bound(py); + let pyerr = py.run_bound("raise err", None, Some(&locals)).unwrap_err(); assert_eq!(pyerr.value(py).to_string(), expected_contents); }) } diff --git a/src/conversions/chrono.rs b/src/conversions/chrono.rs index 6e529918ab2..68df54b9e1f 100644 --- a/src/conversions/chrono.rs +++ b/src/conversions/chrono.rs @@ -564,8 +564,13 @@ fn timezone_utc(py: Python<'_>) -> &PyAny { #[cfg(test)] mod tests { - use super::*; - use crate::{types::PyTuple, Py}; + use super::timezone_utc; + #[cfg(all(Py_3_9, not(target_os = "windows")))] + use crate::types::{any::PyAnyMethods, dict::PyDictMethods}; + use crate::{ + exceptions::PyUserWarning, types::PyTuple, IntoPy, Py, PyAny, PyResult, Python, ToPyObject, + }; + use chrono::{DateTime, Duration, FixedOffset, NaiveDate, NaiveDateTime, NaiveTime, Utc}; use std::{cmp::Ordering, panic}; #[test] @@ -575,11 +580,11 @@ mod tests { #[cfg(all(Py_3_9, not(target_os = "windows")))] fn test_zoneinfo_is_not_fixed_offset() { Python::with_gil(|py| { - let locals = crate::types::PyDict::new(py); - py.run( + let locals = crate::types::PyDict::new_bound(py); + py.run_bound( "import zoneinfo; zi = zoneinfo.ZoneInfo('Europe/London')", None, - Some(locals), + Some(&locals), ) .unwrap(); let result: PyResult = locals.get_item("zi").unwrap().unwrap().extract(); @@ -1095,6 +1100,7 @@ mod tests { mod proptests { use super::*; use crate::tests::common::CatchWarnings; + use crate::types::any::PyAnyMethods; use crate::types::IntoPyDict; use proptest::prelude::*; @@ -1105,9 +1111,9 @@ 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("datetime").unwrap())].into_py_dict_bound(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(); + let t = py.eval_bound(&code, Some(&globals), None).unwrap(); // Get ISO 8601 string from python let py_iso_str = t.call_method0("isoformat").unwrap(); diff --git a/src/conversions/eyre.rs b/src/conversions/eyre.rs index b0559ad1469..d25a10af9ee 100644 --- a/src/conversions/eyre.rs +++ b/src/conversions/eyre.rs @@ -152,8 +152,8 @@ mod tests { let pyerr = PyErr::from(err); Python::with_gil(|py| { - let locals = [("err", pyerr)].into_py_dict(py); - let pyerr = py.run("raise err", None, Some(locals)).unwrap_err(); + let locals = [("err", pyerr)].into_py_dict_bound(py); + let pyerr = py.run_bound("raise err", None, Some(&locals)).unwrap_err(); assert_eq!(pyerr.value(py).to_string(), expected_contents); }) } @@ -169,8 +169,8 @@ mod tests { let pyerr = PyErr::from(err); Python::with_gil(|py| { - let locals = [("err", pyerr)].into_py_dict(py); - let pyerr = py.run("raise err", None, Some(locals)).unwrap_err(); + let locals = [("err", pyerr)].into_py_dict_bound(py); + let pyerr = py.run_bound("raise err", None, Some(&locals)).unwrap_err(); assert_eq!(pyerr.value(py).to_string(), expected_contents); }) } diff --git a/src/conversions/hashbrown.rs b/src/conversions/hashbrown.rs index d2cbe4ad8c6..7138cc35a11 100644 --- a/src/conversions/hashbrown.rs +++ b/src/conversions/hashbrown.rs @@ -33,7 +33,7 @@ where H: hash::BuildHasher, { fn to_object(&self, py: Python<'_>) -> PyObject { - IntoPyDict::into_py_dict(self, py).into() + IntoPyDict::into_py_dict_bound(self, py).into() } } @@ -47,7 +47,7 @@ where let iter = self .into_iter() .map(|(k, v)| (k.into_py(py), v.into_py(py))); - IntoPyDict::into_py_dict(iter, py).into() + IntoPyDict::into_py_dict_bound(iter, py).into() } } @@ -112,7 +112,7 @@ where #[cfg(test)] mod tests { use super::*; - use crate::types::any::PyAnyMethods; + use crate::types::{any::PyAnyMethods, dict::PyDictMethods}; #[test] fn test_hashbrown_hashmap_to_python() { @@ -164,7 +164,7 @@ mod tests { let mut map = hashbrown::HashMap::::new(); map.insert(1, 1); - let py_map = map.into_py_dict(py); + let py_map = map.into_py_dict_bound(py); assert_eq!(py_map.len(), 1); assert_eq!( diff --git a/src/conversions/indexmap.rs b/src/conversions/indexmap.rs index 53f7f9364c3..178d74fec4f 100644 --- a/src/conversions/indexmap.rs +++ b/src/conversions/indexmap.rs @@ -100,7 +100,7 @@ where H: hash::BuildHasher, { fn to_object(&self, py: Python<'_>) -> PyObject { - IntoPyDict::into_py_dict(self, py).into() + IntoPyDict::into_py_dict_bound(self, py).into() } } @@ -114,7 +114,7 @@ where let iter = self .into_iter() .map(|(k, v)| (k.into_py(py), v.into_py(py))); - IntoPyDict::into_py_dict(iter, py).into() + IntoPyDict::into_py_dict_bound(iter, py).into() } } @@ -138,6 +138,7 @@ where mod test_indexmap { use crate::types::*; + use crate::types::{any::PyAnyMethods, dict::PyDictMethods}; use crate::{IntoPy, PyObject, Python, ToPyObject}; #[test] @@ -194,7 +195,7 @@ mod test_indexmap { let mut map = indexmap::IndexMap::::new(); map.insert(1, 1); - let py_map = map.into_py_dict(py); + let py_map = map.into_py_dict_bound(py); assert_eq!(py_map.len(), 1); assert_eq!( @@ -223,7 +224,7 @@ mod test_indexmap { } } - let py_map = map.clone().into_py_dict(py); + let py_map = map.clone().into_py_dict_bound(py); let trip_map = py_map.extract::>().unwrap(); diff --git a/src/conversions/num_bigint.rs b/src/conversions/num_bigint.rs index 1d536623a85..32ecfe80207 100644 --- a/src/conversions/num_bigint.rs +++ b/src/conversions/num_bigint.rs @@ -55,6 +55,8 @@ use crate::{ types::{any::PyAnyMethods, *}, FromPyObject, IntoPy, Py, PyAny, PyObject, PyResult, Python, ToPyObject, }; +#[cfg(Py_LIMITED_API)] +use crate::{types::dict::PyDictMethods, Bound}; use num_bigint::{BigInt, BigUint}; @@ -85,14 +87,18 @@ macro_rules! bigint_conversion { let bytes = $to_bytes(self); let bytes_obj = PyBytes::new_bound(py, &bytes); let kwargs = if $is_signed > 0 { - let kwargs = PyDict::new(py); + let kwargs = PyDict::new_bound(py); kwargs.set_item(crate::intern!(py, "signed"), true).unwrap(); Some(kwargs) } else { None }; py.get_type::() - .call_method("from_bytes", (bytes_obj, "little"), kwargs) + .call_method( + "from_bytes", + (bytes_obj, "little"), + kwargs.as_ref().map(Bound::as_gil_ref), + ) .expect("int.from_bytes() failed during to_object()") // FIXME: #1813 or similar .into() } @@ -262,7 +268,7 @@ fn int_n_bits(long: &Bound<'_, PyLong>) -> PyResult { #[cfg(test)] mod tests { use super::*; - use crate::types::{PyDict, PyModule}; + use crate::types::{dict::PyDictMethods, PyDict, PyModule}; use indoc::indoc; fn rust_fib() -> impl Iterator @@ -340,9 +346,9 @@ mod tests { fn convert_index_class() { Python::with_gil(|py| { let index = python_index_class(py); - let locals = PyDict::new(py); + let locals = PyDict::new_bound(py); locals.set_item("index", index).unwrap(); - let ob = py.eval("index.C(10)", None, Some(locals)).unwrap(); + let ob = py.eval_bound("index.C(10)", None, Some(&locals)).unwrap(); let _: BigInt = ob.extract().unwrap(); }); } diff --git a/src/conversions/rust_decimal.rs b/src/conversions/rust_decimal.rs index 2e38e7808e5..2877761de35 100644 --- a/src/conversions/rust_decimal.rs +++ b/src/conversions/rust_decimal.rs @@ -108,7 +108,7 @@ impl IntoPy for Decimal { mod test_rust_decimal { use super::*; use crate::err::PyErr; - use crate::types::PyDict; + use crate::types::{dict::PyDictMethods, PyDict}; use rust_decimal::Decimal; #[cfg(not(target_arch = "wasm32"))] @@ -121,16 +121,16 @@ mod test_rust_decimal { Python::with_gil(|py| { let rs_orig = $rs; let rs_dec = rs_orig.into_py(py); - let locals = PyDict::new(py); + let locals = PyDict::new_bound(py); locals.set_item("rs_dec", &rs_dec).unwrap(); // Checks if Rust Decimal -> Python Decimal conversion is correct - py.run( + py.run_bound( &format!( "import decimal\npy_dec = decimal.Decimal({})\nassert py_dec == rs_dec", $py ), None, - Some(locals), + Some(&locals), ) .unwrap(); // Checks if Python Decimal -> Rust Decimal conversion is correct @@ -163,13 +163,13 @@ mod test_rust_decimal { let num = Decimal::from_parts(lo, mid, high, negative, scale); Python::with_gil(|py| { let rs_dec = num.into_py(py); - let locals = PyDict::new(py); + let locals = PyDict::new_bound(py); locals.set_item("rs_dec", &rs_dec).unwrap(); - py.run( + py.run_bound( &format!( "import decimal\npy_dec = decimal.Decimal(\"{}\")\nassert py_dec == rs_dec", num), - None, Some(locals)).unwrap(); + None, Some(&locals)).unwrap(); let roundtripped: Decimal = rs_dec.extract(py).unwrap(); assert_eq!(num, roundtripped); }) @@ -189,11 +189,11 @@ mod test_rust_decimal { #[test] fn test_nan() { Python::with_gil(|py| { - let locals = PyDict::new(py); - py.run( + let locals = PyDict::new_bound(py); + py.run_bound( "import decimal\npy_dec = decimal.Decimal(\"NaN\")", None, - Some(locals), + Some(&locals), ) .unwrap(); let py_dec = locals.get_item("py_dec").unwrap().unwrap(); @@ -205,11 +205,11 @@ mod test_rust_decimal { #[test] fn test_infinity() { Python::with_gil(|py| { - let locals = PyDict::new(py); - py.run( + let locals = PyDict::new_bound(py); + py.run_bound( "import decimal\npy_dec = decimal.Decimal(\"Infinity\")", None, - Some(locals), + Some(&locals), ) .unwrap(); let py_dec = locals.get_item("py_dec").unwrap().unwrap(); diff --git a/src/conversions/smallvec.rs b/src/conversions/smallvec.rs index ade64a5106c..f51da1de32a 100644 --- a/src/conversions/smallvec.rs +++ b/src/conversions/smallvec.rs @@ -121,7 +121,7 @@ mod tests { #[test] fn test_smallvec_from_py_object_fails() { Python::with_gil(|py| { - let dict = PyDict::new(py); + let dict = PyDict::new_bound(py); let sv: PyResult> = dict.extract(); assert_eq!( sv.unwrap_err().to_string(), diff --git a/src/conversions/std/array.rs b/src/conversions/std/array.rs index 0ea167135b6..7f6c1fc47aa 100644 --- a/src/conversions/std/array.rs +++ b/src/conversions/std/array.rs @@ -130,7 +130,7 @@ mod tests { sync::atomic::{AtomicUsize, Ordering}, }; - use crate::{types::PyList, IntoPy, PyResult, Python, ToPyObject}; + use crate::{types::any::PyAnyMethods, types::PyList, IntoPy, PyResult, Python, ToPyObject}; #[test] fn array_try_from_fn() { @@ -157,7 +157,7 @@ mod tests { fn test_extract_bytearray_to_array() { Python::with_gil(|py| { let v: [u8; 33] = py - .eval( + .eval_bound( "bytearray(b'abcabcabcabcabcabcabcabcabcabcabc')", None, None, @@ -173,7 +173,7 @@ mod tests { fn test_extract_small_bytearray_to_array() { Python::with_gil(|py| { let v: [u8; 3] = py - .eval("bytearray(b'abc')", None, None) + .eval_bound("bytearray(b'abc')", None, None) .unwrap() .extract() .unwrap(); @@ -197,7 +197,7 @@ mod tests { fn test_extract_invalid_sequence_length() { Python::with_gil(|py| { let v: PyResult<[u8; 3]> = py - .eval("bytearray(b'abcdefg')", None, None) + .eval_bound("bytearray(b'abcdefg')", None, None) .unwrap() .extract(); assert_eq!( @@ -223,7 +223,7 @@ mod tests { #[test] fn test_extract_non_iterable_to_array() { Python::with_gil(|py| { - let v = py.eval("42", None, None).unwrap(); + let v = py.eval_bound("42", None, None).unwrap(); v.extract::().unwrap(); v.extract::<[i32; 1]>().unwrap_err(); }); diff --git a/src/conversions/std/map.rs b/src/conversions/std/map.rs index 1c3f669eaee..700617ec17a 100644 --- a/src/conversions/std/map.rs +++ b/src/conversions/std/map.rs @@ -16,7 +16,7 @@ where H: hash::BuildHasher, { fn to_object(&self, py: Python<'_>) -> PyObject { - IntoPyDict::into_py_dict(self, py).into() + IntoPyDict::into_py_dict_bound(self, py).into() } } @@ -26,7 +26,7 @@ where V: ToPyObject, { fn to_object(&self, py: Python<'_>) -> PyObject { - IntoPyDict::into_py_dict(self, py).into() + IntoPyDict::into_py_dict_bound(self, py).into() } } @@ -40,7 +40,7 @@ where let iter = self .into_iter() .map(|(k, v)| (k.into_py(py), v.into_py(py))); - IntoPyDict::into_py_dict(iter, py).into() + IntoPyDict::into_py_dict_bound(iter, py).into() } #[cfg(feature = "experimental-inspect")] @@ -58,7 +58,7 @@ where let iter = self .into_iter() .map(|(k, v)| (k.into_py(py), v.into_py(py))); - IntoPyDict::into_py_dict(iter, py).into() + IntoPyDict::into_py_dict_bound(iter, py).into() } #[cfg(feature = "experimental-inspect")] diff --git a/src/conversions/std/num.rs b/src/conversions/std/num.rs index 82f63016a7d..39fdf470055 100644 --- a/src/conversions/std/num.rs +++ b/src/conversions/std/num.rs @@ -371,6 +371,8 @@ nonzero_int_impl!(NonZeroUsize, usize); #[cfg(test)] mod test_128bit_integers { use super::*; + use crate::types::any::PyAnyMethods; + #[cfg(not(target_arch = "wasm32"))] use crate::types::PyDict; @@ -383,9 +385,9 @@ mod test_128bit_integers { fn test_i128_roundtrip(x: i128) { Python::with_gil(|py| { let x_py = x.into_py(py); - let locals = PyDict::new(py); + let locals = PyDict::new_bound(py); locals.set_item("x_py", x_py.clone_ref(py)).unwrap(); - py.run(&format!("assert x_py == {}", x), None, Some(locals)).unwrap(); + py.run_bound(&format!("assert x_py == {}", x), None, Some(&locals)).unwrap(); let roundtripped: i128 = x_py.extract(py).unwrap(); assert_eq!(x, roundtripped); }) @@ -399,9 +401,9 @@ mod test_128bit_integers { ) { Python::with_gil(|py| { let x_py = x.into_py(py); - let locals = PyDict::new(py); + let locals = PyDict::new_bound(py); locals.set_item("x_py", x_py.clone_ref(py)).unwrap(); - py.run(&format!("assert x_py == {}", x), None, Some(locals)).unwrap(); + py.run_bound(&format!("assert x_py == {}", x), None, Some(&locals)).unwrap(); let roundtripped: NonZeroI128 = x_py.extract(py).unwrap(); assert_eq!(x, roundtripped); }) @@ -414,9 +416,9 @@ mod test_128bit_integers { fn test_u128_roundtrip(x: u128) { Python::with_gil(|py| { let x_py = x.into_py(py); - let locals = PyDict::new(py); + let locals = PyDict::new_bound(py); locals.set_item("x_py", x_py.clone_ref(py)).unwrap(); - py.run(&format!("assert x_py == {}", x), None, Some(locals)).unwrap(); + py.run_bound(&format!("assert x_py == {}", x), None, Some(&locals)).unwrap(); let roundtripped: u128 = x_py.extract(py).unwrap(); assert_eq!(x, roundtripped); }) @@ -430,9 +432,9 @@ mod test_128bit_integers { ) { Python::with_gil(|py| { let x_py = x.into_py(py); - let locals = PyDict::new(py); + let locals = PyDict::new_bound(py); locals.set_item("x_py", x_py.clone_ref(py)).unwrap(); - py.run(&format!("assert x_py == {}", x), None, Some(locals)).unwrap(); + py.run_bound(&format!("assert x_py == {}", x), None, Some(&locals)).unwrap(); let roundtripped: NonZeroU128 = x_py.extract(py).unwrap(); assert_eq!(x, roundtripped); }) @@ -474,7 +476,7 @@ mod test_128bit_integers { #[test] fn test_i128_overflow() { Python::with_gil(|py| { - let obj = py.eval("(1 << 130) * -1", None, None).unwrap(); + let obj = py.eval_bound("(1 << 130) * -1", None, None).unwrap(); let err = obj.extract::().unwrap_err(); assert!(err.is_instance_of::(py)); }) @@ -483,7 +485,7 @@ mod test_128bit_integers { #[test] fn test_u128_overflow() { Python::with_gil(|py| { - let obj = py.eval("1 << 130", None, None).unwrap(); + let obj = py.eval_bound("1 << 130", None, None).unwrap(); let err = obj.extract::().unwrap_err(); assert!(err.is_instance_of::(py)); }) @@ -527,7 +529,7 @@ mod test_128bit_integers { #[test] fn test_nonzero_i128_overflow() { Python::with_gil(|py| { - let obj = py.eval("(1 << 130) * -1", None, None).unwrap(); + let obj = py.eval_bound("(1 << 130) * -1", None, None).unwrap(); let err = obj.extract::().unwrap_err(); assert!(err.is_instance_of::(py)); }) @@ -536,7 +538,7 @@ mod test_128bit_integers { #[test] fn test_nonzero_u128_overflow() { Python::with_gil(|py| { - let obj = py.eval("1 << 130", None, None).unwrap(); + let obj = py.eval_bound("1 << 130", None, None).unwrap(); let err = obj.extract::().unwrap_err(); assert!(err.is_instance_of::(py)); }) @@ -545,7 +547,7 @@ mod test_128bit_integers { #[test] fn test_nonzero_i128_zero_value() { Python::with_gil(|py| { - let obj = py.eval("0", None, None).unwrap(); + let obj = py.eval_bound("0", None, None).unwrap(); let err = obj.extract::().unwrap_err(); assert!(err.is_instance_of::(py)); }) @@ -554,7 +556,7 @@ mod test_128bit_integers { #[test] fn test_nonzero_u128_zero_value() { Python::with_gil(|py| { - let obj = py.eval("0", None, None).unwrap(); + let obj = py.eval_bound("0", None, None).unwrap(); let err = obj.extract::().unwrap_err(); assert!(err.is_instance_of::(py)); }) diff --git a/src/conversions/std/slice.rs b/src/conversions/std/slice.rs index 62809327f57..7d054b4ef45 100644 --- a/src/conversions/std/slice.rs +++ b/src/conversions/std/slice.rs @@ -26,12 +26,12 @@ impl<'py> FromPyObject<'py> for &'py [u8] { #[cfg(test)] mod tests { - use crate::Python; + use crate::{types::any::PyAnyMethods, Python}; #[test] fn test_extract_bytes() { Python::with_gil(|py| { - let py_bytes = py.eval("b'Hello Python'", None, None).unwrap(); + let py_bytes = py.eval_bound("b'Hello Python'", None, None).unwrap(); let bytes: &[u8] = py_bytes.extract().unwrap(); assert_eq!(bytes, b"Hello Python"); }); diff --git a/src/conversions/std/time.rs b/src/conversions/std/time.rs index bdf938c0bd8..f0c1668c97b 100755 --- a/src/conversions/std/time.rs +++ b/src/conversions/std/time.rs @@ -337,9 +337,11 @@ mod tests { fn max_datetime(py: Python<'_>) -> &PyAny { let naive_max = datetime_class(py).getattr("max").unwrap(); - let kargs = PyDict::new(py); - kargs.set_item("tzinfo", tz_utc(py)).unwrap(); - naive_max.call_method("replace", (), Some(kargs)).unwrap() + let kwargs = PyDict::new_bound(py); + kwargs.set_item("tzinfo", tz_utc(py)).unwrap(); + naive_max + .call_method("replace", (), Some(kwargs.as_gil_ref())) + .unwrap() } #[test] diff --git a/src/err/mod.rs b/src/err/mod.rs index c50e377409e..6f0ddc37dc7 100644 --- a/src/err/mod.rs +++ b/src/err/mod.rs @@ -1030,7 +1030,7 @@ mod tests { Python::with_gil(|py| { let err = py - .run("raise Exception('banana')", None, None) + .run_bound("raise Exception('banana')", None, None) .expect_err("raising should have given us an error"); let debug_str = format!("{:?}", err); @@ -1055,7 +1055,7 @@ mod tests { fn err_display() { Python::with_gil(|py| { let err = py - .run("raise Exception('banana')", None, None) + .run_bound("raise Exception('banana')", None, None) .expect_err("raising should have given us an error"); assert_eq!(err.to_string(), "Exception: banana"); }); @@ -1096,12 +1096,12 @@ mod tests { fn test_pyerr_cause() { Python::with_gil(|py| { let err = py - .run("raise Exception('banana')", None, None) + .run_bound("raise Exception('banana')", None, None) .expect_err("raising should have given us an error"); assert!(err.cause(py).is_none()); let err = py - .run( + .run_bound( "raise Exception('banana') from Exception('apple')", None, None, diff --git a/src/exceptions.rs b/src/exceptions.rs index 19f59742435..eef873ea9eb 100644 --- a/src/exceptions.rs +++ b/src/exceptions.rs @@ -71,8 +71,8 @@ macro_rules! impl_exception_boilerplate { /// import_exception!(socket, gaierror); /// /// Python::with_gil(|py| { -/// let ctx = [("gaierror", py.get_type::())].into_py_dict(py); -/// pyo3::py_run!(py, *ctx, "import socket; assert gaierror is socket.gaierror"); +/// let ctx = [("gaierror", py.get_type::())].into_py_dict_bound(py); +/// pyo3::py_run_bound!(py, *ctx, "import socket; assert gaierror is socket.gaierror"); /// }); /// /// ``` @@ -165,18 +165,18 @@ macro_rules! import_exception { /// # fn main() -> PyResult<()> { /// # Python::with_gil(|py| -> PyResult<()> { /// # let fun = wrap_pyfunction!(raise_myerror, py)?; -/// # let locals = pyo3::types::PyDict::new(py); +/// # let locals = pyo3::types::PyDict::new_bound(py); /// # locals.set_item("MyError", py.get_type::())?; /// # locals.set_item("raise_myerror", fun)?; /// # -/// # py.run( +/// # py.run_bound( /// # "try: /// # raise_myerror() /// # except MyError as e: /// # assert e.__doc__ == 'Some description.' /// # assert str(e) == 'Some error happened.'", /// # None, -/// # Some(locals), +/// # Some(&locals), /// # )?; /// # /// # Ok(()) @@ -338,7 +338,7 @@ use pyo3::prelude::*; use pyo3::exceptions::Py", $name, "; Python::with_gil(|py| { - let result: PyResult<()> = py.run(\"raise ", $name, "\", None, None); + let result: PyResult<()> = py.run_bound(\"raise ", $name, "\", None, None); let error_type = match result { Ok(_) => \"Not an error\", @@ -800,6 +800,8 @@ pub mod socket { #[cfg(test)] mod tests { use super::*; + use crate::types::any::PyAnyMethods; + use crate::types::dict::PyDictMethods; use crate::types::{IntoPyDict, PyDict}; use crate::{PyErr, Python}; @@ -815,7 +817,7 @@ mod tests { .map_err(|e| e.display(py)) .expect("could not import socket"); - let d = PyDict::new(py); + let d = PyDict::new_bound(py); d.set_item("socket", socket) .map_err(|e| e.display(py)) .expect("could not setitem"); @@ -824,7 +826,7 @@ mod tests { .map_err(|e| e.display(py)) .expect("could not setitem"); - py.run("assert isinstance(exc, socket.gaierror)", None, Some(d)) + py.run_bound("assert isinstance(exc, socket.gaierror)", None, Some(&d)) .map_err(|e| e.display(py)) .expect("assertion failed"); }); @@ -839,7 +841,7 @@ mod tests { .map_err(|e| e.display(py)) .expect("could not import email"); - let d = PyDict::new(py); + let d = PyDict::new_bound(py); d.set_item("email", email) .map_err(|e| e.display(py)) .expect("could not setitem"); @@ -847,10 +849,10 @@ mod tests { .map_err(|e| e.display(py)) .expect("could not setitem"); - py.run( + py.run_bound( "assert isinstance(exc, email.errors.MessageError)", None, - Some(d), + Some(&d), ) .map_err(|e| e.display(py)) .expect("assertion failed"); @@ -863,20 +865,20 @@ mod tests { Python::with_gil(|py| { let error_type = py.get_type::(); - let ctx = [("CustomError", error_type)].into_py_dict(py); + let ctx = [("CustomError", error_type)].into_py_dict_bound(py); let type_description: String = py - .eval("str(CustomError)", None, Some(ctx)) + .eval_bound("str(CustomError)", None, Some(&ctx)) .unwrap() .extract() .unwrap(); assert_eq!(type_description, ""); - py.run( + py.run_bound( "assert CustomError('oops').args == ('oops',)", None, - Some(ctx), + Some(&ctx), ) .unwrap(); - py.run("assert CustomError.__doc__ is None", None, Some(ctx)) + py.run_bound("assert CustomError.__doc__ is None", None, Some(&ctx)) .unwrap(); }); } @@ -886,9 +888,9 @@ mod tests { create_exception!(mymodule.exceptions, CustomError, PyException); Python::with_gil(|py| { let error_type = py.get_type::(); - let ctx = [("CustomError", error_type)].into_py_dict(py); + let ctx = [("CustomError", error_type)].into_py_dict_bound(py); let type_description: String = py - .eval("str(CustomError)", None, Some(ctx)) + .eval_bound("str(CustomError)", None, Some(&ctx)) .unwrap() .extract() .unwrap(); @@ -905,21 +907,25 @@ mod tests { Python::with_gil(|py| { let error_type = py.get_type::(); - let ctx = [("CustomError", error_type)].into_py_dict(py); + let ctx = [("CustomError", error_type)].into_py_dict_bound(py); let type_description: String = py - .eval("str(CustomError)", None, Some(ctx)) + .eval_bound("str(CustomError)", None, Some(&ctx)) .unwrap() .extract() .unwrap(); assert_eq!(type_description, ""); - py.run( + py.run_bound( "assert CustomError('oops').args == ('oops',)", None, - Some(ctx), + Some(&ctx), + ) + .unwrap(); + py.run_bound( + "assert CustomError.__doc__ == 'Some docs'", + None, + Some(&ctx), ) .unwrap(); - py.run("assert CustomError.__doc__ == 'Some docs'", None, Some(ctx)) - .unwrap(); }); } @@ -934,23 +940,23 @@ mod tests { Python::with_gil(|py| { let error_type = py.get_type::(); - let ctx = [("CustomError", error_type)].into_py_dict(py); + let ctx = [("CustomError", error_type)].into_py_dict_bound(py); let type_description: String = py - .eval("str(CustomError)", None, Some(ctx)) + .eval_bound("str(CustomError)", None, Some(&ctx)) .unwrap() .extract() .unwrap(); assert_eq!(type_description, ""); - py.run( + py.run_bound( "assert CustomError('oops').args == ('oops',)", None, - Some(ctx), + Some(&ctx), ) .unwrap(); - py.run( + py.run_bound( "assert CustomError.__doc__ == 'Some more docs'", None, - Some(ctx), + Some(&ctx), ) .unwrap(); }); @@ -960,7 +966,7 @@ mod tests { fn native_exception_debug() { Python::with_gil(|py| { let exc = py - .run("raise Exception('banana')", None, None) + .run_bound("raise Exception('banana')", None, None) .expect_err("raising should have given us an error") .into_value(py) .into_ref(py); @@ -975,7 +981,7 @@ mod tests { fn native_exception_display() { Python::with_gil(|py| { let exc = py - .run("raise Exception('banana')", None, None) + .run_bound("raise Exception('banana')", None, None) .expect_err("raising should have given us an error") .into_value(py) .into_ref(py); @@ -992,7 +998,7 @@ mod tests { Python::with_gil(|py| { let exc = py - .run( + .run_bound( "raise Exception('banana') from TypeError('peach')", None, None, @@ -1077,7 +1083,7 @@ mod tests { PyErr::from_value(PyUnicodeDecodeError::new_utf8(py, invalid_utf8, err).unwrap()) }); test_exception!(PyUnicodeEncodeError, |py| py - .eval("chr(40960).encode('ascii')", None, None) + .eval_bound("chr(40960).encode('ascii')", None, None) .unwrap_err()); test_exception!(PyUnicodeTranslateError, |_| { PyUnicodeTranslateError::new_err(("\u{3042}", 0, 1, "ouch")) diff --git a/src/ffi/tests.rs b/src/ffi/tests.rs index 0e0d3688e11..ca65d068f7e 100644 --- a/src/ffi/tests.rs +++ b/src/ffi/tests.rs @@ -1,9 +1,10 @@ use crate::ffi::*; use crate::Python; +use crate::types::any::PyAnyMethods; #[cfg(not(Py_LIMITED_API))] use crate::{ - types::{any::PyAnyMethods, PyDict, PyString}, + types::{dict::PyDictMethods, PyDict, PyString}, IntoPy, Py, PyAny, }; #[cfg(not(any(Py_3_12, Py_LIMITED_API)))] @@ -19,12 +20,12 @@ fn test_datetime_fromtimestamp() { PyDateTime_IMPORT(); py.from_owned_ptr(PyDateTime_FromTimestamp(args.as_ptr())) }; - let locals = PyDict::new(py); + let locals = PyDict::new_bound(py); locals.set_item("dt", dt).unwrap(); - py.run( + py.run_bound( "import datetime; assert dt == datetime.datetime.fromtimestamp(100)", None, - Some(locals), + Some(&locals), ) .unwrap(); }) @@ -40,12 +41,12 @@ fn test_date_fromtimestamp() { PyDateTime_IMPORT(); py.from_owned_ptr(PyDate_FromTimestamp(args.as_ptr())) }; - let locals = PyDict::new(py); + let locals = PyDict::new_bound(py); locals.set_item("dt", dt).unwrap(); - py.run( + py.run_bound( "import datetime; assert dt == datetime.date.fromtimestamp(100)", None, - Some(locals), + Some(&locals), ) .unwrap(); }) @@ -60,12 +61,12 @@ fn test_utc_timezone() { PyDateTime_IMPORT(); py.from_borrowed_ptr(PyDateTime_TimeZone_UTC()) }; - let locals = PyDict::new(py); + let locals = PyDict::new_bound(py); locals.set_item("utc_timezone", utc_timezone).unwrap(); - py.run( + py.run_bound( "import datetime; assert utc_timezone is datetime.timezone.utc", None, - Some(locals), + Some(&locals), ) .unwrap(); }) @@ -81,7 +82,7 @@ fn test_timezone_from_offset() { Python::with_gil(|py| { let delta = PyDelta::new(py, 0, 100, 0, false).unwrap(); let tz: &PyAny = unsafe { py.from_borrowed_ptr(PyTimeZone_FromOffset(delta.as_ptr())) }; - crate::py_run!( + crate::py_run_bound!( py, tz, "import datetime; assert tz == datetime.timezone(datetime.timedelta(seconds=100))" @@ -105,7 +106,7 @@ fn test_timezone_from_offset_and_name() { tzname.as_ptr(), )) }; - crate::py_run!( + crate::py_run_bound!( py, tz, "import datetime; assert tz == datetime.timezone(datetime.timedelta(seconds=100), 'testtz')" @@ -293,7 +294,7 @@ fn test_get_tzinfo() { #[test] fn test_inc_dec_ref() { Python::with_gil(|py| { - let obj = py.eval("object()", None, None).unwrap(); + let obj = py.eval_bound("object()", None, None).unwrap(); let ref_count = obj.get_refcnt(); let ptr = obj.as_ptr(); diff --git a/src/gil.rs b/src/gil.rs index d346ad95ea9..f2bf3e404a0 100644 --- a/src/gil.rs +++ b/src/gil.rs @@ -75,7 +75,7 @@ fn gil_is_acquired() -> bool { /// /// # fn main() -> PyResult<()> { /// pyo3::prepare_freethreaded_python(); -/// Python::with_gil(|py| py.run("print('Hello World')", None, None)) +/// Python::with_gil(|py| py.run_bound("print('Hello World')", None, None)) /// # } /// ``` #[cfg(not(PyPy))] @@ -118,7 +118,7 @@ pub fn prepare_freethreaded_python() { /// ```rust /// unsafe { /// pyo3::with_embedded_python_interpreter(|py| { -/// if let Err(e) = py.run("print('Hello World')", None, None) { +/// if let Err(e) = py.run_bound("print('Hello World')", None, None) { /// // We must make sure to not return a `PyErr`! /// e.print(py); /// } @@ -507,7 +507,7 @@ fn decrement_gil_count() { #[cfg(test)] mod tests { use super::{gil_is_acquired, GILPool, GIL_COUNT, OWNED_OBJECTS, POOL}; - use crate::{ffi, gil, PyObject, Python, ToPyObject}; + use crate::{ffi, gil, types::any::PyAnyMethods, PyObject, Python, ToPyObject}; #[cfg(not(target_arch = "wasm32"))] use parking_lot::{const_mutex, Condvar, Mutex}; use std::ptr::NonNull; @@ -518,7 +518,7 @@ mod tests { let pool = unsafe { py.new_pool() }; let py = pool.python(); - let obj = py.eval("object()", None, None).unwrap(); + let obj = py.eval_bound("object()", None, None).unwrap(); obj.to_object(py) } @@ -735,7 +735,7 @@ mod tests { fn dropping_gil_does_not_invalidate_references() { // Acquiring GIL for the second time should be safe - see #864 Python::with_gil(|py| { - let obj = Python::with_gil(|_| py.eval("object()", None, None).unwrap()); + let obj = Python::with_gil(|_| py.eval_bound("object()", None, None).unwrap()); // After gil2 drops, obj should still have a reference count of one assert_eq!(obj.get_refcnt(), 1); diff --git a/src/impl_/extract_argument.rs b/src/impl_/extract_argument.rs index cd63fe270b0..2015de232df 100644 --- a/src/impl_/extract_argument.rs +++ b/src/impl_/extract_argument.rs @@ -680,7 +680,7 @@ impl<'py> VarkeywordsHandler<'py> for DictVarkeywords { _function_description: &FunctionDescription, ) -> PyResult<()> { varkeywords - .get_or_insert_with(|| PyDict::new(name.py())) + .get_or_insert_with(|| PyDict::new_bound(name.py()).into_gil_ref()) .set_item(name, value) } } @@ -727,7 +727,7 @@ mod tests { Python::with_gil(|py| { let args = PyTuple::new_bound(py, Vec::<&PyAny>::new()); - let kwargs = [("foo", 0u8)].into_py_dict(py); + let kwargs = [("foo", 0u8)].into_py_dict_bound(py); let err = unsafe { function_description .extract_arguments_tuple_dict::( @@ -758,7 +758,7 @@ mod tests { Python::with_gil(|py| { let args = PyTuple::new_bound(py, Vec::<&PyAny>::new()); - let kwargs = [(1u8, 1u8)].into_py_dict(py); + let kwargs = [(1u8, 1u8)].into_py_dict_bound(py); let err = unsafe { function_description .extract_arguments_tuple_dict::( diff --git a/src/instance.rs b/src/instance.rs index d21cc307af9..f05f9dbe1a6 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -423,7 +423,7 @@ impl IntoPy for Borrowed<'_, '_, T> { /// /// // `&PyDict` derives its lifetime from `py` and /// // so won't be able to outlive this closure. -/// let dict: &PyDict = PyDict::new(py); +/// let dict: &PyDict = PyDict::new_bound(py); /// /// // because `Foo` contains `dict` its lifetime /// // is now also tied to `py`. @@ -452,7 +452,7 @@ impl IntoPy for Borrowed<'_, '_, T> { /// #[new] /// fn __new__() -> Foo { /// Python::with_gil(|py| { -/// let dict: Py = PyDict::new(py).into(); +/// let dict: Py = PyDict::new_bound(py).into(); /// Foo { inner: dict } /// }) /// } @@ -524,7 +524,7 @@ impl IntoPy for Borrowed<'_, '_, T> { /// /// # fn main() { /// Python::with_gil(|py| { -/// let first: Py = PyDict::new(py).into(); +/// let first: Py = PyDict::new_bound(py).into(); /// /// // All of these are valid syntax /// let second = Py::clone_ref(&first, py); @@ -948,7 +948,7 @@ impl Py { /// /// # fn main() { /// Python::with_gil(|py| { - /// let first: Py = PyDict::new(py).into(); + /// let first: Py = PyDict::new_bound(py).into(); /// let second = Py::clone_ref(&first, py); /// /// // Both point to the same object @@ -1501,7 +1501,7 @@ impl PyObject { /// use pyo3::types::{PyDict, PyList}; /// /// Python::with_gil(|py| { - /// let any: PyObject = PyDict::new(py).into(); + /// let any: PyObject = PyDict::new_bound(py).into(); /// /// assert!(any.downcast::(py).is_ok()); /// assert!(any.downcast::(py).is_err()); diff --git a/src/lib.rs b/src/lib.rs index 3f91eb56913..5ba0d279aa1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -221,9 +221,9 @@ //! let sys = py.import("sys")?; //! let version: String = sys.getattr("version")?.extract()?; //! -//! let locals = [("os", py.import("os")?)].into_py_dict(py); +//! let locals = [("os", py.import("os")?)].into_py_dict_bound(py); //! let code = "os.getenv('USER') or os.getenv('USERNAME') or 'Unknown'"; -//! let user: String = py.eval(code, None, Some(&locals))?.extract()?; +//! let user: String = py.eval_bound(code, None, Some(&locals))?.extract()?; //! //! println!("Hello {}, I'm Python {}", user, version); //! Ok(()) diff --git a/src/macros.rs b/src/macros.rs index 41de9079c40..29a18ae0a93 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -1,3 +1,27 @@ +/// Deprecated form of [`py_run_bound`][crate::py_run_bound]. +#[cfg_attr( + not(feature = "gil-refs"), + deprecated( + since = "0.21.0", + note = "`py_run` will be replaced by `py_run_bound` in a future PyO3 version" + ) +)] +#[macro_export] +macro_rules! py_run { + ($py:expr, $($val:ident)+, $code:literal) => {{ + $crate::py_run_impl!($py, $($val)+, $crate::indoc::indoc!($code)) + }}; + ($py:expr, $($val:ident)+, $code:expr) => {{ + $crate::py_run_impl!($py, $($val)+, &$crate::unindent::unindent($code)) + }}; + ($py:expr, *$dict:expr, $code:literal) => {{ + $crate::py_run_impl!($py, *$dict.as_borrowed(), $crate::indoc::indoc!($code)) + }}; + ($py:expr, *$dict:expr, $code:expr) => {{ + $crate::py_run_impl!($py, *$dict.as_borrowed(), &$crate::unindent::unindent($code)) + }}; +} + /// A convenient macro to execute a Python code snippet, with some local variables set. /// /// # Panics @@ -9,18 +33,18 @@ /// /// # Examples /// ``` -/// use pyo3::{prelude::*, py_run, types::PyList}; +/// use pyo3::{prelude::*, py_run_bound, types::PyList}; /// /// Python::with_gil(|py| { /// let list = PyList::new_bound(py, &[1, 2, 3]); -/// py_run!(py, list, "assert list == [1, 2, 3]"); +/// py_run_bound!(py, list, "assert list == [1, 2, 3]"); /// }); /// ``` /// /// You can use this macro to test pyfunctions or pyclasses quickly. /// /// ``` -/// use pyo3::{prelude::*, py_run}; +/// use pyo3::{prelude::*, py_run_bound}; /// /// #[pyclass] /// #[derive(Debug)] @@ -47,7 +71,7 @@ /// Python::with_gil(|py| { /// let time = PyCell::new(py, Time {hour: 8, minute: 43, second: 16}).unwrap(); /// let time_as_tuple = (8, 43, 16); -/// py_run!(py, time time_as_tuple, r#" +/// py_run_bound!(py, time time_as_tuple, r#" /// assert time.hour == 8 /// assert time.repl_japanese() == "8時43分16秒" /// assert time.as_tuple() == time_as_tuple @@ -73,12 +97,12 @@ /// } /// /// Python::with_gil(|py| { -/// let locals = [("C", py.get_type::())].into_py_dict(py); -/// pyo3::py_run!(py, *locals, "c = C()"); +/// let locals = [("C", py.get_type::())].into_py_dict_bound(py); +/// pyo3::py_run_bound!(py, *locals, "c = C()"); /// }); /// ``` #[macro_export] -macro_rules! py_run { +macro_rules! py_run_bound { ($py:expr, $($val:ident)+, $code:literal) => {{ $crate::py_run_impl!($py, $($val)+, $crate::indoc::indoc!($code)) }}; @@ -99,17 +123,17 @@ macro_rules! py_run_impl { ($py:expr, $($val:ident)+, $code:expr) => {{ use $crate::types::IntoPyDict; use $crate::ToPyObject; - let d = [$((stringify!($val), $val.to_object($py)),)+].into_py_dict($py); + let d = [$((stringify!($val), $val.to_object($py)),)+].into_py_dict_bound($py); $crate::py_run_impl!($py, *d, $code) }}; ($py:expr, *$dict:expr, $code:expr) => {{ use ::std::option::Option::*; - if let ::std::result::Result::Err(e) = $py.run($code, None, Some($dict)) { + if let ::std::result::Result::Err(e) = $py.run_bound($code, None, Some(&$dict)) { e.print($py); // So when this c api function the last line called printed the error to stderr, // the output is only written into a buffer which is never flushed because we // panic before flushing. This is where this hack comes into place - $py.run("import sys; sys.stderr.flush()", None, None) + $py.run_bound("import sys; sys.stderr.flush()", None, None) .unwrap(); ::std::panic!("{}", $code) } diff --git a/src/marker.rs b/src/marker.rs index 7e5b0ff1044..1824f6a56ba 100644 --- a/src/marker.rs +++ b/src/marker.rs @@ -116,14 +116,18 @@ //! [`Rc`]: std::rc::Rc //! [`Py`]: crate::Py use crate::err::{self, PyDowncastError, PyErr, PyResult}; +use crate::ffi_ptr_ext::FfiPtrExt; use crate::gil::{GILGuard, GILPool, SuspendGIL}; use crate::impl_::not_send::NotSend; use crate::type_object::HasPyGilRef; +use crate::types::any::PyAnyMethods; use crate::types::{ PyAny, PyDict, PyEllipsis, PyModule, PyNone, PyNotImplemented, PyString, PyType, }; use crate::version::PythonVersionInfo; -use crate::{ffi, FromPyPointer, IntoPy, Py, PyObject, PyTypeCheck, PyTypeInfo}; +use crate::{ + ffi, Bound, FromPyPointer, IntoPy, Py, PyNativeType, PyObject, PyTypeCheck, PyTypeInfo, +}; use std::ffi::{CStr, CString}; use std::marker::PhantomData; use std::os::raw::c_int; @@ -357,8 +361,8 @@ pub use nightly::Ungil; /// # fn main () -> PyResult<()> { /// Python::with_gil(|py| -> PyResult<()> { /// for _ in 0..10 { -/// let hello: &PyString = py.eval("\"Hello World!\"", None, None)?.extract()?; -/// println!("Python says: {}", hello.to_str()?); +/// let hello: Bound<'_, PyString> = py.eval_bound("\"Hello World!\"", None, None)?.downcast_into()?; +/// println!("Python says: {}", hello.to_cow()?); /// // Normally variables in a loop scope are dropped here, but `hello` is a reference to /// // something owned by the Python interpreter. Dropping this reference does nothing. /// } @@ -416,7 +420,7 @@ impl Python<'_> { /// /// # fn main() -> PyResult<()> { /// Python::with_gil(|py| -> PyResult<()> { - /// let x: i32 = py.eval("5", None, None)?.extract()?; + /// let x: i32 = py.eval_bound("5", None, None)?.extract()?; /// assert_eq!(x, 5); /// Ok(()) /// }) @@ -545,6 +549,29 @@ impl<'py> Python<'py> { f() } + /// Deprecated form of [`eval_bound`][Python::eval_bound]. + #[cfg_attr( + not(feature = "gil-refs"), + deprecated( + since = "0.21.0", + note = "`eval` will be replaced by `eval_bound` in a future PyO3 version" + ) + )] + #[inline] + pub fn eval( + self, + code: &str, + globals: Option<&PyDict>, + locals: Option<&PyDict>, + ) -> PyResult<&'py PyAny> { + self.eval_bound( + code, + globals.map(PyDict::as_borrowed).as_deref(), + locals.map(PyDict::as_borrowed).as_deref(), + ) + .map(Bound::into_gil_ref) + } + /// Evaluates a Python expression in the given context and returns the result. /// /// If `globals` is `None`, it defaults to Python module `__main__`. @@ -558,18 +585,40 @@ impl<'py> Python<'py> { /// ``` /// # use pyo3::prelude::*; /// # Python::with_gil(|py| { - /// let result = py.eval("[i * 10 for i in range(5)]", None, None).unwrap(); + /// let result = py.eval_bound("[i * 10 for i in range(5)]", None, None).unwrap(); /// let res: Vec = result.extract().unwrap(); /// assert_eq!(res, vec![0, 10, 20, 30, 40]) /// # }); /// ``` - pub fn eval( + pub fn eval_bound( + self, + code: &str, + globals: Option<&Bound<'_, PyDict>>, + locals: Option<&Bound<'_, PyDict>>, + ) -> PyResult> { + self.run_code(code, ffi::Py_eval_input, globals, locals) + } + + /// Deprecated form of [`run_bound`][Python::run_bound]. + #[cfg_attr( + not(feature = "gil-refs"), + deprecated( + since = "0.21.0", + note = "`run` will be replaced by `run_bound` in a future PyO3 version" + ) + )] + #[inline] + pub fn run( self, code: &str, globals: Option<&PyDict>, locals: Option<&PyDict>, - ) -> PyResult<&'py PyAny> { - self.run_code(code, ffi::Py_eval_input, globals, locals) + ) -> PyResult<()> { + self.run_bound( + code, + globals.map(PyDict::as_borrowed).as_deref(), + locals.map(PyDict::as_borrowed).as_deref(), + ) } /// Executes one or more Python statements in the given context. @@ -587,30 +636,30 @@ impl<'py> Python<'py> { /// types::{PyBytes, PyDict}, /// }; /// Python::with_gil(|py| { - /// let locals = PyDict::new(py); - /// py.run( + /// let locals = PyDict::new_bound(py); + /// py.run_bound( /// r#" /// import base64 /// s = 'Hello Rust!' /// ret = base64.b64encode(s.encode('utf-8')) /// "#, /// None, - /// Some(locals), + /// Some(&locals), /// ) /// .unwrap(); /// let ret = locals.get_item("ret").unwrap().unwrap(); - /// let b64: &PyBytes = ret.downcast().unwrap(); + /// let b64: &Bound<'_, PyBytes> = ret.downcast().unwrap(); /// assert_eq!(b64.as_bytes(), b"SGVsbG8gUnVzdCE="); /// }); /// ``` /// - /// You can use [`py_run!`](macro.py_run.html) for a handy alternative of `run` + /// You can use [`py_run_bound!`](macro.py_run_bound.html) for a handy alternative of `run` /// if you don't need `globals` and unwrapping is OK. - pub fn run( + pub fn run_bound( self, code: &str, - globals: Option<&PyDict>, - locals: Option<&PyDict>, + globals: Option<&Bound<'_, PyDict>>, + locals: Option<&Bound<'_, PyDict>>, ) -> PyResult<()> { let res = self.run_code(code, ffi::Py_file_input, globals, locals); res.map(|obj| { @@ -629,9 +678,9 @@ impl<'py> Python<'py> { self, code: &str, start: c_int, - globals: Option<&PyDict>, - locals: Option<&PyDict>, - ) -> PyResult<&'py PyAny> { + globals: Option<&Bound<'_, PyDict>>, + locals: Option<&Bound<'_, PyDict>>, + ) -> PyResult> { let code = CString::new(code)?; unsafe { let mptr = ffi::PyImport_AddModule("__main__\0".as_ptr() as *const _); @@ -640,9 +689,9 @@ impl<'py> Python<'py> { } let globals = globals - .map(|dict| dict.as_ptr()) + .map(Bound::as_ptr) .unwrap_or_else(|| ffi::PyModule_GetDict(mptr)); - let locals = locals.map(|dict| dict.as_ptr()).unwrap_or(globals); + let locals = locals.map(Bound::as_ptr).unwrap_or(globals); // If `globals` don't provide `__builtins__`, most of the code will fail if Python // version is <3.10. That's probably not what user intended, so insert `__builtins__` @@ -667,14 +716,10 @@ impl<'py> Python<'py> { } } - let code_obj = ffi::Py_CompileString(code.as_ptr(), "\0".as_ptr() as _, start); - if code_obj.is_null() { - return Err(PyErr::fetch(self)); - } - let res_ptr = ffi::PyEval_EvalCode(code_obj, globals, locals); - ffi::Py_DECREF(code_obj); + let code_obj = ffi::Py_CompileString(code.as_ptr(), "\0".as_ptr() as _, start) + .assume_owned_or_err(self)?; - self.from_owned_ptr_or_err(res_ptr) + ffi::PyEval_EvalCode(code_obj.as_ptr(), globals, locals).assume_owned_or_err(self) } } @@ -1066,6 +1111,7 @@ impl<'unbound> Python<'unbound> { } #[cfg(test)] +#[cfg_attr(not(feature = "gil-refs"), allow(deprecated))] mod tests { use super::*; use crate::types::{any::PyAnyMethods, IntoPyDict, PyDict, PyList}; diff --git a/src/marshal.rs b/src/marshal.rs index 5e62e6b6289..cfffc35672f 100644 --- a/src/marshal.rs +++ b/src/marshal.rs @@ -38,14 +38,14 @@ pub fn dumps<'py>( /// /// # Examples /// ``` -/// # use pyo3::{marshal, types::PyDict}; +/// # use pyo3::{prelude::*, marshal, types::PyDict}; /// # pyo3::Python::with_gil(|py| { -/// let dict = PyDict::new(py); +/// let dict = PyDict::new_bound(py); /// dict.set_item("aap", "noot").unwrap(); /// dict.set_item("mies", "wim").unwrap(); /// dict.set_item("zus", "jet").unwrap(); /// -/// let bytes = marshal::dumps_bound(py, dict, marshal::VERSION); +/// let bytes = marshal::dumps_bound(py, &dict, marshal::VERSION); /// # }); /// ``` pub fn dumps_bound<'py>( @@ -88,6 +88,7 @@ where } #[cfg(test)] +#[cfg_attr(not(feature = "gil-refs"), allow(deprecated))] mod tests { use super::*; use crate::types::{bytes::PyBytesMethods, PyDict}; diff --git a/src/pycell.rs b/src/pycell.rs index bde95ad8313..508f7d65c85 100644 --- a/src/pycell.rs +++ b/src/pycell.rs @@ -641,7 +641,7 @@ impl fmt::Debug for PyCell { /// } /// # Python::with_gil(|py| { /// # let sub = PyCell::new(py, Child::new()).unwrap(); -/// # pyo3::py_run!(py, sub, "assert sub.format() == 'Caterpillar(base: Butterfly, cnt: 3)'"); +/// # pyo3::py_run_bound!(py, sub, "assert sub.format() == 'Caterpillar(base: Butterfly, cnt: 3)'"); /// # }); /// ``` /// @@ -740,7 +740,7 @@ where /// } /// # Python::with_gil(|py| { /// # let sub = PyCell::new(py, Sub::new()).unwrap(); - /// # pyo3::py_run!(py, sub, "assert sub.name() == 'base1 base2 sub'") + /// # pyo3::py_run_bound!(py, sub, "assert sub.name() == 'base1 base2 sub'") /// # }); /// ``` pub fn into_super(self) -> PyRef<'p, U> { diff --git a/src/pyclass_init.rs b/src/pyclass_init.rs index 63761f435bb..2a18e093b25 100644 --- a/src/pyclass_init.rs +++ b/src/pyclass_init.rs @@ -93,7 +93,7 @@ impl PyObjectInit for PyNativeTypeInitializer { /// /// ``` /// # use pyo3::prelude::*; -/// # use pyo3::py_run; +/// # use pyo3::py_run_bound; /// #[pyclass(subclass)] /// struct BaseClass { /// #[pyo3(get)] @@ -124,7 +124,7 @@ impl PyObjectInit for PyNativeTypeInitializer { /// Python::with_gil(|py| { /// let typeobj = py.get_type::(); /// let sub_sub_class = typeobj.call((), None).unwrap(); -/// py_run!( +/// py_run_bound!( /// py, /// sub_sub_class, /// r#" diff --git a/src/sync.rs b/src/sync.rs index a88a0f4b485..264e058c509 100644 --- a/src/sync.rs +++ b/src/sync.rs @@ -209,12 +209,11 @@ impl GILOnceCell> { /// # Example: Using `intern!` to avoid needlessly recreating the same Python string /// /// ``` -/// use pyo3::intern; -/// # use pyo3::{pyfunction, types::PyDict, wrap_pyfunction, PyResult, Python}; +/// use pyo3::{prelude::*, intern, types::PyDict }; /// /// #[pyfunction] -/// fn create_dict(py: Python<'_>) -> PyResult<&PyDict> { -/// let dict = PyDict::new(py); +/// fn create_dict(py: Python<'_>) -> PyResult> { +/// let dict = PyDict::new_bound(py); /// // 👇 A new `PyString` is created /// // for every call of this function. /// dict.set_item("foo", 42)?; @@ -222,8 +221,8 @@ impl GILOnceCell> { /// } /// /// #[pyfunction] -/// fn create_dict_faster(py: Python<'_>) -> PyResult<&PyDict> { -/// let dict = PyDict::new(py); +/// fn create_dict_faster(py: Python<'_>) -> PyResult> { +/// let dict = PyDict::new_bound(py); /// // 👇 A `PyString` is created once and reused /// // for the lifetime of the program. /// dict.set_item(intern!(py, "foo"), 42)?; @@ -270,7 +269,7 @@ impl Interned { mod tests { use super::*; - use crate::types::PyDict; + use crate::types::{any::PyAnyMethods, dict::PyDictMethods, PyDict}; #[test] fn test_intern() { @@ -279,7 +278,7 @@ mod tests { let foo2 = intern!(py, "foo"); let foo3 = intern!(py, stringify!(foo)); - let dict = PyDict::new(py); + let dict = PyDict::new_bound(py); dict.set_item(foo1, 42_usize).unwrap(); assert!(dict.contains(foo2).unwrap()); assert_eq!( diff --git a/src/tests/common.rs b/src/tests/common.rs index f2082437693..bae884f8596 100644 --- a/src/tests/common.rs +++ b/src/tests/common.rs @@ -16,10 +16,10 @@ mod inner { #[macro_export] macro_rules! py_assert { ($py:expr, $($val:ident)+, $assertion:literal) => { - pyo3::py_run!($py, $($val)+, concat!("assert ", $assertion)) + pyo3::py_run_bound!($py, $($val)+, concat!("assert ", $assertion)) }; ($py:expr, *$dict:expr, $assertion:literal) => { - pyo3::py_run!($py, *$dict, concat!("assert ", $assertion)) + pyo3::py_run_bound!($py, *$dict, concat!("assert ", $assertion)) }; } @@ -35,12 +35,12 @@ mod inner { // Case1: idents & no err_msg ($py:expr, $($val:ident)+, $code:expr, $err:ident) => {{ use pyo3::types::IntoPyDict; - let d = [$((stringify!($val), $val.to_object($py)),)+].into_py_dict($py); + let d = &[$((stringify!($val), $val.to_object($py)),)+].into_py_dict_bound($py); py_expect_exception!($py, *d, $code, $err) }}; // Case2: dict & no err_msg ($py:expr, *$dict:expr, $code:expr, $err:ident) => {{ - let res = $py.run($code, None, Some($dict)); + let res = $py.run_bound($code, None, Some(&$dict)); let err = res.expect_err(&format!("Did not raise {}", stringify!($err))); if !err.matches($py, $py.get_type::()) { panic!("Expected {} but got {:?}", stringify!($err), err) @@ -116,8 +116,10 @@ mod inner { impl<'py> CatchWarnings<'py> { pub fn enter(py: Python<'py>, f: impl FnOnce(&PyList) -> PyResult) -> PyResult { let warnings = py.import("warnings")?; - let kwargs = [("record", true)].into_py_dict(py); - let catch_warnings = warnings.getattr("catch_warnings")?.call((), Some(kwargs))?; + let kwargs = [("record", true)].into_py_dict_bound(py); + let catch_warnings = warnings + .getattr("catch_warnings")? + .call((), Some(kwargs.as_gil_ref()))?; let list = catch_warnings.call_method0("__enter__")?.extract()?; let _guard = Self { catch_warnings }; f(list) diff --git a/src/tests/hygiene/pyfunction.rs b/src/tests/hygiene/pyfunction.rs index 19fe2739407..196f5ecca8e 100644 --- a/src/tests/hygiene/pyfunction.rs +++ b/src/tests/hygiene/pyfunction.rs @@ -11,6 +11,6 @@ fn do_something(x: i32) -> crate::PyResult { fn invoke_wrap_pyfunction() { crate::Python::with_gil(|py| { let func = crate::wrap_pyfunction!(do_something)(py).unwrap(); - crate::py_run!(py, func, r#"func(5)"#); + crate::py_run_bound!(py, func, r#"func(5)"#); }); } diff --git a/src/types/any.rs b/src/types/any.rs index d79a9227cd7..38d0165d618 100644 --- a/src/types/any.rs +++ b/src/types/any.rs @@ -388,9 +388,9 @@ impl PyAny { /// let module = PyModule::from_code(py, CODE, "", "")?; /// let fun = module.getattr("function")?; /// let args = ("hello",); - /// let kwargs = PyDict::new(py); + /// let kwargs = PyDict::new_bound(py); /// kwargs.set_item("cruel", "world")?; - /// let result = fun.call(args, Some(kwargs))?; + /// let result = fun.call(args, Some(kwargs.as_gil_ref()))?; /// assert_eq!(result.extract::<&str>()?, "called with args and kwargs"); /// Ok(()) /// }) @@ -488,9 +488,9 @@ impl PyAny { /// let module = PyModule::from_code(py, CODE, "", "")?; /// let instance = module.getattr("a")?; /// let args = ("hello",); - /// let kwargs = PyDict::new(py); + /// let kwargs = PyDict::new_bound(py); /// kwargs.set_item("cruel", "world")?; - /// let result = instance.call_method("method", args, Some(kwargs))?; + /// let result = instance.call_method("method", args, Some(kwargs.as_gil_ref()))?; /// assert_eq!(result.extract::<&str>()?, "called with args and kwargs"); /// Ok(()) /// }) @@ -691,7 +691,7 @@ impl PyAny { /// use pyo3::types::{PyDict, PyList}; /// /// Python::with_gil(|py| { - /// let dict = PyDict::new(py); + /// let dict = PyDict::new_bound(py).into_gil_ref(); /// assert!(dict.is_instance_of::()); /// let any: &PyAny = dict.as_ref(); /// @@ -1268,9 +1268,9 @@ pub trait PyAnyMethods<'py> { /// let module = PyModule::from_code(py, CODE, "", "")?; /// let fun = module.getattr("function")?; /// let args = ("hello",); - /// let kwargs = PyDict::new(py); + /// let kwargs = PyDict::new_bound(py); /// kwargs.set_item("cruel", "world")?; - /// let result = fun.call(args, Some(kwargs))?; + /// let result = fun.call(args, Some(kwargs.as_gil_ref()))?; /// assert_eq!(result.extract::<&str>()?, "called with args and kwargs"); /// Ok(()) /// }) @@ -1360,9 +1360,9 @@ pub trait PyAnyMethods<'py> { /// let module = PyModule::from_code(py, CODE, "", "")?; /// let instance = module.getattr("a")?; /// let args = ("hello",); - /// let kwargs = PyDict::new(py); + /// let kwargs = PyDict::new_bound(py); /// kwargs.set_item("cruel", "world")?; - /// let result = instance.call_method("method", args, Some(kwargs))?; + /// let result = instance.call_method("method", args, Some(kwargs.as_gil_ref()))?; /// assert_eq!(result.extract::<&str>()?, "called with args and kwargs"); /// Ok(()) /// }) @@ -1519,9 +1519,9 @@ pub trait PyAnyMethods<'py> { /// use pyo3::types::{PyDict, PyList}; /// /// Python::with_gil(|py| { - /// let dict = PyDict::new(py); + /// let dict = PyDict::new_bound(py); /// assert!(dict.is_instance_of::()); - /// let any: &PyAny = dict.as_ref(); + /// let any: &Bound<'_, PyAny> = &dict; /// /// assert!(any.downcast::().is_ok()); /// assert!(any.downcast::().is_err()); diff --git a/src/types/bytearray.rs b/src/types/bytearray.rs index 6303a87de3e..3432fe4c021 100644 --- a/src/types/bytearray.rs +++ b/src/types/bytearray.rs @@ -197,10 +197,10 @@ impl PyByteArray { /// # fn main() -> PyResult<()> { /// # Python::with_gil(|py| -> PyResult<()> { /// # let fun = wrap_pyfunction!(a_valid_function, py)?; - /// # let locals = pyo3::types::PyDict::new(py); + /// # let locals = pyo3::types::PyDict::new_bound(py); /// # locals.set_item("a_valid_function", fun)?; /// # - /// # py.run( + /// # py.run_bound( /// # r#"b = bytearray(b"hello world") /// # a_valid_function(b) /// # @@ -209,7 +209,7 @@ impl PyByteArray { /// # except RuntimeError as e: /// # assert str(e) == 'input is not long enough'"#, /// # None, - /// # Some(locals), + /// # Some(&locals), /// # )?; /// # /// # Ok(()) @@ -274,7 +274,7 @@ impl PyByteArray { /// copied_message[11] = b'!'; /// assert_eq!(b"Hello World!", copied_message.as_slice()); /// - /// pyo3::py_run!(py, bytearray, "assert bytearray == b'Hello World.'"); + /// pyo3::py_run_bound!(py, bytearray, "assert bytearray == b'Hello World.'"); /// # }); /// ``` pub fn to_vec(&self) -> Vec { @@ -359,10 +359,10 @@ pub trait PyByteArrayMethods<'py> { /// # fn main() -> PyResult<()> { /// # Python::with_gil(|py| -> PyResult<()> { /// # let fun = wrap_pyfunction!(a_valid_function, py)?; - /// # let locals = pyo3::types::PyDict::new(py); + /// # let locals = pyo3::types::PyDict::new_bound(py); /// # locals.set_item("a_valid_function", fun)?; /// # - /// # py.run( + /// # py.run_bound( /// # r#"b = bytearray(b"hello world") /// # a_valid_function(b) /// # @@ -371,7 +371,7 @@ pub trait PyByteArrayMethods<'py> { /// # except RuntimeError as e: /// # assert str(e) == 'input is not long enough'"#, /// # None, - /// # Some(locals), + /// # Some(&locals), /// # )?; /// # /// # Ok(()) @@ -432,7 +432,7 @@ pub trait PyByteArrayMethods<'py> { /// copied_message[11] = b'!'; /// assert_eq!(b"Hello World!", copied_message.as_slice()); /// - /// pyo3::py_run!(py, bytearray, "assert bytearray == b'Hello World.'"); + /// pyo3::py_run_bound!(py, bytearray, "assert bytearray == b'Hello World.'"); /// # }); /// ``` fn to_vec(&self) -> Vec; diff --git a/src/types/datetime.rs b/src/types/datetime.rs index 354414b8b4c..6c6d726565b 100644 --- a/src/types/datetime.rs +++ b/src/types/datetime.rs @@ -686,7 +686,7 @@ fn opt_to_pyobj(opt: Option<&PyTzInfo>) -> *mut ffi::PyObject { mod tests { use super::*; #[cfg(feature = "macros")] - use crate::py_run; + use crate::py_run_bound; #[test] #[cfg(feature = "macros")] @@ -694,14 +694,14 @@ mod tests { fn test_datetime_fromtimestamp() { Python::with_gil(|py| { let dt = PyDateTime::from_timestamp(py, 100.0, None).unwrap(); - py_run!( + py_run_bound!( py, dt, "import datetime; assert dt == datetime.datetime.fromtimestamp(100)" ); let dt = PyDateTime::from_timestamp(py, 100.0, Some(timezone_utc(py))).unwrap(); - py_run!( + py_run_bound!( py, dt, "import datetime; assert dt == datetime.datetime.fromtimestamp(100, datetime.timezone.utc)" @@ -715,7 +715,7 @@ mod tests { fn test_date_fromtimestamp() { Python::with_gil(|py| { let dt = PyDate::from_timestamp(py, 100).unwrap(); - py_run!( + py_run_bound!( py, dt, "import datetime; assert dt == datetime.date.fromtimestamp(100)" diff --git a/src/types/dict.rs b/src/types/dict.rs index 3a54e742ed5..c6faea70dce 100644 --- a/src/types/dict.rs +++ b/src/types/dict.rs @@ -57,6 +57,13 @@ pyobject_native_type_core!( impl PyDict { /// Deprecated form of [`new_bound`][PyDict::new_bound]. + #[cfg_attr( + not(feature = "gil-refs"), + deprecated( + since = "0.21.0", + note = "`PyDict::new` will be replaced by `PyDict::new_bound` in a future PyO3 version" + ) + )] #[inline] pub fn new(py: Python<'_>) -> &PyDict { Self::new_bound(py).into_gil_ref() @@ -69,6 +76,13 @@ impl PyDict { /// Deprecated form of [`from_sequence_bound`][PyDict::from_sequence_bound]. #[inline] + #[cfg_attr( + not(feature = "gil-refs"), + deprecated( + since = "0.21.0", + note = "`PyDict::from_sequence` will be replaced by `PyDict::from_sequence_bound` in a future PyO3 version" + ) + )] #[cfg(not(PyPy))] pub fn from_sequence(seq: &PyAny) -> PyResult<&PyDict> { Self::from_sequence_bound(&seq.as_borrowed()).map(Bound::into_gil_ref) @@ -152,16 +166,16 @@ impl PyDict { /// # fn main() { /// # let _ = /// Python::with_gil(|py| -> PyResult<()> { - /// let dict: &PyDict = [("a", 1)].into_py_dict(py); + /// let dict: Bound<'_, PyDict> = [("a", 1)].into_py_dict_bound(py); /// // `a` is in the dictionary, with value 1 /// assert!(dict.get_item("a")?.map_or(Ok(false), |x| x.eq(1))?); /// // `b` is not in the dictionary /// assert!(dict.get_item("b")?.is_none()); /// // `dict` is not hashable, so this returns an error - /// assert!(dict.get_item(dict).unwrap_err().is_instance_of::(py)); + /// assert!(dict.get_item(&dict).unwrap_err().is_instance_of::(py)); /// /// // `PyAny::get_item("b")` will raise a `KeyError` instead of returning `None` - /// let any: &PyAny = dict.as_ref(); + /// let any: &Bound<'_, PyAny> = &dict; /// assert!(any.get_item("b").unwrap_err().is_instance_of::(py)); /// Ok(()) /// }); @@ -653,7 +667,23 @@ impl<'py> IntoIterator for Bound<'py, PyDict> { pub trait IntoPyDict { /// Converts self into a `PyDict` object pointer. Whether pointer owned or borrowed /// depends on implementation. - fn into_py_dict(self, py: Python<'_>) -> &PyDict; + #[cfg_attr( + not(feature = "gil-refs"), + deprecated( + since = "0.21.0", + note = "`into_py_dict` will be replaced by `into_py_dict_bound` in a future PyO3 version" + ) + )] + fn into_py_dict(self, py: Python<'_>) -> &PyDict + where + Self: Sized, + { + self.into_py_dict_bound(py).into_gil_ref() + } + + /// Converts self into a `PyDict` object pointer. Whether pointer owned or borrowed + /// depends on implementation. + fn into_py_dict_bound(self, py: Python<'_>) -> Bound<'_, PyDict>; } impl IntoPyDict for I @@ -661,8 +691,8 @@ where T: PyDictItem, I: IntoIterator, { - fn into_py_dict(self, py: Python<'_>) -> &PyDict { - let dict = PyDict::new(py); + fn into_py_dict_bound(self, py: Python<'_>) -> Bound<'_, PyDict> { + let dict = PyDict::new_bound(py); for item in self { dict.set_item(item.key(), item.value()) .expect("Failed to set_item on dict"); diff --git a/src/types/ellipsis.rs b/src/types/ellipsis.rs index 9151e89df97..54bbd4394bb 100644 --- a/src/types/ellipsis.rs +++ b/src/types/ellipsis.rs @@ -75,7 +75,7 @@ mod tests { #[test] fn test_dict_is_not_ellipsis() { Python::with_gil(|py| { - assert!(PyDict::new(py).downcast::().is_err()); + assert!(PyDict::new_bound(py).downcast::().is_err()); }) } } diff --git a/src/types/function.rs b/src/types/function.rs index c6f0f6b0b02..0c66e615cc5 100644 --- a/src/types/function.rs +++ b/src/types/function.rs @@ -53,7 +53,7 @@ impl PyCFunction { /// /// ``` /// # use pyo3::prelude::*; - /// # use pyo3::{py_run, types::{PyCFunction, PyDict, PyTuple}}; + /// # use pyo3::{py_run_bound, types::{PyCFunction, PyDict, PyTuple}}; /// /// Python::with_gil(|py| { /// let add_one = |args: &PyTuple, _kwargs: Option<&PyDict>| -> PyResult<_> { @@ -61,7 +61,7 @@ impl PyCFunction { /// Ok(i+1) /// }; /// let add_one = PyCFunction::new_closure(py, None, None, add_one).unwrap(); - /// py_run!(py, add_one, "assert add_one(42) == 43"); + /// py_run_bound!(py, add_one, "assert add_one(42) == 43"); /// }); /// ``` pub fn new_closure<'a, F, R>( diff --git a/src/types/iterator.rs b/src/types/iterator.rs index e27032867bc..7a23d91ab55 100644 --- a/src/types/iterator.rs +++ b/src/types/iterator.rs @@ -14,10 +14,10 @@ use crate::{ /// /// # fn main() -> PyResult<()> { /// Python::with_gil(|py| -> PyResult<()> { -/// let list = py.eval("iter([1, 2, 3, 4])", None, None)?; +/// let list = py.eval_bound("iter([1, 2, 3, 4])", None, None)?; /// let numbers: PyResult> = list /// .iter()? -/// .map(|i| i.and_then(PyAny::extract::)) +/// .map(|i| i.and_then(|any| any.extract::())) /// .collect(); /// let sum: usize = numbers?.iter().sum(); /// assert_eq!(sum, 10); @@ -286,7 +286,7 @@ def fibonacci(target): // Regression test for 2913 Python::with_gil(|py| { let downcaster = Py::new(py, Downcaster { failed: None }).unwrap(); - crate::py_run!( + crate::py_run_bound!( py, downcaster, r#" @@ -324,7 +324,7 @@ def fibonacci(target): // Regression test for 2913 Python::with_gil(|py| { let assert_iterator = crate::wrap_pyfunction!(assert_iterator, py).unwrap(); - crate::py_run!( + crate::py_run_bound!( py, assert_iterator, r#" diff --git a/src/types/mod.rs b/src/types/mod.rs index f802348f466..4a2517c8f49 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -59,7 +59,7 @@ pub use self::typeobject::PyType; /// /// # pub fn main() -> PyResult<()> { /// Python::with_gil(|py| { -/// let dict: &PyDict = py.eval("{'a':'b', 'c':'d'}", None, None)?.downcast()?; +/// let dict: Bound<'_, PyDict> = py.eval_bound("{'a':'b', 'c':'d'}", None, None)?.downcast_into::()?; /// /// for (key, value) in dict { /// println!("key: {}, value: {}", key, value); diff --git a/src/types/none.rs b/src/types/none.rs index 3c3b171668d..fec9dfdc7a1 100644 --- a/src/types/none.rs +++ b/src/types/none.rs @@ -114,7 +114,7 @@ mod tests { #[test] fn test_dict_is_not_none() { Python::with_gil(|py| { - assert!(PyDict::new(py).downcast::().is_err()); + assert!(PyDict::new_bound(py).downcast::().is_err()); }) } } diff --git a/src/types/notimplemented.rs b/src/types/notimplemented.rs index 7560dff37d1..9549c762675 100644 --- a/src/types/notimplemented.rs +++ b/src/types/notimplemented.rs @@ -78,7 +78,9 @@ mod tests { #[test] fn test_dict_is_not_notimplemented() { Python::with_gil(|py| { - assert!(PyDict::new(py).downcast::().is_err()); + assert!(PyDict::new_bound(py) + .downcast::() + .is_err()); }) } } diff --git a/src/types/traceback.rs b/src/types/traceback.rs index 84ecda747eb..99433ffd32e 100644 --- a/src/types/traceback.rs +++ b/src/types/traceback.rs @@ -28,7 +28,7 @@ impl PyTraceback { /// # let result: PyResult<()> = /// Python::with_gil(|py| { /// let err = py - /// .run("raise Exception('banana')", None, None) + /// .run_bound("raise Exception('banana')", None, None) /// .expect_err("raise will create a Python error"); /// /// let traceback = err.traceback_bound(py).expect("raised exception will have a traceback"); @@ -71,7 +71,7 @@ pub trait PyTracebackMethods<'py> { /// # let result: PyResult<()> = /// Python::with_gil(|py| { /// let err = py - /// .run("raise Exception('banana')", None, None) + /// .run_bound("raise Exception('banana')", None, None) /// .expect_err("raise will create a Python error"); /// /// let traceback = err.traceback_bound(py).expect("raised exception will have a traceback"); @@ -111,6 +111,7 @@ impl<'py> PyTracebackMethods<'py> for Bound<'py, PyTraceback> { } #[cfg(test)] +#[cfg_attr(not(feature = "gil-refs"), allow(deprecated))] mod tests { use crate::{ prelude::*, diff --git a/tests/test_anyhow.rs b/tests/test_anyhow.rs index f0df4dcc1a4..57b0db1a598 100644 --- a/tests/test_anyhow.rs +++ b/tests/test_anyhow.rs @@ -1,8 +1,10 @@ #![cfg(feature = "anyhow")] +use pyo3::prelude::PyDictMethods; + #[test] fn test_anyhow_py_function_ok_result() { - use pyo3::{py_run, pyfunction, wrap_pyfunction, Python}; + use pyo3::{py_run_bound, pyfunction, wrap_pyfunction, Python}; #[pyfunction] #[allow(clippy::unnecessary_wraps)] @@ -13,7 +15,7 @@ fn test_anyhow_py_function_ok_result() { Python::with_gil(|py| { let func = wrap_pyfunction!(produce_ok_result)(py).unwrap(); - py_run!( + py_run_bound!( py, func, r#" @@ -34,15 +36,15 @@ fn test_anyhow_py_function_err_result() { Python::with_gil(|py| { let func = wrap_pyfunction!(produce_err_result)(py).unwrap(); - let locals = PyDict::new(py); + let locals = PyDict::new_bound(py); locals.set_item("func", func).unwrap(); - py.run( + py.run_bound( r#" func() "#, None, - Some(locals), + Some(&locals), ) .unwrap_err(); }); diff --git a/tests/test_append_to_inittab.rs b/tests/test_append_to_inittab.rs index e0a57da1b5c..00cccdbb49e 100644 --- a/tests/test_append_to_inittab.rs +++ b/tests/test_append_to_inittab.rs @@ -18,7 +18,7 @@ fn test_module_append_to_inittab() { use pyo3::append_to_inittab; append_to_inittab!(module_with_functions); Python::with_gil(|py| { - py.run( + py.run_bound( r#" import module_with_functions assert module_with_functions.foo() == 123 diff --git a/tests/test_arithmetics.rs b/tests/test_arithmetics.rs index f336140e432..40b4c5ec785 100644 --- a/tests/test_arithmetics.rs +++ b/tests/test_arithmetics.rs @@ -2,7 +2,7 @@ use pyo3::class::basic::CompareOp; use pyo3::prelude::*; -use pyo3::py_run; +use pyo3::py_run_bound; #[path = "../src/tests/common.rs"] mod common; @@ -44,11 +44,11 @@ impl UnaryArithmetic { fn unary_arithmetic() { Python::with_gil(|py| { let c = PyCell::new(py, UnaryArithmetic::new(2.7)).unwrap(); - py_run!(py, c, "assert repr(-c) == 'UA(-2.7)'"); - py_run!(py, c, "assert repr(+c) == 'UA(2.7)'"); - py_run!(py, c, "assert repr(abs(c)) == 'UA(2.7)'"); - py_run!(py, c, "assert repr(round(c)) == 'UA(3)'"); - py_run!(py, c, "assert repr(round(c, 1)) == 'UA(3)'"); + py_run_bound!(py, c, "assert repr(-c) == 'UA(-2.7)'"); + py_run_bound!(py, c, "assert repr(+c) == 'UA(2.7)'"); + py_run_bound!(py, c, "assert repr(abs(c)) == 'UA(2.7)'"); + py_run_bound!(py, c, "assert repr(round(c)) == 'UA(3)'"); + py_run_bound!(py, c, "assert repr(round(c, 1)) == 'UA(3)'"); }); } @@ -78,10 +78,10 @@ impl Indexable { fn indexable() { Python::with_gil(|py| { let i = PyCell::new(py, Indexable(5)).unwrap(); - py_run!(py, i, "assert int(i) == 5"); - py_run!(py, i, "assert [0, 1, 2, 3, 4, 5][i] == 5"); - py_run!(py, i, "assert float(i) == 5.0"); - py_run!(py, i, "assert int(~i) == -6"); + py_run_bound!(py, i, "assert int(i) == 5"); + py_run_bound!(py, i, "assert [0, 1, 2, 3, 4, 5][i] == 5"); + py_run_bound!(py, i, "assert float(i) == 5.0"); + py_run_bound!(py, i, "assert int(~i) == -6"); }) } @@ -138,7 +138,7 @@ fn inplace_operations() { Python::with_gil(|py| { let init = |value, code| { let c = PyCell::new(py, InPlaceOperations { value }).unwrap(); - py_run!(py, c, code); + py_run_bound!(py, c, code); }; init(0, "d = c; c += 1; assert repr(c) == repr(d) == 'IPO(1)'"); @@ -211,17 +211,17 @@ impl BinaryArithmetic { fn binary_arithmetic() { Python::with_gil(|py| { let c = PyCell::new(py, BinaryArithmetic {}).unwrap(); - py_run!(py, c, "assert c + c == 'BA + BA'"); - py_run!(py, c, "assert c.__add__(c) == 'BA + BA'"); - py_run!(py, c, "assert c + 1 == 'BA + 1'"); - py_run!(py, c, "assert c - 1 == 'BA - 1'"); - py_run!(py, c, "assert c * 1 == 'BA * 1'"); - py_run!(py, c, "assert c << 1 == 'BA << 1'"); - py_run!(py, c, "assert c >> 1 == 'BA >> 1'"); - py_run!(py, c, "assert c & 1 == 'BA & 1'"); - py_run!(py, c, "assert c ^ 1 == 'BA ^ 1'"); - py_run!(py, c, "assert c | 1 == 'BA | 1'"); - py_run!(py, c, "assert c ** 1 == 'BA ** 1 (mod: None)'"); + py_run_bound!(py, c, "assert c + c == 'BA + BA'"); + py_run_bound!(py, c, "assert c.__add__(c) == 'BA + BA'"); + py_run_bound!(py, c, "assert c + 1 == 'BA + 1'"); + py_run_bound!(py, c, "assert c - 1 == 'BA - 1'"); + py_run_bound!(py, c, "assert c * 1 == 'BA * 1'"); + py_run_bound!(py, c, "assert c << 1 == 'BA << 1'"); + py_run_bound!(py, c, "assert c >> 1 == 'BA >> 1'"); + py_run_bound!(py, c, "assert c & 1 == 'BA & 1'"); + py_run_bound!(py, c, "assert c ^ 1 == 'BA ^ 1'"); + py_run_bound!(py, c, "assert c | 1 == 'BA | 1'"); + py_run_bound!(py, c, "assert c ** 1 == 'BA ** 1 (mod: None)'"); // Class with __add__ only should not allow the reverse op; // this is consistent with Python classes. @@ -236,7 +236,7 @@ fn binary_arithmetic() { py_expect_exception!(py, c, "1 | c", PyTypeError); py_expect_exception!(py, c, "1 ** c", PyTypeError); - py_run!(py, c, "assert pow(c, 1, 100) == 'BA ** 1 (mod: Some(100))'"); + py_run_bound!(py, c, "assert pow(c, 1, 100) == 'BA ** 1 (mod: Some(100))'"); let c: Bound<'_, PyAny> = c.extract().unwrap(); assert_py_eq!(c.add(&c).unwrap(), "BA + BA"); @@ -298,24 +298,24 @@ impl RhsArithmetic { fn rhs_arithmetic() { Python::with_gil(|py| { let c = PyCell::new(py, RhsArithmetic {}).unwrap(); - py_run!(py, c, "assert c.__radd__(1) == '1 + RA'"); - py_run!(py, c, "assert 1 + c == '1 + RA'"); - py_run!(py, c, "assert c.__rsub__(1) == '1 - RA'"); - py_run!(py, c, "assert 1 - c == '1 - RA'"); - py_run!(py, c, "assert c.__rmul__(1) == '1 * RA'"); - py_run!(py, c, "assert 1 * c == '1 * RA'"); - py_run!(py, c, "assert c.__rlshift__(1) == '1 << RA'"); - py_run!(py, c, "assert 1 << c == '1 << RA'"); - py_run!(py, c, "assert c.__rrshift__(1) == '1 >> RA'"); - py_run!(py, c, "assert 1 >> c == '1 >> RA'"); - py_run!(py, c, "assert c.__rand__(1) == '1 & RA'"); - py_run!(py, c, "assert 1 & c == '1 & RA'"); - py_run!(py, c, "assert c.__rxor__(1) == '1 ^ RA'"); - py_run!(py, c, "assert 1 ^ c == '1 ^ RA'"); - py_run!(py, c, "assert c.__ror__(1) == '1 | RA'"); - py_run!(py, c, "assert 1 | c == '1 | RA'"); - py_run!(py, c, "assert c.__rpow__(1) == '1 ** RA'"); - py_run!(py, c, "assert 1 ** c == '1 ** RA'"); + py_run_bound!(py, c, "assert c.__radd__(1) == '1 + RA'"); + py_run_bound!(py, c, "assert 1 + c == '1 + RA'"); + py_run_bound!(py, c, "assert c.__rsub__(1) == '1 - RA'"); + py_run_bound!(py, c, "assert 1 - c == '1 - RA'"); + py_run_bound!(py, c, "assert c.__rmul__(1) == '1 * RA'"); + py_run_bound!(py, c, "assert 1 * c == '1 * RA'"); + py_run_bound!(py, c, "assert c.__rlshift__(1) == '1 << RA'"); + py_run_bound!(py, c, "assert 1 << c == '1 << RA'"); + py_run_bound!(py, c, "assert c.__rrshift__(1) == '1 >> RA'"); + py_run_bound!(py, c, "assert 1 >> c == '1 >> RA'"); + py_run_bound!(py, c, "assert c.__rand__(1) == '1 & RA'"); + py_run_bound!(py, c, "assert 1 & c == '1 & RA'"); + py_run_bound!(py, c, "assert c.__rxor__(1) == '1 ^ RA'"); + py_run_bound!(py, c, "assert 1 ^ c == '1 ^ RA'"); + py_run_bound!(py, c, "assert c.__ror__(1) == '1 | RA'"); + py_run_bound!(py, c, "assert 1 | c == '1 | RA'"); + py_run_bound!(py, c, "assert c.__rpow__(1) == '1 ** RA'"); + py_run_bound!(py, c, "assert 1 ** c == '1 ** RA'"); }); } @@ -428,27 +428,27 @@ fn lhs_fellback_to_rhs() { Python::with_gil(|py| { let c = PyCell::new(py, LhsAndRhs {}).unwrap(); // If the light hand value is `LhsAndRhs`, LHS is used. - py_run!(py, c, "assert c + 1 == 'LR + 1'"); - py_run!(py, c, "assert c - 1 == 'LR - 1'"); - py_run!(py, c, "assert c * 1 == 'LR * 1'"); - py_run!(py, c, "assert c << 1 == 'LR << 1'"); - py_run!(py, c, "assert c >> 1 == 'LR >> 1'"); - py_run!(py, c, "assert c & 1 == 'LR & 1'"); - py_run!(py, c, "assert c ^ 1 == 'LR ^ 1'"); - py_run!(py, c, "assert c | 1 == 'LR | 1'"); - py_run!(py, c, "assert c ** 1 == 'LR ** 1'"); - py_run!(py, c, "assert c @ 1 == 'LR @ 1'"); + py_run_bound!(py, c, "assert c + 1 == 'LR + 1'"); + py_run_bound!(py, c, "assert c - 1 == 'LR - 1'"); + py_run_bound!(py, c, "assert c * 1 == 'LR * 1'"); + py_run_bound!(py, c, "assert c << 1 == 'LR << 1'"); + py_run_bound!(py, c, "assert c >> 1 == 'LR >> 1'"); + py_run_bound!(py, c, "assert c & 1 == 'LR & 1'"); + py_run_bound!(py, c, "assert c ^ 1 == 'LR ^ 1'"); + py_run_bound!(py, c, "assert c | 1 == 'LR | 1'"); + py_run_bound!(py, c, "assert c ** 1 == 'LR ** 1'"); + py_run_bound!(py, c, "assert c @ 1 == 'LR @ 1'"); // Fellback to RHS because of type mismatching - py_run!(py, c, "assert 1 + c == '1 + RA'"); - py_run!(py, c, "assert 1 - c == '1 - RA'"); - py_run!(py, c, "assert 1 * c == '1 * RA'"); - py_run!(py, c, "assert 1 << c == '1 << RA'"); - py_run!(py, c, "assert 1 >> c == '1 >> RA'"); - py_run!(py, c, "assert 1 & c == '1 & RA'"); - py_run!(py, c, "assert 1 ^ c == '1 ^ RA'"); - py_run!(py, c, "assert 1 | c == '1 | RA'"); - py_run!(py, c, "assert 1 ** c == '1 ** RA'"); - py_run!(py, c, "assert 1 @ c == '1 @ RA'"); + py_run_bound!(py, c, "assert 1 + c == '1 + RA'"); + py_run_bound!(py, c, "assert 1 - c == '1 - RA'"); + py_run_bound!(py, c, "assert 1 * c == '1 * RA'"); + py_run_bound!(py, c, "assert 1 << c == '1 << RA'"); + py_run_bound!(py, c, "assert 1 >> c == '1 >> RA'"); + py_run_bound!(py, c, "assert 1 & c == '1 & RA'"); + py_run_bound!(py, c, "assert 1 ^ c == '1 ^ RA'"); + py_run_bound!(py, c, "assert 1 | c == '1 | RA'"); + py_run_bound!(py, c, "assert 1 ** c == '1 ** RA'"); + py_run_bound!(py, c, "assert 1 @ c == '1 @ RA'"); }); } @@ -495,24 +495,24 @@ impl RichComparisons2 { fn rich_comparisons() { Python::with_gil(|py| { let c = PyCell::new(py, RichComparisons {}).unwrap(); - py_run!(py, c, "assert (c < c) == 'RC < RC'"); - py_run!(py, c, "assert (c < 1) == 'RC < 1'"); - py_run!(py, c, "assert (1 < c) == 'RC > 1'"); - py_run!(py, c, "assert (c <= c) == 'RC <= RC'"); - py_run!(py, c, "assert (c <= 1) == 'RC <= 1'"); - py_run!(py, c, "assert (1 <= c) == 'RC >= 1'"); - py_run!(py, c, "assert (c == c) == 'RC == RC'"); - py_run!(py, c, "assert (c == 1) == 'RC == 1'"); - py_run!(py, c, "assert (1 == c) == 'RC == 1'"); - py_run!(py, c, "assert (c != c) == 'RC != RC'"); - py_run!(py, c, "assert (c != 1) == 'RC != 1'"); - py_run!(py, c, "assert (1 != c) == 'RC != 1'"); - py_run!(py, c, "assert (c > c) == 'RC > RC'"); - py_run!(py, c, "assert (c > 1) == 'RC > 1'"); - py_run!(py, c, "assert (1 > c) == 'RC < 1'"); - py_run!(py, c, "assert (c >= c) == 'RC >= RC'"); - py_run!(py, c, "assert (c >= 1) == 'RC >= 1'"); - py_run!(py, c, "assert (1 >= c) == 'RC <= 1'"); + py_run_bound!(py, c, "assert (c < c) == 'RC < RC'"); + py_run_bound!(py, c, "assert (c < 1) == 'RC < 1'"); + py_run_bound!(py, c, "assert (1 < c) == 'RC > 1'"); + py_run_bound!(py, c, "assert (c <= c) == 'RC <= RC'"); + py_run_bound!(py, c, "assert (c <= 1) == 'RC <= 1'"); + py_run_bound!(py, c, "assert (1 <= c) == 'RC >= 1'"); + py_run_bound!(py, c, "assert (c == c) == 'RC == RC'"); + py_run_bound!(py, c, "assert (c == 1) == 'RC == 1'"); + py_run_bound!(py, c, "assert (1 == c) == 'RC == 1'"); + py_run_bound!(py, c, "assert (c != c) == 'RC != RC'"); + py_run_bound!(py, c, "assert (c != 1) == 'RC != 1'"); + py_run_bound!(py, c, "assert (1 != c) == 'RC != 1'"); + py_run_bound!(py, c, "assert (c > c) == 'RC > RC'"); + py_run_bound!(py, c, "assert (c > 1) == 'RC > 1'"); + py_run_bound!(py, c, "assert (1 > c) == 'RC < 1'"); + py_run_bound!(py, c, "assert (c >= c) == 'RC >= RC'"); + py_run_bound!(py, c, "assert (c >= 1) == 'RC >= 1'"); + py_run_bound!(py, c, "assert (1 >= c) == 'RC <= 1'"); }); } @@ -526,12 +526,12 @@ fn rich_comparisons_python_3_type_error() { py_expect_exception!(py, c2, "c2 <= c2", PyTypeError); py_expect_exception!(py, c2, "c2 <= 1", PyTypeError); py_expect_exception!(py, c2, "1 <= c2", PyTypeError); - py_run!(py, c2, "assert (c2 == c2) == True"); - py_run!(py, c2, "assert (c2 == 1) == True"); - py_run!(py, c2, "assert (1 == c2) == True"); - py_run!(py, c2, "assert (c2 != c2) == False"); - py_run!(py, c2, "assert (c2 != 1) == False"); - py_run!(py, c2, "assert (1 != c2) == False"); + py_run_bound!(py, c2, "assert (c2 == c2) == True"); + py_run_bound!(py, c2, "assert (c2 == 1) == True"); + py_run_bound!(py, c2, "assert (1 == c2) == True"); + py_run_bound!(py, c2, "assert (c2 != c2) == False"); + py_run_bound!(py, c2, "assert (c2 != 1) == False"); + py_run_bound!(py, c2, "assert (1 != c2) == False"); py_expect_exception!(py, c2, "c2 > c2", PyTypeError); py_expect_exception!(py, c2, "c2 > 1", PyTypeError); py_expect_exception!(py, c2, "1 > c2", PyTypeError); @@ -621,7 +621,7 @@ mod return_not_implemented { fn _test_binary_dunder(dunder: &str) { Python::with_gil(|py| { let c2 = PyCell::new(py, RichComparisonToSelf {}).unwrap(); - py_run!( + py_run_bound!( py, c2, &format!( diff --git a/tests/test_buffer_protocol.rs b/tests/test_buffer_protocol.rs index b9f3861c65a..0a3a1758bfa 100644 --- a/tests/test_buffer_protocol.rs +++ b/tests/test_buffer_protocol.rs @@ -57,7 +57,7 @@ fn test_buffer() { }, ) .unwrap(); - let env = [("ob", instance)].into_py_dict(py); + let env = [("ob", instance)].into_py_dict_bound(py); py_assert!(py, *env, "bytes(ob) == b' 23'"); }); @@ -122,7 +122,7 @@ fn test_releasebuffer_unraisable_error() { let capture = UnraisableCapture::install(py); let instance = Py::new(py, ReleaseBufferError {}).unwrap(); - let env = [("ob", instance.clone())].into_py_dict(py); + let env = [("ob", instance.clone())].into_py_dict_bound(py); assert!(capture.borrow(py).capture.is_none()); diff --git a/tests/test_class_basics.rs b/tests/test_class_basics.rs index bbf37a2d66b..af8fe16de7d 100644 --- a/tests/test_class_basics.rs +++ b/tests/test_class_basics.rs @@ -2,7 +2,7 @@ use pyo3::prelude::*; use pyo3::types::PyType; -use pyo3::{py_run, PyClass}; +use pyo3::{py_run_bound, PyClass}; #[path = "../src/tests/common.rs"] mod common; @@ -59,22 +59,22 @@ struct ClassWithDocs { fn class_with_docstr() { Python::with_gil(|py| { let typeobj = py.get_type::(); - py_run!( + py_run_bound!( py, typeobj, "assert typeobj.__doc__ == 'Line1\\nLine2\\n Line3'" ); - py_run!( + py_run_bound!( py, typeobj, "assert typeobj.value.__doc__ == 'Property field'" ); - py_run!( + py_run_bound!( py, typeobj, "assert typeobj.readonly.__doc__ == 'Read-only property field'" ); - py_run!( + py_run_bound!( py, typeobj, "assert typeobj.writeonly.__doc__ == 'Write-only property field'" @@ -314,7 +314,7 @@ fn test_pymethods_from_py_with() { Python::with_gil(|py| { let instance = Py::new(py, ClassWithFromPyWithMethods {}).unwrap(); - py_run!( + py_run_bound!( py, instance, r#" @@ -340,7 +340,7 @@ fn test_tuple_struct_class() { py_assert!(py, typeobj, "typeobj.__name__ == 'TupleClass'"); let instance = Py::new(py, TupleClass(5)).unwrap(); - py_run!( + py_run_bound!( py, instance, r#" @@ -371,7 +371,7 @@ fn dunder_dict_support() { }, ) .unwrap(); - py_run!( + py_run_bound!( py, inst, r#" @@ -394,7 +394,7 @@ fn access_dunder_dict() { }, ) .unwrap(); - py_run!( + py_run_bound!( py, inst, r#" @@ -425,7 +425,7 @@ fn inherited_dict() { ), ) .unwrap(); - py_run!( + py_run_bound!( py, inst, r#" @@ -453,7 +453,7 @@ fn weakref_dunder_dict_support() { }, ) .unwrap(); - py_run!( + py_run_bound!( py, inst, "import weakref; assert weakref.ref(inst)() is inst; inst.a = 1; assert inst.a == 1" @@ -477,7 +477,7 @@ fn weakref_support() { }, ) .unwrap(); - py_run!( + py_run_bound!( py, inst, "import weakref; assert weakref.ref(inst)() is inst" @@ -505,7 +505,7 @@ fn inherited_weakref() { ), ) .unwrap(); - py_run!( + py_run_bound!( py, inst, "import weakref; assert weakref.ref(inst)() is inst" diff --git a/tests/test_class_new.rs b/tests/test_class_new.rs index 8cb426861db..9cff7e8368e 100644 --- a/tests/test_class_new.rs +++ b/tests/test_class_new.rs @@ -29,7 +29,10 @@ fn empty_class_with_new() { // Calling with arbitrary args or kwargs is not ok assert!(typeobj.call(("some", "args"), None).is_err()); assert!(typeobj - .call((), Some([("some", "kwarg")].into_py_dict(py))) + .call( + (), + Some([("some", "kwarg")].into_py_dict_bound(py).as_gil_ref()) + ) .is_err()); }); } @@ -169,9 +172,12 @@ c = Class() assert c.from_rust is False "# ); - let globals = PyModule::import(py, "__main__").unwrap().dict(); + let globals = PyModule::import(py, "__main__") + .unwrap() + .as_borrowed() + .dict(); globals.set_item("SuperClass", super_cls).unwrap(); - py.run(source, Some(globals), None) + py.run_bound(source, Some(&globals), None) .map_err(|e| e.display(py)) .unwrap(); }); diff --git a/tests/test_coroutine.rs b/tests/test_coroutine.rs index 206c35da93c..d06f40ca025 100644 --- a/tests/test_coroutine.rs +++ b/tests/test_coroutine.rs @@ -6,7 +6,7 @@ use futures::{channel::oneshot, future::poll_fn, FutureExt}; use pyo3::{ coroutine::CancelHandle, prelude::*, - py_run, + py_run_bound, types::{IntoPyDict, PyType}, }; @@ -31,7 +31,7 @@ fn noop_coroutine() { Python::with_gil(|gil| { let noop = wrap_pyfunction!(noop, gil).unwrap(); let test = "import asyncio; assert asyncio.run(noop()) == 42"; - py_run!(gil, noop, &handle_windows(test)); + py_run_bound!(gil, noop, &handle_windows(test)); }) } @@ -68,8 +68,8 @@ fn test_coroutine_qualname() { ("my_fn", wrap_pyfunction!(my_fn, gil).unwrap().deref()), ("MyClass", gil.get_type::()), ] - .into_py_dict(gil); - py_run!(gil, *locals, &handle_windows(test)); + .into_py_dict_bound(gil); + py_run_bound!(gil, *&locals, &handle_windows(test)); }) } @@ -91,7 +91,7 @@ fn sleep_0_like_coroutine() { Python::with_gil(|gil| { let sleep_0 = wrap_pyfunction!(sleep_0, gil).unwrap(); let test = "import asyncio; assert asyncio.run(sleep_0()) == 42"; - py_run!(gil, sleep_0, &handle_windows(test)); + py_run_bound!(gil, sleep_0, &handle_windows(test)); }) } @@ -110,7 +110,7 @@ fn sleep_coroutine() { Python::with_gil(|gil| { let sleep = wrap_pyfunction!(sleep, gil).unwrap(); let test = r#"import asyncio; assert asyncio.run(sleep(0.1)) == 42"#; - py_run!(gil, sleep, &handle_windows(test)); + py_run_bound!(gil, sleep, &handle_windows(test)); }) } @@ -130,9 +130,9 @@ fn cancelled_coroutine() { let globals = gil.import("__main__").unwrap().dict(); globals.set_item("sleep", sleep).unwrap(); let err = gil - .run( + .run_bound( &pyo3::unindent::unindent(&handle_windows(test)), - Some(globals), + Some(&globals.as_borrowed()), None, ) .unwrap_err(); @@ -170,9 +170,9 @@ fn coroutine_cancel_handle() { globals .set_item("cancellable_sleep", cancellable_sleep) .unwrap(); - gil.run( + gil.run_bound( &pyo3::unindent::unindent(&handle_windows(test)), - Some(globals), + Some(&globals.as_borrowed()), None, ) .unwrap(); @@ -200,9 +200,9 @@ fn coroutine_is_cancelled() { "#; let globals = gil.import("__main__").unwrap().dict(); globals.set_item("sleep_loop", sleep_loop).unwrap(); - gil.run( + gil.run_bound( &pyo3::unindent::unindent(&handle_windows(test)), - Some(globals), + Some(&globals.as_borrowed()), None, ) .unwrap(); @@ -234,7 +234,7 @@ fn coroutine_panic() { else: assert False; "#; - py_run!(gil, panic, &handle_windows(test)); + py_run_bound!(gil, panic, &handle_windows(test)); }) } @@ -259,7 +259,7 @@ fn test_async_method_receiver() { Python::with_gil(|gil| { let test = r#" import asyncio - + obj = Counter() coro1 = obj.get() coro2 = obj.get() @@ -286,7 +286,7 @@ fn test_async_method_receiver() { assert False assert asyncio.run(coro3) == 1 "#; - let locals = [("Counter", gil.get_type::())].into_py_dict(gil); - py_run!(gil, *locals, test); + let locals = [("Counter", gil.get_type::())].into_py_dict_bound(gil); + py_run_bound!(gil, *locals, test); }) } diff --git a/tests/test_datetime.rs b/tests/test_datetime.rs index 32163abe1e0..5d7b1485260 100644 --- a/tests/test_datetime.rs +++ b/tests/test_datetime.rs @@ -4,31 +4,31 @@ use pyo3::prelude::*; use pyo3::types::{timezone_utc, IntoPyDict, PyDate, PyDateTime, PyTime}; use pyo3_ffi::PyDateTime_IMPORT; -fn _get_subclasses<'p>( - py: Python<'p>, +fn _get_subclasses<'py>( + py: Python<'py>, py_type: &str, args: &str, -) -> PyResult<(&'p PyAny, &'p PyAny, &'p PyAny)> { +) -> PyResult<(Bound<'py, PyAny>, Bound<'py, PyAny>, Bound<'py, PyAny>)> { // Import the class from Python and create some subclasses let datetime = py.import("datetime")?; - let locals = [(py_type, datetime.getattr(py_type)?)].into_py_dict(py); + let locals = [(py_type, datetime.getattr(py_type)?)].into_py_dict_bound(py); let make_subclass_py = format!("class Subklass({}):\n pass", py_type); let make_sub_subclass_py = "class SubSubklass(Subklass):\n pass"; - py.run(&make_subclass_py, None, Some(locals))?; - py.run(make_sub_subclass_py, None, Some(locals))?; + py.run_bound(&make_subclass_py, None, Some(&locals))?; + py.run_bound(make_sub_subclass_py, None, Some(&locals))?; // Construct an instance of the base class - let obj = py.eval(&format!("{}({})", py_type, args), None, Some(locals))?; + let obj = py.eval_bound(&format!("{}({})", py_type, args), None, Some(&locals))?; // Construct an instance of the subclass - let sub_obj = py.eval(&format!("Subklass({})", args), None, Some(locals))?; + let sub_obj = py.eval_bound(&format!("Subklass({})", args), None, Some(&locals))?; // Construct an instance of the sub-subclass - let sub_sub_obj = py.eval(&format!("SubSubklass({})", args), None, Some(locals))?; + let sub_sub_obj = py.eval_bound(&format!("SubSubklass({})", args), None, Some(&locals))?; Ok((obj, sub_obj, sub_sub_obj)) } @@ -122,10 +122,10 @@ fn test_datetime_utc() { let dt = PyDateTime::new(py, 2018, 1, 1, 0, 0, 0, 0, Some(utc)).unwrap(); - let locals = [("dt", dt)].into_py_dict(py); + let locals = [("dt", dt)].into_py_dict_bound(py); let offset: f32 = py - .eval("dt.utcoffset().total_seconds()", None, Some(locals)) + .eval_bound("dt.utcoffset().total_seconds()", None, Some(&locals)) .unwrap() .extract() .unwrap(); diff --git a/tests/test_dict_iter.rs b/tests/test_dict_iter.rs index dc32eb61fd7..e502a4ca2b6 100644 --- a/tests/test_dict_iter.rs +++ b/tests/test_dict_iter.rs @@ -6,7 +6,7 @@ use pyo3::types::IntoPyDict; fn iter_dict_nosegv() { Python::with_gil(|py| { const LEN: usize = 10_000_000; - let dict = (0..LEN as u64).map(|i| (i, i * 2)).into_py_dict(py); + let dict = (0..LEN as u64).map(|i| (i, i * 2)).into_py_dict_bound(py); let mut sum = 0; for (k, _v) in dict { let i: u64 = k.extract().unwrap(); diff --git a/tests/test_enum.rs b/tests/test_enum.rs index 33e94c241c7..83f2170bf96 100644 --- a/tests/test_enum.rs +++ b/tests/test_enum.rs @@ -1,7 +1,7 @@ #![cfg(feature = "macros")] use pyo3::prelude::*; -use pyo3::{py_run, wrap_pyfunction}; +use pyo3::{py_run_bound, wrap_pyfunction}; #[path = "../src/tests/common.rs"] mod common; @@ -33,7 +33,7 @@ fn test_return_enum() { let f = wrap_pyfunction!(return_enum)(py).unwrap(); let mynum = py.get_type::(); - py_run!(py, f mynum, "assert f() == mynum.Variant") + py_run_bound!(py, f mynum, "assert f() == mynum.Variant") }); } @@ -48,7 +48,7 @@ fn test_enum_arg() { let f = wrap_pyfunction!(enum_arg)(py).unwrap(); let mynum = py.get_type::(); - py_run!(py, f mynum, "f(mynum.OtherVariant)") + py_run_bound!(py, f mynum, "f(mynum.OtherVariant)") }) } @@ -86,7 +86,7 @@ fn test_custom_discriminant() { let CustomDiscriminant = py.get_type::(); let one = Py::new(py, CustomDiscriminant::One).unwrap(); let two = Py::new(py, CustomDiscriminant::Two).unwrap(); - py_run!(py, CustomDiscriminant one two, r#" + py_run_bound!(py, CustomDiscriminant one two, r#" assert CustomDiscriminant.One == one assert CustomDiscriminant.Two == two assert one != two @@ -101,7 +101,7 @@ fn test_enum_to_int() { py_assert!(py, one, "int(one) == 1"); let v = Py::new(py, MyEnum::Variant).unwrap(); let v_value = MyEnum::Variant as isize; - py_run!(py, v v_value, "int(v) == v_value"); + py_run_bound!(py, v v_value, "int(v) == v_value"); }) } @@ -109,7 +109,7 @@ fn test_enum_to_int() { fn test_enum_compare_int() { Python::with_gil(|py| { let one = Py::new(py, CustomDiscriminant::One).unwrap(); - py_run!( + py_run_bound!( py, one, r#" diff --git a/tests/test_exceptions.rs b/tests/test_exceptions.rs index d6d6b46fcad..d43ffcfd07f 100644 --- a/tests/test_exceptions.rs +++ b/tests/test_exceptions.rs @@ -1,7 +1,7 @@ #![cfg(feature = "macros")] use pyo3::prelude::*; -use pyo3::{exceptions, py_run, PyErr, PyResult}; +use pyo3::{exceptions, py_run_bound, PyErr, PyResult}; use std::error::Error; use std::fmt; #[cfg(not(target_os = "windows"))] @@ -24,7 +24,7 @@ fn test_filenotfounderror() { Python::with_gil(|py| { let fail_to_open_file = wrap_pyfunction!(fail_to_open_file)(py).unwrap(); - py_run!( + py_run_bound!( py, fail_to_open_file, r#" @@ -70,7 +70,7 @@ fn test_custom_error() { let call_fail_with_custom_error = wrap_pyfunction!(call_fail_with_custom_error)(py).unwrap(); - py_run!( + py_run_bound!( py, call_fail_with_custom_error, r#" diff --git a/tests/test_frompyobject.rs b/tests/test_frompyobject.rs index c6f6e148943..03131280019 100644 --- a/tests/test_frompyobject.rs +++ b/tests/test_frompyobject.rs @@ -365,17 +365,17 @@ fn test_enum() { _ => panic!("Expected extracting Foo::StructVarGetAttrArg, got {:?}", f), } - let dict = PyDict::new(py); + let dict = PyDict::new_bound(py); dict.set_item("a", "test").expect("Failed to set item"); - let f = Foo::extract(dict.as_ref()).expect("Failed to extract Foo from dict"); + let f = Foo::extract(dict.into_gil_ref()).expect("Failed to extract Foo from dict"); match f { Foo::StructWithGetItem { a } => assert_eq!(a, "test"), _ => panic!("Expected extracting Foo::StructWithGetItem, got {:?}", f), } - let dict = PyDict::new(py); + let dict = PyDict::new_bound(py); dict.set_item("foo", "test").expect("Failed to set item"); - let f = Foo::extract(dict.as_ref()).expect("Failed to extract Foo from dict"); + let f = Foo::extract(dict.into_gil_ref()).expect("Failed to extract Foo from dict"); match f { Foo::StructWithGetItemArg { a } => assert_eq!(a, "test"), _ => panic!("Expected extracting Foo::StructWithGetItemArg, got {:?}", f), @@ -386,8 +386,8 @@ fn test_enum() { #[test] fn test_enum_error() { Python::with_gil(|py| { - let dict = PyDict::new(py); - let err = Foo::extract(dict.as_ref()).unwrap_err(); + let dict = PyDict::new_bound(py); + let err = Foo::extract(dict.into_gil_ref()).unwrap_err(); assert_eq!( err.to_string(), "\ @@ -430,8 +430,8 @@ enum EnumWithCatchAll<'a> { #[test] fn test_enum_catch_all() { Python::with_gil(|py| { - let dict = PyDict::new(py); - let f = EnumWithCatchAll::extract(dict.as_ref()) + let dict = PyDict::new_bound(py); + let f = EnumWithCatchAll::extract(dict.into_gil_ref()) .expect("Failed to extract EnumWithCatchAll from dict"); match f { EnumWithCatchAll::CatchAll(any) => { @@ -459,8 +459,8 @@ pub enum Bar { #[test] fn test_err_rename() { Python::with_gil(|py| { - let dict = PyDict::new(py); - let f = Bar::extract(dict.as_ref()); + let dict = PyDict::new_bound(py); + let f = Bar::extract(dict.into_gil_ref()); assert!(f.is_err()); assert_eq!( f.unwrap_err().to_string(), @@ -486,14 +486,14 @@ pub struct Zap { fn test_from_py_with() { Python::with_gil(|py| { let py_zap = py - .eval( + .eval_bound( r#"{"name": "whatever", "my_object": [1, 2, 3]}"#, None, None, ) .expect("failed to create dict"); - let zap = Zap::extract(py_zap).unwrap(); + let zap = Zap::extract(py_zap.into_gil_ref()).unwrap(); assert_eq!(zap.name, "whatever"); assert_eq!(zap.some_object_length, 3usize); @@ -507,10 +507,10 @@ pub struct ZapTuple(String, #[pyo3(from_py_with = "PyAny::len")] usize); fn test_from_py_with_tuple_struct() { Python::with_gil(|py| { let py_zap = py - .eval(r#"("whatever", [1, 2, 3])"#, None, None) + .eval_bound(r#"("whatever", [1, 2, 3])"#, None, None) .expect("failed to create tuple"); - let zap = ZapTuple::extract(py_zap).unwrap(); + let zap = ZapTuple::extract(py_zap.into_gil_ref()).unwrap(); assert_eq!(zap.0, "whatever"); assert_eq!(zap.1, 3usize); @@ -521,10 +521,10 @@ fn test_from_py_with_tuple_struct() { fn test_from_py_with_tuple_struct_error() { Python::with_gil(|py| { let py_zap = py - .eval(r#"("whatever", [1, 2, 3], "third")"#, None, None) + .eval_bound(r#"("whatever", [1, 2, 3], "third")"#, None, None) .expect("failed to create tuple"); - let f = ZapTuple::extract(py_zap); + let f = ZapTuple::extract(py_zap.into_gil_ref()); assert!(f.is_err()); assert_eq!( @@ -544,10 +544,10 @@ pub enum ZapEnum { fn test_from_py_with_enum() { Python::with_gil(|py| { let py_zap = py - .eval(r#"("whatever", [1, 2, 3])"#, None, None) + .eval_bound(r#"("whatever", [1, 2, 3])"#, None, None) .expect("failed to create tuple"); - let zap = ZapEnum::extract(py_zap).unwrap(); + let zap = ZapEnum::extract(py_zap.into_gil_ref()).unwrap(); let expected_zap = ZapEnum::Zip(2); assert_eq!(zap, expected_zap); diff --git a/tests/test_gc.rs b/tests/test_gc.rs index 43cdb1b4811..9168d1ff14c 100644 --- a/tests/test_gc.rs +++ b/tests/test_gc.rs @@ -3,7 +3,7 @@ use pyo3::class::PyTraverseError; use pyo3::class::PyVisit; use pyo3::prelude::*; -use pyo3::{py_run, PyCell}; +use pyo3::{py_run_bound, PyCell}; use std::cell::Cell; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; @@ -113,11 +113,11 @@ fn gc_integration() { let mut borrow = inst.borrow_mut(); borrow.self_ref = inst.to_object(py); - py_run!(py, inst, "import gc; assert inst in gc.get_objects()"); + py_run_bound!(py, inst, "import gc; assert inst in gc.get_objects()"); }); Python::with_gil(|py| { - py.run("import gc; gc.collect()", None, None).unwrap(); + py.run_bound("import gc; gc.collect()", None, None).unwrap(); assert!(drop_called.load(Ordering::Relaxed)); }); } @@ -156,7 +156,7 @@ fn gc_null_traversal() { obj.borrow_mut(py).cycle = Some(obj.clone_ref(py)); // the object doesn't have to be cleaned up, it just needs to be traversed. - py.run("import gc; gc.collect()", None, None).unwrap(); + py.run_bound("import gc; gc.collect()", None, None).unwrap(); }); } @@ -469,7 +469,7 @@ fn drop_during_traversal_with_gil() { // (but not too many) collections to get `inst` actually dropped. for _ in 0..10 { Python::with_gil(|py| { - py.run("import gc; gc.collect()", None, None).unwrap(); + py.run_bound("import gc; gc.collect()", None, None).unwrap(); }); } assert!(drop_called.load(Ordering::Relaxed)); @@ -502,7 +502,7 @@ fn drop_during_traversal_without_gil() { // (but not too many) collections to get `inst` actually dropped. for _ in 0..10 { Python::with_gil(|py| { - py.run("import gc; gc.collect()", None, None).unwrap(); + py.run_bound("import gc; gc.collect()", None, None).unwrap(); }); } assert!(drop_called.load(Ordering::Relaxed)); diff --git a/tests/test_getter_setter.rs b/tests/test_getter_setter.rs index 148380ecf67..b99077c5614 100644 --- a/tests/test_getter_setter.rs +++ b/tests/test_getter_setter.rs @@ -3,7 +3,7 @@ use std::cell::Cell; use pyo3::prelude::*; -use pyo3::py_run; +use pyo3::py_run_bound; use pyo3::types::{IntoPyDict, PyList}; #[path = "../src/tests/common.rs"] @@ -52,19 +52,19 @@ fn class_with_properties() { Python::with_gil(|py| { let inst = Py::new(py, ClassWithProperties { num: 10 }).unwrap(); - py_run!(py, inst, "assert inst.get_num() == 10"); - py_run!(py, inst, "assert inst.get_num() == inst.DATA"); - py_run!(py, inst, "inst.DATA = 20"); - py_run!(py, inst, "assert inst.get_num() == 20 == inst.DATA"); + py_run_bound!(py, inst, "assert inst.get_num() == 10"); + py_run_bound!(py, inst, "assert inst.get_num() == inst.DATA"); + py_run_bound!(py, inst, "inst.DATA = 20"); + py_run_bound!(py, inst, "assert inst.get_num() == 20 == inst.DATA"); py_expect_exception!(py, inst, "del inst.DATA", PyAttributeError); - py_run!(py, inst, "assert inst.get_num() == inst.unwrapped == 20"); - py_run!(py, inst, "inst.unwrapped = 42"); - py_run!(py, inst, "assert inst.get_num() == inst.unwrapped == 42"); - py_run!(py, inst, "assert inst.data_list == [42]"); + py_run_bound!(py, inst, "assert inst.get_num() == inst.unwrapped == 20"); + py_run_bound!(py, inst, "inst.unwrapped = 42"); + py_run_bound!(py, inst, "assert inst.get_num() == inst.unwrapped == 42"); + py_run_bound!(py, inst, "assert inst.data_list == [42]"); - let d = [("C", py.get_type::())].into_py_dict(py); + let d = [("C", py.get_type::())].into_py_dict_bound(py); py_assert!(py, *d, "C.DATA.__doc__ == 'a getter for data'"); }); } @@ -96,9 +96,9 @@ fn getter_setter_autogen() { ) .unwrap(); - py_run!(py, inst, "assert inst.num == 10"); - py_run!(py, inst, "inst.num = 20; assert inst.num == 20"); - py_run!( + py_run_bound!(py, inst, "assert inst.num == 10"); + py_run_bound!(py, inst, "inst.num = 20; assert inst.num == 20"); + py_run_bound!( py, inst, "assert inst.text == 'Hello'; inst.text = 'There'; assert inst.text == 'There'" @@ -130,8 +130,8 @@ fn ref_getter_setter() { Python::with_gil(|py| { let inst = Py::new(py, RefGetterSetter { num: 10 }).unwrap(); - py_run!(py, inst, "assert inst.num == 10"); - py_run!(py, inst, "inst.num = 20; assert inst.num == 20"); + py_run_bound!(py, inst, "assert inst.num == 10"); + py_run_bound!(py, inst, "inst.num = 20; assert inst.num == 20"); }); } @@ -157,7 +157,7 @@ fn tuple_struct_getter_setter() { let inst = Py::new(py, TupleClassGetterSetter(10)).unwrap(); py_assert!(py, inst, "inst.num == 10"); - py_run!(py, inst, "inst.num = 20"); + py_run_bound!(py, inst, "inst.num = 20"); py_assert!(py, inst, "inst.num == 20"); }); } @@ -172,8 +172,8 @@ fn get_set_all() { Python::with_gil(|py| { let inst = Py::new(py, All { num: 10 }).unwrap(); - py_run!(py, inst, "assert inst.num == 10"); - py_run!(py, inst, "inst.num = 20; assert inst.num == 20"); + py_run_bound!(py, inst, "assert inst.num == 10"); + py_run_bound!(py, inst, "inst.num = 20; assert inst.num == 20"); }); } @@ -188,8 +188,8 @@ fn get_all_and_set() { Python::with_gil(|py| { let inst = Py::new(py, All2 { num: 10 }).unwrap(); - py_run!(py, inst, "assert inst.num == 10"); - py_run!(py, inst, "inst.num = 20; assert inst.num == 20"); + py_run_bound!(py, inst, "assert inst.num == 10"); + py_run_bound!(py, inst, "inst.num = 20; assert inst.num == 20"); }); } @@ -208,9 +208,9 @@ fn cell_getter_setter() { let inst = Py::new(py, c).unwrap().to_object(py); let cell = Cell::new(20).to_object(py); - py_run!(py, cell, "assert cell == 20"); - py_run!(py, inst, "assert inst.cell_inner == 10"); - py_run!( + py_run_bound!(py, cell, "assert cell == 20"); + py_run_bound!(py, inst, "assert inst.cell_inner == 10"); + py_run_bound!( py, inst, "inst.cell_inner = 20; assert inst.cell_inner == 20" @@ -234,6 +234,6 @@ fn borrowed_value_with_lifetime_of_self() { Python::with_gil(|py| { let inst = Py::new(py, BorrowedValue {}).unwrap().to_object(py); - py_run!(py, inst, "assert inst.value == 'value'"); + py_run_bound!(py, inst, "assert inst.value == 'value'"); }); } diff --git a/tests/test_inheritance.rs b/tests/test_inheritance.rs index d1cfe628ef6..a8aaadb1c90 100644 --- a/tests/test_inheritance.rs +++ b/tests/test_inheritance.rs @@ -1,7 +1,7 @@ #![cfg(feature = "macros")] use pyo3::prelude::*; -use pyo3::py_run; +use pyo3::py_run_bound; use pyo3::types::IntoPyDict; @@ -20,12 +20,12 @@ struct SubclassAble {} #[test] fn subclass() { Python::with_gil(|py| { - let d = [("SubclassAble", py.get_type::())].into_py_dict(py); + let d = [("SubclassAble", py.get_type::())].into_py_dict_bound(py); - py.run( + py.run_bound( "class A(SubclassAble): pass\nassert issubclass(A, SubclassAble)", None, - Some(d), + Some(&d), ) .map_err(|e| e.display(py)) .unwrap(); @@ -74,7 +74,7 @@ fn inheritance_with_new_methods() { Python::with_gil(|py| { let typeobj = py.get_type::(); let inst = typeobj.call((), None).unwrap(); - py_run!(py, inst, "assert inst.val1 == 10; assert inst.val2 == 5"); + py_run_bound!(py, inst, "assert inst.val1 == 10; assert inst.val2 == 5"); }); } @@ -82,7 +82,7 @@ fn inheritance_with_new_methods() { fn call_base_and_sub_methods() { Python::with_gil(|py| { let obj = PyCell::new(py, SubClass::new()).unwrap(); - py_run!( + py_run_bound!( py, obj, r#" @@ -97,9 +97,13 @@ fn call_base_and_sub_methods() { fn mutation_fails() { Python::with_gil(|py| { let obj = PyCell::new(py, SubClass::new()).unwrap(); - let global = Some([("obj", obj)].into_py_dict(py)); + let global = Some([("obj", obj)].into_py_dict_bound(py)); let e = py - .run("obj.base_set(lambda: obj.sub_set_and_ret(1))", global, None) + .run_bound( + "obj.base_set(lambda: obj.sub_set_and_ret(1))", + global.as_ref(), + None, + ) .unwrap_err(); assert_eq!(&e.to_string(), "RuntimeError: Already borrowed"); }); @@ -152,7 +156,7 @@ impl SubClass2 { fn handle_result_in_new() { Python::with_gil(|py| { let subclass = py.get_type::(); - py_run!( + py_run_bound!( py, subclass, r#" @@ -199,7 +203,7 @@ mod inheriting_native_type { Python::with_gil(|py| { let set_sub = pyo3::PyCell::new(py, SetWithName::new()).unwrap(); - py_run!( + py_run_bound!( py, set_sub, r#"set_sub.add(10); assert list(set_sub) == [10]; assert set_sub.name == "Hello :)""# @@ -226,7 +230,7 @@ mod inheriting_native_type { fn inherit_dict() { Python::with_gil(|py| { let dict_sub = pyo3::PyCell::new(py, DictWithName::new()).unwrap(); - py_run!( + py_run_bound!( py, dict_sub, r#"dict_sub[0] = 1; assert dict_sub[0] == 1; assert dict_sub.name == "Hello :)""# @@ -240,10 +244,10 @@ mod inheriting_native_type { let dict_sub = pyo3::Py::new(py, DictWithName::new()).unwrap(); assert_eq!(dict_sub.get_refcnt(py), 1); - let item = py.eval("object()", None, None).unwrap(); + let item = py.eval_bound("object()", None, None).unwrap(); assert_eq!(item.get_refcnt(), 1); - dict_sub.as_ref(py).set_item("foo", item).unwrap(); + dict_sub.as_ref(py).set_item("foo", &item).unwrap(); assert_eq!(item.get_refcnt(), 2); drop(dict_sub); @@ -271,17 +275,17 @@ mod inheriting_native_type { fn custom_exception() { Python::with_gil(|py| { let cls = py.get_type::(); - let dict = [("cls", cls)].into_py_dict(py); - let res = py.run( + let dict = [("cls", cls)].into_py_dict_bound(py); + let res = py.run_bound( "e = cls('hello'); assert str(e) == 'hello'; assert e.context == 'Hello :)'; raise e", None, - Some(dict) + Some(&dict) ); let err = res.unwrap_err(); assert!(err.matches(py, cls), "{}", err); // catching the exception in Python also works: - py_run!( + py_run_bound!( py, cls, r#" @@ -312,7 +316,7 @@ fn test_subclass_ref_counts() { Python::with_gil(|py| { #[allow(non_snake_case)] let SimpleClass = py.get_type::(); - py_run!( + py_run_bound!( py, SimpleClass, r#" diff --git a/tests/test_macro_docs.rs b/tests/test_macro_docs.rs index 964e762886d..5e240816cd2 100644 --- a/tests/test_macro_docs.rs +++ b/tests/test_macro_docs.rs @@ -23,7 +23,7 @@ impl MacroDocs { #[test] fn meth_doc() { Python::with_gil(|py| { - let d = [("C", py.get_type::())].into_py_dict(py); + let d = [("C", py.get_type::())].into_py_dict_bound(py); py_assert!( py, *d, diff --git a/tests/test_mapping.rs b/tests/test_mapping.rs index c029ce27c50..c5e00fb2981 100644 --- a/tests/test_mapping.rs +++ b/tests/test_mapping.rs @@ -4,7 +4,7 @@ use std::collections::HashMap; use pyo3::exceptions::PyKeyError; use pyo3::prelude::*; -use pyo3::py_run; +use pyo3::py_run_bound; use pyo3::types::IntoPyDict; use pyo3::types::PyList; use pyo3::types::PyMapping; @@ -68,9 +68,9 @@ impl Mapping { } /// Return a dict with `m = Mapping(['1', '2', '3'])`. -fn map_dict(py: Python<'_>) -> &pyo3::types::PyDict { - let d = [("Mapping", py.get_type::())].into_py_dict(py); - py_run!(py, *d, "m = Mapping(['1', '2', '3'])"); +fn map_dict(py: Python<'_>) -> Bound<'_, pyo3::types::PyDict> { + let d = [("Mapping", py.get_type::())].into_py_dict_bound(py); + py_run_bound!(py, *d, "m = Mapping(['1', '2', '3'])"); d } @@ -91,8 +91,8 @@ fn test_setitem() { Python::with_gil(|py| { let d = map_dict(py); - py_run!(py, *d, "m['1'] = 4; assert m['1'] == 4"); - py_run!(py, *d, "m['0'] = 0; assert m['0'] == 0"); + py_run_bound!(py, *d, "m['1'] = 4; assert m['1'] == 4"); + py_run_bound!(py, *d, "m['0'] = 0; assert m['0'] == 0"); py_assert!(py, *d, "len(m) == 4"); py_expect_exception!(py, *d, "m[0] = 'hello'", PyTypeError); py_expect_exception!(py, *d, "m[0] = -1", PyTypeError); @@ -103,7 +103,7 @@ fn test_setitem() { fn test_delitem() { Python::with_gil(|py| { let d = map_dict(py); - py_run!( + py_run_bound!( py, *d, "del m['1']; assert len(m) == 2 and m['2'] == 1 and m['3'] == 2" diff --git a/tests/test_methods.rs b/tests/test_methods.rs index 50b179fd911..22e03cd1530 100644 --- a/tests/test_methods.rs +++ b/tests/test_methods.rs @@ -1,7 +1,7 @@ #![cfg(feature = "macros")] use pyo3::prelude::*; -use pyo3::py_run; +use pyo3::py_run_bound; use pyo3::types::{IntoPyDict, PyDict, PyList, PySet, PyString, PyTuple, PyType}; use pyo3::PyCell; @@ -89,7 +89,7 @@ impl ClassMethod { #[test] fn class_method() { Python::with_gil(|py| { - let d = [("C", py.get_type::())].into_py_dict(py); + let d = [("C", py.get_type::())].into_py_dict_bound(py); py_assert!(py, *d, "C.method() == 'ClassMethod.method()!'"); py_assert!(py, *d, "C().method() == 'ClassMethod.method()!'"); py_assert!( @@ -116,7 +116,7 @@ impl ClassMethodWithArgs { #[test] fn class_method_with_args() { Python::with_gil(|py| { - let d = [("C", py.get_type::())].into_py_dict(py); + let d = [("C", py.get_type::())].into_py_dict_bound(py); py_assert!( py, *d, @@ -147,7 +147,7 @@ fn static_method() { Python::with_gil(|py| { assert_eq!(StaticMethod::method(py), "StaticMethod.method()!"); - let d = [("C", py.get_type::())].into_py_dict(py); + let d = [("C", py.get_type::())].into_py_dict_bound(py); py_assert!(py, *d, "C.method() == 'StaticMethod.method()!'"); py_assert!(py, *d, "C().method() == 'StaticMethod.method()!'"); py_assert!(py, *d, "C.method.__doc__ == 'Test static method.'"); @@ -171,7 +171,7 @@ fn static_method_with_args() { Python::with_gil(|py| { assert_eq!(StaticMethodWithArgs::method(py, 1234), "0x4d2"); - let d = [("C", py.get_type::())].into_py_dict(py); + let d = [("C", py.get_type::())].into_py_dict_bound(py); py_assert!(py, *d, "C.method(1337) == '0x539'"); }); } @@ -324,56 +324,56 @@ fn meth_signature() { Python::with_gil(|py| { let inst = Py::new(py, MethSignature {}).unwrap(); - py_run!(py, inst, "assert inst.get_optional() == 10"); - py_run!(py, inst, "assert inst.get_optional(100) == 100"); - py_run!(py, inst, "assert inst.get_optional2() == None"); - py_run!(py, inst, "assert inst.get_optional2(100) == 100"); - py_run!( + py_run_bound!(py, inst, "assert inst.get_optional() == 10"); + py_run_bound!(py, inst, "assert inst.get_optional(100) == 100"); + py_run_bound!(py, inst, "assert inst.get_optional2() == None"); + py_run_bound!(py, inst, "assert inst.get_optional2(100) == 100"); + py_run_bound!( py, inst, "assert inst.get_optional_positional(1, 2, 3) == 2" ); - py_run!(py, inst, "assert inst.get_optional_positional(1) == None"); - py_run!(py, inst, "assert inst.get_default() == 10"); - py_run!(py, inst, "assert inst.get_default(100) == 100"); - py_run!(py, inst, "assert inst.get_kwarg() == 10"); + py_run_bound!(py, inst, "assert inst.get_optional_positional(1) == None"); + py_run_bound!(py, inst, "assert inst.get_default() == 10"); + py_run_bound!(py, inst, "assert inst.get_default(100) == 100"); + py_run_bound!(py, inst, "assert inst.get_kwarg() == 10"); py_expect_exception!(py, inst, "inst.get_kwarg(100)", PyTypeError); - py_run!(py, inst, "assert inst.get_kwarg(test=100) == 100"); - py_run!(py, inst, "assert inst.get_kwargs() == [(), None]"); - py_run!(py, inst, "assert inst.get_kwargs(1,2,3) == [(1,2,3), None]"); - py_run!( + py_run_bound!(py, inst, "assert inst.get_kwarg(test=100) == 100"); + py_run_bound!(py, inst, "assert inst.get_kwargs() == [(), None]"); + py_run_bound!(py, inst, "assert inst.get_kwargs(1,2,3) == [(1,2,3), None]"); + py_run_bound!( py, inst, "assert inst.get_kwargs(t=1,n=2) == [(), {'t': 1, 'n': 2}]" ); - py_run!( + py_run_bound!( py, inst, "assert inst.get_kwargs(1,2,3,t=1,n=2) == [(1,2,3), {'t': 1, 'n': 2}]" ); - py_run!(py, inst, "assert inst.get_pos_arg_kw(1) == [1, (), None]"); - py_run!( + py_run_bound!(py, inst, "assert inst.get_pos_arg_kw(1) == [1, (), None]"); + py_run_bound!( py, inst, "assert inst.get_pos_arg_kw(1, 2, 3) == [1, (2, 3), None]" ); - py_run!( + py_run_bound!( py, inst, "assert inst.get_pos_arg_kw(1, b=2) == [1, (), {'b': 2}]" ); - py_run!(py, inst, "assert inst.get_pos_arg_kw(a=1) == [1, (), None]"); + py_run_bound!(py, inst, "assert inst.get_pos_arg_kw(a=1) == [1, (), None]"); py_expect_exception!(py, inst, "inst.get_pos_arg_kw()", PyTypeError); py_expect_exception!(py, inst, "inst.get_pos_arg_kw(1, a=1)", PyTypeError); py_expect_exception!(py, inst, "inst.get_pos_arg_kw(b=2)", PyTypeError); - py_run!(py, inst, "assert inst.get_pos_only(10, 11) == 21"); + py_run_bound!(py, inst, "assert inst.get_pos_only(10, 11) == 21"); py_expect_exception!(py, inst, "inst.get_pos_only(10, b = 11)", PyTypeError); py_expect_exception!(py, inst, "inst.get_pos_only(a = 10, b = 11)", PyTypeError); - py_run!(py, inst, "assert inst.get_pos_only_and_pos(10, 11) == 21"); - py_run!( + py_run_bound!(py, inst, "assert inst.get_pos_only_and_pos(10, 11) == 21"); + py_run_bound!( py, inst, "assert inst.get_pos_only_and_pos(10, b = 11) == 21" @@ -385,22 +385,22 @@ fn meth_signature() { PyTypeError ); - py_run!( + py_run_bound!( py, inst, "assert inst.get_pos_only_and_pos_and_kw(10, 11) == 26" ); - py_run!( + py_run_bound!( py, inst, "assert inst.get_pos_only_and_pos_and_kw(10, b = 11) == 26" ); - py_run!( + py_run_bound!( py, inst, "assert inst.get_pos_only_and_pos_and_kw(10, 11, c = 0) == 21" ); - py_run!( + py_run_bound!( py, inst, "assert inst.get_pos_only_and_pos_and_kw(10, b = 11, c = 0) == 21" @@ -412,7 +412,7 @@ fn meth_signature() { PyTypeError ); - py_run!( + py_run_bound!( py, inst, "assert inst.get_pos_only_and_kw_only(10, b = 11) == 21" @@ -430,12 +430,12 @@ fn meth_signature() { PyTypeError ); - py_run!( + py_run_bound!( py, inst, "assert inst.get_pos_only_and_kw_only_with_default(10) == 13" ); - py_run!( + py_run_bound!( py, inst, "assert inst.get_pos_only_and_kw_only_with_default(10, b = 11) == 21" @@ -453,17 +453,17 @@ fn meth_signature() { PyTypeError ); - py_run!( + py_run_bound!( py, inst, "assert inst.get_all_arg_types_together(10, 10, c = 10) == 35" ); - py_run!( + py_run_bound!( py, inst, "assert inst.get_all_arg_types_together(10, 10, c = 10, d = 10) == 40" ); - py_run!( + py_run_bound!( py, inst, "assert inst.get_all_arg_types_together(10, b = 10, c = 10, d = 10) == 40" @@ -481,13 +481,13 @@ fn meth_signature() { PyTypeError ); - py_run!(py, inst, "assert inst.get_pos_only_with_varargs(10) == 10"); - py_run!( + py_run_bound!(py, inst, "assert inst.get_pos_only_with_varargs(10) == 10"); + py_run_bound!( py, inst, "assert inst.get_pos_only_with_varargs(10, 10) == 20" ); - py_run!( + py_run_bound!( py, inst, "assert inst.get_pos_only_with_varargs(10, 10, 10, 10, 10) == 50" @@ -499,17 +499,17 @@ fn meth_signature() { PyTypeError ); - py_run!( + py_run_bound!( py, inst, "assert inst.get_pos_only_with_kwargs(10) == [10, None]" ); - py_run!( + py_run_bound!( py, inst, "assert inst.get_pos_only_with_kwargs(10, b = 10) == [10, {'b': 10}]" ); - py_run!( + py_run_bound!( py, inst, "assert inst.get_pos_only_with_kwargs(10, b = 10, c = 10, d = 10, e = 10) == [10, {'b': 10, 'c': 10, 'd': 10, 'e': 10}]" @@ -527,58 +527,58 @@ fn meth_signature() { PyTypeError ); - py_run!( + py_run_bound!( py, inst, "assert inst.get_optional_pos_only_with_kwargs() == [0, None]" ); - py_run!( + py_run_bound!( py, inst, "assert inst.get_optional_pos_only_with_kwargs(10) == [10, None]" ); - py_run!( + py_run_bound!( py, inst, "assert inst.get_optional_pos_only_with_kwargs(a=10) == [0, {'a': 10}]" ); - py_run!(py, inst, "assert inst.get_kwargs_only_with_defaults() == 5"); - py_run!( + py_run_bound!(py, inst, "assert inst.get_kwargs_only_with_defaults() == 5"); + py_run_bound!( py, inst, "assert inst.get_kwargs_only_with_defaults(a = 8) == 11" ); - py_run!( + py_run_bound!( py, inst, "assert inst.get_kwargs_only_with_defaults(b = 8) == 10" ); - py_run!( + py_run_bound!( py, inst, "assert inst.get_kwargs_only_with_defaults(a = 1, b = 1) == 2" ); - py_run!( + py_run_bound!( py, inst, "assert inst.get_kwargs_only_with_defaults(b = 1, a = 1) == 2" ); - py_run!(py, inst, "assert inst.get_kwargs_only(a = 1, b = 1) == 2"); - py_run!(py, inst, "assert inst.get_kwargs_only(b = 1, a = 1) == 2"); + py_run_bound!(py, inst, "assert inst.get_kwargs_only(a = 1, b = 1) == 2"); + py_run_bound!(py, inst, "assert inst.get_kwargs_only(b = 1, a = 1) == 2"); - py_run!( + py_run_bound!( py, inst, "assert inst.get_kwargs_only_with_some_default(a = 2, b = 1) == 3" ); - py_run!( + py_run_bound!( py, inst, "assert inst.get_kwargs_only_with_some_default(b = 1) == 2" ); - py_run!( + py_run_bound!( py, inst, "assert inst.get_kwargs_only_with_some_default(b = 1, a = 2) == 3" @@ -590,12 +590,12 @@ fn meth_signature() { PyTypeError ); - py_run!( + py_run_bound!( py, inst, "assert inst.get_args_and_required_keyword(1, 2, a=3) == ((1, 2), 3)" ); - py_run!( + py_run_bound!( py, inst, "assert inst.get_args_and_required_keyword(a=1) == ((), 1)" @@ -607,42 +607,42 @@ fn meth_signature() { PyTypeError ); - py_run!(py, inst, "assert inst.get_pos_arg_kw_sep1(1) == 6"); - py_run!(py, inst, "assert inst.get_pos_arg_kw_sep1(1, 2) == 6"); - py_run!( + py_run_bound!(py, inst, "assert inst.get_pos_arg_kw_sep1(1) == 6"); + py_run_bound!(py, inst, "assert inst.get_pos_arg_kw_sep1(1, 2) == 6"); + py_run_bound!( py, inst, "assert inst.get_pos_arg_kw_sep1(1, 2, c=13) == 16" ); - py_run!( + py_run_bound!( py, inst, "assert inst.get_pos_arg_kw_sep1(a=1, b=2, c=13) == 16" ); - py_run!( + py_run_bound!( py, inst, "assert inst.get_pos_arg_kw_sep1(b=2, c=13, a=1) == 16" ); - py_run!( + py_run_bound!( py, inst, "assert inst.get_pos_arg_kw_sep1(c=13, b=2, a=1) == 16" ); py_expect_exception!(py, inst, "inst.get_pos_arg_kw_sep1(1, 2, 3)", PyTypeError); - py_run!(py, inst, "assert inst.get_pos_arg_kw_sep2(1) == 6"); - py_run!( + py_run_bound!(py, inst, "assert inst.get_pos_arg_kw_sep2(1) == 6"); + py_run_bound!( py, inst, "assert inst.get_pos_arg_kw_sep2(1, b=12, c=13) == 26" ); py_expect_exception!(py, inst, "inst.get_pos_arg_kw_sep2(1, 2)", PyTypeError); - py_run!(py, inst, "assert inst.get_pos_kw(1, b=2) == [1, {'b': 2}]"); + py_run_bound!(py, inst, "assert inst.get_pos_kw(1, b=2) == [1, {'b': 2}]"); py_expect_exception!(py, inst, "inst.get_pos_kw(1,2)", PyTypeError); - py_run!(py, inst, "assert inst.args_as_vec(1,2,3) == 6"); + py_run_bound!(py, inst, "assert inst.args_as_vec(1,2,3) == 6"); }); } @@ -669,7 +669,7 @@ impl MethDocs { #[test] fn meth_doc() { Python::with_gil(|py| { - let d = [("C", py.get_type::())].into_py_dict(py); + let d = [("C", py.get_type::())].into_py_dict_bound(py); py_assert!(py, *d, "C.__doc__ == 'A class with \"documentation\".'"); py_assert!( py, @@ -704,7 +704,7 @@ impl MethodWithLifeTime { fn method_with_lifetime() { Python::with_gil(|py| { let obj = PyCell::new(py, MethodWithLifeTime {}).unwrap(); - py_run!( + py_run_bound!( py, obj, "assert obj.set_to_list(set((1, 2, 3))) == [1, 2, 3]" @@ -753,27 +753,27 @@ fn method_with_pyclassarg() { Python::with_gil(|py| { let obj1 = PyCell::new(py, MethodWithPyClassArg { value: 10 }).unwrap(); let obj2 = PyCell::new(py, MethodWithPyClassArg { value: 10 }).unwrap(); - let d = [("obj1", obj1), ("obj2", obj2)].into_py_dict(py); - py_run!(py, *d, "obj = obj1.add(obj2); assert obj.value == 20"); - py_run!(py, *d, "obj = obj1.add_pyref(obj2); assert obj.value == 20"); - py_run!(py, *d, "obj = obj1.optional_add(); assert obj.value == 20"); - py_run!( + let d = [("obj1", obj1), ("obj2", obj2)].into_py_dict_bound(py); + py_run_bound!(py, *d, "obj = obj1.add(obj2); assert obj.value == 20"); + py_run_bound!(py, *d, "obj = obj1.add_pyref(obj2); assert obj.value == 20"); + py_run_bound!(py, *d, "obj = obj1.optional_add(); assert obj.value == 20"); + py_run_bound!( py, *d, "obj = obj1.optional_add(obj2); assert obj.value == 20" ); - py_run!(py, *d, "obj1.inplace_add(obj2); assert obj.value == 20"); - py_run!( + py_run_bound!(py, *d, "obj1.inplace_add(obj2); assert obj.value == 20"); + py_run_bound!( py, *d, "obj1.inplace_add_pyref(obj2); assert obj2.value == 30" ); - py_run!( + py_run_bound!( py, *d, "obj1.optional_inplace_add(); assert obj2.value == 30" ); - py_run!( + py_run_bound!( py, *d, "obj1.optional_inplace_add(obj2); assert obj2.value == 40" @@ -938,7 +938,7 @@ fn test_raw_idents() { Python::with_gil(|py| { let raw_idents_type = py.get_type::(); assert_eq!(raw_idents_type.qualname().unwrap(), "RawIdents"); - py_run!( + py_run_bound!( py, raw_idents_type, r#" diff --git a/tests/test_module.rs b/tests/test_module.rs index 2de23b38324..7a476b73b5a 100644 --- a/tests/test_module.rs +++ b/tests/test_module.rs @@ -2,7 +2,7 @@ use pyo3::prelude::*; -use pyo3::py_run; +use pyo3::py_run_bound; use pyo3::types::{IntoPyDict, PyDict, PyTuple}; #[path = "../src/tests/common.rs"] @@ -74,7 +74,7 @@ fn test_module_with_functions() { "module_with_functions", wrap_pymodule!(module_with_functions)(py), )] - .into_py_dict(py); + .into_py_dict_bound(py); py_assert!( py, @@ -127,9 +127,9 @@ fn test_module_renaming() { use pyo3::wrap_pymodule; Python::with_gil(|py| { - let d = [("different_name", wrap_pymodule!(some_name)(py))].into_py_dict(py); + let d = [("different_name", wrap_pymodule!(some_name)(py))].into_py_dict_bound(py); - py_run!(py, *d, "assert different_name.__name__ == 'other_name'"); + py_run_bound!(py, *d, "assert different_name.__name__ == 'other_name'"); }); } diff --git a/tests/test_no_imports.rs b/tests/test_no_imports.rs index df73b9a27d8..7b3e11e1a1a 100644 --- a/tests/test_no_imports.rs +++ b/tests/test_no_imports.rs @@ -90,7 +90,7 @@ fn test_basic() { pyo3::Python::with_gil(|py| { let module = pyo3::wrap_pymodule!(basic_module)(py); let cls = py.get_type::(); - let d = pyo3::types::IntoPyDict::into_py_dict( + let d = pyo3::types::IntoPyDict::into_py_dict_bound( [ ("mod", module.as_ref(py).as_ref()), ("cls", cls.as_ref()), @@ -100,25 +100,25 @@ fn test_basic() { py, ); - pyo3::py_run!(py, *d, "assert mod.answer() == 42"); - pyo3::py_run!(py, *d, "assert mod.identity() is None"); - pyo3::py_run!(py, *d, "v = object(); assert mod.identity(v) is v"); - pyo3::py_run!(py, *d, "assert cls.OKAY"); - pyo3::py_run!(py, *d, "assert (a.v, a.s) == (8, '')"); - pyo3::py_run!(py, *d, "assert (b.v, b.s) == (0, 'foo')"); - pyo3::py_run!(py, *d, "b.property = 314"); - pyo3::py_run!(py, *d, "assert b.property == 300"); - pyo3::py_run!( + pyo3::py_run_bound!(py, *d, "assert mod.answer() == 42"); + pyo3::py_run_bound!(py, *d, "assert mod.identity() is None"); + pyo3::py_run_bound!(py, *d, "v = object(); assert mod.identity(v) is v"); + pyo3::py_run_bound!(py, *d, "assert cls.OKAY"); + pyo3::py_run_bound!(py, *d, "assert (a.v, a.s) == (8, '')"); + pyo3::py_run_bound!(py, *d, "assert (b.v, b.s) == (0, 'foo')"); + pyo3::py_run_bound!(py, *d, "b.property = 314"); + pyo3::py_run_bound!(py, *d, "assert b.property == 300"); + pyo3::py_run_bound!( py, *d, "assert cls.classmethod.__doc__ == 'Some documentation here'" ); - pyo3::py_run!(py, *d, "assert cls.classmethod() is cls"); - pyo3::py_run!(py, *d, "assert cls.staticmethod(5) == '5'"); - pyo3::py_run!(py, *d, "a.s = 'bar'; assert a.s == 'bar'"); - pyo3::py_run!(py, *d, "a.mutate(); assert (a.v, a.s) == (16, 'bar!')"); - pyo3::py_run!(py, *d, "assert a + 9 == 25"); - pyo3::py_run!(py, *d, "b += a; assert (b.v, b.s) == (19, 'foobar!')"); + pyo3::py_run_bound!(py, *d, "assert cls.classmethod() is cls"); + pyo3::py_run_bound!(py, *d, "assert cls.staticmethod(5) == '5'"); + pyo3::py_run_bound!(py, *d, "a.s = 'bar'; assert a.s == 'bar'"); + pyo3::py_run_bound!(py, *d, "a.mutate(); assert (a.v, a.s) == (16, 'bar!')"); + pyo3::py_run_bound!(py, *d, "assert a + 9 == 25"); + pyo3::py_run_bound!(py, *d, "b += a; assert (b.v, b.s) == (19, 'foobar!')"); }); } @@ -141,6 +141,6 @@ impl NewClassMethod { fn test_new_class_method() { pyo3::Python::with_gil(|py| { let cls = py.get_type::(); - pyo3::py_run!(py, cls, "assert cls().cls is cls"); + pyo3::py_run_bound!(py, cls, "assert cls().cls is cls"); }); } diff --git a/tests/test_proto_methods.rs b/tests/test_proto_methods.rs index 50dd99ce50d..8c7c6dc15ca 100644 --- a/tests/test_proto_methods.rs +++ b/tests/test_proto_methods.rs @@ -2,7 +2,7 @@ use pyo3::exceptions::{PyAttributeError, PyIndexError, PyValueError}; use pyo3::types::{PyDict, PyList, PyMapping, PySequence, PySlice, PyType}; -use pyo3::{prelude::*, py_run, PyCell}; +use pyo3::{prelude::*, py_run_bound, PyCell}; use std::{isize, iter}; #[path = "../src/tests/common.rs"] @@ -216,7 +216,7 @@ fn mapping() { let inst = Py::new( py, Mapping { - values: PyDict::new(py).into(), + values: PyDict::new_bound(py).into(), }, ) .unwrap(); @@ -225,9 +225,9 @@ fn mapping() { py_assert!(py, inst, "len(inst) == 0"); - py_run!(py, inst, "inst['foo'] = 'foo'"); + py_run_bound!(py, inst, "inst['foo'] = 'foo'"); py_assert!(py, inst, "inst['foo'] == 'foo'"); - py_run!(py, inst, "del inst['foo']"); + py_run_bound!(py, inst, "del inst['foo']"); py_expect_exception!(py, inst, "inst['foo']", PyKeyError); // Default iteration will call __getitem__ with integer indices @@ -328,7 +328,7 @@ fn sequence() { py_assert!(py, inst, "len(inst) == 0"); py_expect_exception!(py, inst, "inst[0]", PyIndexError); - py_run!(py, inst, "inst.append('foo')"); + py_run_bound!(py, inst, "inst.append('foo')"); py_assert!(py, inst, "inst[0] == 'foo'"); py_assert!(py, inst, "inst[-1] == 'foo'"); @@ -338,7 +338,7 @@ fn sequence() { py_assert!(py, inst, "[*inst] == ['foo']"); - py_run!(py, inst, "del inst[0]"); + py_run_bound!(py, inst, "del inst[0]"); py_expect_exception!(py, inst, "inst['foo']", PyTypeError); @@ -352,7 +352,7 @@ fn sequence() { // however regular python len() works thanks to mp_len slot assert_eq!(inst.as_ref(py).len().unwrap(), 0); - py_run!(py, inst, "inst.append(0)"); + py_run_bound!(py, inst, "inst.append(0)"); sequence.set_item(0, 5).unwrap(); assert_eq!(inst.as_ref(py).len().unwrap(), 1); @@ -438,7 +438,7 @@ impl SetItem { fn setitem() { Python::with_gil(|py| { let c = PyCell::new(py, SetItem { key: 0, val: 0 }).unwrap(); - py_run!(py, c, "c[1] = 2"); + py_run_bound!(py, c, "c[1] = 2"); { let c = c.borrow(); assert_eq!(c.key, 1); @@ -464,7 +464,7 @@ impl DelItem { fn delitem() { Python::with_gil(|py| { let c = PyCell::new(py, DelItem { key: 0 }).unwrap(); - py_run!(py, c, "del c[1]"); + py_run_bound!(py, c, "del c[1]"); { let c = c.borrow(); assert_eq!(c.key, 1); @@ -493,12 +493,12 @@ impl SetDelItem { fn setdelitem() { Python::with_gil(|py| { let c = PyCell::new(py, SetDelItem { val: None }).unwrap(); - py_run!(py, c, "c[1] = 2"); + py_run_bound!(py, c, "c[1] = 2"); { let c = c.borrow(); assert_eq!(c.val, Some(2)); } - py_run!(py, c, "del c[1]"); + py_run_bound!(py, c, "del c[1]"); let c = c.borrow(); assert_eq!(c.val, None); }); @@ -518,8 +518,8 @@ impl Contains { fn contains() { Python::with_gil(|py| { let c = Py::new(py, Contains {}).unwrap(); - py_run!(py, c, "assert 1 in c"); - py_run!(py, c, "assert -1 not in c"); + py_run_bound!(py, c, "assert 1 in c"); + py_run_bound!(py, c, "assert -1 not in c"); py_expect_exception!(py, c, "assert 'wrong type' not in c", PyTypeError); }); } @@ -689,7 +689,7 @@ asyncio.run(main()) "#; let globals = PyModule::import(py, "__main__").unwrap().dict(); globals.set_item("Once", once).unwrap(); - py.run(source, Some(globals), None) + py.run_bound(source, Some(&globals.as_borrowed()), None) .map_err(|e| e.display(py)) .unwrap(); }); @@ -746,7 +746,7 @@ asyncio.run(main()) globals .set_item("AsyncIterator", py.get_type::()) .unwrap(); - py.run(source, Some(globals), None) + py.run_bound(source, Some(&globals.as_borrowed()), None) .map_err(|e| e.display(py)) .unwrap(); }); @@ -815,7 +815,7 @@ assert c.counter.count == 1 ); let globals = PyModule::import(py, "__main__").unwrap().dict(); globals.set_item("Counter", counter).unwrap(); - py.run(source, Some(globals), None) + py.run_bound(source, Some(&globals.as_borrowed()), None) .map_err(|e| e.display(py)) .unwrap(); }); diff --git a/tests/test_pyfunction.rs b/tests/test_pyfunction.rs index f1116363432..90581abce5e 100644 --- a/tests/test_pyfunction.rs +++ b/tests/test_pyfunction.rs @@ -61,7 +61,7 @@ f(a, b) PyBufferError ); - pyo3::py_run!( + pyo3::py_run_bound!( py, f, r#" @@ -92,7 +92,7 @@ fn test_functions_with_function_args() { let py_cfunc_arg = wrap_pyfunction!(function_with_pycfunction_arg)(py).unwrap(); let bool_to_string = wrap_pyfunction!(optional_bool)(py).unwrap(); - pyo3::py_run!( + pyo3::py_run_bound!( py, py_cfunc_arg bool_to_string, @@ -105,7 +105,7 @@ fn test_functions_with_function_args() { { let py_func_arg = wrap_pyfunction!(function_with_pyfunction_arg)(py).unwrap(); - pyo3::py_run!( + pyo3::py_run_bound!( py, py_func_arg, r#" @@ -139,7 +139,7 @@ fn test_function_with_custom_conversion() { Python::with_gil(|py| { let custom_conv_func = wrap_pyfunction!(function_with_custom_conversion)(py).unwrap(); - pyo3::py_run!( + pyo3::py_run_bound!( py, custom_conv_func, r#" diff --git a/tests/test_sequence.rs b/tests/test_sequence.rs index b11e4a6929d..bda4b567691 100644 --- a/tests/test_sequence.rs +++ b/tests/test_sequence.rs @@ -4,7 +4,7 @@ use pyo3::exceptions::{PyIndexError, PyValueError}; use pyo3::types::{IntoPyDict, PyList, PyMapping, PySequence}; use pyo3::{ffi, prelude::*}; -use pyo3::py_run; +use pyo3::py_run_bound; #[path = "../src/tests/common.rs"] mod common; @@ -105,10 +105,10 @@ impl ByteSequence { } /// Return a dict with `s = ByteSequence([1, 2, 3])`. -fn seq_dict(py: Python<'_>) -> &pyo3::types::PyDict { - let d = [("ByteSequence", py.get_type::())].into_py_dict(py); +fn seq_dict(py: Python<'_>) -> Bound<'_, pyo3::types::PyDict> { + let d = [("ByteSequence", py.get_type::())].into_py_dict_bound(py); // Though we can construct `s` in Rust, let's test `__new__` works. - py_run!(py, *d, "s = ByteSequence([1, 2, 3])"); + py_run_bound!(py, *d, "s = ByteSequence([1, 2, 3])"); d } @@ -130,7 +130,7 @@ fn test_setitem() { Python::with_gil(|py| { let d = seq_dict(py); - py_run!(py, *d, "s[0] = 4; assert list(s) == [4, 2, 3]"); + py_run_bound!(py, *d, "s[0] = 4; assert list(s) == [4, 2, 3]"); py_expect_exception!(py, *d, "s[0] = 'hello'", PyTypeError); }); } @@ -138,24 +138,24 @@ fn test_setitem() { #[test] fn test_delitem() { Python::with_gil(|py| { - let d = [("ByteSequence", py.get_type::())].into_py_dict(py); + let d = [("ByteSequence", py.get_type::())].into_py_dict_bound(py); - py_run!( + py_run_bound!( py, *d, "s = ByteSequence([1, 2, 3]); del s[0]; assert list(s) == [2, 3]" ); - py_run!( + py_run_bound!( py, *d, "s = ByteSequence([1, 2, 3]); del s[1]; assert list(s) == [1, 3]" ); - py_run!( + py_run_bound!( py, *d, "s = ByteSequence([1, 2, 3]); del s[-1]; assert list(s) == [1, 2]" ); - py_run!( + py_run_bound!( py, *d, "s = ByteSequence([1, 2, 3]); del s[-2]; assert list(s) == [1, 3]" @@ -193,7 +193,7 @@ fn test_concat() { Python::with_gil(|py| { let d = seq_dict(py); - py_run!( + py_run_bound!( py, *d, "s1 = ByteSequence([1, 2]); s2 = ByteSequence([3, 4]); assert list(s1 + s2) == [1, 2, 3, 4]" @@ -212,7 +212,7 @@ fn test_inplace_concat() { Python::with_gil(|py| { let d = seq_dict(py); - py_run!( + py_run_bound!( py, *d, "s += ByteSequence([4, 5]); assert list(s) == [1, 2, 3, 4, 5]" @@ -226,7 +226,7 @@ fn test_repeat() { Python::with_gil(|py| { let d = seq_dict(py); - py_run!(py, *d, "s2 = s * 2; assert list(s2) == [1, 2, 3, 1, 2, 3]"); + py_run_bound!(py, *d, "s2 = s * 2; assert list(s2) == [1, 2, 3, 1, 2, 3]"); py_expect_exception!(py, *d, "s2 = s * -1", PyValueError); }); } @@ -234,9 +234,9 @@ fn test_repeat() { #[test] fn test_inplace_repeat() { Python::with_gil(|py| { - let d = [("ByteSequence", py.get_type::())].into_py_dict(py); + let d = [("ByteSequence", py.get_type::())].into_py_dict_bound(py); - py_run!( + py_run_bound!( py, *d, "s = ByteSequence([1, 2]); s *= 3; assert list(s) == [1, 2, 1, 2, 1, 2]" @@ -270,7 +270,7 @@ fn test_generic_list_set() { Python::with_gil(|py| { let list = PyCell::new(py, GenericList { items: vec![] }).unwrap(); - py_run!(py, list, "list.items = [1, 2, 3]"); + py_run_bound!(py, list, "list.items = [1, 2, 3]"); assert!(list .borrow() .items diff --git a/tests/test_static_slots.rs b/tests/test_static_slots.rs index 402128c50df..ad6a06d6483 100644 --- a/tests/test_static_slots.rs +++ b/tests/test_static_slots.rs @@ -4,7 +4,7 @@ use pyo3::exceptions::PyIndexError; use pyo3::prelude::*; use pyo3::types::IntoPyDict; -use pyo3::py_run; +use pyo3::py_run_bound; #[path = "../src/tests/common.rs"] mod common; @@ -37,10 +37,10 @@ impl Count5 { } /// Return a dict with `s = Count5()`. -fn test_dict(py: Python<'_>) -> &pyo3::types::PyDict { - let d = [("Count5", py.get_type::())].into_py_dict(py); +fn test_dict(py: Python<'_>) -> Bound<'_, pyo3::types::PyDict> { + let d = [("Count5", py.get_type::())].into_py_dict_bound(py); // Though we can construct `s` in Rust, let's test `__new__` works. - py_run!(py, *d, "s = Count5()"); + py_run_bound!(py, *d, "s = Count5()"); d } diff --git a/tests/test_super.rs b/tests/test_super.rs index 208290df87b..21e637b22e6 100644 --- a/tests/test_super.rs +++ b/tests/test_super.rs @@ -45,7 +45,7 @@ impl SubClass { fn test_call_super_method() { Python::with_gil(|py| { let cls = py.get_type::(); - pyo3::py_run!( + pyo3::py_run_bound!( py, cls, r#" diff --git a/tests/test_unsendable_dict.rs b/tests/test_unsendable_dict.rs index a39aa1ab714..8b10742613b 100644 --- a/tests/test_unsendable_dict.rs +++ b/tests/test_unsendable_dict.rs @@ -1,7 +1,7 @@ #![cfg(feature = "macros")] use pyo3::prelude::*; -use pyo3::py_run; +use pyo3::py_run_bound; #[pyclass(dict, unsendable)] struct UnsendableDictClass {} @@ -19,7 +19,7 @@ impl UnsendableDictClass { fn test_unsendable_dict() { Python::with_gil(|py| { let inst = Py::new(py, UnsendableDictClass {}).unwrap(); - py_run!(py, inst, "assert inst.__dict__ == {}"); + py_run_bound!(py, inst, "assert inst.__dict__ == {}"); }); } @@ -39,8 +39,8 @@ impl UnsendableDictClassWithWeakRef { fn test_unsendable_dict_with_weakref() { Python::with_gil(|py| { let inst = Py::new(py, UnsendableDictClassWithWeakRef {}).unwrap(); - py_run!(py, inst, "assert inst.__dict__ == {}"); - py_run!( + py_run_bound!(py, inst, "assert inst.__dict__ == {}"); + py_run_bound!( py, inst, "import weakref; assert weakref.ref(inst)() is inst; inst.a = 1; assert inst.a == 1" diff --git a/tests/test_various.rs b/tests/test_various.rs index 6560610f35f..2d775280d0f 100644 --- a/tests/test_various.rs +++ b/tests/test_various.rs @@ -2,7 +2,7 @@ use pyo3::prelude::*; use pyo3::types::{PyDict, PyTuple}; -use pyo3::{py_run, PyCell}; +use pyo3::{py_run_bound, PyCell}; use std::fmt; @@ -30,7 +30,7 @@ fn mut_ref_arg() { let inst1 = Py::new(py, MutRefArg { n: 0 }).unwrap(); let inst2 = Py::new(py, MutRefArg { n: 0 }).unwrap(); - py_run!(py, inst1 inst2, "inst1.set_other(inst2)"); + py_run_bound!(py, inst1 inst2, "inst1.set_other(inst2)"); let inst2 = inst2.as_ref(py).borrow(); assert_eq!(inst2.n, 100); }); @@ -151,7 +151,7 @@ fn test_pickle() { module.add_class::().unwrap(); add_module(py, module).unwrap(); let inst = PyCell::new(py, PickleSupport {}).unwrap(); - py_run!( + py_run_bound!( py, inst, r#" diff --git a/tests/ui/wrong_aspyref_lifetimes.rs b/tests/ui/wrong_aspyref_lifetimes.rs index 5cd8a2d3cb6..88bcbaaaaf7 100644 --- a/tests/ui/wrong_aspyref_lifetimes.rs +++ b/tests/ui/wrong_aspyref_lifetimes.rs @@ -1,7 +1,7 @@ use pyo3::{types::PyDict, Py, Python}; fn main() { - let dict: Py = Python::with_gil(|py| PyDict::new(py).into()); + let dict: Py = Python::with_gil(|py| PyDict::new_bound(py).into()); // Should not be able to get access to Py contents outside of with_gil. let dict: &PyDict = Python::with_gil(|py| dict.as_ref(py));