Merge pull request #2518 from mejrs/acquire_gil_tests
Use Python::with_gil in tests
This commit is contained in:
commit
e40b25237d
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
|
@ -181,7 +181,7 @@ jobs:
|
|||
run: |
|
||||
set -x
|
||||
cargo update -p indexmap --precise 1.6.2
|
||||
cargo update -p hashbrown:0.12.2 --precise 0.9.1
|
||||
cargo update -p hashbrown:0.12.3 --precise 0.9.1
|
||||
PROJECTS=("." "examples/decorator" "examples/maturin-starter" "examples/setuptools-rust-starter" "examples/word-count")
|
||||
for PROJ in ${PROJECTS[@]}; do
|
||||
cargo update --manifest-path "$PROJ/Cargo.toml" -p parking_lot --precise 0.11.0
|
||||
|
|
|
@ -5,8 +5,7 @@ use pyo3::types::IntoPyDict;
|
|||
use std::collections::{BTreeMap, HashMap};
|
||||
|
||||
fn iter_dict(b: &mut Bencher<'_>) {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
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 mut sum = 0;
|
||||
|
@ -16,18 +15,18 @@ fn iter_dict(b: &mut Bencher<'_>) {
|
|||
sum += i;
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
fn dict_new(b: &mut Bencher<'_>) {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
const LEN: usize = 50_000;
|
||||
b.iter(|| (0..LEN as u64).map(|i| (i, i * 2)).into_py_dict(py));
|
||||
});
|
||||
}
|
||||
|
||||
fn dict_get_item(b: &mut Bencher<'_>) {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
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 mut sum = 0;
|
||||
|
@ -36,31 +35,32 @@ fn dict_get_item(b: &mut Bencher<'_>) {
|
|||
sum += dict.get_item(i).unwrap().extract::<usize>().unwrap();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
fn extract_hashmap(b: &mut Bencher<'_>) {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
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::<u64, u64>::extract(dict));
|
||||
});
|
||||
}
|
||||
|
||||
fn extract_btreemap(b: &mut Bencher<'_>) {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
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::<u64, u64>::extract(dict));
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(feature = "hashbrown")]
|
||||
fn extract_hashbrown_map(b: &mut Bencher<'_>) {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
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::<u64, u64>::extract(dict));
|
||||
});
|
||||
}
|
||||
|
||||
fn criterion_benchmark(c: &mut Criterion) {
|
||||
|
|
|
@ -13,7 +13,7 @@ fn bench_clean_gilpool_new(b: &mut Bencher<'_>) {
|
|||
fn bench_clean_acquire_gil(b: &mut Bencher<'_>) {
|
||||
// Acquiring first GIL will also create a "clean" GILPool, so this measures the Python overhead.
|
||||
b.iter(|| {
|
||||
let _ = Python::acquire_gil();
|
||||
let _ = Python::with_gil(|_| {});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ fn bench_dirty_acquire_gil(b: &mut Bencher<'_>) {
|
|||
let _ = obj.clone();
|
||||
},
|
||||
|_| {
|
||||
let _ = Python::acquire_gil();
|
||||
let _ = Python::with_gil(|_| {});
|
||||
},
|
||||
BatchSize::NumBatches(1),
|
||||
);
|
||||
|
|
|
@ -4,8 +4,7 @@ use pyo3::prelude::*;
|
|||
use pyo3::types::PyList;
|
||||
|
||||
fn iter_list(b: &mut Bencher<'_>) {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
const LEN: usize = 100_000;
|
||||
let list = PyList::new(py, 0..LEN);
|
||||
let mut sum = 0;
|
||||
|
@ -15,18 +14,18 @@ fn iter_list(b: &mut Bencher<'_>) {
|
|||
sum += i;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
fn list_new(b: &mut Bencher<'_>) {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
const LEN: usize = 50_000;
|
||||
b.iter(|| PyList::new(py, 0..LEN));
|
||||
});
|
||||
}
|
||||
|
||||
fn list_get_item(b: &mut Bencher<'_>) {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
const LEN: usize = 50_000;
|
||||
let list = PyList::new(py, 0..LEN);
|
||||
let mut sum = 0;
|
||||
|
@ -35,12 +34,12 @@ fn list_get_item(b: &mut Bencher<'_>) {
|
|||
sum += list.get_item(i).unwrap().extract::<usize>().unwrap();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(not(Py_LIMITED_API))]
|
||||
fn list_get_item_unchecked(b: &mut Bencher<'_>) {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
const LEN: usize = 50_000;
|
||||
let list = PyList::new(py, 0..LEN);
|
||||
let mut sum = 0;
|
||||
|
@ -51,6 +50,7 @@ fn list_get_item_unchecked(b: &mut Bencher<'_>) {
|
|||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
fn criterion_benchmark(c: &mut Criterion) {
|
||||
|
|
|
@ -27,14 +27,14 @@ impl MyClass {
|
|||
}
|
||||
|
||||
pub fn first_time_init(b: &mut criterion::Bencher<'_>) {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
b.iter(|| {
|
||||
// This is using an undocumented internal PyO3 API to measure pyclass performance; please
|
||||
// don't use this in your own code!
|
||||
let ty = LazyStaticType::new();
|
||||
ty.get_or_init::<MyClass>(py);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
fn criterion_benchmark(c: &mut Criterion) {
|
||||
|
|
|
@ -3,13 +3,13 @@ use criterion::{criterion_group, criterion_main, Bencher, Criterion};
|
|||
use pyo3::prelude::*;
|
||||
|
||||
fn drop_many_objects(b: &mut Bencher<'_>) {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
b.iter(|| {
|
||||
for _ in 0..1000 {
|
||||
std::mem::drop(py.None());
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
fn criterion_benchmark(c: &mut Criterion) {
|
||||
|
|
|
@ -5,8 +5,7 @@ use pyo3::types::PySet;
|
|||
use std::collections::{BTreeSet, HashSet};
|
||||
|
||||
fn iter_set(b: &mut Bencher<'_>) {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
const LEN: usize = 100_000;
|
||||
let set = PySet::new(py, &(0..LEN).collect::<Vec<_>>()).unwrap();
|
||||
let mut sum = 0;
|
||||
|
@ -16,31 +15,32 @@ fn iter_set(b: &mut Bencher<'_>) {
|
|||
sum += i;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
fn extract_hashset(b: &mut Bencher<'_>) {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
const LEN: usize = 100_000;
|
||||
let set = PySet::new(py, &(0..LEN).collect::<Vec<_>>()).unwrap();
|
||||
b.iter(|| HashSet::<u64>::extract(set));
|
||||
});
|
||||
}
|
||||
|
||||
fn extract_btreeset(b: &mut Bencher<'_>) {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
const LEN: usize = 100_000;
|
||||
let set = PySet::new(py, &(0..LEN).collect::<Vec<_>>()).unwrap();
|
||||
b.iter(|| BTreeSet::<u64>::extract(set));
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(feature = "hashbrown")]
|
||||
fn extract_hashbrown_set(b: &mut Bencher<'_>) {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
const LEN: usize = 100_000;
|
||||
let set = PySet::new(py, &(0..LEN).collect::<Vec<_>>()).unwrap();
|
||||
b.iter(|| hashbrown::HashSet::<u64>::extract(set));
|
||||
});
|
||||
}
|
||||
|
||||
fn criterion_benchmark(c: &mut Criterion) {
|
||||
|
|
|
@ -4,8 +4,7 @@ use pyo3::prelude::*;
|
|||
use pyo3::types::PyTuple;
|
||||
|
||||
fn iter_tuple(b: &mut Bencher<'_>) {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
const LEN: usize = 100_000;
|
||||
let tuple = PyTuple::new(py, 0..LEN);
|
||||
let mut sum = 0;
|
||||
|
@ -15,18 +14,18 @@ fn iter_tuple(b: &mut Bencher<'_>) {
|
|||
sum += i;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
fn tuple_new(b: &mut Bencher<'_>) {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
const LEN: usize = 50_000;
|
||||
b.iter(|| PyTuple::new(py, 0..LEN));
|
||||
});
|
||||
}
|
||||
|
||||
fn tuple_get_item(b: &mut Bencher<'_>) {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
const LEN: usize = 50_000;
|
||||
let tuple = PyTuple::new(py, 0..LEN);
|
||||
let mut sum = 0;
|
||||
|
@ -35,12 +34,12 @@ fn tuple_get_item(b: &mut Bencher<'_>) {
|
|||
sum += tuple.get_item(i).unwrap().extract::<usize>().unwrap();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(not(Py_LIMITED_API))]
|
||||
fn tuple_get_item_unchecked(b: &mut Bencher<'_>) {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
const LEN: usize = 50_000;
|
||||
let tuple = PyTuple::new(py, 0..LEN);
|
||||
let mut sum = 0;
|
||||
|
@ -51,6 +50,7 @@ fn tuple_get_item_unchecked(b: &mut Bencher<'_>) {
|
|||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
fn criterion_benchmark(c: &mut Criterion) {
|
||||
|
|
|
@ -796,12 +796,12 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn set_typeerror() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let err: PyErr = exceptions::PyTypeError::new_err(());
|
||||
err.restore(py);
|
||||
assert!(PyErr::occurred(py));
|
||||
drop(PyErr::fetch(py));
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -41,15 +41,14 @@ impl UnaryArithmetic {
|
|||
|
||||
#[test]
|
||||
fn unary_arithmetic() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
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)'");
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -135,8 +134,7 @@ impl InPlaceOperations {
|
|||
|
||||
#[test]
|
||||
fn inplace_operations() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let init = |value, code| {
|
||||
let c = PyCell::new(py, InPlaceOperations { value }).unwrap();
|
||||
py_run!(py, c, code);
|
||||
|
@ -155,6 +153,7 @@ fn inplace_operations() {
|
|||
3,
|
||||
"d = c; c.__ipow__(4); assert repr(c) == repr(d) == 'IPO(81)'",
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -205,9 +204,7 @@ impl BinaryArithmetic {
|
|||
|
||||
#[test]
|
||||
fn binary_arithmetic() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
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'");
|
||||
|
@ -235,6 +232,7 @@ fn binary_arithmetic() {
|
|||
py_expect_exception!(py, c, "1 ** c", PyTypeError);
|
||||
|
||||
py_run!(py, c, "assert pow(c, 1, 100) == 'BA ** 1 (mod: Some(100))'");
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -281,9 +279,7 @@ impl RhsArithmetic {
|
|||
|
||||
#[test]
|
||||
fn rhs_arithmetic() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
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'");
|
||||
|
@ -303,6 +299,7 @@ fn rhs_arithmetic() {
|
|||
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'");
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -411,9 +408,7 @@ impl LhsAndRhs {
|
|||
|
||||
#[test]
|
||||
fn lhs_fellback_to_rhs() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
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'");
|
||||
|
@ -437,6 +432,7 @@ fn lhs_fellback_to_rhs() {
|
|||
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'");
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -480,9 +476,7 @@ impl RichComparisons2 {
|
|||
|
||||
#[test]
|
||||
fn rich_comparisons() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
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'");
|
||||
|
@ -502,13 +496,12 @@ fn rich_comparisons() {
|
|||
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'");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rich_comparisons_python_3_type_error() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let c2 = PyCell::new(py, RichComparisons2 {}).unwrap();
|
||||
py_expect_exception!(py, c2, "c2 < c2", PyTypeError);
|
||||
py_expect_exception!(py, c2, "c2 < 1", PyTypeError);
|
||||
|
@ -528,6 +521,7 @@ 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);
|
||||
});
|
||||
}
|
||||
|
||||
// Checks that binary operations for which the arguments don't match the
|
||||
|
@ -608,8 +602,7 @@ mod return_not_implemented {
|
|||
}
|
||||
|
||||
fn _test_binary_dunder(dunder: &str) {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let c2 = PyCell::new(py, RichComparisonToSelf {}).unwrap();
|
||||
py_run!(
|
||||
py,
|
||||
|
@ -619,13 +612,13 @@ mod return_not_implemented {
|
|||
dunder
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
fn _test_binary_operator(operator: &str, dunder: &str) {
|
||||
_test_binary_dunder(dunder);
|
||||
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let c2 = PyCell::new(py, RichComparisonToSelf {}).unwrap();
|
||||
py_expect_exception!(
|
||||
py,
|
||||
|
@ -633,6 +626,7 @@ mod return_not_implemented {
|
|||
&format!("class Other: pass\nc2 {} Other()", operator),
|
||||
PyTypeError
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
fn _test_inplace_binary_operator(operator: &str, dunder: &str) {
|
||||
|
|
|
@ -44,13 +44,12 @@ impl PyNumberProtocol for UnaryArithmetic {
|
|||
|
||||
#[test]
|
||||
fn unary_arithmetic() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
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)'");
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -115,8 +114,7 @@ impl PyNumberProtocol for InPlaceOperations {
|
|||
}
|
||||
#[test]
|
||||
fn inplace_operations() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let init = |value, code| {
|
||||
let c = PyCell::new(py, InPlaceOperations { value }).unwrap();
|
||||
py_run!(py, c, code);
|
||||
|
@ -135,6 +133,7 @@ fn inplace_operations() {
|
|||
3,
|
||||
"d = c; c.__ipow__(4); assert repr(c) == repr(d) == 'IPO(81)'",
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[pyproto]
|
||||
|
@ -182,9 +181,7 @@ impl PyNumberProtocol for BinaryArithmetic {
|
|||
|
||||
#[test]
|
||||
fn binary_arithmetic() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
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'");
|
||||
|
@ -211,6 +208,7 @@ fn binary_arithmetic() {
|
|||
py_run!(py, c, "assert 1 ** c == '1 ** BA (mod: None)'");
|
||||
|
||||
py_run!(py, c, "assert pow(c, 1, 100) == 'BA ** 1 (mod: Some(100))'");
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -261,9 +259,7 @@ impl PyNumberProtocol for RhsArithmetic {
|
|||
|
||||
#[test]
|
||||
fn rhs_arithmetic() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
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'");
|
||||
|
@ -285,6 +281,7 @@ fn rhs_arithmetic() {
|
|||
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'");
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -396,9 +393,7 @@ impl PyObjectProtocol for LhsAndRhs {
|
|||
|
||||
#[test]
|
||||
fn lhs_fellback_to_rhs() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
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'");
|
||||
|
@ -424,6 +419,7 @@ fn lhs_fellback_to_rhs() {
|
|||
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'");
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -467,9 +463,7 @@ impl PyObjectProtocol for RichComparisons2 {
|
|||
|
||||
#[test]
|
||||
fn rich_comparisons() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
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'");
|
||||
|
@ -489,13 +483,12 @@ fn rich_comparisons() {
|
|||
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'");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rich_comparisons_python_3_type_error() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let c2 = PyCell::new(py, RichComparisons2 {}).unwrap();
|
||||
py_expect_exception!(py, c2, "c2 < c2", PyTypeError);
|
||||
py_expect_exception!(py, c2, "c2 < 1", PyTypeError);
|
||||
|
@ -515,6 +508,7 @@ 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);
|
||||
});
|
||||
}
|
||||
|
||||
// Checks that binary operations for which the arguments don't match the
|
||||
|
@ -598,8 +592,7 @@ mod return_not_implemented {
|
|||
}
|
||||
|
||||
fn _test_binary_dunder(dunder: &str) {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let c2 = PyCell::new(py, RichComparisonToSelf {}).unwrap();
|
||||
py_run!(
|
||||
py,
|
||||
|
@ -609,13 +602,13 @@ mod return_not_implemented {
|
|||
dunder
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
fn _test_binary_operator(operator: &str, dunder: &str) {
|
||||
_test_binary_dunder(dunder);
|
||||
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let c2 = PyCell::new(py, RichComparisonToSelf {}).unwrap();
|
||||
py_expect_exception!(
|
||||
py,
|
||||
|
@ -623,6 +616,7 @@ mod return_not_implemented {
|
|||
&format!("class Other: pass\nc2 {} Other()", operator),
|
||||
PyTypeError
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
fn _test_inplace_binary_operator(operator: &str, dunder: &str) {
|
||||
|
|
|
@ -87,8 +87,7 @@ fn test_buffer() {
|
|||
let drop_called = Arc::new(AtomicBool::new(false));
|
||||
|
||||
{
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let instance = Py::new(
|
||||
py,
|
||||
TestBufferClass {
|
||||
|
@ -99,6 +98,7 @@ fn test_buffer() {
|
|||
.unwrap();
|
||||
let env = [("ob", instance)].into_py_dict(py);
|
||||
py_assert!(py, *env, "bytes(ob) == b' 23'");
|
||||
});
|
||||
}
|
||||
|
||||
assert!(drop_called.load(Ordering::Relaxed));
|
||||
|
@ -110,8 +110,7 @@ fn test_buffer_referenced() {
|
|||
|
||||
let buf = {
|
||||
let input = vec![b' ', b'2', b'3'];
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let instance: PyObject = TestBufferClass {
|
||||
vec: input.clone(),
|
||||
drop_called: drop_called.clone(),
|
||||
|
@ -122,14 +121,14 @@ fn test_buffer_referenced() {
|
|||
assert_eq!(buf.to_vec(py).unwrap(), input);
|
||||
drop(instance);
|
||||
buf
|
||||
})
|
||||
};
|
||||
|
||||
assert!(!drop_called.load(Ordering::Relaxed));
|
||||
|
||||
{
|
||||
let _py = Python::acquire_gil().python();
|
||||
Python::with_gil(|_| {
|
||||
drop(buf);
|
||||
}
|
||||
});
|
||||
|
||||
assert!(drop_called.load(Ordering::Relaxed));
|
||||
}
|
||||
|
|
|
@ -85,9 +85,7 @@ impl Drop for TestBufferClass {
|
|||
fn test_buffer() {
|
||||
let drop_called = Arc::new(AtomicBool::new(false));
|
||||
|
||||
{
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let instance = Py::new(
|
||||
py,
|
||||
TestBufferClass {
|
||||
|
@ -98,7 +96,7 @@ fn test_buffer() {
|
|||
.unwrap();
|
||||
let env = [("ob", instance)].into_py_dict(py);
|
||||
py_assert!(py, *env, "bytes(ob) == b' 23'");
|
||||
}
|
||||
});
|
||||
|
||||
assert!(drop_called.load(Ordering::Relaxed));
|
||||
}
|
||||
|
@ -107,10 +105,9 @@ fn test_buffer() {
|
|||
fn test_buffer_referenced() {
|
||||
let drop_called = Arc::new(AtomicBool::new(false));
|
||||
|
||||
let buf = {
|
||||
let buf: PyBuffer<u8> = {
|
||||
let input = vec![b' ', b'2', b'3'];
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let instance: PyObject = TestBufferClass {
|
||||
vec: input.clone(),
|
||||
drop_called: drop_called.clone(),
|
||||
|
@ -121,14 +118,14 @@ fn test_buffer_referenced() {
|
|||
assert_eq!(buf.to_vec(py).unwrap(), input);
|
||||
drop(instance);
|
||||
buf
|
||||
})
|
||||
};
|
||||
|
||||
assert!(!drop_called.load(Ordering::Relaxed));
|
||||
|
||||
{
|
||||
let _py = Python::acquire_gil().python();
|
||||
Python::with_gil(|_| {
|
||||
drop(buf);
|
||||
}
|
||||
});
|
||||
|
||||
assert!(drop_called.load(Ordering::Relaxed));
|
||||
}
|
||||
|
|
|
@ -12,11 +12,10 @@ fn bytes_pybytes_conversion(bytes: &[u8]) -> &[u8] {
|
|||
|
||||
#[test]
|
||||
fn test_pybytes_bytes_conversion() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let f = wrap_pyfunction!(bytes_pybytes_conversion)(py).unwrap();
|
||||
py_assert!(py, f, "f(b'Hello World') == b'Hello World'");
|
||||
});
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
|
@ -26,33 +25,26 @@ fn bytes_vec_conversion(py: Python<'_>, bytes: Vec<u8>) -> &PyBytes {
|
|||
|
||||
#[test]
|
||||
fn test_pybytes_vec_conversion() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let f = wrap_pyfunction!(bytes_vec_conversion)(py).unwrap();
|
||||
py_assert!(py, f, "f(b'Hello World') == b'Hello World'");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bytearray_vec_conversion() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let f = wrap_pyfunction!(bytes_vec_conversion)(py).unwrap();
|
||||
py_assert!(py, f, "f(bytearray(b'Hello World')) == b'Hello World'");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_py_as_bytes() {
|
||||
let pyobj: pyo3::Py<pyo3::types::PyBytes>;
|
||||
let data: &[u8];
|
||||
let pyobj: pyo3::Py<pyo3::types::PyBytes> =
|
||||
Python::with_gil(|py| pyo3::types::PyBytes::new(py, b"abc").into_py(py));
|
||||
|
||||
{
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
pyobj = pyo3::types::PyBytes::new(py, b"abc").into_py(py);
|
||||
data = pyobj.as_bytes(py);
|
||||
}
|
||||
let data = Python::with_gil(|py| pyobj.as_bytes(py));
|
||||
|
||||
assert_eq!(data, b"abc");
|
||||
}
|
||||
|
|
|
@ -54,8 +54,7 @@ impl Foo {
|
|||
|
||||
#[test]
|
||||
fn class_attributes() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let foo_obj = py.get_type::<Foo>();
|
||||
py_assert!(py, foo_obj, "foo_obj.MY_CONST == 'foobar'");
|
||||
py_assert!(py, foo_obj, "foo_obj.RENAMED_CONST == 'foobar_2'");
|
||||
|
@ -63,6 +62,7 @@ fn class_attributes() {
|
|||
py_assert!(py, foo_obj, "foo_obj.B == 'bar'");
|
||||
py_assert!(py, foo_obj, "foo_obj.a_foo.x == 1");
|
||||
py_assert!(py, foo_obj, "foo_obj.a_foo_with_py.x == 1");
|
||||
});
|
||||
}
|
||||
|
||||
// Ignored because heap types are not immutable:
|
||||
|
@ -70,10 +70,10 @@ fn class_attributes() {
|
|||
#[test]
|
||||
#[ignore]
|
||||
fn class_attributes_are_immutable() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let foo_obj = py.get_type::<Foo>();
|
||||
py_expect_exception!(py, foo_obj, "foo_obj.a = 6", PyTypeError);
|
||||
});
|
||||
}
|
||||
|
||||
#[pymethods]
|
||||
|
@ -86,14 +86,13 @@ impl Bar {
|
|||
|
||||
#[test]
|
||||
fn recursive_class_attributes() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let foo_obj = py.get_type::<Foo>();
|
||||
let bar_obj = py.get_type::<Bar>();
|
||||
py_assert!(py, foo_obj, "foo_obj.a_foo.x == 1");
|
||||
py_assert!(py, foo_obj, "foo_obj.bar.x == 2");
|
||||
py_assert!(py, bar_obj, "bar_obj.a_foo.x == 3");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -11,13 +11,13 @@ struct EmptyClass {}
|
|||
|
||||
#[test]
|
||||
fn empty_class() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let typeobj = py.get_type::<EmptyClass>();
|
||||
// By default, don't allow creating instances from python.
|
||||
assert!(typeobj.call((), None).is_err());
|
||||
|
||||
py_assert!(py, typeobj, "typeobj.__name__ == 'EmptyClass'");
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -56,9 +56,7 @@ struct ClassWithDocs {
|
|||
|
||||
#[test]
|
||||
fn class_with_docstr() {
|
||||
{
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let typeobj = py.get_type::<ClassWithDocs>();
|
||||
py_run!(
|
||||
py,
|
||||
|
@ -80,7 +78,7 @@ fn class_with_docstr() {
|
|||
typeobj,
|
||||
"assert typeobj.writeonly.__doc__ == 'Write-only property field'"
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass(name = "CustomName")]
|
||||
|
@ -104,8 +102,7 @@ impl EmptyClass2 {
|
|||
|
||||
#[test]
|
||||
fn custom_names() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let typeobj = py.get_type::<EmptyClass2>();
|
||||
py_assert!(py, typeobj, "typeobj.__name__ == 'CustomName'");
|
||||
py_assert!(py, typeobj, "typeobj.custom_fn.__name__ == 'custom_fn'");
|
||||
|
@ -122,6 +119,7 @@ fn custom_names() {
|
|||
py_assert!(py, typeobj, "not hasattr(typeobj, 'bar')");
|
||||
py_assert!(py, typeobj, "not hasattr(typeobj, 'bar_static')");
|
||||
py_assert!(py, typeobj, "not hasattr(typeobj, 'foo')");
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -137,12 +135,12 @@ impl RawIdents {
|
|||
|
||||
#[test]
|
||||
fn test_raw_idents() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let typeobj = py.get_type::<RawIdents>();
|
||||
py_assert!(py, typeobj, "not hasattr(typeobj, 'r#fn')");
|
||||
py_assert!(py, typeobj, "hasattr(typeobj, 'fn')");
|
||||
py_assert!(py, typeobj, "hasattr(typeobj, 'type')");
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -154,8 +152,7 @@ struct EmptyClassInModule {}
|
|||
#[test]
|
||||
#[ignore]
|
||||
fn empty_class_in_module() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let module = PyModule::new(py, "test_module.nested").unwrap();
|
||||
module.add_class::<EmptyClassInModule>().unwrap();
|
||||
|
||||
|
@ -171,6 +168,7 @@ fn empty_class_in_module() {
|
|||
// We currently have no way of determining a canonical module, so builtins is better
|
||||
// than using whatever calls init first.
|
||||
assert_eq!(module, "builtins");
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -191,11 +189,11 @@ impl ClassWithObjectField {
|
|||
|
||||
#[test]
|
||||
fn class_with_object_field() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let ty = py.get_type::<ClassWithObjectField>();
|
||||
py_assert!(py, ty, "ty(5).value == 5");
|
||||
py_assert!(py, ty, "ty(None).value == None");
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass(unsendable, subclass)]
|
||||
|
@ -355,8 +353,7 @@ struct DunderDictSupport {
|
|||
#[test]
|
||||
#[cfg_attr(all(Py_LIMITED_API, not(Py_3_9)), ignore)]
|
||||
fn dunder_dict_support() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let inst = PyCell::new(
|
||||
py,
|
||||
DunderDictSupport {
|
||||
|
@ -372,14 +369,14 @@ fn dunder_dict_support() {
|
|||
assert inst.a == 1
|
||||
"#
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// Accessing inst.__dict__ only supported in limited API from Python 3.10
|
||||
#[test]
|
||||
#[cfg_attr(all(Py_LIMITED_API, not(Py_3_10)), ignore)]
|
||||
fn access_dunder_dict() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let inst = PyCell::new(
|
||||
py,
|
||||
DunderDictSupport {
|
||||
|
@ -395,6 +392,7 @@ fn access_dunder_dict() {
|
|||
assert inst.__dict__ == {'a': 1}
|
||||
"#
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// If the base class has dict support, child class also has dict
|
||||
|
@ -406,8 +404,7 @@ struct InheritDict {
|
|||
#[test]
|
||||
#[cfg_attr(all(Py_LIMITED_API, not(Py_3_9)), ignore)]
|
||||
fn inherited_dict() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let inst = PyCell::new(
|
||||
py,
|
||||
(
|
||||
|
@ -426,6 +423,7 @@ fn inherited_dict() {
|
|||
assert inst.a == 1
|
||||
"#
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass(weakref, dict)]
|
||||
|
@ -437,8 +435,7 @@ struct WeakRefDunderDictSupport {
|
|||
#[test]
|
||||
#[cfg_attr(all(Py_LIMITED_API, not(Py_3_9)), ignore)]
|
||||
fn weakref_dunder_dict_support() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let inst = PyCell::new(
|
||||
py,
|
||||
WeakRefDunderDictSupport {
|
||||
|
@ -451,6 +448,7 @@ fn weakref_dunder_dict_support() {
|
|||
inst,
|
||||
"import weakref; assert weakref.ref(inst)() is inst; inst.a = 1; assert inst.a == 1"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass(weakref, subclass)]
|
||||
|
@ -461,8 +459,7 @@ struct WeakRefSupport {
|
|||
#[test]
|
||||
#[cfg_attr(all(Py_LIMITED_API, not(Py_3_9)), ignore)]
|
||||
fn weakref_support() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let inst = PyCell::new(
|
||||
py,
|
||||
WeakRefSupport {
|
||||
|
@ -475,6 +472,7 @@ fn weakref_support() {
|
|||
inst,
|
||||
"import weakref; assert weakref.ref(inst)() is inst"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// If the base class has weakref support, child class also has weakref.
|
||||
|
@ -486,8 +484,7 @@ struct InheritWeakRef {
|
|||
#[test]
|
||||
#[cfg_attr(all(Py_LIMITED_API, not(Py_3_9)), ignore)]
|
||||
fn inherited_weakref() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let inst = PyCell::new(
|
||||
py,
|
||||
(
|
||||
|
@ -503,4 +500,5 @@ fn inherited_weakref() {
|
|||
inst,
|
||||
"import weakref; assert weakref.ref(inst)() is inst"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -16,9 +16,7 @@ struct Cloneable {
|
|||
fn test_cloneable_pyclass() {
|
||||
let c = Cloneable { x: 10 };
|
||||
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let py_c = Py::new(py, c.clone()).unwrap().to_object(py);
|
||||
|
||||
let c2: Cloneable = py_c.extract(py).unwrap();
|
||||
|
@ -30,6 +28,7 @@ fn test_cloneable_pyclass() {
|
|||
}
|
||||
let mrc: PyRefMut<'_, Cloneable> = py_c.extract(py).unwrap();
|
||||
assert_eq!(&c, &*mrc);
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass(subclass)]
|
||||
|
@ -63,9 +62,7 @@ struct PolymorphicContainer {
|
|||
|
||||
#[test]
|
||||
fn test_polymorphic_container_stores_base_class() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let p = PyCell::new(
|
||||
py,
|
||||
PolymorphicContainer {
|
||||
|
@ -76,13 +73,12 @@ fn test_polymorphic_container_stores_base_class() {
|
|||
.to_object(py);
|
||||
|
||||
py_assert!(py, p, "p.inner.foo() == 'BaseClass'");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_polymorphic_container_stores_sub_class() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let p = PyCell::new(
|
||||
py,
|
||||
PolymorphicContainer {
|
||||
|
@ -104,13 +100,12 @@ fn test_polymorphic_container_stores_sub_class() {
|
|||
.unwrap();
|
||||
|
||||
py_assert!(py, p, "p.inner.foo() == 'SubClass'");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_polymorphic_container_does_not_accept_other_types() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let p = PyCell::new(
|
||||
py,
|
||||
PolymorphicContainer {
|
||||
|
@ -125,13 +120,12 @@ fn test_polymorphic_container_does_not_accept_other_types() {
|
|||
assert!(setattr(1i32.into_py(py)).is_err());
|
||||
assert!(setattr(py.None()).is_err());
|
||||
assert!(setattr((1i32, 2i32).into_py(py)).is_err());
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_pyref_as_base() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let cell = PyCell::new(py, (SubClass {}, BaseClass { value: 120 })).unwrap();
|
||||
|
||||
// First try PyRefMut
|
||||
|
@ -146,13 +140,12 @@ fn test_pyref_as_base() {
|
|||
let sub: PyRef<'_, SubClass> = cell.borrow();
|
||||
let base: PyRef<'_, BaseClass> = sub.into_super();
|
||||
assert_eq!(999, base.value);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_pycell_deref() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let cell = PyCell::new(py, (SubClass {}, BaseClass { value: 120 })).unwrap();
|
||||
|
||||
// Should be able to deref as PyAny
|
||||
|
@ -162,4 +155,5 @@ fn test_pycell_deref() {
|
|||
.unwrap(),
|
||||
"SubClass"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -16,14 +16,14 @@ impl EmptyClassWithNew {
|
|||
|
||||
#[test]
|
||||
fn empty_class_with_new() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let typeobj = py.get_type::<EmptyClassWithNew>();
|
||||
assert!(typeobj
|
||||
.call((), None)
|
||||
.unwrap()
|
||||
.cast_as::<PyCell<EmptyClassWithNew>>()
|
||||
.is_ok());
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -87,13 +87,13 @@ impl NewWithOneArg {
|
|||
|
||||
#[test]
|
||||
fn new_with_one_arg() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let typeobj = py.get_type::<NewWithOneArg>();
|
||||
let wrp = typeobj.call((42,), None).unwrap();
|
||||
let obj = wrp.cast_as::<PyCell<NewWithOneArg>>().unwrap();
|
||||
let obj_ref = obj.borrow();
|
||||
assert_eq!(obj_ref._data, 42);
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -115,8 +115,7 @@ impl NewWithTwoArgs {
|
|||
|
||||
#[test]
|
||||
fn new_with_two_args() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let typeobj = py.get_type::<NewWithTwoArgs>();
|
||||
let wrp = typeobj
|
||||
.call((10, 20), None)
|
||||
|
@ -126,6 +125,7 @@ fn new_with_two_args() {
|
|||
let obj_ref = obj.borrow();
|
||||
assert_eq!(obj_ref._data1, 10);
|
||||
assert_eq!(obj_ref._data2, 20);
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass(subclass)]
|
||||
|
@ -146,8 +146,7 @@ impl SuperClass {
|
|||
/// See https://github.com/PyO3/pyo3/issues/947 for the corresponding bug.
|
||||
#[test]
|
||||
fn subclass_new() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let super_cls = py.get_type::<SuperClass>();
|
||||
let source = pyo3::indoc::indoc!(
|
||||
r#"
|
||||
|
@ -167,6 +166,7 @@ assert c.from_rust is False
|
|||
py.run(source, Some(globals), None)
|
||||
.map_err(|e| e.print(py))
|
||||
.unwrap();
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -191,9 +191,9 @@ impl NewWithCustomError {
|
|||
|
||||
#[test]
|
||||
fn new_with_custom_error() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let typeobj = py.get_type::<NewWithCustomError>();
|
||||
let err = typeobj.call0().unwrap_err();
|
||||
assert_eq!(err.to_string(), "ValueError: custom error");
|
||||
});
|
||||
}
|
||||
|
|
|
@ -55,31 +55,30 @@ macro_rules! assert_check_only {
|
|||
|
||||
#[test]
|
||||
fn test_date_check() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let (obj, sub_obj, sub_sub_obj) = _get_subclasses(py, "date", "2018, 1, 1").unwrap();
|
||||
unsafe { PyDateTime_IMPORT() }
|
||||
assert_check_exact!(PyDate_Check, PyDate_CheckExact, obj);
|
||||
assert_check_only!(PyDate_Check, PyDate_CheckExact, sub_obj);
|
||||
assert_check_only!(PyDate_Check, PyDate_CheckExact, sub_sub_obj);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_time_check() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let (obj, sub_obj, sub_sub_obj) = _get_subclasses(py, "time", "12, 30, 15").unwrap();
|
||||
unsafe { PyDateTime_IMPORT() }
|
||||
|
||||
assert_check_exact!(PyTime_Check, PyTime_CheckExact, obj);
|
||||
assert_check_only!(PyTime_Check, PyTime_CheckExact, sub_obj);
|
||||
assert_check_only!(PyTime_Check, PyTime_CheckExact, sub_sub_obj);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_datetime_check() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let (obj, sub_obj, sub_sub_obj) = _get_subclasses(py, "datetime", "2018, 1, 1, 13, 30, 15")
|
||||
.map_err(|e| e.print(py))
|
||||
.unwrap();
|
||||
|
@ -89,18 +88,19 @@ fn test_datetime_check() {
|
|||
assert_check_exact!(PyDateTime_Check, PyDateTime_CheckExact, obj);
|
||||
assert_check_only!(PyDateTime_Check, PyDateTime_CheckExact, sub_obj);
|
||||
assert_check_only!(PyDateTime_Check, PyDateTime_CheckExact, sub_sub_obj);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_delta_check() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let (obj, sub_obj, sub_sub_obj) = _get_subclasses(py, "timedelta", "1, -3").unwrap();
|
||||
unsafe { PyDateTime_IMPORT() }
|
||||
|
||||
assert_check_exact!(PyDelta_Check, PyDelta_CheckExact, obj);
|
||||
assert_check_only!(PyDelta_Check, PyDelta_CheckExact, sub_obj);
|
||||
assert_check_only!(PyDelta_Check, PyDelta_CheckExact, sub_sub_obj);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -108,8 +108,7 @@ fn test_datetime_utc() {
|
|||
use assert_approx_eq::assert_approx_eq;
|
||||
use pyo3::types::PyDateTime;
|
||||
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let utc = timezone_utc(py);
|
||||
|
||||
let dt = PyDateTime::new(py, 2018, 1, 1, 0, 0, 0, 0, Some(utc)).unwrap();
|
||||
|
@ -122,6 +121,7 @@ fn test_datetime_utc() {
|
|||
.extract()
|
||||
.unwrap();
|
||||
assert_approx_eq!(offset, 0f32);
|
||||
});
|
||||
}
|
||||
|
||||
static INVALID_DATES: &[(i32, u8, u8)] = &[
|
||||
|
@ -143,26 +143,26 @@ static INVALID_TIMES: &[(u8, u8, u8, u32)] =
|
|||
fn test_pydate_out_of_bounds() {
|
||||
use pyo3::types::PyDate;
|
||||
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
for val in INVALID_DATES {
|
||||
let (year, month, day) = val;
|
||||
let dt = PyDate::new(py, *year, *month, *day);
|
||||
dt.unwrap_err();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_pytime_out_of_bounds() {
|
||||
use pyo3::types::PyTime;
|
||||
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
for val in INVALID_TIMES {
|
||||
let (hour, minute, second, microsecond) = val;
|
||||
let dt = PyTime::new(py, *hour, *minute, *second, *microsecond, None);
|
||||
dt.unwrap_err();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -170,8 +170,7 @@ fn test_pydatetime_out_of_bounds() {
|
|||
use pyo3::types::PyDateTime;
|
||||
use std::iter;
|
||||
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let valid_time = (0, 0, 0, 0);
|
||||
let valid_date = (2018, 1, 1);
|
||||
|
||||
|
@ -197,4 +196,5 @@ fn test_pydatetime_out_of_bounds() {
|
|||
);
|
||||
dt.unwrap_err();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -4,8 +4,7 @@ use pyo3::types::IntoPyDict;
|
|||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", ignore)] // Not sure why this fails.
|
||||
fn iter_dict_nosegv() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
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 mut sum = 0;
|
||||
|
@ -14,4 +13,5 @@ fn iter_dict_nosegv() {
|
|||
sum += i;
|
||||
}
|
||||
assert_eq!(sum, 49_999_995_000_000);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -28,12 +28,12 @@ fn return_enum() -> MyEnum {
|
|||
|
||||
#[test]
|
||||
fn test_return_enum() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let f = wrap_pyfunction!(return_enum)(py).unwrap();
|
||||
let mynum = py.get_type::<MyEnum>();
|
||||
|
||||
py_run!(py, f mynum, "assert f() == mynum.Variant")
|
||||
});
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
|
|
|
@ -20,8 +20,7 @@ fn fail_to_open_file() -> PyResult<()> {
|
|||
#[cfg_attr(target_arch = "wasm32", ignore)] // Not sure why this fails.
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
fn test_filenotfounderror() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let fail_to_open_file = wrap_pyfunction!(fail_to_open_file)(py).unwrap();
|
||||
|
||||
py_run!(
|
||||
|
@ -34,6 +33,7 @@ fn test_filenotfounderror() {
|
|||
assert str(e) == "No such file or directory (os error 2)"
|
||||
"#
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -65,9 +65,9 @@ fn call_fail_with_custom_error() -> PyResult<()> {
|
|||
|
||||
#[test]
|
||||
fn test_custom_error() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let call_fail_with_custom_error = wrap_pyfunction!(call_fail_with_custom_error)(py).unwrap();
|
||||
Python::with_gil(|py| {
|
||||
let call_fail_with_custom_error =
|
||||
wrap_pyfunction!(call_fail_with_custom_error)(py).unwrap();
|
||||
|
||||
py_run!(
|
||||
py,
|
||||
|
@ -79,6 +79,7 @@ fn test_custom_error() {
|
|||
assert str(e) == "Oh no!"
|
||||
"#
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -15,27 +15,21 @@ struct ClassWithFreelist {}
|
|||
|
||||
#[test]
|
||||
fn class_with_freelist() {
|
||||
let ptr;
|
||||
{
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let ptr = Python::with_gil(|py| {
|
||||
let inst = Py::new(py, ClassWithFreelist {}).unwrap();
|
||||
let _inst2 = Py::new(py, ClassWithFreelist {}).unwrap();
|
||||
ptr = inst.as_ptr();
|
||||
let ptr = inst.as_ptr();
|
||||
drop(inst);
|
||||
}
|
||||
|
||||
{
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
ptr
|
||||
});
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let inst3 = Py::new(py, ClassWithFreelist {}).unwrap();
|
||||
assert_eq!(ptr, inst3.as_ptr());
|
||||
|
||||
let inst4 = Py::new(py, ClassWithFreelist {}).unwrap();
|
||||
assert_ne!(ptr, inst4.as_ptr())
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
struct TestDropCall {
|
||||
|
@ -60,9 +54,7 @@ fn data_is_dropped() {
|
|||
let drop_called1 = Arc::new(AtomicBool::new(false));
|
||||
let drop_called2 = Arc::new(AtomicBool::new(false));
|
||||
|
||||
{
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let data_is_dropped = DataIsDropped {
|
||||
member1: TestDropCall {
|
||||
drop_called: Arc::clone(&drop_called1),
|
||||
|
@ -75,7 +67,7 @@ fn data_is_dropped() {
|
|||
assert!(!drop_called1.load(Ordering::Relaxed));
|
||||
assert!(!drop_called2.load(Ordering::Relaxed));
|
||||
drop(inst);
|
||||
}
|
||||
});
|
||||
|
||||
assert!(drop_called1.load(Ordering::Relaxed));
|
||||
assert!(drop_called2.load(Ordering::Relaxed));
|
||||
|
@ -95,8 +87,9 @@ impl GcIntegration {
|
|||
}
|
||||
|
||||
fn __clear__(&mut self) {
|
||||
let gil = Python::acquire_gil();
|
||||
self.self_ref = gil.python().None();
|
||||
Python::with_gil(|py| {
|
||||
self.self_ref = py.None();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -104,9 +97,7 @@ impl GcIntegration {
|
|||
fn gc_integration() {
|
||||
let drop_called = Arc::new(AtomicBool::new(false));
|
||||
|
||||
{
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let inst = PyCell::new(
|
||||
py,
|
||||
GcIntegration {
|
||||
|
@ -122,12 +113,12 @@ fn gc_integration() {
|
|||
borrow.self_ref = inst.to_object(py);
|
||||
|
||||
py_run!(py, inst, "import gc; assert inst in gc.get_objects()");
|
||||
}
|
||||
});
|
||||
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
py.run("import gc; gc.collect()", None, None).unwrap();
|
||||
assert!(drop_called.load(Ordering::Relaxed));
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass(subclass)]
|
||||
|
@ -180,9 +171,7 @@ fn inheritance_with_new_methods_with_drop() {
|
|||
let drop_called1 = Arc::new(AtomicBool::new(false));
|
||||
let drop_called2 = Arc::new(AtomicBool::new(false));
|
||||
|
||||
{
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let _typebase = py.get_type::<BaseClassWithDrop>();
|
||||
let typeobj = py.get_type::<SubClassWithDrop>();
|
||||
let inst = typeobj.call((), None).unwrap();
|
||||
|
@ -192,7 +181,7 @@ fn inheritance_with_new_methods_with_drop() {
|
|||
obj_ref_mut.data = Some(Arc::clone(&drop_called1));
|
||||
let base: &mut BaseClassWithDrop = obj_ref_mut.as_mut();
|
||||
base.data = Some(Arc::clone(&drop_called2));
|
||||
}
|
||||
});
|
||||
|
||||
assert!(drop_called1.load(Ordering::Relaxed));
|
||||
assert!(drop_called2.load(Ordering::Relaxed));
|
||||
|
@ -228,9 +217,7 @@ unsafe fn get_type_traverse(tp: *mut pyo3::ffi::PyTypeObject) -> Option<pyo3::ff
|
|||
|
||||
#[test]
|
||||
fn gc_during_borrow() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
unsafe {
|
||||
// declare a dummy visitor function
|
||||
extern "C" fn novisit(
|
||||
|
@ -262,6 +249,7 @@ fn gc_during_borrow() {
|
|||
assert!(!guard.traversed.load(Ordering::Relaxed));
|
||||
drop(guard);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
|
|
@ -17,27 +17,21 @@ struct ClassWithFreelist {}
|
|||
|
||||
#[test]
|
||||
fn class_with_freelist() {
|
||||
let ptr;
|
||||
{
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let ptr = Python::with_gil(|py| {
|
||||
let inst = Py::new(py, ClassWithFreelist {}).unwrap();
|
||||
let _inst2 = Py::new(py, ClassWithFreelist {}).unwrap();
|
||||
ptr = inst.as_ptr();
|
||||
let ptr = inst.as_ptr();
|
||||
drop(inst);
|
||||
}
|
||||
|
||||
{
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
ptr
|
||||
});
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let inst3 = Py::new(py, ClassWithFreelist {}).unwrap();
|
||||
assert_eq!(ptr, inst3.as_ptr());
|
||||
|
||||
let inst4 = Py::new(py, ClassWithFreelist {}).unwrap();
|
||||
assert_ne!(ptr, inst4.as_ptr())
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
struct TestDropCall {
|
||||
|
@ -62,9 +56,7 @@ fn data_is_dropped() {
|
|||
let drop_called1 = Arc::new(AtomicBool::new(false));
|
||||
let drop_called2 = Arc::new(AtomicBool::new(false));
|
||||
|
||||
{
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let data_is_dropped = DataIsDropped {
|
||||
member1: TestDropCall {
|
||||
drop_called: Arc::clone(&drop_called1),
|
||||
|
@ -77,7 +69,7 @@ fn data_is_dropped() {
|
|||
assert!(!drop_called1.load(Ordering::Relaxed));
|
||||
assert!(!drop_called2.load(Ordering::Relaxed));
|
||||
drop(inst);
|
||||
}
|
||||
});
|
||||
|
||||
assert!(drop_called1.load(Ordering::Relaxed));
|
||||
assert!(drop_called2.load(Ordering::Relaxed));
|
||||
|
@ -97,8 +89,9 @@ impl PyGCProtocol for GcIntegration {
|
|||
}
|
||||
|
||||
fn __clear__(&mut self) {
|
||||
let gil = Python::acquire_gil();
|
||||
self.self_ref = gil.python().None();
|
||||
Python::with_gil(|py| {
|
||||
self.self_ref = py.None();
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -106,9 +99,7 @@ impl PyGCProtocol for GcIntegration {
|
|||
fn gc_integration() {
|
||||
let drop_called = Arc::new(AtomicBool::new(false));
|
||||
|
||||
{
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let inst = PyCell::new(
|
||||
py,
|
||||
GcIntegration {
|
||||
|
@ -122,12 +113,12 @@ fn gc_integration() {
|
|||
|
||||
let mut borrow = inst.borrow_mut();
|
||||
borrow.self_ref = inst.to_object(py);
|
||||
}
|
||||
});
|
||||
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
py.run("import gc; gc.collect()", None, None).unwrap();
|
||||
assert!(drop_called.load(Ordering::Relaxed));
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -143,10 +134,10 @@ impl PyGCProtocol for GcIntegration2 {
|
|||
|
||||
#[test]
|
||||
fn gc_integration2() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let inst = PyCell::new(py, GcIntegration2 {}).unwrap();
|
||||
py_run!(py, inst, "import gc; assert inst in gc.get_objects()");
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass(subclass)]
|
||||
|
@ -199,9 +190,7 @@ fn inheritance_with_new_methods_with_drop() {
|
|||
let drop_called1 = Arc::new(AtomicBool::new(false));
|
||||
let drop_called2 = Arc::new(AtomicBool::new(false));
|
||||
|
||||
{
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let _typebase = py.get_type::<BaseClassWithDrop>();
|
||||
let typeobj = py.get_type::<SubClassWithDrop>();
|
||||
let inst = typeobj.call((), None).unwrap();
|
||||
|
@ -211,7 +200,7 @@ fn inheritance_with_new_methods_with_drop() {
|
|||
obj_ref_mut.data = Some(Arc::clone(&drop_called1));
|
||||
let base: &mut BaseClassWithDrop = obj_ref_mut.as_mut();
|
||||
base.data = Some(Arc::clone(&drop_called2));
|
||||
}
|
||||
});
|
||||
|
||||
assert!(drop_called1.load(Ordering::Relaxed));
|
||||
assert!(drop_called2.load(Ordering::Relaxed));
|
||||
|
@ -245,9 +234,7 @@ unsafe fn get_type_traverse(tp: *mut pyo3::ffi::PyTypeObject) -> Option<pyo3::ff
|
|||
|
||||
#[test]
|
||||
fn gc_during_borrow() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
unsafe {
|
||||
// declare a dummy visitor function
|
||||
extern "C" fn novisit(
|
||||
|
@ -279,4 +266,5 @@ fn gc_during_borrow() {
|
|||
assert!(!guard.traversed.load(Ordering::Relaxed));
|
||||
drop(guard);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -46,9 +46,7 @@ impl ClassWithProperties {
|
|||
|
||||
#[test]
|
||||
fn class_with_properties() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let inst = Py::new(py, ClassWithProperties { num: 10 }).unwrap();
|
||||
|
||||
py_run!(py, inst, "assert inst.get_num() == 10");
|
||||
|
@ -65,6 +63,7 @@ fn class_with_properties() {
|
|||
|
||||
let d = [("C", py.get_type::<ClassWithProperties>())].into_py_dict(py);
|
||||
py_assert!(py, *d, "C.DATA.__doc__ == 'a getter for data'");
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -84,9 +83,7 @@ impl GetterSetter {
|
|||
|
||||
#[test]
|
||||
fn getter_setter_autogen() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let inst = Py::new(
|
||||
py,
|
||||
GetterSetter {
|
||||
|
@ -103,6 +100,7 @@ fn getter_setter_autogen() {
|
|||
inst,
|
||||
"assert inst.text == 'Hello'; inst.text = 'There'; assert inst.text == 'There'"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -126,13 +124,12 @@ impl RefGetterSetter {
|
|||
#[test]
|
||||
fn ref_getter_setter() {
|
||||
// Regression test for #837
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
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");
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -153,12 +150,11 @@ impl TupleClassGetterSetter {
|
|||
|
||||
#[test]
|
||||
fn tuple_struct_getter_setter() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let inst = Py::new(py, TupleClassGetterSetter(10)).unwrap();
|
||||
|
||||
py_assert!(py, inst, "inst.num == 10");
|
||||
py_run!(py, inst, "inst.num = 20");
|
||||
py_assert!(py, inst, "inst.num == 20");
|
||||
});
|
||||
}
|
||||
|
|
|
@ -18,8 +18,7 @@ struct SubclassAble {}
|
|||
|
||||
#[test]
|
||||
fn subclass() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let d = [("SubclassAble", py.get_type::<SubclassAble>())].into_py_dict(py);
|
||||
|
||||
py.run(
|
||||
|
@ -29,6 +28,7 @@ fn subclass() {
|
|||
)
|
||||
.map_err(|e| e.print(py))
|
||||
.unwrap();
|
||||
});
|
||||
}
|
||||
|
||||
#[pymethods]
|
||||
|
@ -70,17 +70,16 @@ impl SubClass {
|
|||
|
||||
#[test]
|
||||
fn inheritance_with_new_methods() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let typeobj = py.get_type::<SubClass>();
|
||||
let inst = typeobj.call((), None).unwrap();
|
||||
py_run!(py, inst, "assert inst.val1 == 10; assert inst.val2 == 5");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn call_base_and_sub_methods() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let obj = PyCell::new(py, SubClass::new()).unwrap();
|
||||
py_run!(
|
||||
py,
|
||||
|
@ -90,25 +89,24 @@ fn call_base_and_sub_methods() {
|
|||
assert obj.sub_method(10) == 50
|
||||
"#
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mutation_fails() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let obj = PyCell::new(py, SubClass::new()).unwrap();
|
||||
let global = Some([("obj", obj)].into_py_dict(py));
|
||||
let e = py
|
||||
.run("obj.base_set(lambda: obj.sub_set_and_ret(1))", global, None)
|
||||
.unwrap_err();
|
||||
assert_eq!(&e.to_string(), "RuntimeError: Already borrowed")
|
||||
assert_eq!(&e.to_string(), "RuntimeError: Already borrowed");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn is_subclass_and_is_instance() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let sub_ty = SubClass::type_object(py);
|
||||
let base_ty = BaseClass::type_object(py);
|
||||
assert!(sub_ty.is_subclass_of::<BaseClass>().unwrap());
|
||||
|
@ -119,6 +117,7 @@ fn is_subclass_and_is_instance() {
|
|||
assert!(obj.is_instance_of::<BaseClass>().unwrap());
|
||||
assert!(obj.is_instance(sub_ty).unwrap());
|
||||
assert!(obj.is_instance(base_ty).unwrap());
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass(subclass)]
|
||||
|
@ -150,8 +149,7 @@ impl SubClass2 {
|
|||
|
||||
#[test]
|
||||
fn handle_result_in_new() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let subclass = py.get_type::<SubClass2>();
|
||||
py_run!(
|
||||
py,
|
||||
|
@ -166,6 +164,7 @@ except Exception as e:
|
|||
raise e
|
||||
"#
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// Subclassing builtin types is not allowed in the LIMITED API.
|
||||
|
@ -197,14 +196,14 @@ mod inheriting_native_type {
|
|||
}
|
||||
}
|
||||
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let set_sub = pyo3::PyCell::new(py, SetWithName::new()).unwrap();
|
||||
py_run!(
|
||||
py,
|
||||
set_sub,
|
||||
r#"set_sub.add(10); assert list(set_sub) == [10]; assert set_sub.name == "Hello :)""#
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass(extends=PyDict)]
|
||||
|
@ -224,14 +223,14 @@ mod inheriting_native_type {
|
|||
|
||||
#[test]
|
||||
fn inherit_dict() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let dict_sub = pyo3::PyCell::new(py, DictWithName::new()).unwrap();
|
||||
py_run!(
|
||||
py,
|
||||
dict_sub,
|
||||
r#"dict_sub[0] = 1; assert dict_sub[0] == 1; assert dict_sub.name == "Hello :)""#
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -75,20 +75,19 @@ fn map_dict(py: Python<'_>) -> &pyo3::types::PyDict {
|
|||
|
||||
#[test]
|
||||
fn test_getitem() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let d = map_dict(py);
|
||||
|
||||
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();
|
||||
Python::with_gil(|py| {
|
||||
let d = map_dict(py);
|
||||
|
||||
py_run!(py, *d, "m['1'] = 4; assert m['1'] == 4");
|
||||
|
@ -96,13 +95,12 @@ fn test_setitem() {
|
|||
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]
|
||||
fn test_delitem() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let d = map_dict(py);
|
||||
py_run!(
|
||||
py,
|
||||
|
@ -111,6 +109,7 @@ fn test_delitem() {
|
|||
);
|
||||
py_expect_exception!(py, *d, "del m[-1]", PyTypeError);
|
||||
py_expect_exception!(py, *d, "del m['4']", PyKeyError);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -72,20 +72,19 @@ fn map_dict(py: Python<'_>) -> &pyo3::types::PyDict {
|
|||
|
||||
#[test]
|
||||
fn test_getitem() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let d = map_dict(py);
|
||||
|
||||
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();
|
||||
Python::with_gil(|py| {
|
||||
let d = map_dict(py);
|
||||
|
||||
py_run!(py, *d, "m['1'] = 4; assert m['1'] == 4");
|
||||
|
@ -93,13 +92,12 @@ fn test_setitem() {
|
|||
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]
|
||||
fn test_delitem() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let d = map_dict(py);
|
||||
py_run!(
|
||||
py,
|
||||
|
@ -108,4 +106,5 @@ fn test_delitem() {
|
|||
);
|
||||
py_expect_exception!(py, *d, "del m[-1]", PyTypeError);
|
||||
py_expect_exception!(py, *d, "del m['4']", PyKeyError);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -27,15 +27,14 @@ impl InstanceMethod {
|
|||
|
||||
#[test]
|
||||
fn instance_method() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let obj = PyCell::new(py, InstanceMethod { member: 42 }).unwrap();
|
||||
let obj_ref = obj.borrow();
|
||||
assert_eq!(obj_ref.method(), 42);
|
||||
py_assert!(py, obj, "obj.method() == 42");
|
||||
py_assert!(py, obj, "obj.add_other(obj) == 84");
|
||||
py_assert!(py, obj, "obj.method.__doc__ == 'Test method'");
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -52,14 +51,13 @@ impl InstanceMethodWithArgs {
|
|||
|
||||
#[test]
|
||||
fn instance_method_with_args() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let obj = PyCell::new(py, InstanceMethodWithArgs { member: 7 }).unwrap();
|
||||
let obj_ref = obj.borrow();
|
||||
assert_eq!(obj_ref.method(6), 42);
|
||||
py_assert!(py, obj, "obj.method(3) == 21");
|
||||
py_assert!(py, obj, "obj.method(multiplier=6) == 42");
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -81,14 +79,13 @@ impl ClassMethod {
|
|||
|
||||
#[test]
|
||||
fn class_method() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let d = [("C", py.get_type::<ClassMethod>())].into_py_dict(py);
|
||||
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]
|
||||
|
@ -104,15 +101,14 @@ impl ClassMethodWithArgs {
|
|||
|
||||
#[test]
|
||||
fn class_method_with_args() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let d = [("C", py.get_type::<ClassMethodWithArgs>())].into_py_dict(py);
|
||||
py_assert!(
|
||||
py,
|
||||
*d,
|
||||
"C.method('abc') == 'ClassMethodWithArgs.method(abc)'"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -134,9 +130,7 @@ impl StaticMethod {
|
|||
|
||||
#[test]
|
||||
fn static_method() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
assert_eq!(StaticMethod::method(py), "StaticMethod.method()!");
|
||||
|
||||
let d = [("C", py.get_type::<StaticMethod>())].into_py_dict(py);
|
||||
|
@ -144,6 +138,7 @@ fn static_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]
|
||||
|
@ -159,13 +154,12 @@ impl StaticMethodWithArgs {
|
|||
|
||||
#[test]
|
||||
fn static_method_with_args() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
assert_eq!(StaticMethodWithArgs::method(py, 1234), "0x4d2");
|
||||
|
||||
let d = [("C", py.get_type::<StaticMethodWithArgs>())].into_py_dict(py);
|
||||
py_assert!(py, *d, "C.method(1337) == '0x539'");
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -305,8 +299,7 @@ impl MethArgs {
|
|||
|
||||
#[test]
|
||||
fn meth_args() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let inst = Py::new(py, MethArgs {}).unwrap();
|
||||
|
||||
py_run!(py, inst, "assert inst.get_optional() == 10");
|
||||
|
@ -614,6 +607,7 @@ fn meth_args() {
|
|||
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");
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -638,8 +632,7 @@ impl MethDocs {
|
|||
|
||||
#[test]
|
||||
fn meth_doc() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let d = [("C", py.get_type::<MethDocs>())].into_py_dict(py);
|
||||
py_assert!(py, *d, "C.__doc__ == 'A class with \"documentation\".'");
|
||||
py_assert!(
|
||||
|
@ -652,6 +645,7 @@ fn meth_doc() {
|
|||
*d,
|
||||
"C.x.__doc__ == '`int`: a very \"important\" member of \\'this\\' instance.'"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -672,14 +666,14 @@ impl MethodWithLifeTime {
|
|||
|
||||
#[test]
|
||||
fn method_with_lifetime() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let obj = PyCell::new(py, MethodWithLifeTime {}).unwrap();
|
||||
py_run!(
|
||||
py,
|
||||
obj,
|
||||
"assert obj.set_to_list(set((1, 2, 3))) == [1, 2, 3]"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -720,8 +714,7 @@ impl MethodWithPyClassArg {
|
|||
|
||||
#[test]
|
||||
fn method_with_pyclassarg() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
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);
|
||||
|
@ -749,6 +742,7 @@ fn method_with_pyclassarg() {
|
|||
*d,
|
||||
"obj1.optional_inplace_add(obj2); assert obj2.value == 40"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -783,8 +777,7 @@ impl CfgStruct {
|
|||
|
||||
#[test]
|
||||
fn test_cfg_attrs() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let inst = Py::new(py, CfgStruct {}).unwrap();
|
||||
|
||||
#[cfg(unix)]
|
||||
|
@ -800,6 +793,7 @@ fn test_cfg_attrs() {
|
|||
}
|
||||
|
||||
py_assert!(py, inst, "not hasattr(inst, 'never_compiled_method')");
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -825,10 +819,10 @@ impl FromSequence {
|
|||
|
||||
#[test]
|
||||
fn test_from_sequence() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let typeobj = py.get_type::<FromSequence>();
|
||||
py_assert!(py, typeobj, "typeobj(range(0, 4)).numbers == [0, 1, 2, 3]")
|
||||
py_assert!(py, typeobj, "typeobj(range(0, 4)).numbers == [0, 1, 2, 3]");
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
|
|
@ -67,9 +67,7 @@ fn module_with_functions(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
|
|||
fn test_module_with_functions() {
|
||||
use pyo3::wrap_pymodule;
|
||||
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let d = [(
|
||||
"module_with_functions",
|
||||
wrap_pymodule!(module_with_functions)(py),
|
||||
|
@ -112,6 +110,7 @@ fn test_module_with_functions() {
|
|||
*d,
|
||||
"module_with_functions.with_module() == 'module_with_functions'"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[pymodule]
|
||||
|
@ -125,19 +124,16 @@ fn some_name(_: Python<'_>, m: &PyModule) -> PyResult<()> {
|
|||
fn test_module_renaming() {
|
||||
use pyo3::wrap_pymodule;
|
||||
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let d = [("different_name", wrap_pymodule!(some_name)(py))].into_py_dict(py);
|
||||
|
||||
py_run!(py, *d, "assert different_name.__name__ == 'other_name'");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_module_from_code() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let adder_mod = PyModule::from_code(
|
||||
py,
|
||||
"def add(a,b):\n\treturn a+b",
|
||||
|
@ -158,6 +154,7 @@ fn test_module_from_code() {
|
|||
.expect("The value should be able to be converted to an i32");
|
||||
|
||||
assert_eq!(ret_value, 3);
|
||||
});
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
|
@ -174,12 +171,11 @@ fn raw_ident_module(_py: Python<'_>, module: &PyModule) -> PyResult<()> {
|
|||
fn test_raw_idents() {
|
||||
use pyo3::wrap_pymodule;
|
||||
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let module = wrap_pymodule!(raw_ident_module)(py);
|
||||
|
||||
py_assert!(py, module, "module.move() == 42");
|
||||
});
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
|
@ -197,31 +193,30 @@ fn foobar_module(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
|
|||
|
||||
#[test]
|
||||
fn test_custom_names() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let module = pyo3::wrap_pymodule!(foobar_module)(py);
|
||||
|
||||
py_assert!(py, module, "not hasattr(module, 'custom_named_fn')");
|
||||
py_assert!(py, module, "module.foobar() == 42");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_module_dict() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let module = pyo3::wrap_pymodule!(foobar_module)(py);
|
||||
|
||||
py_assert!(py, module, "module.yay == 'me'");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_module_dunder_all() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let module = pyo3::wrap_pymodule!(foobar_module)(py);
|
||||
|
||||
py_assert!(py, module, "module.__all__ == ['foobar']");
|
||||
});
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
|
@ -261,8 +256,7 @@ fn supermodule(py: Python<'_>, module: &PyModule) -> PyResult<()> {
|
|||
fn test_module_nesting() {
|
||||
use pyo3::wrap_pymodule;
|
||||
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let supermodule = wrap_pymodule!(supermodule)(py);
|
||||
|
||||
py_assert!(
|
||||
|
@ -280,6 +274,7 @@ fn test_module_nesting() {
|
|||
supermodule,
|
||||
"supermodule.submodule_with_init_fn.subfunction() == 'Subfunction'"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// Test that argument parsing specification works for pyfunctions
|
||||
|
@ -302,8 +297,7 @@ fn vararg_module(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
|
|||
|
||||
#[test]
|
||||
fn test_vararg_module() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let m = pyo3::wrap_pymodule!(vararg_module)(py);
|
||||
|
||||
py_assert!(py, m, "m.ext_vararg_fn() == [5, ()]");
|
||||
|
@ -311,6 +305,7 @@ fn test_vararg_module() {
|
|||
|
||||
py_assert!(py, m, "m.int_vararg_fn() == [5, ()]");
|
||||
py_assert!(py, m, "m.int_vararg_fn(1, 2) == [1, (2,)]");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -397,8 +392,7 @@ fn module_with_functions_with_module(_py: Python<'_>, m: &PyModule) -> PyResult<
|
|||
|
||||
#[test]
|
||||
fn test_module_functions_with_module() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let m = pyo3::wrap_pymodule!(module_with_functions_with_module)(py);
|
||||
py_assert!(
|
||||
py,
|
||||
|
@ -427,6 +421,7 @@ fn test_module_functions_with_module() {
|
|||
m,
|
||||
"m.pyfunction_with_pass_module_in_attribute() == 'module_with_functions_with_module'"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -377,9 +377,7 @@ impl Iterator {
|
|||
|
||||
#[test]
|
||||
fn iterator() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let inst = Py::new(
|
||||
py,
|
||||
Iterator {
|
||||
|
@ -389,6 +387,7 @@ fn iterator() {
|
|||
.unwrap();
|
||||
py_assert!(py, inst, "iter(inst) is inst");
|
||||
py_assert!(py, inst, "list(inst) == [5, 6, 7]");
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -406,15 +405,14 @@ struct NotCallable;
|
|||
|
||||
#[test]
|
||||
fn callable() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let c = Py::new(py, Callable).unwrap();
|
||||
py_assert!(py, c, "callable(c)");
|
||||
py_assert!(py, c, "c(7) == 42");
|
||||
|
||||
let nc = Py::new(py, NotCallable).unwrap();
|
||||
py_assert!(py, nc, "not callable(nc)");
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -434,9 +432,7 @@ impl SetItem {
|
|||
|
||||
#[test]
|
||||
fn setitem() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let c = PyCell::new(py, SetItem { key: 0, val: 0 }).unwrap();
|
||||
py_run!(py, c, "c[1] = 2");
|
||||
{
|
||||
|
@ -445,6 +441,7 @@ fn setitem() {
|
|||
assert_eq!(c.val, 2);
|
||||
}
|
||||
py_expect_exception!(py, c, "del c[1]", PyNotImplementedError);
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -461,9 +458,7 @@ impl DelItem {
|
|||
|
||||
#[test]
|
||||
fn delitem() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let c = PyCell::new(py, DelItem { key: 0 }).unwrap();
|
||||
py_run!(py, c, "del c[1]");
|
||||
{
|
||||
|
@ -471,6 +466,7 @@ fn delitem() {
|
|||
assert_eq!(c.key, 1);
|
||||
}
|
||||
py_expect_exception!(py, c, "c[1] = 2", PyNotImplementedError);
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -491,9 +487,7 @@ impl SetDelItem {
|
|||
|
||||
#[test]
|
||||
fn setdelitem() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let c = PyCell::new(py, SetDelItem { val: None }).unwrap();
|
||||
py_run!(py, c, "c[1] = 2");
|
||||
{
|
||||
|
@ -503,6 +497,7 @@ fn setdelitem() {
|
|||
py_run!(py, c, "del c[1]");
|
||||
let c = c.borrow();
|
||||
assert_eq!(c.val, None);
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -517,13 +512,12 @@ impl Contains {
|
|||
|
||||
#[test]
|
||||
fn contains() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
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_expect_exception!(py, c, "assert 'wrong type' not in c", PyTypeError);
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -548,13 +542,12 @@ impl GetItem {
|
|||
|
||||
#[test]
|
||||
fn test_getitem() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let ob = Py::new(py, GetItem {}).unwrap();
|
||||
|
||||
py_assert!(py, ob, "ob[1] == 'int'");
|
||||
py_assert!(py, ob, "ob[100:200:1] == 'slice'");
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -572,11 +565,11 @@ impl ClassWithGetAttr {
|
|||
|
||||
#[test]
|
||||
fn getattr_doesnt_override_member() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let inst = PyCell::new(py, ClassWithGetAttr { data: 4 }).unwrap();
|
||||
py_assert!(py, inst, "inst.data == 4");
|
||||
py_assert!(py, inst, "inst.a == 8");
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -594,11 +587,11 @@ impl ClassWithGetAttribute {
|
|||
|
||||
#[test]
|
||||
fn getattribute_overrides_member() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let inst = PyCell::new(py, ClassWithGetAttribute { data: 4 }).unwrap();
|
||||
py_assert!(py, inst, "inst.data == 8");
|
||||
py_assert!(py, inst, "inst.y == 8");
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -627,13 +620,13 @@ impl ClassWithGetAttrAndGetAttribute {
|
|||
|
||||
#[test]
|
||||
fn getattr_and_getattribute() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let inst = PyCell::new(py, ClassWithGetAttrAndGetAttribute).unwrap();
|
||||
py_assert!(py, inst, "inst.exists == 42");
|
||||
py_assert!(py, inst, "inst.lucky == 57");
|
||||
py_expect_exception!(py, inst, "inst.error", PyValueError);
|
||||
py_expect_exception!(py, inst, "inst.unlucky", PyAttributeError);
|
||||
});
|
||||
}
|
||||
|
||||
/// Wraps a Python future and yield it once.
|
||||
|
@ -674,8 +667,7 @@ impl OnceFuture {
|
|||
#[test]
|
||||
#[cfg(not(target_arch = "wasm32"))] // Won't work without wasm32 event loop (e.g., Pyodide has WebLoop)
|
||||
fn test_await() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let once = py.get_type::<OnceFuture>();
|
||||
let source = r#"
|
||||
import asyncio
|
||||
|
@ -696,6 +688,7 @@ asyncio.run(main())
|
|||
py.run(source, Some(globals), None)
|
||||
.map_err(|e| e.print(py))
|
||||
.unwrap();
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -724,8 +717,7 @@ impl AsyncIterator {
|
|||
#[test]
|
||||
#[cfg(not(target_arch = "wasm32"))] // Won't work without wasm32 event loop (e.g., Pyodide has WebLoop)
|
||||
fn test_anext_aiter() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let once = py.get_type::<OnceFuture>();
|
||||
let source = r#"
|
||||
import asyncio
|
||||
|
@ -753,6 +745,7 @@ asyncio.run(main())
|
|||
py.run(source, Some(globals), None)
|
||||
.map_err(|e| e.print(py))
|
||||
.unwrap();
|
||||
});
|
||||
}
|
||||
|
||||
/// Increment the count when `__get__` is called.
|
||||
|
@ -789,8 +782,7 @@ impl DescrCounter {
|
|||
|
||||
#[test]
|
||||
fn descr_getset() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let counter = py.get_type::<DescrCounter>();
|
||||
let source = pyo3::indoc::indoc!(
|
||||
r#"
|
||||
|
@ -822,6 +814,7 @@ assert c.counter.count == 1
|
|||
py.run(source, Some(globals), None)
|
||||
.map_err(|e| e.print(py))
|
||||
.unwrap();
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
|
|
@ -17,14 +17,14 @@ fn optional_bool(arg: Option<bool>) -> String {
|
|||
#[test]
|
||||
fn test_optional_bool() {
|
||||
// Regression test for issue #932
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let f = wrap_pyfunction!(optional_bool)(py).unwrap();
|
||||
|
||||
py_assert!(py, f, "f() == 'Some(true)'");
|
||||
py_assert!(py, f, "f(True) == 'Some(true)'");
|
||||
py_assert!(py, f, "f(False) == 'Some(false)'");
|
||||
py_assert!(py, f, "f(None) == 'None'");
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(not(Py_LIMITED_API))]
|
||||
|
@ -41,8 +41,7 @@ fn buffer_inplace_add(py: Python<'_>, x: PyBuffer<i32>, y: PyBuffer<i32>) {
|
|||
#[cfg(not(Py_LIMITED_API))]
|
||||
#[test]
|
||||
fn test_buffer_add() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let f = wrap_pyfunction!(buffer_inplace_add)(py).unwrap();
|
||||
|
||||
py_expect_exception!(
|
||||
|
@ -68,6 +67,7 @@ f(a, b)
|
|||
assert a, array.array("i", [2, 4, 6, 8])
|
||||
"#
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(not(Py_LIMITED_API))]
|
||||
|
@ -83,8 +83,7 @@ fn function_with_pycfunction_arg(fun: &PyCFunction) -> PyResult<&PyAny> {
|
|||
|
||||
#[test]
|
||||
fn test_functions_with_function_args() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let py_cfunc_arg = wrap_pyfunction!(function_with_pycfunction_arg)(py).unwrap();
|
||||
let bool_to_string = wrap_pyfunction!(optional_bool)(py).unwrap();
|
||||
|
||||
|
@ -110,6 +109,7 @@ fn test_functions_with_function_args() {
|
|||
"#
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(not(Py_LIMITED_API))]
|
||||
|
@ -131,9 +131,7 @@ fn function_with_custom_conversion(
|
|||
#[cfg(not(Py_LIMITED_API))]
|
||||
#[test]
|
||||
fn test_function_with_custom_conversion() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let custom_conv_func = wrap_pyfunction!(function_with_custom_conversion)(py).unwrap();
|
||||
|
||||
pyo3::py_run!(
|
||||
|
@ -146,14 +144,13 @@ fn test_function_with_custom_conversion() {
|
|||
assert custom_conv_func(dt) == 1612040400
|
||||
"#
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(not(Py_LIMITED_API))]
|
||||
#[test]
|
||||
fn test_function_with_custom_conversion_error() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let custom_conv_func = wrap_pyfunction!(function_with_custom_conversion)(py).unwrap();
|
||||
|
||||
py_expect_exception!(
|
||||
|
@ -163,6 +160,7 @@ fn test_function_with_custom_conversion_error() {
|
|||
PyTypeError,
|
||||
"argument 'timestamp': 'list' object cannot be converted to 'PyDateTime'"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -188,9 +186,7 @@ fn conversion_error(
|
|||
|
||||
#[test]
|
||||
fn test_conversion_error() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let conversion_error = wrap_pyfunction!(conversion_error)(py).unwrap();
|
||||
py_expect_exception!(
|
||||
py,
|
||||
|
@ -258,6 +254,7 @@ conversion_error('string1', -100, ('string2', 10.), None, ValueClass(-5))",
|
|||
"TypeError: argument 'struct_arg': failed to \
|
||||
extract field ValueClass.value: OverflowError: can't convert negative int to unsigned"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/// Helper function that concatenates the error message from
|
||||
|
@ -277,9 +274,7 @@ fn extract_traceback(py: Python<'_>, mut error: PyErr) -> String {
|
|||
fn test_pycfunction_new() {
|
||||
use pyo3::ffi;
|
||||
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
unsafe extern "C" fn c_fn(
|
||||
_self: *mut ffi::PyObject,
|
||||
_args: *mut ffi::PyObject,
|
||||
|
@ -301,6 +296,7 @@ fn test_pycfunction_new() {
|
|||
py_fn,
|
||||
"py_fn.__doc__ == 'py_fn for test (this is the docstring)'"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -310,9 +306,7 @@ fn test_pycfunction_new_with_keywords() {
|
|||
use std::os::raw::{c_char, c_long};
|
||||
use std::ptr;
|
||||
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
unsafe extern "C" fn c_fn(
|
||||
_self: *mut ffi::PyObject,
|
||||
args: *mut ffi::PyObject,
|
||||
|
@ -333,7 +327,14 @@ fn test_pycfunction_new_with_keywords() {
|
|||
|
||||
let arg_pattern: *const c_char = CString::new("l|l").unwrap().into_raw();
|
||||
|
||||
ffi::PyArg_ParseTupleAndKeywords(args, kwds, arg_pattern, arglist_ptr, foo_ptr, bar_ptr);
|
||||
ffi::PyArg_ParseTupleAndKeywords(
|
||||
args,
|
||||
kwds,
|
||||
arg_pattern,
|
||||
arglist_ptr,
|
||||
foo_ptr,
|
||||
bar_ptr,
|
||||
);
|
||||
|
||||
ffi::PyLong_FromLong(foo * bar)
|
||||
}
|
||||
|
@ -353,16 +354,14 @@ fn test_pycfunction_new_with_keywords() {
|
|||
py_fn,
|
||||
"py_fn.__doc__ == 'py_fn for test (this is the docstring)'"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_closure() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let f = |args: &types::PyTuple, _kwargs: Option<&types::PyDict>| -> PyResult<_> {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let res: Vec<_> = args
|
||||
.iter()
|
||||
.map(|elem| {
|
||||
|
@ -379,6 +378,7 @@ fn test_closure() {
|
|||
})
|
||||
.collect();
|
||||
Ok(res)
|
||||
})
|
||||
};
|
||||
let closure_py = PyCFunction::new_closure(f, py).unwrap();
|
||||
|
||||
|
@ -388,13 +388,12 @@ fn test_closure() {
|
|||
closure_py,
|
||||
"closure_py(42, 3.14, 'foo') == [43, 6.28, 'foo-py']"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_closure_counter() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let counter = std::cell::RefCell::new(0);
|
||||
let counter_fn =
|
||||
move |_args: &types::PyTuple, _kwargs: Option<&types::PyDict>| -> PyResult<i32> {
|
||||
|
@ -407,6 +406,7 @@ fn test_closure_counter() {
|
|||
py_assert!(py, counter_py, "counter_py() == 1");
|
||||
py_assert!(py, counter_py, "counter_py() == 2");
|
||||
py_assert!(py, counter_py, "counter_py() == 3");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -29,9 +29,7 @@ impl PyMappingProtocol for Len {
|
|||
|
||||
#[test]
|
||||
fn len() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let inst = Py::new(py, Len { l: 10 }).unwrap();
|
||||
py_assert!(py, inst, "len(inst) == 10");
|
||||
unsafe {
|
||||
|
@ -47,6 +45,7 @@ fn len() {
|
|||
)
|
||||
.unwrap();
|
||||
py_expect_exception!(py, inst, "len(inst)", PyOverflowError);
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -67,9 +66,7 @@ impl PyIterProtocol for Iterator {
|
|||
|
||||
#[test]
|
||||
fn iterator() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let inst = Py::new(
|
||||
py,
|
||||
Iterator {
|
||||
|
@ -79,6 +76,7 @@ fn iterator() {
|
|||
.unwrap();
|
||||
py_assert!(py, inst, "iter(inst) is inst");
|
||||
py_assert!(py, inst, "list(inst) == [5, 6, 7]");
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -97,12 +95,11 @@ impl PyObjectProtocol for StringMethods {
|
|||
|
||||
#[test]
|
||||
fn string_methods() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let obj = Py::new(py, StringMethods {}).unwrap();
|
||||
py_assert!(py, obj, "str(obj) == 'str'");
|
||||
py_assert!(py, obj, "repr(obj) == 'repr'");
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -122,9 +119,7 @@ impl PyObjectProtocol for Comparisons {
|
|||
|
||||
#[test]
|
||||
fn comparisons() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let zero = Py::new(py, Comparisons { val: 0 }).unwrap();
|
||||
let one = Py::new(py, Comparisons { val: 1 }).unwrap();
|
||||
let ten = Py::new(py, Comparisons { val: 10 }).unwrap();
|
||||
|
@ -135,6 +130,7 @@ fn comparisons() {
|
|||
|
||||
py_assert!(py, one, "bool(one) is True");
|
||||
py_assert!(py, zero, "not zero");
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -181,9 +177,7 @@ impl PySequenceProtocol for Sequence {
|
|||
|
||||
#[test]
|
||||
fn sequence() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let c = Py::new(py, Sequence::default()).unwrap();
|
||||
py_assert!(py, c, "list(c) == ['A', 'B', 'C', 'D', 'E', 'F', 'G']");
|
||||
py_assert!(py, c, "c[-1] == 'G'");
|
||||
|
@ -196,6 +190,7 @@ fn sequence() {
|
|||
"#
|
||||
);
|
||||
py_expect_exception!(py, c, "c['abc']", PyTypeError);
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -215,9 +210,7 @@ impl PyMappingProtocol for SetItem {
|
|||
|
||||
#[test]
|
||||
fn setitem() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let c = PyCell::new(py, SetItem { key: 0, val: 0 }).unwrap();
|
||||
py_run!(py, c, "c[1] = 2");
|
||||
{
|
||||
|
@ -226,6 +219,7 @@ fn setitem() {
|
|||
assert_eq!(c.val, 2);
|
||||
}
|
||||
py_expect_exception!(py, c, "del c[1]", PyNotImplementedError);
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -242,9 +236,7 @@ impl PyMappingProtocol<'a> for DelItem {
|
|||
|
||||
#[test]
|
||||
fn delitem() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let c = PyCell::new(py, DelItem { key: 0 }).unwrap();
|
||||
py_run!(py, c, "del c[1]");
|
||||
{
|
||||
|
@ -252,6 +244,7 @@ fn delitem() {
|
|||
assert_eq!(c.key, 1);
|
||||
}
|
||||
py_expect_exception!(py, c, "c[1] = 2", PyNotImplementedError);
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -272,9 +265,7 @@ impl PyMappingProtocol for SetDelItem {
|
|||
|
||||
#[test]
|
||||
fn setdelitem() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let c = PyCell::new(py, SetDelItem { val: None }).unwrap();
|
||||
py_run!(py, c, "c[1] = 2");
|
||||
{
|
||||
|
@ -284,6 +275,7 @@ fn setdelitem() {
|
|||
py_run!(py, c, "del c[1]");
|
||||
let c = c.borrow();
|
||||
assert_eq!(c.val, None);
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -298,26 +290,24 @@ impl PySequenceProtocol for Contains {
|
|||
|
||||
#[test]
|
||||
fn contains() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
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_expect_exception!(py, c, "assert 'wrong type' not in c", PyTypeError);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_basics() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let v = PySlice::new(py, 1, 10, 2);
|
||||
let indices = v.indices(100).unwrap();
|
||||
assert_eq!(1, indices.start);
|
||||
assert_eq!(10, indices.stop);
|
||||
assert_eq!(2, indices.step);
|
||||
assert_eq!(5, indices.slicelength);
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -342,13 +332,12 @@ impl<'p> PyMappingProtocol<'p> for Test {
|
|||
|
||||
#[test]
|
||||
fn test_cls_impl() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let ob = Py::new(py, Test {}).unwrap();
|
||||
|
||||
py_assert!(py, ob, "ob[1] == 'int'");
|
||||
py_assert!(py, ob, "ob[100:200:1] == 'slice'");
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -366,11 +355,11 @@ impl PyObjectProtocol for ClassWithGetAttr {
|
|||
|
||||
#[test]
|
||||
fn getattr_doesnt_override_member() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let inst = PyCell::new(py, ClassWithGetAttr { data: 4 }).unwrap();
|
||||
py_assert!(py, inst, "inst.data == 4");
|
||||
py_assert!(py, inst, "inst.a == 8");
|
||||
});
|
||||
}
|
||||
|
||||
/// Wraps a Python future and yield it once.
|
||||
|
@ -415,8 +404,7 @@ impl PyIterProtocol for OnceFuture {
|
|||
|
||||
#[test]
|
||||
fn test_await() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let once = py.get_type::<OnceFuture>();
|
||||
let source = pyo3::indoc::indoc!(
|
||||
r#"
|
||||
|
@ -441,6 +429,7 @@ loop.close()
|
|||
py.run(source, Some(globals), None)
|
||||
.map_err(|e| e.print(py))
|
||||
.unwrap();
|
||||
});
|
||||
}
|
||||
|
||||
/// Increment the count when `__get__` is called.
|
||||
|
@ -475,8 +464,7 @@ impl PyDescrProtocol for DescrCounter {
|
|||
|
||||
#[test]
|
||||
fn descr_getset() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let counter = py.get_type::<DescrCounter>();
|
||||
let source = pyo3::indoc::indoc!(
|
||||
r#"
|
||||
|
@ -494,4 +482,5 @@ assert c.counter.count == 3
|
|||
py.run(source, Some(globals), None)
|
||||
.map_err(|e| e.print(py))
|
||||
.unwrap();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -89,29 +89,28 @@ fn reader() -> Reader {
|
|||
|
||||
#[test]
|
||||
fn test_nested_iter() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let reader: PyObject = reader().into_py(py);
|
||||
py_assert!(
|
||||
py,
|
||||
reader,
|
||||
"list(reader.get_iter(bytes([3, 5, 2]))) == ['c', 'e', 'b']"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_clone_ref() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let reader: PyObject = reader().into_py(py);
|
||||
py_assert!(py, reader, "reader == reader.clone_ref()");
|
||||
py_assert!(py, reader, "reader == reader.clone_ref_with_py()");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_nested_iter_reset() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let reader = PyCell::new(py, reader()).unwrap();
|
||||
py_assert!(
|
||||
py,
|
||||
|
@ -120,4 +119,5 @@ fn test_nested_iter_reset() {
|
|||
);
|
||||
let reader_ref = reader.borrow();
|
||||
assert!(reader_ref.inner.is_empty());
|
||||
});
|
||||
}
|
||||
|
|
|
@ -113,8 +113,7 @@ fn seq_dict(py: Python<'_>) -> &pyo3::types::PyDict {
|
|||
|
||||
#[test]
|
||||
fn test_getitem() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let d = seq_dict(py);
|
||||
|
||||
py_assert!(py, *d, "s[0] == 1");
|
||||
|
@ -122,23 +121,22 @@ fn test_getitem() {
|
|||
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();
|
||||
Python::with_gil(|py| {
|
||||
let d = seq_dict(py);
|
||||
|
||||
py_run!(py, *d, "s[0] = 4; assert list(s) == [4, 2, 3]");
|
||||
py_expect_exception!(py, *d, "s[0] = 'hello'", PyTypeError);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_delitem() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let d = [("ByteSequence", py.get_type::<ByteSequence>())].into_py_dict(py);
|
||||
|
||||
py_run!(
|
||||
|
@ -173,13 +171,12 @@ fn test_delitem() {
|
|||
"s = ByteSequence([1, 2, 3]); del s[4]",
|
||||
PyIndexError
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_contains() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let d = seq_dict(py);
|
||||
|
||||
py_assert!(py, *d, "1 in s");
|
||||
|
@ -187,13 +184,12 @@ fn test_contains() {
|
|||
py_assert!(py, *d, "3 in s");
|
||||
py_assert!(py, *d, "4 not in s");
|
||||
py_assert!(py, *d, "'hello' not in s");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_concat() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let d = seq_dict(py);
|
||||
|
||||
py_run!(
|
||||
|
@ -207,13 +203,12 @@ fn test_concat() {
|
|||
"s1 = ByteSequence([1, 2]); s2 = 'hello'; s1 + s2",
|
||||
PyTypeError
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inplace_concat() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let d = seq_dict(py);
|
||||
|
||||
py_run!(
|
||||
|
@ -222,24 +217,22 @@ fn test_inplace_concat() {
|
|||
"s += ByteSequence([4, 5]); assert list(s) == [1, 2, 3, 4, 5]"
|
||||
);
|
||||
py_expect_exception!(py, *d, "s += 'hello'", PyTypeError);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_repeat() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
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_expect_exception!(py, *d, "s2 = s * -1", PyValueError);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inplace_repeat() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let d = [("ByteSequence", py.get_type::<ByteSequence>())].into_py_dict(py);
|
||||
|
||||
py_run!(
|
||||
|
@ -248,6 +241,7 @@ fn test_inplace_repeat() {
|
|||
"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>
|
||||
|
@ -260,22 +254,19 @@ struct GenericList {
|
|||
|
||||
#[test]
|
||||
fn test_generic_list_get() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let list: PyObject = GenericList {
|
||||
items: [1, 2, 3].iter().map(|i| i.to_object(py)).collect(),
|
||||
}
|
||||
.into_py(py);
|
||||
|
||||
py_assert!(py, list, "list.items == [1, 2, 3]");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_generic_list_set() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let list = PyCell::new(py, GenericList { items: vec![] }).unwrap();
|
||||
|
||||
py_run!(py, list, "list.items = [1, 2, 3]");
|
||||
|
@ -285,6 +276,7 @@ fn test_generic_list_set() {
|
|||
.iter()
|
||||
.zip(&[1u32, 2, 3])
|
||||
.all(|(a, b)| a.as_ref(py).eq(&b.into_py(py)).unwrap()));
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -306,9 +298,7 @@ impl OptionList {
|
|||
#[test]
|
||||
fn test_option_list_get() {
|
||||
// Regression test for #798
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let list = PyCell::new(
|
||||
py,
|
||||
OptionList {
|
||||
|
@ -320,4 +310,5 @@ fn test_option_list_get() {
|
|||
py_assert!(py, list, "list[0] == 1");
|
||||
py_assert!(py, list, "list[1] == None");
|
||||
py_expect_exception!(py, list, "list[2]", PyIndexError);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -97,8 +97,7 @@ fn seq_dict(py: Python<'_>) -> &pyo3::types::PyDict {
|
|||
|
||||
#[test]
|
||||
fn test_getitem() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let d = seq_dict(py);
|
||||
|
||||
py_assert!(py, *d, "s[0] == 1");
|
||||
|
@ -106,23 +105,22 @@ fn test_getitem() {
|
|||
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();
|
||||
Python::with_gil(|py| {
|
||||
let d = seq_dict(py);
|
||||
|
||||
py_run!(py, *d, "s[0] = 4; assert list(s) == [4, 2, 3]");
|
||||
py_expect_exception!(py, *d, "s[0] = 'hello'", PyTypeError);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_delitem() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let d = [("ByteSequence", py.get_type::<ByteSequence>())].into_py_dict(py);
|
||||
|
||||
py_run!(
|
||||
|
@ -157,13 +155,12 @@ fn test_delitem() {
|
|||
"s = ByteSequence([1, 2, 3]); del s[4]",
|
||||
PyIndexError
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_contains() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let d = seq_dict(py);
|
||||
|
||||
py_assert!(py, *d, "1 in s");
|
||||
|
@ -171,13 +168,12 @@ fn test_contains() {
|
|||
py_assert!(py, *d, "3 in s");
|
||||
py_assert!(py, *d, "4 not in s");
|
||||
py_assert!(py, *d, "'hello' not in s");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_concat() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let d = seq_dict(py);
|
||||
|
||||
py_run!(
|
||||
|
@ -191,13 +187,12 @@ fn test_concat() {
|
|||
"s1 = ByteSequence([1, 2]); s2 = 'hello'; s1 + s2",
|
||||
PyTypeError
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inplace_concat() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let d = seq_dict(py);
|
||||
|
||||
py_run!(
|
||||
|
@ -206,24 +201,22 @@ fn test_inplace_concat() {
|
|||
"s += ByteSequence([4, 5]); assert list(s) == [1, 2, 3, 4, 5]"
|
||||
);
|
||||
py_expect_exception!(py, *d, "s += 'hello'", PyTypeError);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_repeat() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
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_expect_exception!(py, *d, "s2 = s * -1", PyValueError);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inplace_repeat() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let d = [("ByteSequence", py.get_type::<ByteSequence>())].into_py_dict(py);
|
||||
|
||||
py_run!(
|
||||
|
@ -232,6 +225,7 @@ fn test_inplace_repeat() {
|
|||
"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>
|
||||
|
@ -244,22 +238,19 @@ struct GenericList {
|
|||
|
||||
#[test]
|
||||
fn test_generic_list_get() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let list: PyObject = GenericList {
|
||||
items: [1, 2, 3].iter().map(|i| i.to_object(py)).collect(),
|
||||
}
|
||||
.into_py(py);
|
||||
|
||||
py_assert!(py, list, "list.items == [1, 2, 3]");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_generic_list_set() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let list = PyCell::new(py, GenericList { items: vec![] }).unwrap();
|
||||
|
||||
py_run!(py, list, "list.items = [1, 2, 3]");
|
||||
|
@ -269,6 +260,7 @@ fn test_generic_list_set() {
|
|||
.iter()
|
||||
.zip(&[1u32, 2, 3])
|
||||
.all(|(a, b)| a.as_ref(py).eq(&b.into_py(py)).unwrap()));
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -290,9 +282,7 @@ impl PySequenceProtocol for OptionList {
|
|||
#[test]
|
||||
fn test_option_list_get() {
|
||||
// Regression test for #798
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let list = PyCell::new(
|
||||
py,
|
||||
OptionList {
|
||||
|
@ -304,4 +294,5 @@ fn test_option_list_get() {
|
|||
py_assert!(py, list, "list[0] == 1");
|
||||
py_assert!(py, list, "list[1] == None");
|
||||
py_expect_exception!(py, list, "list[2]", PyIndexError);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -9,9 +9,7 @@ fn take_str(_s: &str) {}
|
|||
|
||||
#[test]
|
||||
fn test_unicode_encode_error() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let take_str = wrap_pyfunction!(take_str)(py).unwrap();
|
||||
py_expect_exception!(
|
||||
py,
|
||||
|
@ -20,4 +18,5 @@ fn test_unicode_encode_error() {
|
|||
PyUnicodeEncodeError,
|
||||
"'utf-8' codec can't encode character '\\ud800' in position 0: surrogates not allowed"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -10,12 +10,12 @@ fn class_without_docs_or_signature() {
|
|||
#[pyclass]
|
||||
struct MyClass {}
|
||||
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let typeobj = py.get_type::<MyClass>();
|
||||
|
||||
py_assert!(py, typeobj, "typeobj.__doc__ is None");
|
||||
py_assert!(py, typeobj, "typeobj.__text_signature__ is None");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -25,12 +25,12 @@ fn class_with_docs() {
|
|||
/// docs line2
|
||||
struct MyClass {}
|
||||
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let typeobj = py.get_type::<MyClass>();
|
||||
|
||||
py_assert!(py, typeobj, "typeobj.__doc__ == 'docs line1\\ndocs line2'");
|
||||
py_assert!(py, typeobj, "typeobj.__text_signature__ is None");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -53,8 +53,7 @@ fn class_with_docs_and_signature() {
|
|||
}
|
||||
}
|
||||
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let typeobj = py.get_type::<MyClass>();
|
||||
|
||||
py_assert!(
|
||||
|
@ -67,6 +66,7 @@ fn class_with_docs_and_signature() {
|
|||
typeobj,
|
||||
"typeobj.__text_signature__ == '(a, b=None, *, c=42)'"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -86,8 +86,7 @@ fn class_with_signature() {
|
|||
}
|
||||
}
|
||||
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let typeobj = py.get_type::<MyClass>();
|
||||
|
||||
py_assert!(
|
||||
|
@ -100,6 +99,7 @@ fn class_with_signature() {
|
|||
typeobj,
|
||||
"typeobj.__text_signature__ == '(a, b=None, *, c=42)'"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -110,11 +110,11 @@ fn test_function() {
|
|||
let _ = (a, b, c);
|
||||
}
|
||||
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let f = wrap_pyfunction!(my_function)(py).unwrap();
|
||||
|
||||
py_assert!(py, f, "f.__text_signature__ == '(a, b=None, *, c=42)'");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -129,8 +129,7 @@ fn test_pyfn() {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let m = wrap_pymodule!(my_module)(py);
|
||||
|
||||
py_assert!(
|
||||
|
@ -138,6 +137,7 @@ fn test_pyfn() {
|
|||
m,
|
||||
"m.my_function.__text_signature__ == '(a, b=None, *, c=42)'"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -167,8 +167,7 @@ fn test_methods() {
|
|||
}
|
||||
}
|
||||
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let typeobj = py.get_type::<MyClass>();
|
||||
|
||||
py_assert!(
|
||||
|
@ -191,6 +190,7 @@ fn test_methods() {
|
|||
typeobj,
|
||||
"typeobj.static_method.__text_signature__ == '(d)'"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -210,8 +210,7 @@ fn test_raw_identifiers() {
|
|||
fn r#method(&self) {}
|
||||
}
|
||||
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let typeobj = py.get_type::<MyClass>();
|
||||
|
||||
py_assert!(py, typeobj, "typeobj.__text_signature__ == '($self)'");
|
||||
|
@ -221,4 +220,5 @@ fn test_raw_identifiers() {
|
|||
typeobj,
|
||||
"typeobj.method.__text_signature__ == '($self)'"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -17,10 +17,10 @@ impl UnsendableDictClass {
|
|||
#[test]
|
||||
#[cfg_attr(all(Py_LIMITED_API, not(Py_3_10)), ignore)]
|
||||
fn test_unsendable_dict() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let inst = Py::new(py, UnsendableDictClass {}).unwrap();
|
||||
py_run!(py, inst, "assert inst.__dict__ == {}");
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass(dict, unsendable, weakref)]
|
||||
|
@ -37,8 +37,7 @@ impl UnsendableDictClassWithWeakRef {
|
|||
#[test]
|
||||
#[cfg_attr(all(Py_LIMITED_API, not(Py_3_10)), ignore)]
|
||||
fn test_unsendable_dict_with_weakref() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let inst = Py::new(py, UnsendableDictClassWithWeakRef {}).unwrap();
|
||||
py_run!(py, inst, "assert inst.__dict__ == {}");
|
||||
py_run!(
|
||||
|
@ -46,4 +45,5 @@ fn test_unsendable_dict_with_weakref() {
|
|||
inst,
|
||||
"import weakref; assert weakref.ref(inst)() is inst; inst.a = 1; assert inst.a == 1"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -25,18 +25,17 @@ impl MyClass {
|
|||
|
||||
#[test]
|
||||
fn variable_args() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let my_obj = py.get_type::<MyClass>();
|
||||
py_assert!(py, my_obj, "my_obj.test_args() == ()");
|
||||
py_assert!(py, my_obj, "my_obj.test_args(1) == (1,)");
|
||||
py_assert!(py, my_obj, "my_obj.test_args(1, 2) == (1, 2)");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn variable_kwargs() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let my_obj = py.get_type::<MyClass>();
|
||||
py_assert!(py, my_obj, "my_obj.test_kwargs() == None");
|
||||
py_assert!(py, my_obj, "my_obj.test_kwargs(test=1) == {'test': 1}");
|
||||
|
@ -45,4 +44,5 @@ fn variable_kwargs() {
|
|||
my_obj,
|
||||
"my_obj.test_kwargs(test1=1, test2=2) == {'test1':1, 'test2':2}"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -25,14 +25,14 @@ impl MutRefArg {
|
|||
|
||||
#[test]
|
||||
fn mut_ref_arg() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
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)");
|
||||
let inst2 = inst2.as_ref(py).borrow();
|
||||
assert_eq!(inst2.n, 100);
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -50,27 +50,25 @@ fn get_zero() -> PyUsize {
|
|||
/// Checks that we can use return a custom class in arbitrary function and use those functions
|
||||
/// both in rust and python
|
||||
fn return_custom_class() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
// Using from rust
|
||||
assert_eq!(get_zero().value, 0);
|
||||
|
||||
// Using from python
|
||||
let get_zero = wrap_pyfunction!(get_zero)(py).unwrap();
|
||||
py_assert!(py, get_zero, "get_zero().value == 0");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn intopytuple_primitive() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let tup = (1, 2, "foo");
|
||||
py_assert!(py, tup, "tup == (1, 2, 'foo')");
|
||||
py_assert!(py, tup, "tup[0] == 1");
|
||||
py_assert!(py, tup, "tup[1] == 2");
|
||||
py_assert!(py, tup, "tup[2] == 'foo'");
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -78,9 +76,7 @@ struct SimplePyClass {}
|
|||
|
||||
#[test]
|
||||
fn intopytuple_pyclass() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let tup = (
|
||||
PyCell::new(py, SimplePyClass {}).unwrap(),
|
||||
PyCell::new(py, SimplePyClass {}).unwrap(),
|
||||
|
@ -88,22 +84,20 @@ fn intopytuple_pyclass() {
|
|||
py_assert!(py, tup, "type(tup[0]).__name__ == 'SimplePyClass'");
|
||||
py_assert!(py, tup, "type(tup[0]).__name__ == type(tup[1]).__name__");
|
||||
py_assert!(py, tup, "tup[0] != tup[1]");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pytuple_primitive_iter() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let tup = PyTuple::new(py, [1u32, 2, 3].iter());
|
||||
py_assert!(py, tup, "tup == (1, 2, 3)");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pytuple_pyclass_iter() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let tup = PyTuple::new(
|
||||
py,
|
||||
[
|
||||
|
@ -115,6 +109,7 @@ fn pytuple_pyclass_iter() {
|
|||
py_assert!(py, tup, "type(tup[0]).__name__ == 'SimplePyClass'");
|
||||
py_assert!(py, tup, "type(tup[0]).__name__ == type(tup[0]).__name__");
|
||||
py_assert!(py, tup, "tup[0] != tup[1]");
|
||||
});
|
||||
}
|
||||
|
||||
#[pyclass(dict, module = "test_module")]
|
||||
|
@ -149,8 +144,7 @@ fn add_module(py: Python<'_>, module: &PyModule) -> PyResult<()> {
|
|||
#[test]
|
||||
#[cfg_attr(all(Py_LIMITED_API, not(Py_3_10)), ignore)]
|
||||
fn test_pickle() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
let module = PyModule::new(py, "test_module").unwrap();
|
||||
module.add_class::<PickleSupport>().unwrap();
|
||||
add_module(py, module).unwrap();
|
||||
|
@ -168,6 +162,7 @@ fn test_pickle() {
|
|||
assert inst2.__dict__ == {'a': 1}
|
||||
"#
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/// Testing https://github.com/PyO3/pyo3/issues/1106. A result type that
|
||||
|
@ -203,7 +198,7 @@ fn result_conversion_function() -> Result<(), MyError> {
|
|||
|
||||
#[test]
|
||||
fn test_result_conversion() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
Python::with_gil(|py| {
|
||||
wrap_pyfunction!(result_conversion_function)(py).unwrap();
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue