remove py param

This commit is contained in:
Nikolay Kim 2017-07-25 18:11:45 -07:00
parent 3ab5e4526c
commit 65a42a2b1a
10 changed files with 86 additions and 62 deletions

View File

@ -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());
}

View File

@ -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
}
}

View File

@ -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)
}
}
}
);

View File

@ -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())
}
}
}

View File

@ -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)

View File

@ -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 {

View File

@ -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()))

View File

@ -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`.

View File

@ -206,7 +206,6 @@ impl Drop for GILPool {
}
}
pub unsafe fn register_pointer(obj: *mut ffi::PyObject)
{
let pool: &'static mut ReleasePool = &mut *POOL;

View File

@ -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))
}