remove py param
This commit is contained in:
parent
3ab5e4526c
commit
65a42a2b1a
|
@ -143,8 +143,7 @@ fn impl_class(cls: &syn::Ident, base: &syn::Ident,
|
|||
FREELIST = Box::into_raw(Box::new(
|
||||
_pyo3::freelist::FreeList::with_capacity(#freelist)));
|
||||
|
||||
<#cls as _pyo3::typeob::PyTypeObject>::init_type(
|
||||
_pyo3::Python::assume_gil_acquired());
|
||||
<#cls as _pyo3::typeob::PyTypeObject>::init_type();
|
||||
}
|
||||
&mut *FREELIST
|
||||
}
|
||||
|
@ -177,11 +176,10 @@ fn impl_class(cls: &syn::Ident, base: &syn::Ident,
|
|||
const NAME: &'static str = #cls_name;
|
||||
const DESCRIPTION: &'static str = #doc;
|
||||
|
||||
const SIZE: usize = Self::OFFSET as usize + std::mem::size_of::<#cls>();
|
||||
const SIZE: usize = Self::OFFSET as usize + std::mem::size_of::<#cls>() + #weakref;
|
||||
const OFFSET: isize = {
|
||||
// round base_size up to next multiple of align
|
||||
((<#base as _pyo3::typeob::PyTypeInfo>::SIZE + #weakref +
|
||||
std::mem::align_of::<#cls>() - 1) /
|
||||
((<#base as _pyo3::typeob::PyTypeInfo>::SIZE + std::mem::align_of::<#cls>()-1) /
|
||||
std::mem::align_of::<#cls>() * std::mem::align_of::<#cls>()) as isize
|
||||
};
|
||||
|
||||
|
@ -202,14 +200,17 @@ fn impl_class(cls: &syn::Ident, base: &syn::Ident,
|
|||
|
||||
impl _pyo3::typeob::PyTypeObject for #cls {
|
||||
#[inline(always)]
|
||||
fn init_type(py: Python) {
|
||||
fn init_type() {
|
||||
static START: std::sync::Once = std::sync::ONCE_INIT;
|
||||
START.call_once(|| {
|
||||
let mut ty = unsafe{<#cls as _pyo3::typeob::PyTypeInfo>::type_object()};
|
||||
let ty = unsafe{<#cls as _pyo3::typeob::PyTypeInfo>::type_object()};
|
||||
|
||||
if (ty.tp_flags & _pyo3::ffi::Py_TPFLAGS_READY) == 0 {
|
||||
let gil = _pyo3::Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
// automatically initialize the class on-demand
|
||||
_pyo3::typeob::initialize_type::<#cls>(py, None, ty).expect(
|
||||
_pyo3::typeob::initialize_type::<#cls>(py, None).expect(
|
||||
format!("An error occurred while initializing class {}",
|
||||
<#cls as _pyo3::typeob::PyTypeInfo>::NAME).as_ref());
|
||||
}
|
||||
|
|
25
src/err.rs
25
src/err.rs
|
@ -56,16 +56,19 @@ macro_rules! py_exception {
|
|||
$crate::PyErr::new::<$name, T>(py, args)
|
||||
}
|
||||
#[inline(always)]
|
||||
fn type_object(py: $crate::Python) -> *mut $crate::ffi::PyTypeObject {
|
||||
fn type_object() -> *mut $crate::ffi::PyTypeObject {
|
||||
#[allow(non_upper_case_globals)]
|
||||
static mut type_object: *mut $crate::ffi::PyTypeObject =
|
||||
0 as *mut $crate::ffi::PyTypeObject;
|
||||
|
||||
unsafe {
|
||||
if type_object.is_null() {
|
||||
let gil = $crate::Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
type_object = $crate::PyErr::new_type(
|
||||
py, concat!(stringify!($module), ".", stringify!($name)),
|
||||
Some(py.get_type::<$base>()), None).as_type_ptr();
|
||||
Some(py.get_type::<$base>()), None);
|
||||
}
|
||||
type_object
|
||||
}
|
||||
|
@ -74,13 +77,13 @@ macro_rules! py_exception {
|
|||
|
||||
impl $crate::typeob::PyTypeObject for $name {
|
||||
#[inline(always)]
|
||||
fn init_type(py: $crate::Python) {
|
||||
let _ = $name::type_object(py);
|
||||
fn init_type() {
|
||||
let _ = $name::type_object();
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn type_object<'p>(py: $crate::Python<'p>) -> &'p $crate::PyType {
|
||||
unsafe { $crate::PyType::from_type_ptr(py, $name::type_object(py)) }
|
||||
fn type_object() -> $crate::Py<$crate::PyType> {
|
||||
unsafe { $crate::PyType::new($name::type_object()) }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -143,9 +146,9 @@ impl PyErr {
|
|||
///
|
||||
/// `base` can be an existing exception type to subclass, or a tuple of classes
|
||||
/// `dict` specifies an optional dictionary of class variables and methods
|
||||
pub fn new_type<'p>(py: Python<'p>,
|
||||
pub fn new_type<'p>(_py: Python<'p>,
|
||||
name: &str, base: Option<&PyType>, dict: Option<PyObject>)
|
||||
-> &'p PyType
|
||||
-> *mut ffi::PyTypeObject
|
||||
{
|
||||
let base: *mut ffi::PyObject = match base {
|
||||
None => std::ptr::null_mut(),
|
||||
|
@ -159,10 +162,8 @@ impl PyErr {
|
|||
|
||||
unsafe {
|
||||
let null_terminated_name = CString::new(name).expect("Failed to initialize nul terminated exception name");
|
||||
let ptr = ffi::PyErr_NewException(
|
||||
null_terminated_name.as_ptr() as *mut c_char, base, dict)
|
||||
as *mut ffi::PyTypeObject;
|
||||
PyType::from_type_ptr(py, ptr)
|
||||
ffi::PyErr_NewException(null_terminated_name.as_ptr() as *mut c_char, base, dict)
|
||||
as *mut ffi::PyTypeObject
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,11 +22,13 @@ macro_rules! exc_type(
|
|||
|
||||
impl $crate::typeob::PyTypeObject for $name {
|
||||
#[inline(always)]
|
||||
fn init_type(_py: Python) {}
|
||||
fn init_type() {}
|
||||
|
||||
#[inline]
|
||||
fn type_object(py: $crate::python::Python) -> &$crate::PyType {
|
||||
unsafe { PyType::from_type_ptr(py, ffi::$exc_name as *mut ffi::PyTypeObject) }
|
||||
fn type_object() -> $crate::Py<$crate::PyType> {
|
||||
unsafe {
|
||||
PyType::new(ffi::$exc_name as *mut ffi::PyTypeObject)
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
|
|
@ -154,11 +154,14 @@ macro_rules! pyobject_nativetype(
|
|||
|
||||
impl $crate::typeob::PyTypeObject for $name {
|
||||
#[inline(always)]
|
||||
fn init_type(_py: $crate::Python) {}
|
||||
fn init_type() {}
|
||||
|
||||
#[inline]
|
||||
fn type_object(py: $crate::Python) -> &$crate::PyType {
|
||||
unsafe { $crate::PyType::from_type_ptr(py, &mut $crate::ffi::$typeobject) }
|
||||
fn type_object() -> $crate::Py<$crate::PyType> {
|
||||
unsafe {
|
||||
$crate::PyType::new(
|
||||
<$name as $crate::typeob::PyTypeInfo>::type_object())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -109,16 +109,18 @@ impl PyModule {
|
|||
/// and adds the type to this module.
|
||||
pub fn add_class<T>(&self) -> PyResult<()> where T: PyTypeInfo
|
||||
{
|
||||
let mut ty = unsafe{<T as PyTypeInfo>::type_object()};
|
||||
let ty = unsafe {
|
||||
let ty = <T as PyTypeInfo>::type_object();
|
||||
|
||||
let ty = if (ty.tp_flags & ffi::Py_TPFLAGS_READY) != 0 {
|
||||
unsafe { PyType::from_type_ptr(self.py(), ty) }
|
||||
} else {
|
||||
// automatically initialize the class
|
||||
initialize_type::<T>(self.py(), Some(self.name()?), ty)
|
||||
.expect(
|
||||
format!("An error occurred while initializing class {}", T::NAME).as_ref());
|
||||
unsafe { PyType::from_type_ptr(self.py(), ty) }
|
||||
if ((*ty).tp_flags & ffi::Py_TPFLAGS_READY) != 0 {
|
||||
PyType::new(ty)
|
||||
} else {
|
||||
// automatically initialize the class
|
||||
initialize_type::<T>(self.py(), Some(self.name()?))
|
||||
.expect(
|
||||
format!("An error occurred while initializing class {}", T::NAME).as_ref());
|
||||
PyType::new(ty)
|
||||
}
|
||||
};
|
||||
|
||||
self.setattr(T::NAME, ty)
|
||||
|
|
|
@ -101,6 +101,14 @@ impl PyBytes {
|
|||
}
|
||||
}
|
||||
|
||||
/// Creates a new Python byte string object from raw pointer.
|
||||
///
|
||||
/// Panics if out of memory.
|
||||
pub unsafe fn from_ptr(_py: Python, ptr: *const u8, len: usize) -> Py<PyBytes> {
|
||||
Py::from_owned_ptr_or_panic(
|
||||
ffi::PyBytes_FromStringAndSize(ptr as *const _, len as isize))
|
||||
}
|
||||
|
||||
/// Gets the Python string data as byte slice.
|
||||
pub fn data(&self) -> &[u8] {
|
||||
unsafe {
|
||||
|
|
|
@ -9,7 +9,7 @@ use ffi;
|
|||
use object::PyObject;
|
||||
use python::{Python, ToPyPointer};
|
||||
use err::{PyErr, PyResult};
|
||||
use instance::PyObjectWithToken;
|
||||
use instance::{Py, PyObjectWithToken};
|
||||
use typeob::PyTypeObject;
|
||||
|
||||
/// Represents a reference to a Python `type object`.
|
||||
|
@ -20,6 +20,12 @@ pyobject_nativetype!(PyType, PyType_Type, PyType_Check);
|
|||
|
||||
|
||||
impl PyType {
|
||||
#[inline]
|
||||
pub unsafe fn new(ptr: *mut ffi::PyTypeObject) -> Py<PyType>
|
||||
{
|
||||
Py::from_borrowed_ptr(ptr as *mut ffi::PyObject)
|
||||
}
|
||||
|
||||
/// Retrieves the underlying FFI pointer associated with this Python object.
|
||||
#[inline]
|
||||
pub unsafe fn as_type_ptr(&self) -> *mut ffi::PyTypeObject {
|
||||
|
@ -47,7 +53,7 @@ impl PyType {
|
|||
where T: PyTypeObject
|
||||
{
|
||||
let result = unsafe {
|
||||
ffi::PyObject_IsSubclass(self.as_ptr(), T::type_object(self.py()).as_ptr())
|
||||
ffi::PyObject_IsSubclass(self.as_ptr(), T::type_object().as_ptr())
|
||||
};
|
||||
if result == -1 {
|
||||
Err(PyErr::fetch(self.py()))
|
||||
|
|
|
@ -9,7 +9,7 @@ use std::os::raw::c_int;
|
|||
|
||||
use ffi;
|
||||
use typeob::{PyTypeInfo, PyTypeObject, PyObjectAlloc};
|
||||
use instance::{Py, PyToken, PyObjectWithToken};
|
||||
use instance::{Py, PyToken, PyObjectWithToken, AsPyRef};
|
||||
use object::PyObject;
|
||||
use objects::{PyObjectRef, PyType, PyDict, PyModule};
|
||||
use err::{PyErr, PyResult, PyDowncastError, ToPyErr};
|
||||
|
@ -231,7 +231,7 @@ impl<'p> Python<'p> {
|
|||
|
||||
/// Gets the Python type object for type `T`.
|
||||
pub fn get_type<T>(self) -> &'p PyType where T: PyTypeObject {
|
||||
T::type_object(self)
|
||||
unsafe{ self.cast_from_borrowed_ptr(T::type_object().into_ptr()) }
|
||||
}
|
||||
|
||||
/// Import the Python module with the specified name.
|
||||
|
@ -241,7 +241,7 @@ impl<'p> Python<'p> {
|
|||
|
||||
/// Check whether `obj` is an instance of type `T` like Python `isinstance` function
|
||||
pub fn is_instance<T: PyTypeObject, V: ToPyPointer>(self, obj: &V) -> PyResult<bool> {
|
||||
T::type_object(self).is_instance(obj)
|
||||
T::type_object().as_ref(self).is_instance(obj)
|
||||
}
|
||||
|
||||
/// Check whether type `T` is subclass of type `U` like Python `issubclass` function
|
||||
|
@ -249,7 +249,7 @@ impl<'p> Python<'p> {
|
|||
where T: PyTypeObject,
|
||||
U: PyTypeObject
|
||||
{
|
||||
T::type_object(self).is_subclass::<U>()
|
||||
T::type_object().as_ref(self).is_subclass::<U>()
|
||||
}
|
||||
|
||||
/// Gets the Python builtin value `None`.
|
||||
|
|
|
@ -206,7 +206,6 @@ impl Drop for GILPool {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
pub unsafe fn register_pointer(obj: *mut ffi::PyObject)
|
||||
{
|
||||
let pool: &'static mut ReleasePool = &mut *POOL;
|
||||
|
|
|
@ -9,6 +9,7 @@ use std::collections::HashMap;
|
|||
|
||||
use {ffi, class, pythonrun};
|
||||
use err::{PyErr, PyResult};
|
||||
use instance::Py;
|
||||
use python::Python;
|
||||
use objects::PyType;
|
||||
use class::methods::PyMethodDefType;
|
||||
|
@ -84,9 +85,9 @@ pub trait PyObjectAlloc<T> {
|
|||
|
||||
impl<T> PyObjectAlloc<T> for T where T : PyTypeInfo {
|
||||
|
||||
default unsafe fn alloc(py: Python, value: T) -> PyResult<*mut ffi::PyObject> {
|
||||
default unsafe fn alloc(_py: Python, value: T) -> PyResult<*mut ffi::PyObject> {
|
||||
// TODO: remove this
|
||||
T::init_type(py);
|
||||
T::init_type();
|
||||
|
||||
let obj = ffi::PyType_GenericAlloc(T::type_object(), 0);
|
||||
|
||||
|
@ -118,39 +119,39 @@ impl<T> PyObjectAlloc<T> for T where T : PyTypeInfo {
|
|||
pub trait PyTypeObject {
|
||||
|
||||
/// Initialize type object
|
||||
fn init_type(py: Python);
|
||||
fn init_type();
|
||||
|
||||
/// Retrieves the type object for this Python object type.
|
||||
fn type_object(py: Python) -> &PyType;
|
||||
fn type_object() -> Py<PyType>;
|
||||
|
||||
}
|
||||
|
||||
impl<T> PyTypeObject for T where T: PyObjectAlloc<T> + PyTypeInfo {
|
||||
|
||||
#[inline]
|
||||
default fn init_type(py: Python) {
|
||||
let mut ty = unsafe { <T as PyTypeInfo>::type_object() };
|
||||
default fn init_type() {
|
||||
unsafe {
|
||||
if ((*<T>::type_object()).tp_flags & ffi::Py_TPFLAGS_READY) == 0 {
|
||||
// automatically initialize the class on-demand
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
if (ty.tp_flags & ffi::Py_TPFLAGS_READY) == 0 {
|
||||
// automatically initialize the class on-demand
|
||||
initialize_type::<T>(py, None, ty).expect(
|
||||
format!("An error occurred while initializing class {}", T::NAME).as_ref());
|
||||
initialize_type::<T>(py, None).expect(
|
||||
format!("An error occurred while initializing class {}", T::NAME).as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
default fn type_object(py: Python) -> &PyType {
|
||||
<T as PyTypeObject>::init_type(py);
|
||||
|
||||
unsafe { PyType::from_type_ptr(py, <T as PyTypeInfo>::type_object()) }
|
||||
default fn type_object() -> Py<PyType> {
|
||||
<T as PyTypeObject>::init_type();
|
||||
unsafe { PyType::new(T::type_object()) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Register new type in python object system.
|
||||
pub fn initialize_type<'p, T>(py: Python<'p>,
|
||||
module_name: Option<&str>,
|
||||
type_object: &mut ffi::PyTypeObject) -> PyResult<&'p PyType>
|
||||
pub fn initialize_type<'p, T>(py: Python<'p>, module_name: Option<&str>) -> PyResult<()>
|
||||
where T: PyObjectAlloc<T> + PyTypeInfo
|
||||
{
|
||||
// type name
|
||||
|
@ -161,6 +162,7 @@ pub fn initialize_type<'p, T>(py: Python<'p>,
|
|||
let name = name.expect(
|
||||
"Module name/type name must not contain NUL byte").into_raw();
|
||||
|
||||
let type_object: &mut ffi::PyTypeObject = unsafe{&mut *T::type_object()};
|
||||
type_object.tp_name = name;
|
||||
type_object.tp_doc = T::DESCRIPTION.as_ptr() as *const _;
|
||||
|
||||
|
@ -172,8 +174,8 @@ pub fn initialize_type<'p, T>(py: Python<'p>,
|
|||
|
||||
// weakref support (check py3cls::py_class::impl_class)
|
||||
if T::FLAGS & PY_TYPE_FLAG_WEAKREF != 0 {
|
||||
type_object.tp_weaklistoffset = T::OFFSET -
|
||||
(std::mem::size_of::<*const ffi::PyObject>() as isize);
|
||||
type_object.tp_weaklistoffset =
|
||||
(T::SIZE - std::mem::size_of::<*const ffi::PyObject>()) as isize;
|
||||
}
|
||||
|
||||
// GC support
|
||||
|
@ -245,7 +247,7 @@ pub fn initialize_type<'p, T>(py: Python<'p>,
|
|||
// register type object
|
||||
unsafe {
|
||||
if ffi::PyType_Ready(type_object) == 0 {
|
||||
Ok(PyType::from_type_ptr(py, type_object))
|
||||
Ok(())
|
||||
} else {
|
||||
Err(PyErr::fetch(py))
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue