Remove the unnecessary type parameter PyObjectAlloc
This commit is contained in:
parent
c77049541a
commit
d2ba436d6d
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
113
src/typeob.rs
113
src/typeob.rs
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue