diff --git a/src/object.rs b/src/object.rs index d52440dd..c465a8c8 100644 --- a/src/object.rs +++ b/src/object.rs @@ -162,7 +162,7 @@ impl PyObject { where D: FromPyObject<'p>, { - FromPyObject::extract(self.as_ref(py).into()) + FromPyObject::extract(self.as_ref(py)) } /// Retrieves an attribute value. diff --git a/src/pyclass.rs b/src/pyclass.rs index f772b2c0..8ec9897f 100644 --- a/src/pyclass.rs +++ b/src/pyclass.rs @@ -307,12 +307,21 @@ pub struct PyClassInitializer { super_init: Option<*mut PyClassInitializer>, } +impl Default for PyClassInitializer { + fn default() -> Self { + Self { + init: None, + super_init: None, + } + } +} + impl PyClassInitializer { /// Construct `PyClassInitializer` for specified value `value`. /// /// Same as /// ```ignore - /// let mut init = PyClassInitializer::(); + /// let mut init = PyClassInitializer::default::(); /// init.init(value); /// ``` pub fn from_value(value: T) -> Self { @@ -322,17 +331,8 @@ impl PyClassInitializer { } } - /// Make new `PyClassInitializer` with empty values. - pub fn new() -> Self { - PyClassInitializer { - init: None, - super_init: None, - } - } - #[must_use] - #[doc(hiddden)] - pub fn init_class(self, shell: &mut T::ConcreteLayout) -> PyResult<()> { + fn init_class(self, shell: &mut T::ConcreteLayout) -> PyResult<()> { macro_rules! raise_err { ($name: path) => { return Err(PyErr::new::(format!( @@ -369,7 +369,7 @@ impl PyClassInitializer { if let Some(super_init) = self.super_init { return unsafe { &mut *super_init }; } - let super_init = Box::into_raw(Box::new(PyClassInitializer::new())); + let super_init = Box::into_raw(Box::new(PyClassInitializer::default())); self.super_init = Some(super_init); unsafe { &mut *super_init } } diff --git a/src/pyclass_slots.rs b/src/pyclass_slots.rs index 60b57d46..b79a546c 100644 --- a/src/pyclass_slots.rs +++ b/src/pyclass_slots.rs @@ -1,5 +1,4 @@ //! This module contains additional fields pf pyclass -// TODO(kngwyu): Add vectorcall support use crate::{ffi, Python}; const POINTER_SIZE: isize = std::mem::size_of::<*mut ffi::PyObject>() as _; @@ -8,7 +7,7 @@ const POINTER_SIZE: isize = std::mem::size_of::<*mut ffi::PyObject>() as _; pub trait PyClassDict { const OFFSET: Option = None; fn new() -> Self; - fn clear_dict(&mut self, _py: Python) {} + unsafe fn clear_dict(&mut self, _py: Python) {} private_decl! {} } @@ -16,7 +15,7 @@ pub trait PyClassDict { pub trait PyClassWeakRef { const OFFSET: Option = None; fn new() -> Self; - fn clear_weakrefs(&mut self, _obj: *mut ffi::PyObject, _py: Python) {} + unsafe fn clear_weakrefs(&mut self, _obj: *mut ffi::PyObject, _py: Python) {} private_decl! {} } @@ -47,9 +46,9 @@ impl PyClassDict for PyClassDictSlot { fn new() -> Self { Self(std::ptr::null_mut()) } - fn clear_dict(&mut self, _py: Python) { - if self.0 != std::ptr::null_mut() { - unsafe { ffi::PyDict_Clear(self.0) } + unsafe fn clear_dict(&mut self, _py: Python) { + if !self.0.is_null() { + ffi::PyDict_Clear(self.0) } } } @@ -64,9 +63,9 @@ impl PyClassWeakRef for PyClassWeakRefSlot { fn new() -> Self { Self(std::ptr::null_mut()) } - fn clear_weakrefs(&mut self, obj: *mut ffi::PyObject, _py: Python) { - if self.0 != std::ptr::null_mut() { - unsafe { ffi::PyObject_ClearWeakRefs(obj) } + unsafe fn clear_weakrefs(&mut self, obj: *mut ffi::PyObject, _py: Python) { + if !self.0.is_null() { + ffi::PyObject_ClearWeakRefs(obj) } } } diff --git a/src/type_object.rs b/src/type_object.rs index 36f4d2ef..1db2070c 100644 --- a/src/type_object.rs +++ b/src/type_object.rs @@ -7,7 +7,11 @@ use crate::types::{PyAny, PyType}; use crate::{ffi, AsPyPointer, Python}; use std::ptr::NonNull; -/// TODO: write document +/// `T: PyObjectLayout` represents that `T` is a concrete representaion of `U` in Python heap. +/// E.g., `PyClassShell` is a concrete representaion of all `pyclass`es, and `ffi::PyObject` +/// is of `PyAny`. +/// +/// This trait is intended to be used internally. pub trait PyObjectLayout { const NEED_INIT: bool = false; const IS_NATIVE_TYPE: bool = true; @@ -19,6 +23,8 @@ pub trait PyObjectLayout { unsafe fn internal_ref_cast(obj: &PyAny) -> &T { &*(obj as *const _ as *const T) } + + #[allow(clippy::mut_from_ref)] unsafe fn internal_mut_cast(obj: &PyAny) -> &mut T { &mut *(obj as *const _ as *const T as *mut T) } @@ -27,6 +33,11 @@ pub trait PyObjectLayout { unsafe fn py_drop(&mut self, _py: Python) {} } +/// `T: PyObjectSizedLayout` represents `T` is not a instance of +/// [`PyVarObject`](https://docs.python.org/3.8/c-api/structures.html?highlight=pyvarobject#c.PyVarObject). +/// , in addition that `T` is a concrete representaion of `U`. +/// +/// `pyclass`es need this trait for their base class. pub trait PyObjectSizedLayout: PyObjectLayout + Sized {} /// Our custom type flags diff --git a/src/types/string.rs b/src/types/string.rs index b355e27e..51d490f1 100644 --- a/src/types/string.rs +++ b/src/types/string.rs @@ -207,7 +207,7 @@ mod test { let s = "Hello Python"; let py_string = s.to_object(py); - let s2: &str = FromPyObject::extract(py_string.as_ref(py).into()).unwrap(); + let s2: &str = FromPyObject::extract(py_string.as_ref(py)).unwrap(); assert_eq!(s, s2); } diff --git a/src/types/tuple.rs b/src/types/tuple.rs index 2626c71f..f7a62640 100644 --- a/src/types/tuple.rs +++ b/src/types/tuple.rs @@ -119,7 +119,7 @@ impl<'a> Iterator for PyTupleIterator<'a> { if self.index < self.slice.len() { let item = self.slice[self.index].as_ref(self.py); self.index += 1; - Some(item.into()) + Some(item) } else { None } diff --git a/tests/test_inheritance.rs b/tests/test_inheritance.rs index 19f6439e..0052bd51 100644 --- a/tests/test_inheritance.rs +++ b/tests/test_inheritance.rs @@ -91,7 +91,7 @@ struct InvalidSubClass2 { impl InvalidSubClass2 { #[new] fn new() -> PyClassInitializer { - PyClassInitializer::new() + PyClassInitializer::default() } }