diff --git a/CHANGELOG.md b/CHANGELOG.md index c29d803b..6c2c4654 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ # Changelog + All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) @@ -10,22 +11,31 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. * Added a `wrap_pymodule!` macro similar to the existing `wrap_pyfunction!` macro. Only available on python 3 * Added support for cross compiling (e.g. to arm v7) by mtp401 in [#327](https://github.com/PyO3/pyo3/pull/327). See the "Cross Compiling" section in the "Building and Distribution" chapter of the guide for more details. + * The `PyRef` and `PyRefMut` types, which allow to differentiate between an instance of a rust struct on the rust heap and an instance that is embedded inside a python object. By kngwyu in [#335](https://github.com/PyO3/pyo3/pull/335) ### Changed * Renamed `add_function` to `add_wrapped` as it now also supports modules. - * Renamed `#[pymodinit]` to `#[pymodule]`. - * `init`, `init_ref` and `init_mut` now take a value instead of a function that returns the value. (Migrating normally just removing `||`) - * Renamed `py_exception` to `create_exception` and refactored the error macros. + * Renamed `#[pymodinit]` to `#[pymodule]` + * `py.init(|| value)` becomes `Py::new(value)` + * `py.init_ref(|| value)` becomes `PyRef::new(value)` + * `py.init_mut(|| value)` becomes `PyRefMut::new(value)`. + * `PyRawObject::init` is now infallible, e.g. it returns `()` instead of `PyResult<()>`. + * Renamed `py_exception!` to `create_exception!` and refactored the error macros. * Renamed `wrap_function!` to `wrap_pyfunction!` * Migrated to the 2018 edition * Replace `IntoPyTuple` with `IntoPy>`. Eventually `IntoPy` should replace `ToPyObject` and be itself implemented through `FromPy` + * PyTypeObject is now a direct subtrait PyTypeCreate, removing the old cyclical implementation in [#350](https://github.com/PyO3/pyo3/pull/350) ### Removed * `PyToken` was removed due to unsoundness (See [#94](https://github.com/PyO3/pyo3/issues/94)). * Removed the unnecessary type parameter from `PyObjectAlloc` +### Fixed + + * A soudness hole where every instances of a `#[pyclass]` struct was considered to be part of a python object, even though you can create instances that are not part of the python heap. This was fixed through `PyRef` and `PyRefMut`. + ## [0.5.3] - 2019-01-04 ### Fixed diff --git a/Cargo.toml b/Cargo.toml index add83a70..1c0b0af2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pyo3" -version = "0.6.0-alpha.2" +version = "0.6.0-alpha.3" description = "Bindings to Python interpreter" authors = ["PyO3 Project and Contributors "] readme = "README.md" diff --git a/examples/rustapi_module/src/datetime.rs b/examples/rustapi_module/src/datetime.rs index 6af0c83e..359d584e 100644 --- a/examples/rustapi_module/src/datetime.rs +++ b/examples/rustapi_module/src/datetime.rs @@ -191,7 +191,7 @@ pub struct TzClass {} impl TzClass { #[new] fn __new__(obj: &PyRawObject) -> PyResult<()> { - obj.init(TzClass {}) + Ok(obj.init(TzClass {})) } fn utcoffset(&self, py: Python<'_>, _dt: &PyDateTime) -> PyResult> { diff --git a/examples/rustapi_module/src/dict_iter.rs b/examples/rustapi_module/src/dict_iter.rs index 626a4d46..69cf5bb8 100644 --- a/examples/rustapi_module/src/dict_iter.rs +++ b/examples/rustapi_module/src/dict_iter.rs @@ -17,7 +17,7 @@ pub struct DictSize { impl DictSize { #[new] fn __new__(obj: &PyRawObject, expected: u32) -> PyResult<()> { - obj.init(DictSize { expected }) + Ok(obj.init(DictSize { expected })) } fn iter_dict(&mut self, _py: Python<'_>, dict: &PyDict) -> PyResult { diff --git a/examples/rustapi_module/src/othermod.rs b/examples/rustapi_module/src/othermod.rs index 651d5e3b..0f6f3f6b 100644 --- a/examples/rustapi_module/src/othermod.rs +++ b/examples/rustapi_module/src/othermod.rs @@ -14,9 +14,9 @@ pub struct ModClass { impl ModClass { #[new] fn __new__(obj: &PyRawObject) -> PyResult<()> { - obj.init(ModClass { + Ok(obj.init(ModClass { _somefield: String::from("contents"), - }) + })) } fn noop(&self, x: usize) -> usize { diff --git a/examples/rustapi_module/src/subclassing.rs b/examples/rustapi_module/src/subclassing.rs index 6b32bb6f..4e4ce0db 100644 --- a/examples/rustapi_module/src/subclassing.rs +++ b/examples/rustapi_module/src/subclassing.rs @@ -9,7 +9,7 @@ pub struct Subclassable {} impl Subclassable { #[new] fn __new__(obj: &PyRawObject) -> PyResult<()> { - obj.init(Subclassable {}) + Ok(obj.init(Subclassable {})) } } diff --git a/examples/word-count/src/lib.rs b/examples/word-count/src/lib.rs index f7407906..f6aeb81e 100644 --- a/examples/word-count/src/lib.rs +++ b/examples/word-count/src/lib.rs @@ -17,9 +17,9 @@ struct WordCounter { impl WordCounter { #[new] fn __new__(obj: &PyRawObject, path: String) -> PyResult<()> { - obj.init(WordCounter { + Ok(obj.init(WordCounter { path: PathBuf::from(path), - }) + })) } /// Searches for the word, parallelized by rayon diff --git a/src/freelist.rs b/src/freelist.rs index 0f8fc7ed..bff7286b 100644 --- a/src/freelist.rs +++ b/src/freelist.rs @@ -2,7 +2,6 @@ //! Free allocation list -use crate::err::PyResult; use crate::ffi; use crate::python::Python; use crate::typeob::{pytype_drop, PyObjectAlloc, PyTypeInfo}; @@ -72,15 +71,13 @@ impl PyObjectAlloc for T where T: PyObjectWithFreeList, { - unsafe fn alloc(_py: Python) -> PyResult<*mut ffi::PyObject> { - let obj = if let Some(obj) = ::get_free_list().pop() { + unsafe fn alloc(_py: Python) -> *mut ffi::PyObject { + if let Some(obj) = ::get_free_list().pop() { ffi::PyObject_Init(obj, ::type_object()); obj } else { ffi::PyType_GenericAlloc(::type_object(), 0) - }; - - Ok(obj) + } } #[cfg(Py_3)] diff --git a/src/instance.rs b/src/instance.rs index e2bf93dd..44093442 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -71,7 +71,7 @@ where { pub fn new(py: Python, value: T) -> PyResult> { let obj = T::create(py)?; - obj.init(value)?; + obj.init(value); let ref_ = unsafe { py.from_owned_ptr(obj.into_ptr()) }; Ok(PyRef::from_ref(ref_)) } @@ -134,7 +134,7 @@ where { pub fn new(py: Python, value: T) -> PyResult> { let obj = T::create(py)?; - obj.init(value)?; + obj.init(value); let ref_ = unsafe { py.mut_from_owned_ptr(obj.into_ptr()) }; Ok(PyRefMut::from_mut(ref_)) } @@ -257,15 +257,30 @@ pub trait AsPyRef: Sized { } /// Safe wrapper around unsafe `*mut ffi::PyObject` pointer with specified type information. +/// +/// `Py` is thread-safe, because any python related operations require a Python<'p> token. #[derive(Debug)] #[repr(transparent)] pub struct Py(NonNull, std::marker::PhantomData); -// `Py` is thread-safe, because any python related operations require a Python<'p> token. unsafe impl Send for Py {} unsafe impl Sync for Py {} +impl Py +where + T: PyTypeCreate + PyTypeObject, +{ + /// Create new instance of T and move it under python management + pub fn new(py: Python, value: T) -> PyResult> { + let ob = T::create(py)?; + ob.init(value); + + let ob = unsafe { Py::from_owned_ptr(ob.into_ptr()) }; + Ok(ob) + } +} + impl Py { /// Creates a `Py` instance for the given FFI pointer. /// This moves ownership over the pointer into the `Py`. @@ -338,48 +353,6 @@ impl Py { } } -impl Py -where - T: PyTypeCreate, -{ - /// Create new instance of T and move it under python management - /// Returns `Py`. - pub fn new(py: Python, value: T) -> PyResult> - where - T: PyTypeObject + PyTypeInfo, - { - let ob = ::create(py)?; - ob.init(value)?; - - let ob = unsafe { Py::from_owned_ptr(ob.into_ptr()) }; - Ok(ob) - } - - /// Create new instance of `T` and move it under python management. - /// Returns references to `T` - pub fn new_ref(py: Python, value: T) -> PyResult<&T> - where - T: PyTypeObject + PyTypeInfo, - { - let ob = ::create(py)?; - ob.init(value)?; - - unsafe { Ok(py.from_owned_ptr(ob.into_ptr())) } - } - - /// Create new instance of `T` and move it under python management. - /// Returns mutable references to `T` - pub fn new_mut(py: Python, value: T) -> PyResult<&mut T> - where - T: PyTypeObject + PyTypeInfo, - { - let ob = ::create(py)?; - ob.init(value)?; - - unsafe { Ok(py.mut_from_owned_ptr(ob.into_ptr())) } - } -} - /// Specialization workaround trait AsPyRefDispatch: ToPyPointer { fn as_ref_dispatch(&self, _py: Python) -> &T { diff --git a/src/typeob.rs b/src/typeob.rs index 8f1a314f..93c23578 100644 --- a/src/typeob.rs +++ b/src/typeob.rs @@ -83,7 +83,7 @@ pub const PY_TYPE_FLAG_DICT: usize = 1 << 3; /// impl MyClass { /// #[new] /// fn __new__(obj: &PyRawObject) -> PyResult<()> { -/// obj.init(MyClass { }) +/// Ok(obj.init(MyClass { })) /// } /// } /// ``` @@ -139,16 +139,12 @@ impl PyRawObject { } } - pub fn init(&self, value: T) -> PyResult<()> - where - T: PyTypeInfo, - { + pub fn init(&self, value: T) { unsafe { // The `as *mut u8` part is required because the offset is in bytes let ptr = (self.ptr as *mut u8).offset(T::OFFSET) as *mut T; std::ptr::write(ptr, value); } - Ok(()) } /// Type object @@ -195,12 +191,10 @@ pub(crate) unsafe fn pytype_drop(py: Python, obj: *mut ffi::PyObj /// All native types and all `#[pyclass]` types use the default functions, while /// [PyObjectWithFreeList](crate::freelist::PyObjectWithFreeList) gets a special version. pub trait PyObjectAlloc: PyTypeInfo + Sized { - unsafe fn alloc(_py: Python) -> PyResult<*mut ffi::PyObject> { + unsafe fn alloc(_py: Python) -> *mut ffi::PyObject { let tp_ptr = Self::type_object(); let alloc = (*tp_ptr).tp_alloc.unwrap_or(ffi::PyType_GenericAlloc); - let obj = alloc(tp_ptr, 0); - - Ok(obj) + alloc(tp_ptr, 0) } /// Calls the rust destructor for the object and frees the memory @@ -286,7 +280,7 @@ pub trait PyTypeCreate: PyObjectAlloc + PyTypeObject + Sized { Self::init_type(); unsafe { - let ptr = Self::alloc(py)?; + let ptr = Self::alloc(py); PyRawObject::new_with_ptr( py, ptr, diff --git a/tests/test_arithmetics.rs b/tests/test_arithmetics.rs index 365ad535..f043e107 100644 --- a/tests/test_arithmetics.rs +++ b/tests/test_arithmetics.rs @@ -32,7 +32,7 @@ fn unary_arithmetic() { let gil = Python::acquire_gil(); let py = gil.python(); - let c = py.init(UnaryArithmetic {}).unwrap(); + let c = Py::new(py, UnaryArithmetic {}).unwrap(); py_run!(py, c, "assert -c == 'neg'"); py_run!(py, c, "assert +c == 'pos'"); py_run!(py, c, "assert abs(c) == 'abs'"); @@ -110,7 +110,7 @@ fn inplace_operations() { let py = gil.python(); let init = |value, code| { - let c = py.init(InPlaceOperations { value }).unwrap(); + let c = Py::new(py, InPlaceOperations { value }).unwrap(); py_run!(py, c, code); }; @@ -164,7 +164,7 @@ fn binary_arithmetic() { let gil = Python::acquire_gil(); let py = gil.python(); - let c = py.init(BinaryArithmetic {}).unwrap(); + let c = Py::new(py, BinaryArithmetic {}).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'"); @@ -230,7 +230,7 @@ fn rich_comparisons() { let gil = Python::acquire_gil(); let py = gil.python(); - let c = py.init(RichComparisons {}).unwrap(); + let c = Py::new(py, RichComparisons {}).unwrap(); py_run!(py, c, "assert (c < c) == 'RC < RC'"); py_run!(py, c, "assert (c < 1) == 'RC < 1'"); py_run!(py, c, "assert (1 < c) == 'RC > 1'"); @@ -257,7 +257,7 @@ fn rich_comparisons_python_3_type_error() { let gil = Python::acquire_gil(); let py = gil.python(); - let c2 = py.init(RichComparisons2 {}).unwrap(); + let c2 = Py::new(py, RichComparisons2 {}).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); diff --git a/tests/test_buffer_protocol.rs b/tests/test_buffer_protocol.rs index 7619c44e..9fcd0501 100644 --- a/tests/test_buffer_protocol.rs +++ b/tests/test_buffer_protocol.rs @@ -65,11 +65,13 @@ fn test_buffer() { let gil = Python::acquire_gil(); let py = gil.python(); - let t = py - .init(TestClass { + let t = Py::new( + py, + TestClass { vec: vec![b' ', b'2', b'3'], - }) - .unwrap(); + }, + ) + .unwrap(); let d = PyDict::new(py); d.set_item("ob", t).unwrap(); @@ -82,11 +84,13 @@ fn test_buffer() { let gil = Python::acquire_gil(); let py = gil.python(); - let t = py - .init(TestClass { + let t = Py::new( + py, + TestClass { vec: vec![b' ', b'2', b'3'], - }) - .unwrap(); + }, + ) + .unwrap(); let d = PyDict::new(py); d.set_item("ob", t).unwrap(); diff --git a/tests/test_class_new.rs b/tests/test_class_new.rs index 31ff99d9..1fa5074d 100644 --- a/tests/test_class_new.rs +++ b/tests/test_class_new.rs @@ -8,7 +8,7 @@ struct EmptyClassWithNew {} impl EmptyClassWithNew { #[__new__] fn __new__(obj: &PyRawObject) -> PyResult<()> { - obj.init(EmptyClassWithNew {}) + Ok(obj.init(EmptyClassWithNew {})) } } @@ -33,7 +33,7 @@ struct NewWithOneArg { impl NewWithOneArg { #[new] fn __new__(obj: &PyRawObject, arg: i32) -> PyResult<()> { - obj.init(NewWithOneArg { _data: arg }) + Ok(obj.init(NewWithOneArg { _data: arg })) } } @@ -57,10 +57,10 @@ struct NewWithTwoArgs { impl NewWithTwoArgs { #[new] fn __new__(obj: &PyRawObject, arg1: i32, arg2: i32) -> PyResult<()> { - obj.init(NewWithTwoArgs { + Ok(obj.init(NewWithTwoArgs { _data1: arg1, _data2: arg2, - }) + })) } } diff --git a/tests/test_dunder.rs b/tests/test_dunder.rs index 03beaf77..86eaaf04 100644 --- a/tests/test_dunder.rs +++ b/tests/test_dunder.rs @@ -188,7 +188,7 @@ fn sequence() { let gil = Python::acquire_gil(); let py = gil.python(); - let c = py.init(Sequence {}).unwrap(); + let c = Py::new(py, Sequence {}).unwrap(); py_assert!(py, c, "list(c) == [0, 1, 2, 3, 4]"); py_expect_exception!(py, c, "c['abc']", TypeError); } @@ -209,11 +209,11 @@ fn callable() { let gil = Python::acquire_gil(); let py = gil.python(); - let c = py.init(Callable {}).unwrap(); + let c = Py::new(py, Callable {}).unwrap(); py_assert!(py, c, "callable(c)"); py_assert!(py, c, "c(7) == 42"); - let nc = py.init(Comparisons { val: 0 }).unwrap(); + let nc = Py::new(py, Comparisons { val: 0 }).unwrap(); py_assert!(py, nc, "not callable(nc)"); } @@ -237,7 +237,7 @@ fn setitem() { let gil = Python::acquire_gil(); let py = gil.python(); - let c = py.init_ref(SetItem { key: 0, val: 0 }).unwrap(); + let c = PyRef::new(py, SetItem { key: 0, val: 0 }).unwrap(); py_run!(py, c, "c[1] = 2"); assert_eq!(c.key, 1); assert_eq!(c.val, 2); @@ -262,7 +262,7 @@ fn delitem() { let gil = Python::acquire_gil(); let py = gil.python(); - let c = py.init_ref(DelItem { key: 0 }).unwrap(); + let c = PyRef::new(py, DelItem { key: 0 }).unwrap(); py_run!(py, c, "del c[1]"); assert_eq!(c.key, 1); py_expect_exception!(py, c, "c[1] = 2", NotImplementedError); @@ -291,7 +291,7 @@ fn setdelitem() { let gil = Python::acquire_gil(); let py = gil.python(); - let c = py.init_ref(SetDelItem { val: None }).unwrap(); + let c = PyRef::new(py, SetDelItem { val: None }).unwrap(); py_run!(py, c, "c[1] = 2"); assert_eq!(c.val, Some(2)); py_run!(py, c, "del c[1]"); @@ -313,7 +313,7 @@ fn reversed() { let gil = Python::acquire_gil(); let py = gil.python(); - let c = py.init(Reversed {}).unwrap(); + let c = Py::new(py, Reversed {}).unwrap(); py_run!(py, c, "assert reversed(c) == 'I am reversed'"); } @@ -332,7 +332,7 @@ fn contains() { let gil = Python::acquire_gil(); let py = gil.python(); - let c = py.init(Contains {}).unwrap(); + 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", TypeError); @@ -370,7 +370,7 @@ fn context_manager() { let gil = Python::acquire_gil(); let py = gil.python(); - let mut c = py.init_mut(ContextManager { exit_called: false }).unwrap(); + let mut c = PyRefMut::new(py, ContextManager { exit_called: false }).unwrap(); py_run!(py, c, "with c as x: assert x == 42"); assert!(c.exit_called); @@ -427,7 +427,7 @@ fn test_cls_impl() { let gil = Python::acquire_gil(); let py = gil.python(); - let ob = py.init(Test {}).unwrap(); + let ob = Py::new(py, Test {}).unwrap(); let d = PyDict::new(py); d.set_item("ob", ob).unwrap(); diff --git a/tests/test_gc.rs b/tests/test_gc.rs index c912ef60..5106b07e 100644 --- a/tests/test_gc.rs +++ b/tests/test_gc.rs @@ -67,16 +67,15 @@ fn data_is_dropped() { { let gil = Python::acquire_gil(); let py = gil.python(); - let inst = py - .init(DataIsDropped { - member1: TestDropCall { - drop_called: Arc::clone(&drop_called1), - }, - member2: TestDropCall { - drop_called: Arc::clone(&drop_called2), - }, - }) - .unwrap(); + let data_is_dropped = DataIsDropped { + member1: TestDropCall { + drop_called: Arc::clone(&drop_called1), + }, + member2: TestDropCall { + drop_called: Arc::clone(&drop_called2), + }, + }; + let inst = Py::new(py, data_is_dropped).unwrap(); assert!(!drop_called1.load(Ordering::Relaxed)); assert!(!drop_called2.load(Ordering::Relaxed)); drop(inst); @@ -114,7 +113,7 @@ fn create_pointers_in_drop() { let empty = PyTuple::empty(py); ptr = empty.as_ptr(); cnt = empty.get_refcnt() - 1; - let inst = py.init(ClassWithDrop {}).unwrap(); + let inst = Py::new(py, ClassWithDrop {}).unwrap(); drop(inst); } @@ -215,7 +214,7 @@ struct BaseClassWithDrop { impl BaseClassWithDrop { #[new] fn __new__(obj: &PyRawObject) -> PyResult<()> { - obj.init(BaseClassWithDrop { data: None }) + Ok(obj.init(BaseClassWithDrop { data: None })) } } @@ -236,7 +235,7 @@ struct SubClassWithDrop { impl SubClassWithDrop { #[new] fn __new__(obj: &PyRawObject) -> PyResult<()> { - obj.init(SubClassWithDrop { data: None })?; + obj.init(SubClassWithDrop { data: None }); BaseClassWithDrop::__new__(obj) } } diff --git a/tests/test_getter_setter.rs b/tests/test_getter_setter.rs index 0f5c5bbd..bc2de94e 100644 --- a/tests/test_getter_setter.rs +++ b/tests/test_getter_setter.rs @@ -31,7 +31,7 @@ fn class_with_properties() { let gil = Python::acquire_gil(); let py = gil.python(); - let inst = py.init(ClassWithProperties { num: 10 }).unwrap(); + let inst = Py::new(py, ClassWithProperties { num: 10 }).unwrap(); py_run!(py, inst, "assert inst.get_num() == 10"); py_run!(py, inst, "assert inst.get_num() == inst.DATA"); @@ -60,12 +60,14 @@ fn getter_setter_autogen() { let gil = Python::acquire_gil(); let py = gil.python(); - let inst = py - .init(GetterSetter { + let inst = Py::new( + py, + GetterSetter { num: 10, text: "Hello".to_string(), - }) - .unwrap(); + }, + ) + .unwrap(); py_run!(py, inst, "assert inst.num == 10"); py_run!(py, inst, "inst.num = 20; assert inst.num == 20"); diff --git a/tests/test_inheritance.rs b/tests/test_inheritance.rs index 7ec3003c..f13785ea 100644 --- a/tests/test_inheritance.rs +++ b/tests/test_inheritance.rs @@ -35,7 +35,7 @@ fn subclass() { impl BaseClass { #[new] fn __new__(obj: &PyRawObject) -> PyResult<()> { - obj.init(BaseClass { val1: 10 }) + Ok(obj.init(BaseClass { val1: 10 })) } } @@ -49,7 +49,7 @@ struct SubClass { impl SubClass { #[new] fn __new__(obj: &PyRawObject) -> PyResult<()> { - obj.init(SubClass { val2: 5 })?; + obj.init(SubClass { val2: 5 }); BaseClass::__new__(obj) } } diff --git a/tests/test_methods.rs b/tests/test_methods.rs index fe80d3bb..956d1882 100644 --- a/tests/test_methods.rs +++ b/tests/test_methods.rs @@ -23,7 +23,7 @@ fn instance_method() { let gil = Python::acquire_gil(); let py = gil.python(); - let obj = py.init_ref(InstanceMethod { member: 42 }).unwrap(); + let obj = PyRefMut::new(py, InstanceMethod { member: 42 }).unwrap(); assert_eq!(obj.method().unwrap(), 42); let d = PyDict::new(py); d.set_item("obj", obj).unwrap(); @@ -50,7 +50,7 @@ fn instance_method_with_args() { let gil = Python::acquire_gil(); let py = gil.python(); - let obj = py.init_ref(InstanceMethodWithArgs { member: 7 }).unwrap(); + let obj = PyRefMut::new(py, InstanceMethodWithArgs { member: 7 }).unwrap(); assert_eq!(obj.method(6).unwrap(), 42); let d = PyDict::new(py); d.set_item("obj", obj).unwrap(); @@ -66,7 +66,7 @@ struct ClassMethod {} impl ClassMethod { #[new] fn __new__(obj: &PyRawObject) -> PyResult<()> { - obj.init(ClassMethod {}) + Ok(obj.init(ClassMethod {})) } #[classmethod] @@ -130,7 +130,7 @@ struct StaticMethod {} impl StaticMethod { #[new] fn __new__(obj: &PyRawObject) -> PyResult<()> { - obj.init(StaticMethod {}) + Ok(obj.init(StaticMethod {})) } #[staticmethod] @@ -219,7 +219,7 @@ impl MethArgs { fn meth_args() { let gil = Python::acquire_gil(); let py = gil.python(); - let inst = py.init(MethArgs {}).unwrap(); + let inst = Py::new(py, MethArgs {}).unwrap(); py_run!(py, inst, "assert inst.get_optional() == 10"); py_run!(py, inst, "assert inst.get_optional(100) == 100"); diff --git a/tests/test_various.rs b/tests/test_various.rs index 74bcff9c..a0ab5a42 100644 --- a/tests/test_various.rs +++ b/tests/test_various.rs @@ -26,8 +26,8 @@ impl MutRefArg { fn mut_ref_arg() { let gil = Python::acquire_gil(); let py = gil.python(); - let inst1 = py.init(MutRefArg { n: 0 }).unwrap(); - let inst2 = py.init(MutRefArg { n: 0 }).unwrap(); + let inst1 = Py::new(py, MutRefArg { n: 0 }).unwrap(); + let inst2 = Py::new(py, MutRefArg { n: 0 }).unwrap(); let d = PyDict::new(py); d.set_item("inst1", &inst1).unwrap();