Refactor tests to use shorter macros

This commit is contained in:
kngwyu 2021-03-14 16:34:05 +09:00
parent 7ec1fed798
commit 9b88a452e2
9 changed files with 216 additions and 178 deletions

View File

@ -331,10 +331,11 @@ macro_rules! wrap_pymodule {
/// });
/// ```
///
/// If you need to prepare the `locals` dict by yourself, you can pass it by `*locals`.
/// If you need to prepare the `locals` dict by yourself, you can pass it as `*locals`.
///
/// ```
/// # use pyo3::prelude::*;
/// use pyo3::prelude::*;
/// use pyo3::types::IntoPyDict;
/// #[pyclass]
/// struct MyClass {}
/// #[pymethods]
@ -343,7 +344,7 @@ macro_rules! wrap_pymodule {
/// fn new() -> Self { MyClass {} }
/// }
/// Python::with_gil(|py| {
/// let locals = [("C", py.get_type::<MyClass>())];
/// let locals = [("C", py.get_type::<MyClass>())].into_py_dict(py);
/// pyo3::py_run!(py, *locals, "c = C()");
/// });
/// ```

View File

@ -13,6 +13,8 @@ use std::ptr;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
mod common;
#[pyclass]
struct TestBufferClass {
vec: Vec<u8>,
@ -93,8 +95,7 @@ fn test_buffer() {
)
.unwrap();
let env = [("ob", instance)].into_py_dict(py);
py.run("assert bytes(ob) == b' 23'", None, Some(env))
.unwrap();
py_assert!(py, *env, "bytes(ob) == b' 23'");
}
assert!(drop_called.load(Ordering::Relaxed));

View File

@ -4,7 +4,7 @@ use pyo3::class::{
};
use pyo3::exceptions::{PyIndexError, PyValueError};
use pyo3::prelude::*;
use pyo3::types::{IntoPyDict, PySlice, PyType};
use pyo3::types::{PySlice, PyType};
use pyo3::{ffi, py_run, AsPyPointer, PyCell};
use std::convert::TryFrom;
use std::{isize, iter};
@ -446,11 +446,9 @@ fn test_cls_impl() {
let py = gil.python();
let ob = Py::new(py, Test {}).unwrap();
let d = [("ob", ob)].into_py_dict(py);
py.run("assert ob[1] == 'int'", None, Some(d)).unwrap();
py.run("assert ob[100:200:1] == 'slice'", None, Some(d))
.unwrap();
py_assert!(py, ob, "ob[1] == 'int'");
py_assert!(py, ob, "ob[100:200:1] == 'slice'");
}
#[pyclass(dict, subclass)]

View File

@ -60,12 +60,7 @@ fn class_with_properties() {
py_run!(py, inst, "assert inst.data_list == [42]");
let d = [("C", py.get_type::<ClassWithProperties>())].into_py_dict(py);
py.run(
"assert C.DATA.__doc__ == 'a getter for data'",
None,
Some(d),
)
.unwrap();
py_assert!(py, *d, "C.DATA.__doc__ == 'a getter for data'");
}
#[pyclass]

View File

@ -2,10 +2,13 @@ use std::collections::HashMap;
use pyo3::exceptions::PyKeyError;
use pyo3::prelude::*;
use pyo3::py_run;
use pyo3::types::IntoPyDict;
use pyo3::types::PyList;
use pyo3::PyMappingProtocol;
mod common;
#[pyclass]
struct Mapping {
index: HashMap<String, usize>,
@ -66,35 +69,36 @@ impl PyMappingProtocol for Mapping {
}
}
/// Return a dict with `m = Mapping(['1', '2', '3'])`.
fn map_dict(py: Python) -> &pyo3::types::PyDict {
let d = [("Mapping", py.get_type::<Mapping>())].into_py_dict(py);
py_run!(py, *d, "m = Mapping(['1', '2', '3'])");
d
}
#[test]
fn test_getitem() {
let gil = Python::acquire_gil();
let py = gil.python();
let d = [("Mapping", py.get_type::<Mapping>())].into_py_dict(py);
let d = map_dict(py);
let run = |code| py.run(code, None, Some(d)).unwrap();
let err = |code| py.run(code, None, Some(d)).unwrap_err();
run("m = Mapping(['1', '2', '3']); assert m['1'] == 0");
run("m = Mapping(['1', '2', '3']); assert m['2'] == 1");
run("m = Mapping(['1', '2', '3']); assert m['3'] == 2");
err("m = Mapping(['1', '2', '3']); print(m['4'])");
py_assert!(py, *d, "m['1'] == 0");
py_assert!(py, *d, "m['2'] == 1");
py_assert!(py, *d, "m['3'] == 2");
py_expect_exception!(py, *d, "print(m['4'])", PyKeyError);
}
#[test]
fn test_setitem() {
let gil = Python::acquire_gil();
let py = gil.python();
let d = [("Mapping", py.get_type::<Mapping>())].into_py_dict(py);
let d = map_dict(py);
let run = |code| py.run(code, None, Some(d)).unwrap();
let err = |code| py.run(code, None, Some(d)).unwrap_err();
run("m = Mapping(['1', '2', '3']); m['1'] = 4; assert m['1'] == 4");
run("m = Mapping(['1', '2', '3']); m['0'] = 0; assert m['0'] == 0");
run("m = Mapping(['1', '2', '3']); len(m) == 4");
err("m = Mapping(['1', '2', '3']); m[0] = 'hello'");
err("m = Mapping(['1', '2', '3']); m[0] = -1");
py_run!(py, *d, "m['1'] = 4; assert m['1'] == 4");
py_run!(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);
}
#[test]
@ -102,16 +106,14 @@ fn test_delitem() {
let gil = Python::acquire_gil();
let py = gil.python();
let d = [("Mapping", py.get_type::<Mapping>())].into_py_dict(py);
let run = |code| py.run(code, None, Some(d)).unwrap();
let err = |code| py.run(code, None, Some(d)).unwrap_err();
run(
"m = Mapping(['1', '2', '3']); del m['1']; assert len(m) == 2; \
assert m['2'] == 1; assert m['3'] == 2",
let d = map_dict(py);
py_run!(
py,
*d,
"del m['1']; assert len(m) == 2 and m['2'] == 1 and m['3'] == 2"
);
err("m = Mapping(['1', '2', '3']); del m[-1]");
err("m = Mapping(['1', '2', '3']); del m['4']");
py_expect_exception!(py, *d, "del m[-1]", PyTypeError);
py_expect_exception!(py, *d, "del m['4']", PyKeyError);
}
#[test]
@ -119,8 +121,6 @@ fn test_reversed() {
let gil = Python::acquire_gil();
let py = gil.python();
let d = [("Mapping", py.get_type::<Mapping>())].into_py_dict(py);
let run = |code| py.run(code, None, Some(d)).unwrap();
run("m = Mapping(['1', '2']); assert set(reversed(m)) == {'1', '2'}");
let d = map_dict(py);
py_assert!(py, *d, "set(reversed(m)) == {'1', '2', '3'}");
}

View File

@ -56,10 +56,8 @@ fn instance_method_with_args() {
let obj = PyCell::new(py, InstanceMethodWithArgs { member: 7 }).unwrap();
let obj_ref = obj.borrow();
assert_eq!(obj_ref.method(6), 42);
let d = [("obj", obj)].into_py_dict(py);
py.run("assert obj.method(3) == 21", None, Some(d)).unwrap();
py.run("assert obj.method(multiplier=6) == 42", None, Some(d))
.unwrap();
py_assert!(py, obj, "obj.method(3) == 21");
py_assert!(py, obj, "obj.method(multiplier=6) == 42");
}
#[pyclass]
@ -85,15 +83,10 @@ fn class_method() {
let py = gil.python();
let d = [("C", py.get_type::<ClassMethod>())].into_py_dict(py);
let run = |code| {
py.run(code, None, Some(d))
.map_err(|e| e.print(py))
.unwrap()
};
run("assert C.method() == 'ClassMethod.method()!'");
run("assert C().method() == 'ClassMethod.method()!'");
run("assert C.method.__doc__ == 'Test class method.'");
run("assert C().method.__doc__ == 'Test class method.'");
py_assert!(py, *d, "C.method() == 'ClassMethod.method()!'");
py_assert!(py, *d, "C().method() == 'ClassMethod.method()!'");
py_assert!(py, *d, "C.method.__doc__ == 'Test class method.'");
py_assert!(py, *d, "C().method.__doc__ == 'Test class method.'");
}
#[pyclass]
@ -113,12 +106,11 @@ fn class_method_with_args() {
let py = gil.python();
let d = [("C", py.get_type::<ClassMethodWithArgs>())].into_py_dict(py);
py.run(
"assert C.method('abc') == 'ClassMethodWithArgs.method(abc)'",
None,
Some(d),
)
.unwrap();
py_assert!(
py,
*d,
"C.method('abc') == 'ClassMethodWithArgs.method(abc)'"
);
}
#[pyclass]
@ -146,15 +138,10 @@ fn static_method() {
assert_eq!(StaticMethod::method(py), "StaticMethod.method()!");
let d = [("C", py.get_type::<StaticMethod>())].into_py_dict(py);
let run = |code| {
py.run(code, None, Some(d))
.map_err(|e| e.print(py))
.unwrap()
};
run("assert C.method() == 'StaticMethod.method()!'");
run("assert C().method() == 'StaticMethod.method()!'");
run("assert C.method.__doc__ == 'Test static method.'");
run("assert C().method.__doc__ == 'Test static method.'");
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.'");
py_assert!(py, *d, "C().method.__doc__ == 'Test static method.'");
}
#[pyclass]
@ -176,8 +163,7 @@ fn static_method_with_args() {
assert_eq!(StaticMethodWithArgs::method(py, 1234), "0x4d2");
let d = [("C", py.get_type::<StaticMethodWithArgs>())].into_py_dict(py);
py.run("assert C.method(1337) == '0x539'", None, Some(d))
.unwrap();
py_assert!(py, *d, "C.method(1337) == '0x539'");
}
#[pyclass]
@ -449,15 +435,17 @@ fn meth_doc() {
let gil = Python::acquire_gil();
let py = gil.python();
let d = [("C", py.get_type::<MethDocs>())].into_py_dict(py);
let run = |code| {
py.run(code, None, Some(d))
.map_err(|e| e.print(py))
.unwrap()
};
run("assert C.__doc__ == 'A class with \"documentation\".'");
run("assert C.method.__doc__ == 'A method with \"documentation\" as well.'");
run("assert C.x.__doc__ == '`int`: a very \"important\" member of \\'this\\' instance.'");
py_assert!(py, *d, "C.__doc__ == 'A class with \"documentation\".'");
py_assert!(
py,
*d,
"C.method.__doc__ == 'A method with \"documentation\" as well.'"
);
py_assert!(
py,
*d,
"C.x.__doc__ == '`int`: a very \"important\" member of \\'this\\' instance.'"
);
}
#[pyclass]
@ -530,20 +518,31 @@ fn method_with_pyclassarg() {
let py = gil.python();
let obj1 = PyCell::new(py, MethodWithPyClassArg { value: 10 }).unwrap();
let obj2 = PyCell::new(py, MethodWithPyClassArg { value: 10 }).unwrap();
let objs = [("obj1", obj1), ("obj2", obj2)].into_py_dict(py);
let run = |code| {
py.run(code, None, Some(objs))
.map_err(|e| e.print(py))
.unwrap()
};
run("obj = obj1.add(obj2); assert obj.value == 20");
run("obj = obj1.add_pyref(obj2); assert obj.value == 20");
run("obj = obj1.optional_add(); assert obj.value == 20");
run("obj = obj1.optional_add(obj2); assert obj.value == 20");
run("obj1.inplace_add(obj2); assert obj.value == 20");
run("obj1.inplace_add_pyref(obj2); assert obj2.value == 30");
run("obj1.optional_inplace_add(); assert obj2.value == 30");
run("obj1.optional_inplace_add(obj2); assert obj2.value == 40");
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!(
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,
*d,
"obj1.inplace_add_pyref(obj2); assert obj2.value == 30"
);
py_run!(
py,
*d,
"obj1.optional_inplace_add(); assert obj2.value == 30"
);
py_run!(
py,
*d,
"obj1.optional_inplace_add(obj2); assert obj2.value == 40"
);
}
#[pyclass]

View File

@ -1,7 +1,7 @@
use pyo3::prelude::*;
use pyo3::py_run;
use pyo3::types::{IntoPyDict, PyDict, PyTuple};
mod common;
#[pyclass]
@ -83,25 +83,43 @@ fn test_module_with_functions() {
)]
.into_py_dict(py);
let run = |code| {
py.run(code, None, Some(d))
.map_err(|e| e.print(py))
.unwrap()
};
run("assert module_with_functions.__doc__ == 'This module is implemented in Rust.'");
run("assert module_with_functions.sum_as_string(1, 2) == '3'");
run("assert module_with_functions.no_parameters() == 42");
run("assert module_with_functions.foo == 'bar'");
run("assert module_with_functions.AnonClass != None");
run("assert module_with_functions.LocatedClass != None");
run("assert module_with_functions.LocatedClass.__module__ == 'module'");
run("assert module_with_functions.double(3) == 6");
run("assert module_with_functions.double.__doc__ == 'Doubles the given value'");
run("assert module_with_functions.also_double(3) == 6");
run("assert module_with_functions.also_double.__doc__ == 'Doubles the given value'");
run("assert module_with_functions.double_value(module_with_functions.ValueClass(1)) == 2");
run("assert module_with_functions.with_module() == 'module_with_functions'");
py_assert!(
py,
*d,
"module_with_functions.__doc__ == 'This module is implemented in Rust.'"
);
py_assert!(py, *d, "module_with_functions.sum_as_string(1, 2) == '3'");
py_assert!(py, *d, "module_with_functions.no_parameters() == 42");
py_assert!(py, *d, "module_with_functions.foo == 'bar'");
py_assert!(py, *d, "module_with_functions.AnonClass != None");
py_assert!(py, *d, "module_with_functions.LocatedClass != None");
py_assert!(
py,
*d,
"module_with_functions.LocatedClass.__module__ == 'module'"
);
py_assert!(py, *d, "module_with_functions.double(3) == 6");
py_assert!(
py,
*d,
"module_with_functions.double.__doc__ == 'Doubles the given value'"
);
py_assert!(py, *d, "module_with_functions.also_double(3) == 6");
py_assert!(
py,
*d,
"module_with_functions.also_double.__doc__ == 'Doubles the given value'"
);
py_assert!(
py,
*d,
"module_with_functions.double_value(module_with_functions.ValueClass(1)) == 2"
);
py_assert!(
py,
*d,
"module_with_functions.with_module() == 'module_with_functions'"
);
}
#[pymodule(other_name)]
@ -119,12 +137,7 @@ fn test_module_renaming() {
let d = [("different_name", wrap_pymodule!(other_name)(py))].into_py_dict(py);
py.run(
"assert different_name.__name__ == 'other_name'",
None,
Some(d),
)
.unwrap();
py_run!(py, *d, "assert different_name.__name__ == 'other_name'");
}
#[test]

View File

@ -83,33 +83,35 @@ impl PySequenceProtocol for ByteSequence {
}
}
/// Return a dict with `s = ByteSequence([1, 2, 3])`.
fn seq_dict(py: Python) -> &pyo3::types::PyDict {
let d = [("ByteSequence", py.get_type::<ByteSequence>())].into_py_dict(py);
// Though we can construct `s` in Rust, let's test `__new__` works.
py_run!(py, *d, "s = ByteSequence([1, 2, 3])");
d
}
#[test]
fn test_getitem() {
let gil = Python::acquire_gil();
let py = gil.python();
let d = [("ByteSequence", py.get_type::<ByteSequence>())].into_py_dict(py);
let d = seq_dict(py);
let run = |code| py.run(code, None, Some(d)).unwrap();
let err = |code| py.run(code, None, Some(d)).unwrap_err();
run("s = ByteSequence([1, 2, 3]); assert s[0] == 1");
run("s = ByteSequence([1, 2, 3]); assert s[1] == 2");
run("s = ByteSequence([1, 2, 3]); assert s[2] == 3");
err("s = ByteSequence([1, 2, 3]); print(s[-4])");
err("s = ByteSequence([1, 2, 3]); print(s[4])");
py_assert!(py, *d, "s[0] == 1");
py_assert!(py, *d, "s[1] == 2");
py_assert!(py, *d, "s[2] == 3");
py_expect_exception!(py, *d, "print(s[-4])", PyIndexError);
py_expect_exception!(py, *d, "print(s[4])", PyIndexError);
}
#[test]
fn test_setitem() {
let gil = Python::acquire_gil();
let py = gil.python();
let d = [("ByteSequence", py.get_type::<ByteSequence>())].into_py_dict(py);
let d = seq_dict(py);
let run = |code| py.run(code, None, Some(d)).unwrap();
let err = |code| py.run(code, None, Some(d)).unwrap_err();
run("s = ByteSequence([1, 2, 3]); s[0] = 4; assert list(s) == [4, 2, 3]");
err("s = ByteSequence([1, 2, 3]); s[0] = 'hello'");
py_run!(py, *d, "s[0] = 4; assert list(s) == [4, 2, 3]");
py_expect_exception!(py, *d, "s[0] = 'hello'", PyTypeError);
}
#[test]
@ -118,15 +120,39 @@ fn test_delitem() {
let py = gil.python();
let d = [("ByteSequence", py.get_type::<ByteSequence>())].into_py_dict(py);
let run = |code| py.run(code, None, Some(d)).unwrap();
let err = |code| py.run(code, None, Some(d)).unwrap_err();
run("s = ByteSequence([1, 2, 3]); del s[0]; assert list(s) == [2, 3]");
run("s = ByteSequence([1, 2, 3]); del s[1]; assert list(s) == [1, 3]");
run("s = ByteSequence([1, 2, 3]); del s[-1]; assert list(s) == [1, 2]");
run("s = ByteSequence([1, 2, 3]); del s[-2]; assert list(s) == [1, 3]");
err("s = ByteSequence([1, 2, 3]); del s[-4]; print(list(s))");
err("s = ByteSequence([1, 2, 3]); del s[4]");
py_run!(
py,
*d,
"s = ByteSequence([1, 2, 3]); del s[0]; assert list(s) == [2, 3]"
);
py_run!(
py,
*d,
"s = ByteSequence([1, 2, 3]); del s[1]; assert list(s) == [1, 3]"
);
py_run!(
py,
*d,
"s = ByteSequence([1, 2, 3]); del s[-1]; assert list(s) == [1, 2]"
);
py_run!(
py,
*d,
"s = ByteSequence([1, 2, 3]); del s[-2]; assert list(s) == [1, 3]"
);
py_expect_exception!(
py,
*d,
"s = ByteSequence([1, 2, 3]); del s[-4]; print(list(s))",
PyIndexError
);
py_expect_exception!(
py,
*d,
"s = ByteSequence([1, 2, 3]); del s[4]",
PyIndexError
);
}
#[test]
@ -134,14 +160,13 @@ fn test_contains() {
let gil = Python::acquire_gil();
let py = gil.python();
let d = [("ByteSequence", py.get_type::<ByteSequence>())].into_py_dict(py);
let run = |code| py.run(code, None, Some(d)).unwrap();
let d = seq_dict(py);
run("s = ByteSequence([1, 2, 3]); assert 1 in s");
run("s = ByteSequence([1, 2, 3]); assert 2 in s");
run("s = ByteSequence([1, 2, 3]); assert 3 in s");
run("s = ByteSequence([1, 2, 3]); assert 4 not in s");
run("s = ByteSequence([1, 2, 3]); assert 'hello' not in s");
py_assert!(py, *d, "1 in s");
py_assert!(py, *d, "2 in s");
py_assert!(py, *d, "3 in s");
py_assert!(py, *d, "4 not in s");
py_assert!(py, *d, "'hello' not in s");
}
#[test]
@ -149,12 +174,19 @@ fn test_concat() {
let gil = Python::acquire_gil();
let py = gil.python();
let d = [("ByteSequence", py.get_type::<ByteSequence>())].into_py_dict(py);
let run = |code| py.run(code, None, Some(d)).unwrap();
let err = |code| py.run(code, None, Some(d)).unwrap_err();
let d = seq_dict(py);
run("s1 = ByteSequence([1, 2]); s2 = ByteSequence([3, 4]); assert list(s1+s2) == [1, 2, 3, 4]");
err("s1 = ByteSequence([1, 2]); s2 = 'hello'; s1 + s2");
py_run!(
py,
*d,
"s1 = ByteSequence([1, 2]); s2 = ByteSequence([3, 4]); assert list(s1 + s2) == [1, 2, 3, 4]"
);
py_expect_exception!(
py,
*d,
"s1 = ByteSequence([1, 2]); s2 = 'hello'; s1 + s2",
PyTypeError
);
}
#[test]
@ -162,12 +194,14 @@ fn test_inplace_concat() {
let gil = Python::acquire_gil();
let py = gil.python();
let d = [("ByteSequence", py.get_type::<ByteSequence>())].into_py_dict(py);
let run = |code| py.run(code, None, Some(d)).unwrap();
let err = |code| py.run(code, None, Some(d)).unwrap_err();
let d = seq_dict(py);
run("s = ByteSequence([1, 2]); s += ByteSequence([3, 4]); assert list(s) == [1, 2, 3, 4]");
err("s = ByteSequence([1, 2]); s += 'hello'");
py_run!(
py,
*d,
"s += ByteSequence([4, 5]); assert list(s) == [1, 2, 3, 4, 5]"
);
py_expect_exception!(py, *d, "s += 'hello'", PyTypeError);
}
#[test]
@ -175,12 +209,10 @@ fn test_repeat() {
let gil = Python::acquire_gil();
let py = gil.python();
let d = [("ByteSequence", py.get_type::<ByteSequence>())].into_py_dict(py);
let run = |code| py.run(code, None, Some(d)).unwrap();
let err = |code| py.run(code, None, Some(d)).unwrap_err();
let d = seq_dict(py);
run("s1 = ByteSequence([1, 2, 3]); s2 = s1*2; assert list(s2) == [1, 2, 3, 1, 2, 3]");
err("s1 = ByteSequence([1, 2, 3]); s2 = s1*-1; assert list(s2) == [1, 2, 3, 1, 2, 3]");
py_run!(py, *d, "s2 = s * 2; assert list(s2) == [1, 2, 3, 1, 2, 3]");
py_expect_exception!(py, *d, "s2 = s * -1", PyValueError);
}
#[test]
@ -189,11 +221,13 @@ fn test_inplace_repeat() {
let py = gil.python();
let d = [("ByteSequence", py.get_type::<ByteSequence>())].into_py_dict(py);
let run = |code| py.run(code, None, Some(d)).unwrap();
let err = |code| py.run(code, None, Some(d)).unwrap_err();
run("s = ByteSequence([1, 2]); s *= 3; assert list(s) == [1, 2, 1, 2, 1, 2]");
err("s = ByteSequence([1, 2); s *= -1");
py_run!(
py,
*d,
"s = ByteSequence([1, 2]); s *= 3; assert list(s) == [1, 2, 1, 2, 1, 2]"
);
py_expect_exception!(py, *d, "s = ByteSequence([1, 2]); s *= -1", PyValueError);
}
// Check that #[pyo3(get, set)] works correctly for Vec<PyObject>

View File

@ -1,5 +1,4 @@
use pyo3::prelude::*;
use pyo3::types::IntoPyDict;
use pyo3::types::{PyDict, PyTuple};
use pyo3::{py_run, wrap_pyfunction, PyCell};
@ -29,9 +28,7 @@ fn mut_ref_arg() {
let inst1 = Py::new(py, MutRefArg { n: 0 }).unwrap();
let inst2 = Py::new(py, MutRefArg { n: 0 }).unwrap();
let d = [("inst1", &inst1), ("inst2", &inst2)].into_py_dict(py);
py.run("inst1.set_other(inst2)", None, Some(d)).unwrap();
py_run!(py, inst1 inst2, "inst1.set_other(inst2)");
let inst2 = inst2.as_ref(py).borrow();
assert_eq!(inst2.n, 100);
}