rudtfmt the tests
With some careful refactoring alongside
This commit is contained in:
parent
f9ff7cd465
commit
80096ae143
|
@ -3,28 +3,35 @@
|
|||
pub fn indoc(commands: &str) -> String {
|
||||
let indent;
|
||||
if let Some(second) = commands.lines().nth(1) {
|
||||
indent = second.chars().take_while(char::is_ascii_whitespace).collect::<String>();
|
||||
indent = second
|
||||
.chars()
|
||||
.take_while(char::is_ascii_whitespace)
|
||||
.collect::<String>();
|
||||
} else {
|
||||
indent = "".to_string();
|
||||
}
|
||||
|
||||
commands.trim_right().replace(&("\n".to_string() + &indent), "\n") + "\n"
|
||||
commands
|
||||
.trim_right()
|
||||
.replace(&("\n".to_string() + &indent), "\n") + "\n"
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! py_run {
|
||||
($py:expr, $val:ident, $code:expr) => {{
|
||||
($py:expr, $val:expr, $code:expr) => {{
|
||||
let d = PyDict::new($py);
|
||||
d.set_item(stringify!($val), &$val).unwrap();
|
||||
$py.run(&common::indoc($code), None, Some(d))
|
||||
.map_err(|e| e.print($py))
|
||||
.expect(&common::indoc($code));
|
||||
}}
|
||||
}};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! py_assert {
|
||||
($py:expr, $val:ident, $assertion:expr) => { py_run!($py, $val, concat!("assert ", $assertion)) };
|
||||
($py:expr, $val:ident, $assertion:expr) => {
|
||||
py_run!($py, $val, concat!("assert ", $assertion))
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
|
@ -37,5 +44,5 @@ macro_rules! py_expect_exception {
|
|||
if !err.matches($py, $py.get_type::<exc::$err>()) {
|
||||
panic!(format!("Expected {} but got {:?}", stringify!($err), err))
|
||||
}
|
||||
}}
|
||||
}};
|
||||
}
|
||||
|
|
|
@ -3,20 +3,19 @@
|
|||
extern crate pyo3;
|
||||
|
||||
use pyo3::prelude::*;
|
||||
|
||||
use pyo3::py::class as pyclass;
|
||||
use pyo3::py::proto as pyproto;
|
||||
|
||||
|
||||
#[macro_use]
|
||||
mod common;
|
||||
|
||||
#[pyclass]
|
||||
struct UnaryArithmetic {token: PyToken}
|
||||
struct UnaryArithmetic {
|
||||
token: PyToken,
|
||||
}
|
||||
|
||||
#[pyproto]
|
||||
impl PyNumberProtocol for UnaryArithmetic {
|
||||
|
||||
fn __neg__(&self) -> PyResult<&'static str> {
|
||||
Ok("neg")
|
||||
}
|
||||
|
@ -39,17 +38,16 @@ fn unary_arithmetic() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let c = py.init(|t| UnaryArithmetic{token: t}).unwrap();
|
||||
let c = py.init(|t| UnaryArithmetic { token: t }).unwrap();
|
||||
py_run!(py, c, "assert -c == 'neg'");
|
||||
py_run!(py, c, "assert +c == 'pos'");
|
||||
py_run!(py, c, "assert abs(c) == 'abs'");
|
||||
py_run!(py, c, "assert ~c == 'invert'");
|
||||
}
|
||||
|
||||
|
||||
#[pyclass]
|
||||
struct BinaryArithmetic {
|
||||
token: PyToken
|
||||
token: PyToken,
|
||||
}
|
||||
|
||||
#[pyproto]
|
||||
|
@ -59,7 +57,6 @@ impl PyObjectProtocol for BinaryArithmetic {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#[pyclass]
|
||||
struct InPlaceOperations {
|
||||
value: u32,
|
||||
|
@ -121,29 +118,19 @@ fn inplace_operations() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let c = py.init(|t| InPlaceOperations{value: 0, token: t}).unwrap();
|
||||
py_run!(py, c, "d = c; c += 1; assert repr(c) == repr(d) == 'IPO(1)'");
|
||||
let init = |value, code| {
|
||||
let c = py.init(|t| InPlaceOperations { value, token: t }).unwrap();
|
||||
py_run!(py, c, code);
|
||||
};
|
||||
|
||||
let c = py.init(|t| InPlaceOperations{value:10, token: t}).unwrap();
|
||||
py_run!(py, c, "d = c; c -= 1; assert repr(c) == repr(d) == 'IPO(9)'");
|
||||
|
||||
let c = py.init(|t| InPlaceOperations{value: 3, token: t}).unwrap();
|
||||
py_run!(py, c, "d = c; c *= 3; assert repr(c) == repr(d) == 'IPO(9)'");
|
||||
|
||||
let c = py.init(|t| InPlaceOperations{value: 3, token: t}).unwrap();
|
||||
py_run!(py, c, "d = c; c <<= 2; assert repr(c) == repr(d) == 'IPO(12)'");
|
||||
|
||||
let c = py.init(|t| InPlaceOperations{value: 12, token: t}).unwrap();
|
||||
py_run!(py, c, "d = c; c >>= 2; assert repr(c) == repr(d) == 'IPO(3)'");
|
||||
|
||||
let c = py.init(|t| InPlaceOperations{value: 12, token: t}).unwrap();
|
||||
py_run!(py, c, "d = c; c &= 10; assert repr(c) == repr(d) == 'IPO(8)'");
|
||||
|
||||
let c = py.init(|t| InPlaceOperations{value: 12, token: t}).unwrap();
|
||||
py_run!(py, c, "d = c; c |= 3; assert repr(c) == repr(d) == 'IPO(15)'");
|
||||
|
||||
let c = py.init(|t| InPlaceOperations{value: 12, token: t}).unwrap();
|
||||
py_run!(py, c, "d = c; c ^= 5; assert repr(c) == repr(d) == 'IPO(9)'");
|
||||
init(0, "d = c; c += 1; assert repr(c) == repr(d) == 'IPO(1)'");
|
||||
init(10, "d = c; c -= 1; assert repr(c) == repr(d) == 'IPO(9)'");
|
||||
init(3, "d = c; c *= 3; assert repr(c) == repr(d) == 'IPO(9)'");
|
||||
init(3, "d = c; c <<= 2; assert repr(c) == repr(d) == 'IPO(12)'");
|
||||
init(12, "d = c; c >>= 2; assert repr(c) == repr(d) == 'IPO(3)'");
|
||||
init(12, "d = c; c &= 10; assert repr(c) == repr(d) == 'IPO(8)'");
|
||||
init(12, "d = c; c |= 3; assert repr(c) == repr(d) == 'IPO(15)'");
|
||||
init(12, "d = c; c ^= 5; assert repr(c) == repr(d) == 'IPO(9)'");
|
||||
}
|
||||
|
||||
#[pyproto]
|
||||
|
@ -186,7 +173,7 @@ fn binary_arithmetic() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let c = py.init(|t| BinaryArithmetic{token: t}).unwrap();
|
||||
let c = py.init(|t| BinaryArithmetic { token: t }).unwrap();
|
||||
py_run!(py, c, "assert c + c == 'BA + BA'");
|
||||
py_run!(py, c, "assert c + 1 == 'BA + 1'");
|
||||
py_run!(py, c, "assert 1 + c == '1 + BA'");
|
||||
|
@ -207,10 +194,9 @@ fn binary_arithmetic() {
|
|||
py_run!(py, c, "assert 1 | c == '1 | BA'");
|
||||
}
|
||||
|
||||
|
||||
#[pyclass]
|
||||
struct RichComparisons {
|
||||
token: PyToken
|
||||
token: PyToken,
|
||||
}
|
||||
|
||||
#[pyproto]
|
||||
|
@ -226,14 +212,14 @@ impl PyObjectProtocol for RichComparisons {
|
|||
CompareOp::Eq => Ok(format!("{} == {:?}", self.__repr__().unwrap(), other)),
|
||||
CompareOp::Ne => Ok(format!("{} != {:?}", self.__repr__().unwrap(), other)),
|
||||
CompareOp::Gt => Ok(format!("{} > {:?}", self.__repr__().unwrap(), other)),
|
||||
CompareOp::Ge => Ok(format!("{} >= {:?}", self.__repr__().unwrap(), other))
|
||||
CompareOp::Ge => Ok(format!("{} >= {:?}", self.__repr__().unwrap(), other)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
struct RichComparisons2 {
|
||||
py: PyToken
|
||||
py: PyToken,
|
||||
}
|
||||
|
||||
#[pyproto]
|
||||
|
@ -246,7 +232,7 @@ impl PyObjectProtocol for RichComparisons2 {
|
|||
match op {
|
||||
CompareOp::Eq => Ok(true.to_object(self.py())),
|
||||
CompareOp::Ne => Ok(false.to_object(self.py())),
|
||||
_ => Ok(self.py().NotImplemented())
|
||||
_ => Ok(self.py().NotImplemented()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -256,7 +242,7 @@ fn rich_comparisons() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let c = py.init(|t| RichComparisons{token: t}).unwrap();
|
||||
let c = py.init(|t| RichComparisons { token: t }).unwrap();
|
||||
py_run!(py, c, "assert (c < c) == 'RC < RC'");
|
||||
py_run!(py, c, "assert (c < 1) == 'RC < 1'");
|
||||
py_run!(py, c, "assert (1 < c) == 'RC > 1'");
|
||||
|
@ -283,7 +269,7 @@ fn rich_comparisons_python_3_type_error() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let c2 = py.init(|t| RichComparisons2{py: t}).unwrap();
|
||||
let c2 = py.init(|t| RichComparisons2 { py: t }).unwrap();
|
||||
py_expect_exception!(py, c2, "c2 < c2", TypeError);
|
||||
py_expect_exception!(py, c2, "c2 < 1", TypeError);
|
||||
py_expect_exception!(py, c2, "1 < c2", TypeError);
|
||||
|
|
|
@ -2,16 +2,15 @@
|
|||
|
||||
extern crate pyo3;
|
||||
|
||||
use std::ptr;
|
||||
use std::os::raw::{c_int, c_void};
|
||||
use std::ptr;
|
||||
|
||||
use pyo3::prelude::*;
|
||||
use pyo3::ffi;
|
||||
use pyo3::prelude::*;
|
||||
|
||||
use pyo3::py::class as pyclass;
|
||||
use pyo3::py::proto as pyproto;
|
||||
|
||||
|
||||
#[pyclass]
|
||||
struct TestClass {
|
||||
vec: Vec<u8>,
|
||||
|
@ -20,10 +19,9 @@ struct TestClass {
|
|||
|
||||
#[pyproto]
|
||||
impl PyBufferProtocol for TestClass {
|
||||
|
||||
fn bf_getbuffer(&self, view: *mut ffi::Py_buffer, flags: c_int) -> PyResult<()> {
|
||||
if view.is_null() {
|
||||
return Err(PyErr::new::<exc::BufferError, _>("View is null"))
|
||||
return Err(PyErr::new::<exc::BufferError, _>("View is null"));
|
||||
}
|
||||
|
||||
unsafe {
|
||||
|
@ -31,7 +29,7 @@ impl PyBufferProtocol for TestClass {
|
|||
}
|
||||
|
||||
if (flags & ffi::PyBUF_WRITABLE) == ffi::PyBUF_WRITABLE {
|
||||
return Err(PyErr::new::<exc::BufferError, _>("Object is not writable"))
|
||||
return Err(PyErr::new::<exc::BufferError, _>("Object is not writable"));
|
||||
}
|
||||
|
||||
let bytes = &self.vec;
|
||||
|
@ -67,14 +65,17 @@ impl PyBufferProtocol for TestClass {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(Py_3)]
|
||||
#[test]
|
||||
fn test_buffer() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let t = py.init(|t| TestClass{vec: vec![b' ', b'2', b'3'], token: t}).unwrap();
|
||||
let t =
|
||||
py.init(|t| TestClass {
|
||||
vec: vec![b' ', b'2', b'3'],
|
||||
token: t,
|
||||
}).unwrap();
|
||||
|
||||
let d = PyDict::new(py);
|
||||
d.set_item("ob", t).unwrap();
|
||||
|
@ -87,9 +88,14 @@ fn test_buffer() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let t = py.init(|t| TestClass{vec: vec![b' ', b'2', b'3'], token: t}).unwrap();
|
||||
let t =
|
||||
py.init(|t| TestClass {
|
||||
vec: vec![b' ', b'2', b'3'],
|
||||
token: t,
|
||||
}).unwrap();
|
||||
|
||||
let d = PyDict::new(py);
|
||||
d.set_item("ob", t).unwrap();
|
||||
py.run("assert memoryview(ob).tobytes() == ' 23'", None, Some(d)).unwrap();
|
||||
py.run("assert memoryview(ob).tobytes() == ' 23'", None, Some(d))
|
||||
.unwrap();
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ use pyo3::py::class as pyclass;
|
|||
mod common;
|
||||
|
||||
#[pyclass]
|
||||
struct EmptyClass { }
|
||||
struct EmptyClass {}
|
||||
|
||||
#[test]
|
||||
fn empty_class() {
|
||||
|
@ -28,7 +28,7 @@ fn empty_class() {
|
|||
/// Line3
|
||||
// this is not doc string
|
||||
#[pyclass]
|
||||
struct ClassWithDocs { }
|
||||
struct ClassWithDocs {}
|
||||
|
||||
#[test]
|
||||
fn class_with_docstr() {
|
||||
|
@ -36,12 +36,16 @@ fn class_with_docstr() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let typeobj = py.get_type::<ClassWithDocs>();
|
||||
py_run!(py, typeobj, "assert typeobj.__doc__ == 'Line1\\nLine2\\n Line3'");
|
||||
py_run!(
|
||||
py,
|
||||
typeobj,
|
||||
"assert typeobj.__doc__ == 'Line1\\nLine2\\n Line3'"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass(name=CustomName)]
|
||||
struct EmptyClass2 { }
|
||||
struct EmptyClass2 {}
|
||||
|
||||
#[test]
|
||||
fn custom_class_name() {
|
||||
|
@ -52,7 +56,7 @@ fn custom_class_name() {
|
|||
}
|
||||
|
||||
#[pyclass]
|
||||
struct EmptyClassInModule { }
|
||||
struct EmptyClassInModule {}
|
||||
|
||||
#[test]
|
||||
fn empty_class_in_module() {
|
||||
|
@ -62,6 +66,15 @@ fn empty_class_in_module() {
|
|||
module.add_class::<EmptyClassInModule>().unwrap();
|
||||
|
||||
let ty = module.getattr("EmptyClassInModule").unwrap();
|
||||
assert_eq!(ty.getattr("__name__").unwrap().extract::<String>().unwrap(), "EmptyClassInModule");
|
||||
assert_eq!(ty.getattr("__module__").unwrap().extract::<String>().unwrap(), "test_module.nested");
|
||||
assert_eq!(
|
||||
ty.getattr("__name__").unwrap().extract::<String>().unwrap(),
|
||||
"EmptyClassInModule"
|
||||
);
|
||||
assert_eq!(
|
||||
ty.getattr("__module__")
|
||||
.unwrap()
|
||||
.extract::<String>()
|
||||
.unwrap(),
|
||||
"test_module.nested"
|
||||
);
|
||||
}
|
||||
|
|
|
@ -9,14 +9,14 @@ use pyo3::py::methods as pymethods;
|
|||
|
||||
#[pyclass]
|
||||
struct EmptyClassWithNew {
|
||||
token: PyToken
|
||||
token: PyToken,
|
||||
}
|
||||
|
||||
#[pymethods]
|
||||
impl EmptyClassWithNew {
|
||||
#[__new__]
|
||||
fn __new__(obj: &PyRawObject) -> PyResult<()> {
|
||||
obj.init(|t| EmptyClassWithNew{token: t})
|
||||
obj.init(|t| EmptyClassWithNew { token: t })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,20 +25,29 @@ fn empty_class_with_new() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let typeobj = py.get_type::<EmptyClassWithNew>();
|
||||
assert!(typeobj.call(NoArgs, NoArgs).unwrap().cast_as::<EmptyClassWithNew>().is_ok());
|
||||
assert!(
|
||||
typeobj
|
||||
.call(NoArgs, NoArgs)
|
||||
.unwrap()
|
||||
.cast_as::<EmptyClassWithNew>()
|
||||
.is_ok()
|
||||
);
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
struct NewWithOneArg {
|
||||
_data: i32,
|
||||
token: PyToken
|
||||
token: PyToken,
|
||||
}
|
||||
|
||||
#[pymethods]
|
||||
impl NewWithOneArg {
|
||||
#[new]
|
||||
fn __new__(obj: &PyRawObject, arg: i32) -> PyResult<()> {
|
||||
obj.init(|t| NewWithOneArg{_data: arg, token: t})
|
||||
obj.init(|t| NewWithOneArg {
|
||||
_data: arg,
|
||||
token: t,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,15 +66,18 @@ struct NewWithTwoArgs {
|
|||
_data1: i32,
|
||||
_data2: i32,
|
||||
|
||||
token: PyToken
|
||||
token: PyToken,
|
||||
}
|
||||
|
||||
#[pymethods]
|
||||
impl NewWithTwoArgs {
|
||||
#[new]
|
||||
fn __new__(obj: &PyRawObject, arg1: i32, arg2: i32) -> PyResult<()>
|
||||
{
|
||||
obj.init(|t| NewWithTwoArgs{_data1: arg1, _data2: arg2, token: t})
|
||||
fn __new__(obj: &PyRawObject, arg1: i32, arg2: i32) -> PyResult<()> {
|
||||
obj.init(|t| NewWithTwoArgs {
|
||||
_data1: arg1,
|
||||
_data2: arg2,
|
||||
token: t,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,7 +86,10 @@ fn new_with_two_args() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let typeobj = py.get_type::<NewWithTwoArgs>();
|
||||
let wrp = typeobj.call((10, 20), NoArgs).map_err(|e| e.print(py)).unwrap();
|
||||
let wrp = typeobj
|
||||
.call((10, 20), NoArgs)
|
||||
.map_err(|e| e.print(py))
|
||||
.unwrap();
|
||||
let obj = wrp.cast_as::<NewWithTwoArgs>().unwrap();
|
||||
assert_eq!(obj._data1, 10);
|
||||
assert_eq!(obj._data2, 20);
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
extern crate docmatic;
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::default::Default;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
fn assert_file<P: AsRef<Path>>(path: P) {
|
||||
let mut doc = docmatic::Assert::default();
|
||||
if cfg!(windows) {
|
||||
doc.library_path(option_env!("PYTHON").map(|py| PathBuf::from(py).join("libs")).unwrap());
|
||||
doc.library_path(
|
||||
option_env!("PYTHON")
|
||||
.map(|py| PathBuf::from(py).join("libs"))
|
||||
.unwrap(),
|
||||
);
|
||||
}
|
||||
doc.test_file(path.as_ref())
|
||||
}
|
||||
|
|
|
@ -2,19 +2,17 @@
|
|||
|
||||
extern crate pyo3;
|
||||
|
||||
use pyo3::ffi;
|
||||
use pyo3::prelude::*;
|
||||
use std::{isize, iter};
|
||||
use pyo3::ffi;
|
||||
|
||||
use pyo3::py::class as pyclass;
|
||||
use pyo3::py::methods as pymethods;
|
||||
use pyo3::py::proto as pyproto;
|
||||
|
||||
|
||||
#[macro_use]
|
||||
mod common;
|
||||
|
||||
|
||||
#[pyclass]
|
||||
pub struct Len {
|
||||
l: usize,
|
||||
|
@ -33,20 +31,23 @@ fn len() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let inst = Py::new(py, |t| Len{l: 10, token: t}).unwrap();
|
||||
let inst = Py::new(py, |t| Len { l: 10, token: t }).unwrap();
|
||||
py_assert!(py, inst, "len(inst) == 10");
|
||||
unsafe {
|
||||
assert_eq!(ffi::PyObject_Size(inst.as_ptr()), 10);
|
||||
assert_eq!(ffi::PyMapping_Size(inst.as_ptr()), 10);
|
||||
}
|
||||
|
||||
let inst = Py::new(py, |t| Len{l: (isize::MAX as usize) + 1, token: t}).unwrap();
|
||||
let inst = Py::new(py, |t| Len {
|
||||
l: (isize::MAX as usize) + 1,
|
||||
token: t,
|
||||
}).unwrap();
|
||||
py_expect_exception!(py, inst, "len(inst)", OverflowError);
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
struct Iterator{
|
||||
iter: Box<iter::Iterator<Item=i32> + Send>,
|
||||
struct Iterator {
|
||||
iter: Box<iter::Iterator<Item = i32> + Send>,
|
||||
token: PyToken,
|
||||
}
|
||||
|
||||
|
@ -66,13 +67,18 @@ fn iterator() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let inst = Py::new(py, |t| Iterator{iter: Box::new(5..8), token: t}).unwrap();
|
||||
let inst = Py::new(py, |t| Iterator {
|
||||
iter: Box::new(5..8),
|
||||
token: t,
|
||||
}).unwrap();
|
||||
py_assert!(py, inst, "iter(inst) is inst");
|
||||
py_assert!(py, inst, "list(inst) == [5, 6, 7]");
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
struct StringMethods {token: PyToken}
|
||||
struct StringMethods {
|
||||
token: PyToken,
|
||||
}
|
||||
|
||||
#[pyproto]
|
||||
impl<'p> PyObjectProtocol<'p> for StringMethods {
|
||||
|
@ -103,7 +109,7 @@ fn string_methods() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let obj = Py::new(py, |t| StringMethods{token: t}).unwrap();
|
||||
let obj = Py::new(py, |t| StringMethods { token: t }).unwrap();
|
||||
py_assert!(py, obj, "str(obj) == 'str'");
|
||||
py_assert!(py, obj, "repr(obj) == 'repr'");
|
||||
py_assert!(py, obj, "'{0:x}'.format(obj) == 'format(x)'");
|
||||
|
@ -116,14 +122,13 @@ fn string_methods() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let obj = Py::new(py, |t| StringMethods{token: t}).unwrap();
|
||||
let obj = Py::new(py, |t| StringMethods { token: t }).unwrap();
|
||||
py_assert!(py, obj, "str(obj) == 'str'");
|
||||
py_assert!(py, obj, "repr(obj) == 'repr'");
|
||||
py_assert!(py, obj, "unicode(obj) == 'unicode'");
|
||||
py_assert!(py, obj, "'{0:x}'.format(obj) == 'format(x)'");
|
||||
}
|
||||
|
||||
|
||||
#[pyclass]
|
||||
struct Comparisons {
|
||||
val: i32,
|
||||
|
@ -140,16 +145,15 @@ impl PyObjectProtocol for Comparisons {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn comparisons() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let zero = Py::new(py, |t| Comparisons{val: 0, token: t}).unwrap();
|
||||
let one = Py::new(py, |t| Comparisons{val: 1, token: t}).unwrap();
|
||||
let ten = Py::new(py, |t| Comparisons{val: 10, token: t}).unwrap();
|
||||
let minus_one = Py::new(py, |t| Comparisons{val: -1, token: t}).unwrap();
|
||||
let zero = Py::new(py, |t| Comparisons { val: 0, token: t }).unwrap();
|
||||
let one = Py::new(py, |t| Comparisons { val: 1, token: t }).unwrap();
|
||||
let ten = Py::new(py, |t| Comparisons { val: 10, token: t }).unwrap();
|
||||
let minus_one = Py::new(py, |t| Comparisons { val: -1, token: t }).unwrap();
|
||||
py_assert!(py, one, "hash(one) == 1");
|
||||
py_assert!(py, ten, "hash(ten) == 10");
|
||||
py_assert!(py, minus_one, "hash(minus_one) == -2");
|
||||
|
@ -158,10 +162,9 @@ fn comparisons() {
|
|||
py_assert!(py, zero, "not zero");
|
||||
}
|
||||
|
||||
|
||||
#[pyclass]
|
||||
struct Sequence {
|
||||
token: PyToken
|
||||
token: PyToken,
|
||||
}
|
||||
|
||||
#[pyproto]
|
||||
|
@ -183,18 +186,18 @@ fn sequence() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let c = py.init(|t| Sequence{token: t}).unwrap();
|
||||
let c = py.init(|t| Sequence { token: t }).unwrap();
|
||||
py_assert!(py, c, "list(c) == [0, 1, 2, 3, 4]");
|
||||
py_expect_exception!(py, c, "c['abc']", TypeError);
|
||||
}
|
||||
|
||||
|
||||
#[pyclass]
|
||||
struct Callable {token: PyToken}
|
||||
struct Callable {
|
||||
token: PyToken,
|
||||
}
|
||||
|
||||
#[pymethods]
|
||||
impl Callable {
|
||||
|
||||
#[__call__]
|
||||
fn __call__(&self, arg: i32) -> PyResult<i32> {
|
||||
Ok(arg * 6)
|
||||
|
@ -206,11 +209,11 @@ fn callable() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let c = py.init(|t| Callable{token: t}).unwrap();
|
||||
let c = py.init(|t| Callable { token: t }).unwrap();
|
||||
py_assert!(py, c, "callable(c)");
|
||||
py_assert!(py, c, "c(7) == 42");
|
||||
|
||||
let nc = py.init(|t| Comparisons{val: 0, token: t}).unwrap();
|
||||
let nc = py.init(|t| Comparisons { val: 0, token: t }).unwrap();
|
||||
py_assert!(py, nc, "not callable(nc)");
|
||||
}
|
||||
|
||||
|
@ -235,7 +238,12 @@ fn setitem() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let c = py.init_ref(|t| SetItem{key: 0, val: 0, token: t}).unwrap();
|
||||
let c =
|
||||
py.init_ref(|t| SetItem {
|
||||
key: 0,
|
||||
val: 0,
|
||||
token: t,
|
||||
}).unwrap();
|
||||
py_run!(py, c, "c[1] = 2");
|
||||
assert_eq!(c.key, 1);
|
||||
assert_eq!(c.val, 2);
|
||||
|
@ -261,7 +269,7 @@ fn delitem() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let c = py.init_ref(|t| DelItem{key:0, token:t}).unwrap();
|
||||
let c = py.init_ref(|t| DelItem { key: 0, token: t }).unwrap();
|
||||
py_run!(py, c, "del c[1]");
|
||||
assert_eq!(c.key, 1);
|
||||
py_expect_exception!(py, c, "c[1] = 2", NotImplementedError);
|
||||
|
@ -291,7 +299,11 @@ fn setdelitem() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let c = py.init_ref(|t| SetDelItem{val: None, token: t}).unwrap();
|
||||
let c =
|
||||
py.init_ref(|t| SetDelItem {
|
||||
val: None,
|
||||
token: t,
|
||||
}).unwrap();
|
||||
py_run!(py, c, "c[1] = 2");
|
||||
assert_eq!(c.val, Some(2));
|
||||
py_run!(py, c, "del c[1]");
|
||||
|
@ -299,10 +311,12 @@ fn setdelitem() {
|
|||
}
|
||||
|
||||
#[pyclass]
|
||||
struct Reversed {token: PyToken}
|
||||
struct Reversed {
|
||||
token: PyToken,
|
||||
}
|
||||
|
||||
#[pyproto]
|
||||
impl PyMappingProtocol for Reversed{
|
||||
impl PyMappingProtocol for Reversed {
|
||||
fn __reversed__(&self) -> PyResult<&'static str> {
|
||||
Ok("I am reversed")
|
||||
}
|
||||
|
@ -313,12 +327,14 @@ fn reversed() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let c = py.init(|t| Reversed{token: t}).unwrap();
|
||||
let c = py.init(|t| Reversed { token: t }).unwrap();
|
||||
py_run!(py, c, "assert reversed(c) == 'I am reversed'");
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
struct Contains {token: PyToken}
|
||||
struct Contains {
|
||||
token: PyToken,
|
||||
}
|
||||
|
||||
#[pyproto]
|
||||
impl PySequenceProtocol for Contains {
|
||||
|
@ -332,13 +348,12 @@ fn contains() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let c = py.init(|t| Contains{token: t}).unwrap();
|
||||
let c = py.init(|t| Contains { token: t }).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", TypeError);
|
||||
}
|
||||
|
||||
|
||||
#[pyclass]
|
||||
struct ContextManager {
|
||||
exit_called: bool,
|
||||
|
@ -347,15 +362,16 @@ struct ContextManager {
|
|||
|
||||
#[pyproto]
|
||||
impl<'p> PyContextProtocol<'p> for ContextManager {
|
||||
|
||||
fn __enter__(&mut self) -> PyResult<i32> {
|
||||
Ok(42)
|
||||
}
|
||||
|
||||
fn __exit__(&mut self,
|
||||
ty: Option<&'p PyType>,
|
||||
_value: Option<&'p PyObjectRef>,
|
||||
_traceback: Option<&'p PyObjectRef>) -> PyResult<bool> {
|
||||
fn __exit__(
|
||||
&mut self,
|
||||
ty: Option<&'p PyType>,
|
||||
_value: Option<&'p PyObjectRef>,
|
||||
_traceback: Option<&'p PyObjectRef>,
|
||||
) -> PyResult<bool> {
|
||||
self.exit_called = true;
|
||||
if ty == Some(self.py().get_type::<exc::ValueError>()) {
|
||||
Ok(true)
|
||||
|
@ -370,7 +386,11 @@ fn context_manager() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let c = py.init_mut(|t| ContextManager{exit_called: false, token: t}).unwrap();
|
||||
let c =
|
||||
py.init_mut(|t| ContextManager {
|
||||
exit_called: false,
|
||||
token: t,
|
||||
}).unwrap();
|
||||
py_run!(py, c, "with c as x: assert x == 42");
|
||||
assert!(c.exit_called);
|
||||
|
||||
|
@ -380,11 +400,14 @@ fn context_manager() {
|
|||
|
||||
c.exit_called = false;
|
||||
py_expect_exception!(
|
||||
py, c, "with c as x: raise NotImplementedError", NotImplementedError);
|
||||
py,
|
||||
c,
|
||||
"with c as x: raise NotImplementedError",
|
||||
NotImplementedError
|
||||
);
|
||||
assert!(c.exit_called);
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_basics() {
|
||||
let gil = Python::acquire_gil();
|
||||
|
@ -400,22 +423,20 @@ fn test_basics() {
|
|||
|
||||
#[pyclass]
|
||||
struct Test {
|
||||
token: PyToken
|
||||
token: PyToken,
|
||||
}
|
||||
|
||||
#[pyproto]
|
||||
impl<'p> PyMappingProtocol<'p> for Test
|
||||
{
|
||||
impl<'p> PyMappingProtocol<'p> for Test {
|
||||
fn __getitem__(&self, idx: &PyObjectRef) -> PyResult<PyObject> {
|
||||
if let Ok(slice) = idx.cast_as::<PySlice>() {
|
||||
let indices = slice.indices(1000)?;
|
||||
if indices.start == 100 && indices.stop == 200 && indices.step == 1 {
|
||||
return Ok("slice".into_object(self.py()))
|
||||
return Ok("slice".into_object(self.py()));
|
||||
}
|
||||
}
|
||||
else if let Ok(idx) = idx.extract::<isize>() {
|
||||
} else if let Ok(idx) = idx.extract::<isize>() {
|
||||
if idx == 1 {
|
||||
return Ok("int".into_object(self.py()))
|
||||
return Ok("int".into_object(self.py()));
|
||||
}
|
||||
}
|
||||
Err(PyErr::new::<exc::ValueError, _>("error"))
|
||||
|
@ -427,12 +448,13 @@ fn test_cls_impl() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let ob = py.init(|t| Test{token: t}).unwrap();
|
||||
let ob = py.init(|t| Test { token: t }).unwrap();
|
||||
let d = PyDict::new(py);
|
||||
d.set_item("ob", ob).unwrap();
|
||||
|
||||
py.run("assert ob[1] == 'int'", None, Some(d)).unwrap();
|
||||
py.run("assert ob[100:200:1] == 'slice'", None, Some(d)).unwrap();
|
||||
py.run("assert ob[100:200:1] == 'slice'", None, Some(d))
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[pyclass(dict)]
|
||||
|
@ -444,11 +466,15 @@ struct DunderDictSupport {
|
|||
fn dunder_dict_support() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let inst = Py::new_ref(py, |t| DunderDictSupport{token: t}).unwrap();
|
||||
py_run!(py, inst, r#"
|
||||
let inst = Py::new_ref(py, |t| DunderDictSupport { token: t }).unwrap();
|
||||
py_run!(
|
||||
py,
|
||||
inst,
|
||||
r#"
|
||||
inst.a = 1
|
||||
assert inst.a == 1
|
||||
"#);
|
||||
"#
|
||||
);
|
||||
}
|
||||
|
||||
#[pyclass(weakref, dict)]
|
||||
|
@ -460,6 +486,10 @@ struct WeakRefDunderDictSupport {
|
|||
fn weakref_dunder_dict_support() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let inst = Py::new_ref(py, |t| WeakRefDunderDictSupport{token: t}).unwrap();
|
||||
py_run!(py, inst, "import weakref; assert weakref.ref(inst)() is inst; inst.a = 1; assert inst.a == 1");
|
||||
let inst = Py::new_ref(py, |t| WeakRefDunderDictSupport { token: t }).unwrap();
|
||||
py_run!(
|
||||
py,
|
||||
inst,
|
||||
"import weakref; assert weakref.ref(inst)() is inst; inst.a = 1; assert inst.a == 1"
|
||||
);
|
||||
}
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
extern crate pyo3;
|
||||
|
||||
use pyo3::ffi;
|
||||
use pyo3::prelude::*;
|
||||
use std::sync::Arc;
|
||||
use std::cell::RefCell;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use pyo3::ffi;
|
||||
use std::sync::Arc;
|
||||
|
||||
use pyo3::py::class as pyclass;
|
||||
use pyo3::py::methods as pymethods;
|
||||
|
@ -15,9 +15,10 @@ use pyo3::py::proto as pyproto;
|
|||
#[macro_use]
|
||||
mod common;
|
||||
|
||||
|
||||
#[pyclass(freelist=2)]
|
||||
struct ClassWithFreelist{token: PyToken}
|
||||
#[pyclass(freelist = 2)]
|
||||
struct ClassWithFreelist {
|
||||
token: PyToken,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn class_with_freelist() {
|
||||
|
@ -26,8 +27,8 @@ fn class_with_freelist() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let inst = Py::new(py, |t| ClassWithFreelist{token: t}).unwrap();
|
||||
let _inst2 = Py::new(py, |t| ClassWithFreelist{token: t}).unwrap();
|
||||
let inst = Py::new(py, |t| ClassWithFreelist { token: t }).unwrap();
|
||||
let _inst2 = Py::new(py, |t| ClassWithFreelist { token: t }).unwrap();
|
||||
ptr = inst.as_ptr();
|
||||
drop(inst);
|
||||
}
|
||||
|
@ -36,16 +37,16 @@ fn class_with_freelist() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let inst3 = Py::new(py, |t| ClassWithFreelist{token: t}).unwrap();
|
||||
let inst3 = Py::new(py, |t| ClassWithFreelist { token: t }).unwrap();
|
||||
assert_eq!(ptr, inst3.as_ptr());
|
||||
|
||||
let inst4 = Py::new(py, |t| ClassWithFreelist{token: t}).unwrap();
|
||||
let inst4 = Py::new(py, |t| ClassWithFreelist { token: t }).unwrap();
|
||||
assert_ne!(ptr, inst4.as_ptr())
|
||||
}
|
||||
}
|
||||
|
||||
struct TestDropCall {
|
||||
drop_called: Arc<AtomicBool>
|
||||
drop_called: Arc<AtomicBool>,
|
||||
}
|
||||
impl Drop for TestDropCall {
|
||||
fn drop(&mut self) {
|
||||
|
@ -69,11 +70,16 @@ fn data_is_dropped() {
|
|||
{
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let inst = py.init(|t| DataIsDropped{
|
||||
member1: TestDropCall { drop_called: Arc::clone(&drop_called1) },
|
||||
member2: TestDropCall { drop_called: Arc::clone(&drop_called2) },
|
||||
token: t
|
||||
}).unwrap();
|
||||
let inst =
|
||||
py.init(|t| DataIsDropped {
|
||||
member1: TestDropCall {
|
||||
drop_called: Arc::clone(&drop_called1),
|
||||
},
|
||||
member2: TestDropCall {
|
||||
drop_called: Arc::clone(&drop_called2),
|
||||
},
|
||||
token: t,
|
||||
}).unwrap();
|
||||
assert!(!drop_called1.load(Ordering::Relaxed));
|
||||
assert!(!drop_called2.load(Ordering::Relaxed));
|
||||
drop(inst);
|
||||
|
@ -112,20 +118,20 @@ fn create_pointers_in_drop() {
|
|||
let empty = PyTuple::empty(py);
|
||||
ptr = empty.as_ptr();
|
||||
cnt = empty.get_refcnt() - 1;
|
||||
let inst = py.init(|t| ClassWithDrop{token: t}).unwrap();
|
||||
let inst = py.init(|t| ClassWithDrop { token: t }).unwrap();
|
||||
drop(inst);
|
||||
}
|
||||
|
||||
// empty1 and empty2 are still alive (stored in pointers list)
|
||||
{
|
||||
let _gil = Python::acquire_gil();
|
||||
assert_eq!(cnt + 2, unsafe {ffi::Py_REFCNT(ptr)});
|
||||
assert_eq!(cnt + 2, unsafe { ffi::Py_REFCNT(ptr) });
|
||||
}
|
||||
|
||||
// empty1 and empty2 should be released
|
||||
{
|
||||
let _gil = Python::acquire_gil();
|
||||
assert_eq!(cnt, unsafe {ffi::Py_REFCNT(ptr)});
|
||||
assert_eq!(cnt, unsafe { ffi::Py_REFCNT(ptr) });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -155,10 +161,13 @@ fn gc_integration() {
|
|||
{
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let inst = Py::new_ref(py, |t| GCIntegration{
|
||||
let inst = Py::new_ref(py, |t| GCIntegration {
|
||||
self_ref: RefCell::new(py.None()),
|
||||
dropped: TestDropCall { drop_called: Arc::clone(&drop_called) },
|
||||
token: t}).unwrap();
|
||||
dropped: TestDropCall {
|
||||
drop_called: Arc::clone(&drop_called),
|
||||
},
|
||||
token: t,
|
||||
}).unwrap();
|
||||
|
||||
*inst.self_ref.borrow_mut() = inst.into();
|
||||
}
|
||||
|
@ -177,7 +186,7 @@ struct GCIntegration2 {
|
|||
fn gc_integration2() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let inst = Py::new_ref(py, |t| GCIntegration2{token: t}).unwrap();
|
||||
let inst = Py::new_ref(py, |t| GCIntegration2 { token: t }).unwrap();
|
||||
py_run!(py, inst, "import gc; assert inst in gc.get_objects()");
|
||||
}
|
||||
|
||||
|
@ -189,8 +198,12 @@ struct WeakRefSupport {
|
|||
fn weakref_support() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let inst = Py::new_ref(py, |t| WeakRefSupport{token: t}).unwrap();
|
||||
py_run!(py, inst, "import weakref; assert weakref.ref(inst)() is inst");
|
||||
let inst = Py::new_ref(py, |t| WeakRefSupport { token: t }).unwrap();
|
||||
py_run!(
|
||||
py,
|
||||
inst,
|
||||
"import weakref; assert weakref.ref(inst)() is inst"
|
||||
);
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
@ -203,7 +216,10 @@ struct BaseClassWithDrop {
|
|||
impl BaseClassWithDrop {
|
||||
#[new]
|
||||
fn __new__(obj: &PyRawObject) -> PyResult<()> {
|
||||
obj.init(|t| BaseClassWithDrop{token: t, data: None})
|
||||
obj.init(|t| BaseClassWithDrop {
|
||||
token: t,
|
||||
data: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -225,7 +241,10 @@ struct SubClassWithDrop {
|
|||
impl SubClassWithDrop {
|
||||
#[new]
|
||||
fn __new__(obj: &PyRawObject) -> PyResult<()> {
|
||||
obj.init(|t| SubClassWithDrop{token: t, data: None})?;
|
||||
obj.init(|t| SubClassWithDrop {
|
||||
token: t,
|
||||
data: None,
|
||||
})?;
|
||||
BaseClassWithDrop::__new__(obj)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@ use pyo3::py::methods as pymethods;
|
|||
#[macro_use]
|
||||
mod common;
|
||||
|
||||
|
||||
#[pyclass]
|
||||
struct ClassWithProperties {
|
||||
num: i32,
|
||||
|
@ -20,7 +19,6 @@ struct ClassWithProperties {
|
|||
|
||||
#[pymethods]
|
||||
impl ClassWithProperties {
|
||||
|
||||
fn get_num(&self) -> PyResult<i32> {
|
||||
Ok(self.num)
|
||||
}
|
||||
|
@ -41,7 +39,9 @@ fn class_with_properties() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let inst = py.init(|t| ClassWithProperties{num: 10, token: t}).unwrap();
|
||||
let inst = py
|
||||
.init(|t| ClassWithProperties { num: 10, token: t })
|
||||
.unwrap();
|
||||
|
||||
py_run!(py, inst, "assert inst.get_num() == 10");
|
||||
py_run!(py, inst, "assert inst.get_num() == inst.DATA");
|
||||
|
@ -56,12 +56,11 @@ struct GetterSetter {
|
|||
num: i32,
|
||||
#[prop(get, set)]
|
||||
text: String,
|
||||
token: PyToken
|
||||
token: PyToken,
|
||||
}
|
||||
|
||||
#[pymethods]
|
||||
impl GetterSetter {
|
||||
|
||||
fn get_num2(&self) -> PyResult<i32> {
|
||||
Ok(self.num)
|
||||
}
|
||||
|
@ -72,9 +71,18 @@ fn getter_setter_autogen() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let inst = py.init(|t| GetterSetter{num: 10, token: t, text: "Hello".to_string()}).unwrap();
|
||||
let inst =
|
||||
py.init(|t| GetterSetter {
|
||||
num: 10,
|
||||
token: t,
|
||||
text: "Hello".to_string(),
|
||||
}).unwrap();
|
||||
|
||||
py_run!(py, inst, "assert inst.num == 10");
|
||||
py_run!(py, inst, "inst.num = 20; assert inst.num == 20");
|
||||
py_run!(py, inst, "assert inst.text == 'Hello'; inst.text = 'There'; assert inst.text == 'There'");
|
||||
py_run!(
|
||||
py,
|
||||
inst,
|
||||
"assert inst.text == 'Hello'; inst.text = 'There'; assert inst.text == 'There'"
|
||||
);
|
||||
}
|
||||
|
|
|
@ -11,14 +11,12 @@ use pyo3::py::methods as pymethods;
|
|||
#[macro_use]
|
||||
mod common;
|
||||
|
||||
|
||||
#[pyclass]
|
||||
struct BaseClass {
|
||||
#[prop(get)]
|
||||
val1: usize,
|
||||
}
|
||||
|
||||
|
||||
#[pyclass(subclass)]
|
||||
struct SubclassAble {}
|
||||
|
||||
|
@ -28,17 +26,21 @@ fn subclass() {
|
|||
let py = gil.python();
|
||||
|
||||
let d = PyDict::new(py);
|
||||
d.set_item("SubclassAble", py.get_type::<SubclassAble>()).unwrap();
|
||||
py.run("class A(SubclassAble): pass\nassert issubclass(A, SubclassAble)", None, Some(d))
|
||||
.map_err(|e| e.print(py))
|
||||
.unwrap();
|
||||
d.set_item("SubclassAble", py.get_type::<SubclassAble>())
|
||||
.unwrap();
|
||||
py.run(
|
||||
"class A(SubclassAble): pass\nassert issubclass(A, SubclassAble)",
|
||||
None,
|
||||
Some(d),
|
||||
).map_err(|e| e.print(py))
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[pymethods]
|
||||
impl BaseClass {
|
||||
#[new]
|
||||
fn __new__(obj: &PyRawObject) -> PyResult<()> {
|
||||
obj.init(|_| BaseClass{val1: 10})
|
||||
obj.init(|_| BaseClass { val1: 10 })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,7 +54,7 @@ struct SubClass {
|
|||
impl SubClass {
|
||||
#[new]
|
||||
fn __new__(obj: &PyRawObject) -> PyResult<()> {
|
||||
obj.init(|_| SubClass{val2: 5})?;
|
||||
obj.init(|_| SubClass { val2: 5 })?;
|
||||
BaseClass::__new__(obj)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ mod common;
|
|||
#[pyclass]
|
||||
struct InstanceMethod {
|
||||
member: i32,
|
||||
token: PyToken
|
||||
token: PyToken,
|
||||
}
|
||||
|
||||
#[pymethods]
|
||||
|
@ -29,18 +29,23 @@ fn instance_method() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let obj = py.init_ref(|t| InstanceMethod{member: 42, token: t}).unwrap();
|
||||
let obj =
|
||||
py.init_ref(|t| InstanceMethod {
|
||||
member: 42,
|
||||
token: t,
|
||||
}).unwrap();
|
||||
assert!(obj.method().unwrap() == 42);
|
||||
let d = PyDict::new(py);
|
||||
d.set_item("obj", obj).unwrap();
|
||||
py.run("assert obj.method() == 42", None, Some(d)).unwrap();
|
||||
py.run("assert obj.method.__doc__ == 'Test method'", None, Some(d)).unwrap();
|
||||
py.run("assert obj.method.__doc__ == 'Test method'", None, Some(d))
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
struct InstanceMethodWithArgs {
|
||||
member: i32,
|
||||
token: PyToken
|
||||
token: PyToken,
|
||||
}
|
||||
|
||||
#[pymethods]
|
||||
|
@ -56,23 +61,29 @@ fn instance_method_with_args() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let obj = py.init_ref(|t| InstanceMethodWithArgs{member: 7, token: t}).unwrap();
|
||||
let obj =
|
||||
py.init_ref(|t| InstanceMethodWithArgs {
|
||||
member: 7,
|
||||
token: t,
|
||||
}).unwrap();
|
||||
assert!(obj.method(6).unwrap() == 42);
|
||||
let d = PyDict::new(py);
|
||||
d.set_item("obj", obj).unwrap();
|
||||
py.run("assert obj.method(3) == 21", None, Some(d)).unwrap();
|
||||
py.run("assert obj.method(multiplier=6) == 42", None, Some(d)).unwrap();
|
||||
py.run("assert obj.method(multiplier=6) == 42", None, Some(d))
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
|
||||
#[pyclass]
|
||||
struct ClassMethod {token: PyToken}
|
||||
struct ClassMethod {
|
||||
token: PyToken,
|
||||
}
|
||||
|
||||
#[pymethods]
|
||||
impl ClassMethod {
|
||||
#[new]
|
||||
fn __new__(obj: &PyRawObject) -> PyResult<()> {
|
||||
obj.init(|t| ClassMethod{token: t})
|
||||
obj.init(|t| ClassMethod { token: t })
|
||||
}
|
||||
|
||||
#[classmethod]
|
||||
|
@ -88,13 +99,22 @@ fn class_method() {
|
|||
|
||||
let d = PyDict::new(py);
|
||||
d.set_item("C", py.get_type::<ClassMethod>()).unwrap();
|
||||
py.run("assert C.method() == 'ClassMethod.method()!'", None, Some(d)).unwrap();
|
||||
py.run("assert C().method() == 'ClassMethod.method()!'", None, Some(d)).unwrap();
|
||||
py.run(
|
||||
"assert C.method() == 'ClassMethod.method()!'",
|
||||
None,
|
||||
Some(d),
|
||||
).unwrap();
|
||||
py.run(
|
||||
"assert C().method() == 'ClassMethod.method()!'",
|
||||
None,
|
||||
Some(d),
|
||||
).unwrap();
|
||||
}
|
||||
|
||||
|
||||
#[pyclass]
|
||||
struct ClassMethodWithArgs{token: PyToken}
|
||||
struct ClassMethodWithArgs {
|
||||
token: PyToken,
|
||||
}
|
||||
|
||||
#[pymethods]
|
||||
impl ClassMethodWithArgs {
|
||||
|
@ -110,20 +130,25 @@ fn class_method_with_args() {
|
|||
let py = gil.python();
|
||||
|
||||
let d = PyDict::new(py);
|
||||
d.set_item("C", py.get_type::<ClassMethodWithArgs>()).unwrap();
|
||||
py.run("assert C.method('abc') == 'ClassMethodWithArgs.method(abc)'", None, Some(d)).unwrap();
|
||||
d.set_item("C", py.get_type::<ClassMethodWithArgs>())
|
||||
.unwrap();
|
||||
py.run(
|
||||
"assert C.method('abc') == 'ClassMethodWithArgs.method(abc)'",
|
||||
None,
|
||||
Some(d),
|
||||
).unwrap();
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
struct StaticMethod {
|
||||
token: PyToken
|
||||
token: PyToken,
|
||||
}
|
||||
|
||||
#[pymethods]
|
||||
impl StaticMethod {
|
||||
#[new]
|
||||
fn __new__(obj: &PyRawObject) -> PyResult<()> {
|
||||
obj.init(|t| StaticMethod{token: t})
|
||||
obj.init(|t| StaticMethod { token: t })
|
||||
}
|
||||
|
||||
#[staticmethod]
|
||||
|
@ -140,16 +165,25 @@ fn static_method() {
|
|||
assert_eq!(StaticMethod::method(py).unwrap(), "StaticMethod.method()!");
|
||||
let d = PyDict::new(py);
|
||||
d.set_item("C", py.get_type::<StaticMethod>()).unwrap();
|
||||
py.run("assert C.method() == 'StaticMethod.method()!'", None, Some(d)).unwrap();
|
||||
py.run("assert C().method() == 'StaticMethod.method()!'", None, Some(d)).unwrap();
|
||||
py.run(
|
||||
"assert C.method() == 'StaticMethod.method()!'",
|
||||
None,
|
||||
Some(d),
|
||||
).unwrap();
|
||||
py.run(
|
||||
"assert C().method() == 'StaticMethod.method()!'",
|
||||
None,
|
||||
Some(d),
|
||||
).unwrap();
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
struct StaticMethodWithArgs{token: PyToken}
|
||||
struct StaticMethodWithArgs {
|
||||
token: PyToken,
|
||||
}
|
||||
|
||||
#[pymethods]
|
||||
impl StaticMethodWithArgs {
|
||||
|
||||
#[staticmethod]
|
||||
fn method(_py: Python, input: i32) -> PyResult<String> {
|
||||
Ok(format!("0x{:x}", input))
|
||||
|
@ -164,32 +198,33 @@ fn static_method_with_args() {
|
|||
assert_eq!(StaticMethodWithArgs::method(py, 1234).unwrap(), "0x4d2");
|
||||
|
||||
let d = PyDict::new(py);
|
||||
d.set_item("C", py.get_type::<StaticMethodWithArgs>()).unwrap();
|
||||
py.run("assert C.method(1337) == '0x539'", None, Some(d)).unwrap();
|
||||
d.set_item("C", py.get_type::<StaticMethodWithArgs>())
|
||||
.unwrap();
|
||||
py.run("assert C.method(1337) == '0x539'", None, Some(d))
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
struct MethArgs {
|
||||
token: PyToken
|
||||
token: PyToken,
|
||||
}
|
||||
|
||||
#[pymethods]
|
||||
impl MethArgs {
|
||||
|
||||
#[args(test)]
|
||||
fn get_optional(&self, test: Option<i32>) -> PyResult<i32> {
|
||||
Ok(test.unwrap_or(10))
|
||||
}
|
||||
|
||||
#[args(test="10")]
|
||||
#[args(test = "10")]
|
||||
fn get_default(&self, test: i32) -> PyResult<i32> {
|
||||
Ok(test)
|
||||
}
|
||||
#[args("*", test=10)]
|
||||
#[args("*", test = 10)]
|
||||
fn get_kwarg(&self, test: i32) -> PyResult<i32> {
|
||||
Ok(test)
|
||||
}
|
||||
#[args(args="*", kwargs="**")]
|
||||
#[args(args = "*", kwargs = "**")]
|
||||
fn get_kwargs(&self, args: &PyTuple, kwargs: Option<&PyDict>) -> PyResult<PyObject> {
|
||||
Ok([args.into(), kwargs.to_object(self.py())].to_object(self.py()))
|
||||
}
|
||||
|
@ -199,7 +234,7 @@ impl MethArgs {
|
|||
fn meth_args() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let inst = py.init(|t| MethArgs{token: t}).unwrap();
|
||||
let inst = py.init(|t| MethArgs { token: t }).unwrap();
|
||||
|
||||
py_run!(py, inst, "assert inst.get_optional() == 10");
|
||||
py_run!(py, inst, "assert inst.get_optional(100) == 100");
|
||||
|
@ -210,7 +245,15 @@ fn meth_args() {
|
|||
py_run!(py, inst, "assert inst.get_kwarg(test=100) == 100");
|
||||
py_run!(py, inst, "assert inst.get_kwargs() == [(), None]");
|
||||
py_run!(py, inst, "assert inst.get_kwargs(1,2,3) == [(1,2,3), None]");
|
||||
py_run!(py, inst, "assert inst.get_kwargs(t=1,n=2) == [(), {'t': 1, 'n': 2}]");
|
||||
py_run!(py, inst, "assert inst.get_kwargs(1,2,3,t=1,n=2) == [(1,2,3), {'t': 1, 'n': 2}]");
|
||||
py_run!(
|
||||
py,
|
||||
inst,
|
||||
"assert inst.get_kwargs(t=1,n=2) == [(), {'t': 1, 'n': 2}]"
|
||||
);
|
||||
py_run!(
|
||||
py,
|
||||
inst,
|
||||
"assert inst.get_kwargs(1,2,3,t=1,n=2) == [(1,2,3), {'t': 1, 'n': 2}]"
|
||||
);
|
||||
// py_expect_exception!(py, inst, "inst.get_kwarg(100)", TypeError);
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ extern crate pyo3;
|
|||
use pyo3::prelude::*;
|
||||
use pyo3::py::{class, function, modinit};
|
||||
|
||||
|
||||
#[class]
|
||||
struct EmptyClass {}
|
||||
|
||||
|
@ -50,28 +49,33 @@ fn test_module_with_functions() {
|
|||
let py = gil.python();
|
||||
|
||||
let d = PyDict::new(py);
|
||||
d.set_item("module_with_functions", unsafe { PyObject::from_owned_ptr(py, PyInit_module_with_functions()) }).unwrap();
|
||||
py.run("assert module_with_functions.__doc__ == 'This module is implemented in Rust.'", None, Some(d)).unwrap();
|
||||
py.run("assert module_with_functions.sum_as_string(1, 2) == '3'", None, Some(d)).unwrap();
|
||||
py.run("assert module_with_functions.no_parameters() == 42", None, Some(d)).unwrap();
|
||||
py.run("assert module_with_functions.foo == 'bar'", None, Some(d)).unwrap();
|
||||
py.run("assert module_with_functions.EmptyClass != None", None, Some(d)).unwrap();
|
||||
py.run("assert module_with_functions.double(3) == 6", None, Some(d)).unwrap();
|
||||
py.run("assert module_with_functions.also_double(3) == 6", None, Some(d)).unwrap();
|
||||
d.set_item("module_with_functions", unsafe {
|
||||
PyObject::from_owned_ptr(py, PyInit_module_with_functions())
|
||||
}).unwrap();
|
||||
|
||||
let run = |code| py.run(code, None, Some(d)).unwrap();
|
||||
|
||||
run("assert module_with_functions.__doc__ == 'This module is implemented in Rust.'");
|
||||
run("assert module_with_functions.sum_as_string(1, 2) == '3'");
|
||||
run("assert module_with_functions.no_parameters() == 42");
|
||||
run("assert module_with_functions.foo == 'bar'");
|
||||
run("assert module_with_functions.EmptyClass != None");
|
||||
run("assert module_with_functions.double(3) == 6");
|
||||
run("assert module_with_functions.also_double(3) == 6");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(Py_3)]
|
||||
fn test_module_from_code() {
|
||||
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let adder_mod = PyModule::from_code(py,
|
||||
let adder_mod = PyModule::from_code(
|
||||
py,
|
||||
"def add(a,b):\n\treturn a+b",
|
||||
"adder_mod.py",
|
||||
"adder_mod")
|
||||
.expect("Module code should be loaded");
|
||||
"adder_mod",
|
||||
).expect("Module code should be loaded");
|
||||
|
||||
let add_func = adder_mod
|
||||
.get("add")
|
||||
|
|
|
@ -19,7 +19,6 @@ struct MutRefArg {
|
|||
|
||||
#[pymethods]
|
||||
impl MutRefArg {
|
||||
|
||||
fn get(&self) -> PyResult<i32> {
|
||||
Ok(self.n)
|
||||
}
|
||||
|
@ -33,8 +32,8 @@ impl MutRefArg {
|
|||
fn mut_ref_arg() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let inst1 = py.init(|t| MutRefArg{token: t, n: 0}).unwrap();
|
||||
let inst2 = py.init(|t| MutRefArg{token: t, n: 0}).unwrap();
|
||||
let inst1 = py.init(|t| MutRefArg { token: t, n: 0 }).unwrap();
|
||||
let inst2 = py.init(|t| MutRefArg { token: t, n: 0 }).unwrap();
|
||||
|
||||
let d = PyDict::new(py);
|
||||
d.set_item("inst1", &inst1).unwrap();
|
||||
|
|
Loading…
Reference in New Issue