Remove the unnecessary type parameter PyObjectAlloc

This commit is contained in:
konstin 2018-11-12 14:37:06 +01:00
parent c77049541a
commit d2ba436d6d
4 changed files with 70 additions and 70 deletions

View File

@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
## [Unreleased] ## [Unreleased]
### Removed
* Removed the unnecessary type parameter from `PyObjectAlloc`
## [0.5.0] - 2018-11-11 ## [0.5.0] - 2018-11-11
### Added ### Added

View File

@ -3,9 +3,6 @@
#[macro_use] #[macro_use]
extern crate pyo3; extern crate pyo3;
use pyo3::prelude::*;
use subclassing::Subclassable;
pub mod datetime; pub mod datetime;
pub mod othermod; pub mod othermod;
pub mod subclassing; pub mod subclassing;

View File

@ -68,16 +68,16 @@ impl<T> FreeList<T> {
} }
} }
impl<T> PyObjectAlloc<T> for T impl<T> PyObjectAlloc for T
where where
T: PyObjectWithFreeList, T: PyObjectWithFreeList,
{ {
unsafe fn alloc(_py: Python) -> PyResult<*mut ffi::PyObject> { unsafe fn alloc(_py: Python) -> PyResult<*mut ffi::PyObject> {
let obj = if let Some(obj) = <T as PyObjectWithFreeList>::get_free_list().pop() { let obj = if let Some(obj) = <Self as PyObjectWithFreeList>::get_free_list().pop() {
ffi::PyObject_Init(obj, <T as PyTypeInfo>::type_object()); ffi::PyObject_Init(obj, <Self as PyTypeInfo>::type_object());
obj obj
} else { } else {
ffi::PyType_GenericAlloc(<T as PyTypeInfo>::type_object(), 0) ffi::PyType_GenericAlloc(<Self as PyTypeInfo>::type_object(), 0)
}; };
Ok(obj) Ok(obj)
@ -85,14 +85,14 @@ where
#[cfg(Py_3)] #[cfg(Py_3)]
unsafe fn dealloc(py: Python, obj: *mut ffi::PyObject) { unsafe fn dealloc(py: Python, obj: *mut ffi::PyObject) {
pytype_drop::<T>(py, obj); pytype_drop::<Self>(py, obj);
if ffi::PyObject_CallFinalizerFromDealloc(obj) < 0 { if ffi::PyObject_CallFinalizerFromDealloc(obj) < 0 {
return; return;
} }
if let Some(obj) = <T as PyObjectWithFreeList>::get_free_list().insert(obj) { if let Some(obj) = <Self as PyObjectWithFreeList>::get_free_list().insert(obj) {
match (*T::type_object()).tp_free { match Self::type_object().tp_free {
Some(free) => free(obj as *mut c_void), Some(free) => free(obj as *mut c_void),
None => { None => {
let ty = ffi::Py_TYPE(obj); let ty = ffi::Py_TYPE(obj);
@ -114,10 +114,10 @@ where
#[cfg(not(Py_3))] #[cfg(not(Py_3))]
unsafe fn dealloc(py: Python, obj: *mut ffi::PyObject) { unsafe fn dealloc(py: Python, obj: *mut ffi::PyObject) {
pytype_drop::<T>(py, obj); pytype_drop::<Self>(py, obj);
if let Some(obj) = <T as PyObjectWithFreeList>::get_free_list().insert(obj) { if let Some(obj) = <Self as PyObjectWithFreeList>::get_free_list().insert(obj) {
match (*T::type_object()).tp_free { match Self::type_object().tp_free {
Some(free) => free(obj as *mut c_void), Some(free) => free(obj as *mut c_void),
None => { None => {
let ty = ffi::Py_TYPE(obj); let ty = ffi::Py_TYPE(obj);

View File

@ -2,20 +2,21 @@
//! Python type object information //! Python type object information
use crate::class::methods::PyMethodDefType;
use crate::err::{PyErr, PyResult};
use crate::instance::{Py, PyObjectWithToken, PyToken};
use crate::python::ToPyPointer;
use crate::python::{IntoPyPointer, Python};
use crate::types::PyObjectRef;
use crate::types::PyType;
use crate::{class, ffi, pythonrun};
use std; use std;
use std::collections::HashMap; use std::collections::HashMap;
use std::ffi::CString; use std::ffi::CString;
use std::mem; use std::mem;
use std::os::raw::c_void; use std::os::raw::c_void;
use crate::{class, ffi, pythonrun};
use crate::class::methods::PyMethodDefType;
use crate::err::{PyErr, PyResult};
use crate::instance::{Py, PyObjectWithToken, PyToken};
use crate::python::{IntoPyPointer, Python};
use crate::python::ToPyPointer;
use crate::types::PyObjectRef;
use crate::types::PyType;
/// Python type information. /// Python type information.
pub trait PyTypeInfo { pub trait PyTypeInfo {
/// Type of objects to store in PyObject struct /// Type of objects to store in PyObject struct
@ -143,9 +144,9 @@ impl PyRawObject {
} }
pub fn init<T, F>(&self, f: F) -> PyResult<()> pub fn init<T, F>(&self, f: F) -> PyResult<()>
where where
F: FnOnce(PyToken) -> T, F: FnOnce(PyToken) -> T,
T: PyTypeInfo, T: PyTypeInfo,
{ {
let value = f(PyToken::new()); let value = f(PyToken::new());
@ -196,7 +197,7 @@ pub(crate) unsafe fn pytype_drop<T: PyTypeInfo>(py: Python, obj: *mut ffi::PyObj
} }
/// A Python object allocator that is usable as a base type for `#[pyclass]` /// A Python object allocator that is usable as a base type for `#[pyclass]`
pub trait PyObjectAlloc<T> { pub trait PyObjectAlloc: PyTypeInfo {
/// Allocates a new object (usually by calling ty->tp_alloc), /// Allocates a new object (usually by calling ty->tp_alloc),
unsafe fn alloc(py: Python) -> PyResult<*mut ffi::PyObject>; unsafe fn alloc(py: Python) -> PyResult<*mut ffi::PyObject>;
@ -209,21 +210,19 @@ pub trait PyObjectAlloc<T> {
unsafe fn drop(_py: Python, _obj: *mut ffi::PyObject) {} unsafe fn drop(_py: Python, _obj: *mut ffi::PyObject) {}
} }
impl<T> PyObjectAlloc<T> for T impl<T> PyObjectAlloc for T where T: PyTypeInfo
where
T: PyTypeInfo,
{ {
#[allow(unconditional_recursion)] #[allow(unconditional_recursion)]
/// Calls the rust destructor for the object. /// Calls the rust destructor for the object.
default unsafe fn drop(py: Python, obj: *mut ffi::PyObject) { default unsafe fn drop(py: Python, obj: *mut ffi::PyObject) {
pytype_drop::<T>(py, obj); pytype_drop::<Self>(py, obj);
} }
default unsafe fn alloc(_py: Python) -> PyResult<*mut ffi::PyObject> { default unsafe fn alloc(_py: Python) -> PyResult<*mut ffi::PyObject> {
// TODO: remove this // TODO: remove this
<T as PyTypeCreate>::init_type(); <Self as PyTypeCreate>::init_type();
let tp_ptr = T::type_object(); let tp_ptr = Self::type_object();
let alloc = (*tp_ptr).tp_alloc.unwrap_or(ffi::PyType_GenericAlloc); let alloc = (*tp_ptr).tp_alloc.unwrap_or(ffi::PyType_GenericAlloc);
let obj = alloc(tp_ptr, 0); let obj = alloc(tp_ptr, 0);
@ -234,13 +233,13 @@ where
Self::drop(py, obj); Self::drop(py, obj);
#[cfg(Py_3)] #[cfg(Py_3)]
{ {
if ffi::PyObject_CallFinalizerFromDealloc(obj) < 0 { if ffi::PyObject_CallFinalizerFromDealloc(obj) < 0 {
return; return;
}
} }
}
match (*T::type_object()).tp_free { match Self::type_object().tp_free {
Some(free) => free(obj as *mut c_void), Some(free) => free(obj as *mut c_void),
None => { None => {
let ty = ffi::Py_TYPE(obj); let ty = ffi::Py_TYPE(obj);
@ -271,7 +270,7 @@ pub trait PyTypeObject {
/// Python object types that have a corresponding type object and be /// Python object types that have a corresponding type object and be
/// instanciated with [Self::create()] /// instanciated with [Self::create()]
pub trait PyTypeCreate: PyObjectAlloc<Self> + PyTypeInfo + Sized { pub trait PyTypeCreate: PyObjectAlloc + PyTypeInfo + Sized {
#[inline] #[inline]
fn init_type() { fn init_type() {
let type_object = unsafe { *<Self as PyTypeInfo>::type_object() }; let type_object = unsafe { *<Self as PyTypeInfo>::type_object() };
@ -299,7 +298,7 @@ pub trait PyTypeCreate: PyObjectAlloc<Self> + PyTypeInfo + Sized {
<Self as PyTypeObject>::init_type(); <Self as PyTypeObject>::init_type();
unsafe { unsafe {
let ptr = <Self as PyObjectAlloc<Self>>::alloc(py)?; let ptr = <Self as PyObjectAlloc>::alloc(py)?;
PyRawObject::new_with_ptr( PyRawObject::new_with_ptr(
py, py,
ptr, ptr,
@ -310,11 +309,11 @@ pub trait PyTypeCreate: PyObjectAlloc<Self> + PyTypeInfo + Sized {
} }
} }
impl<T> PyTypeCreate for T where T: PyObjectAlloc<Self> + PyTypeInfo + Sized {} impl<T> PyTypeCreate for T where T: PyObjectAlloc + PyTypeInfo + Sized {}
impl<T> PyTypeObject for T impl<T> PyTypeObject for T
where where
T: PyTypeCreate, T: PyTypeCreate,
{ {
fn init_type() { fn init_type() {
<T as PyTypeCreate>::init_type() <T as PyTypeCreate>::init_type()
@ -328,8 +327,8 @@ where
/// Register new type in python object system. /// Register new type in python object system.
#[cfg(not(Py_LIMITED_API))] #[cfg(not(Py_LIMITED_API))]
pub fn initialize_type<T>(py: Python, module_name: Option<&str>) -> PyResult<()> pub fn initialize_type<T>(py: Python, module_name: Option<&str>) -> PyResult<()>
where where
T: PyObjectAlloc<T> + PyTypeInfo, T: PyObjectAlloc + PyTypeInfo,
{ {
// type name // type name
let name = match module_name { let name = match module_name {
@ -466,12 +465,12 @@ fn async_methods<T>(type_info: &mut ffi::PyTypeObject) {
fn async_methods<T>(_type_info: &mut ffi::PyTypeObject) {} fn async_methods<T>(_type_info: &mut ffi::PyTypeObject) {}
unsafe extern "C" fn tp_dealloc_callback<T>(obj: *mut ffi::PyObject) unsafe extern "C" fn tp_dealloc_callback<T>(obj: *mut ffi::PyObject)
where where
T: PyObjectAlloc<T>, T: PyObjectAlloc,
{ {
let _pool = pythonrun::GILPool::new_no_pointers(); let _pool = pythonrun::GILPool::new_no_pointers();
let py = Python::assume_gil_acquired(); let py = Python::assume_gil_acquired();
<T as PyObjectAlloc<T>>::dealloc(py, obj) <T as PyObjectAlloc>::dealloc(py, obj)
} }
#[cfg(Py_3)] #[cfg(Py_3)]
@ -479,9 +478,9 @@ fn py_class_flags<T: PyTypeInfo>(type_object: &mut ffi::PyTypeObject) {
if type_object.tp_traverse != None if type_object.tp_traverse != None
|| type_object.tp_clear != None || type_object.tp_clear != None
|| T::FLAGS & PY_TYPE_FLAG_GC != 0 || T::FLAGS & PY_TYPE_FLAG_GC != 0
{ {
type_object.tp_flags = ffi::Py_TPFLAGS_DEFAULT | ffi::Py_TPFLAGS_HAVE_GC; type_object.tp_flags = ffi::Py_TPFLAGS_DEFAULT | ffi::Py_TPFLAGS_HAVE_GC;
} else { } else {
type_object.tp_flags = ffi::Py_TPFLAGS_DEFAULT; type_object.tp_flags = ffi::Py_TPFLAGS_DEFAULT;
} }
if T::FLAGS & PY_TYPE_FLAG_BASETYPE != 0 { if T::FLAGS & PY_TYPE_FLAG_BASETYPE != 0 {
@ -494,10 +493,10 @@ fn py_class_flags<T: PyTypeInfo>(type_object: &mut ffi::PyTypeObject) {
if type_object.tp_traverse != None if type_object.tp_traverse != None
|| type_object.tp_clear != None || type_object.tp_clear != None
|| T::FLAGS & PY_TYPE_FLAG_GC != 0 || T::FLAGS & PY_TYPE_FLAG_GC != 0
{ {
type_object.tp_flags = type_object.tp_flags =
ffi::Py_TPFLAGS_DEFAULT | ffi::Py_TPFLAGS_CHECKTYPES | ffi::Py_TPFLAGS_HAVE_GC; ffi::Py_TPFLAGS_DEFAULT | ffi::Py_TPFLAGS_CHECKTYPES | ffi::Py_TPFLAGS_HAVE_GC;
} else { } else {
type_object.tp_flags = ffi::Py_TPFLAGS_DEFAULT | ffi::Py_TPFLAGS_CHECKTYPES; type_object.tp_flags = ffi::Py_TPFLAGS_DEFAULT | ffi::Py_TPFLAGS_CHECKTYPES;
} }
if !type_object.tp_as_buffer.is_null() { if !type_object.tp_as_buffer.is_null() {
@ -586,27 +585,27 @@ fn py_class_properties<T>() -> Vec<ffi::PyGetSetDef> {
for def in <T as class::methods::PyMethodsProtocolImpl>::py_methods() for def in <T as class::methods::PyMethodsProtocolImpl>::py_methods()
.iter() .iter()
.chain(<T as class::methods::PyPropMethodsProtocolImpl>::py_methods().iter()) .chain(<T as class::methods::PyPropMethodsProtocolImpl>::py_methods().iter())
{ {
match *def { match *def {
PyMethodDefType::Getter(ref getter) => { PyMethodDefType::Getter(ref getter) => {
let name = getter.name.to_string(); let name = getter.name.to_string();
if !defs.contains_key(&name) { if !defs.contains_key(&name) {
let _ = defs.insert(name.clone(), ffi::PyGetSetDef_INIT); let _ = defs.insert(name.clone(), ffi::PyGetSetDef_INIT);
}
let def = defs.get_mut(&name).expect("Failed to call get_mut");
getter.copy_to(def);
} }
let def = defs.get_mut(&name).expect("Failed to call get_mut"); PyMethodDefType::Setter(ref setter) => {
getter.copy_to(def); let name = setter.name.to_string();
} if !defs.contains_key(&name) {
PyMethodDefType::Setter(ref setter) => { let _ = defs.insert(name.clone(), ffi::PyGetSetDef_INIT);
let name = setter.name.to_string(); }
if !defs.contains_key(&name) { let def = defs.get_mut(&name).expect("Failed to call get_mut");
let _ = defs.insert(name.clone(), ffi::PyGetSetDef_INIT); setter.copy_to(def);
} }
let def = defs.get_mut(&name).expect("Failed to call get_mut"); _ => (),
setter.copy_to(def);
} }
_ => (),
} }
}
defs.values().cloned().collect() defs.values().cloned().collect()
} }