fix sequence protocol; convert buffer protocol
This commit is contained in:
parent
51ac8c9c78
commit
ad38688378
|
@ -110,6 +110,21 @@ pub const ASYNC: Proto = Proto {
|
|||
],
|
||||
};
|
||||
|
||||
pub const BUFFER: Proto = Proto {
|
||||
name: "Buffer",
|
||||
methods: &[
|
||||
MethodProto::Unary{
|
||||
name: "bf_getbuffer",
|
||||
pyres: false,
|
||||
proto: "::pyo3::class::buffer::PyBufferGetBufferProtocol"},
|
||||
MethodProto::Unary{
|
||||
name: "bf_releasebuffer",
|
||||
pyres: false,
|
||||
proto: "::pyo3::class::buffer::PyBufferReleaseBufferProtocol"},
|
||||
],
|
||||
py_methods: &[],
|
||||
};
|
||||
|
||||
pub const CONTEXT: Proto = Proto {
|
||||
name: "Context",
|
||||
methods: &[
|
||||
|
@ -134,6 +149,8 @@ pub const CONTEXT: Proto = Proto {
|
|||
],
|
||||
};
|
||||
|
||||
|
||||
|
||||
pub const DESCR: Proto = Proto {
|
||||
name: "Descriptor",
|
||||
methods: &[
|
||||
|
|
|
@ -41,8 +41,7 @@ pub fn build_py_proto(ast: &mut syn::Item) -> Tokens {
|
|||
"PyDescrProtocol" =>
|
||||
impl_proto_impl(ty, impl_items, &defs::DESCR),
|
||||
"PyBufferProtocol" =>
|
||||
impl_protocol("_pyo3::class::buffer::PyBufferProtocolImpl",
|
||||
path.clone(), ty, impl_items, &DEFAULT_METHODS),
|
||||
impl_proto_impl(ty, impl_items, &defs::BUFFER),
|
||||
"PyGCProtocol" =>
|
||||
impl_protocol("_pyo3::class::gc::PyGCProtocolImpl",
|
||||
path.clone(), ty, impl_items, &DEFAULT_METHODS),
|
||||
|
|
|
@ -10,80 +10,76 @@ use std::os::raw::c_int;
|
|||
use ffi;
|
||||
use err::PyResult;
|
||||
use python::Python;
|
||||
use objects::PyObject;
|
||||
use typeob::PyTypeInfo;
|
||||
use callback::{handle, UnitCallbackConverter};
|
||||
use class::NO_METHODS;
|
||||
use callback::UnitCallbackConverter;
|
||||
|
||||
|
||||
/// Buffer protocol interface
|
||||
pub trait PyBufferProtocol<'p> : PyTypeInfo {
|
||||
|
||||
#[allow(unused_variables)]
|
||||
pub trait PyBufferProtocol<'p> : PyTypeInfo + Sized + 'static
|
||||
{
|
||||
fn bf_getbuffer(&'p self, py: Python<'p>,
|
||||
view: *mut ffi::Py_buffer, flags: c_int) -> PyResult<()>;
|
||||
view: *mut ffi::Py_buffer, flags: c_int) -> Self::Result
|
||||
where Self: PyBufferGetBufferProtocol<'p> { unimplemented!() }
|
||||
|
||||
fn bf_releasebuffer(&'p self, py: Python<'p>, view: *mut ffi::Py_buffer) -> PyResult<()>;
|
||||
fn bf_releasebuffer(&'p self, py: Python<'p>, view: *mut ffi::Py_buffer) -> Self::Result
|
||||
where Self: PyBufferReleaseBufferProtocol<'p> { unimplemented!() }
|
||||
}
|
||||
|
||||
pub trait PyBufferGetBufferProtocol<'p>: PyBufferProtocol<'p> {
|
||||
type Result: Into<PyResult<()>>;
|
||||
}
|
||||
|
||||
pub trait PyBufferReleaseBufferProtocol<'p>: PyBufferProtocol<'p> {
|
||||
type Result: Into<PyResult<()>>;
|
||||
}
|
||||
|
||||
|
||||
#[doc(hidden)]
|
||||
pub trait PyBufferProtocolImpl {
|
||||
fn methods() -> &'static [&'static str];
|
||||
fn tp_as_buffer() -> Option<ffi::PyBufferProcs>;
|
||||
}
|
||||
|
||||
impl<T> PyBufferProtocolImpl for T {
|
||||
default fn methods() -> &'static [&'static str] {
|
||||
NO_METHODS
|
||||
default fn tp_as_buffer() -> Option<ffi::PyBufferProcs> { None }
|
||||
}
|
||||
|
||||
impl<'p, T> PyBufferProtocolImpl for T where T: PyBufferProtocol<'p> {
|
||||
#[inline]
|
||||
fn tp_as_buffer() -> Option<ffi::PyBufferProcs> {
|
||||
Some(ffi::PyBufferProcs{
|
||||
bf_getbuffer: Self::cb_bf_getbuffer(),
|
||||
bf_releasebuffer: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'p, T> PyBufferProtocol<'p> for T where T: PyTypeInfo {
|
||||
trait PyBufferGetBufferProtocolImpl {
|
||||
fn cb_bf_getbuffer() -> Option<ffi::getbufferproc>;
|
||||
}
|
||||
|
||||
default fn bf_getbuffer(&'p self, _py: Python<'p>,
|
||||
_view: *mut ffi::Py_buffer, _flags: c_int) -> PyResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
default fn bf_releasebuffer(&'p self, _py: Python<'p>,
|
||||
_view: *mut ffi::Py_buffer) -> PyResult<()> {
|
||||
Ok(())
|
||||
impl<'p, T> PyBufferGetBufferProtocolImpl for T where T: PyBufferProtocol<'p>
|
||||
{
|
||||
#[inline]
|
||||
default fn cb_bf_getbuffer() -> Option<ffi::getbufferproc> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl ffi::PyBufferProcs {
|
||||
|
||||
/// Construct PyBufferProcs struct for PyTypeObject.tp_as_buffer
|
||||
pub fn new<'p, T>() -> Option<ffi::PyBufferProcs>
|
||||
where T: PyBufferProtocol<'p> + PyBufferProtocolImpl
|
||||
{
|
||||
let methods = T::methods();
|
||||
if methods.is_empty() {
|
||||
return None
|
||||
impl<T> PyBufferGetBufferProtocolImpl for T where T: for<'p> PyBufferGetBufferProtocol<'p>
|
||||
{
|
||||
#[inline]
|
||||
fn cb_bf_getbuffer() -> Option<ffi::getbufferproc> {
|
||||
unsafe extern "C" fn wrap<T>(slf: *mut ffi::PyObject,
|
||||
arg1: *mut ffi::Py_buffer,
|
||||
arg2: c_int) -> c_int
|
||||
where T: for<'p> PyBufferGetBufferProtocol<'p>
|
||||
{
|
||||
const LOCATION: &'static str = concat!(stringify!(T), ".buffer_get::<PyBufferProtocol>()");
|
||||
::callback::cb_unary::<T, _, _, _>(LOCATION, slf, UnitCallbackConverter, |py, slf| {
|
||||
slf.bf_getbuffer(py, arg1, arg2).into()
|
||||
})
|
||||
}
|
||||
|
||||
let mut buf_procs: ffi::PyBufferProcs = ffi::PyBufferProcs_INIT;
|
||||
|
||||
for name in methods {
|
||||
match name {
|
||||
&"bf_getbuffer" => {
|
||||
buf_procs.bf_getbuffer = {
|
||||
unsafe extern "C" fn wrap<'p, T>(slf: *mut ffi::PyObject,
|
||||
arg1: *mut ffi::Py_buffer,
|
||||
arg2: c_int) -> c_int
|
||||
where T: PyBufferProtocol<'p>
|
||||
{
|
||||
const LOCATION: &'static str = concat!(stringify!(T), ".buffer_get::<PyBufferProtocol>()");
|
||||
handle(LOCATION, UnitCallbackConverter, |py| {
|
||||
let slf = PyObject::from_borrowed_ptr(py, slf);
|
||||
slf.bf_getbuffer(py, arg1, arg2)
|
||||
})
|
||||
}
|
||||
Some(wrap::<T>)
|
||||
}
|
||||
},
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
|
||||
Some(buf_procs)
|
||||
Some(wrap::<T>)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ macro_rules! py_unary_func_self {
|
|||
($trait:ident, $class:ident :: $f:ident, $res_type:ty, $conv:ty) => {{
|
||||
unsafe extern "C" fn wrap<T>(slf: *mut $crate::ffi::PyObject)
|
||||
-> *mut $crate::ffi::PyObject
|
||||
where T: for<'p> $trait<'p> + $crate::ToPyObject + $crate::IntoPyObject
|
||||
where T: for<'p> $trait<'p>
|
||||
{
|
||||
const LOCATION: &'static str = concat!(stringify!($class), ".", stringify!($f), "()");
|
||||
|
||||
|
@ -221,7 +221,7 @@ macro_rules! py_ssizearg_func {
|
|||
#[allow(unused_mut)]
|
||||
unsafe extern "C" fn wrap<T>(slf: *mut ffi::PyObject,
|
||||
arg: $crate::Py_ssize_t) -> *mut $crate::ffi::PyObject
|
||||
where T: for<'p> $trait<'p> + ToPyObject + IntoPyObject
|
||||
where T: for<'p> $trait<'p>
|
||||
{
|
||||
const LOCATION: &'static str = concat!(stringify!($class), ".", stringify!($f), "()");
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ pub static NO_PY_METHODS: &'static [PyMethodDefType] = &[];
|
|||
use ffi;
|
||||
use typeob::PyTypeInfo;
|
||||
use python::ToPythonPointer;
|
||||
use token::PythonObjectWithToken;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum CompareOp {
|
||||
|
@ -47,7 +48,7 @@ pub enum CompareOp {
|
|||
|
||||
pub trait PyCustomObject : PyTypeInfo + Sized {}
|
||||
|
||||
impl<'p, T> ToPythonPointer for T where T: PyCustomObject {
|
||||
impl<'p, T> ToPythonPointer for T where T: PyCustomObject + PythonObjectWithToken {
|
||||
#[inline]
|
||||
fn as_ptr(&self) -> *mut ffi::PyObject {
|
||||
let offset = <T as PyTypeInfo>::offset();
|
||||
|
|
|
@ -83,12 +83,12 @@ pub trait PySequenceRepeatProtocol<'p>: PySequenceProtocol<'p> {
|
|||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
pub trait PySequenceInplaceConcatProtocol<'p>: PySequenceProtocol<'p> + ToPyObject {
|
||||
pub trait PySequenceInplaceConcatProtocol<'p>: PySequenceProtocol<'p> + IntoPyObject {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Result: Into<PyResult<Self>>;
|
||||
}
|
||||
|
||||
pub trait PySequenceInplaceRepeatProtocol<'p>: PySequenceProtocol<'p> + ToPyObject {
|
||||
pub trait PySequenceInplaceRepeatProtocol<'p>: PySequenceProtocol<'p> + IntoPyObject {
|
||||
type Result: Into<PyResult<Self>>;
|
||||
}
|
||||
|
||||
|
@ -113,7 +113,6 @@ impl<'p, T> PySequenceProtocolImpl for T where T: PySequenceProtocol<'p> {
|
|||
Self::sq_ass_item()
|
||||
};
|
||||
|
||||
|
||||
Some(ffi::PySequenceMethods {
|
||||
sq_length: Self::sq_length(),
|
||||
sq_concat: Self::sq_concat(),
|
||||
|
@ -161,8 +160,7 @@ impl<'p, T> PySequenceGetItemProtocolImpl for T where T: PySequenceProtocol<'p>
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> PySequenceGetItemProtocolImpl for T
|
||||
where T: for<'p> PySequenceGetItemProtocol<'p> + ToPyObject + IntoPyObject
|
||||
impl<T> PySequenceGetItemProtocolImpl for T where T: for<'p> PySequenceGetItemProtocol<'p>
|
||||
{
|
||||
#[inline]
|
||||
fn sq_item() -> Option<ffi::ssizeargfunc> {
|
||||
|
@ -365,8 +363,7 @@ impl<'p, T> PySequenceRepeatProtocolImpl for T
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> PySequenceRepeatProtocolImpl for T
|
||||
where T: for<'p> PySequenceRepeatProtocol<'p> + ToPyObject + IntoPyObject
|
||||
impl<T> PySequenceRepeatProtocolImpl for T where T: for<'p> PySequenceRepeatProtocol<'p>
|
||||
{
|
||||
#[inline]
|
||||
fn sq_repeat() -> Option<ffi::ssizeargfunc> {
|
||||
|
@ -388,7 +385,7 @@ impl<'p, T> PySequenceInplaceConcatProtocolImpl for T where T: PySequenceProtoco
|
|||
}
|
||||
|
||||
impl<T> PySequenceInplaceConcatProtocolImpl for T
|
||||
where T: for<'p> PySequenceInplaceConcatProtocol<'p> + ToPyObject + IntoPyObject
|
||||
where T: for<'p> PySequenceInplaceConcatProtocol<'p>
|
||||
{
|
||||
#[inline]
|
||||
fn sq_inplace_concat() -> Option<ffi::binaryfunc> {
|
||||
|
@ -410,7 +407,7 @@ impl<'p, T> PySequenceInplaceRepeatProtocolImpl for T where T: PySequenceProtoco
|
|||
}
|
||||
|
||||
impl<T> PySequenceInplaceRepeatProtocolImpl for T
|
||||
where T: for<'p> PySequenceInplaceRepeatProtocol<'p> + ToPyObject + IntoPyObject
|
||||
where T: for<'p> PySequenceInplaceRepeatProtocol<'p>
|
||||
{
|
||||
#[inline]
|
||||
fn sq_inplace_repeat() -> Option<ffi::ssizeargfunc> {
|
||||
|
|
33
src/err.rs
33
src/err.rs
|
@ -1,5 +1,6 @@
|
|||
use std;
|
||||
use std::ffi::CString;
|
||||
use std::os::raw::c_char;
|
||||
use libc;
|
||||
|
||||
use ffi;
|
||||
|
@ -34,7 +35,7 @@ let gil = Python::acquire_gil();
|
|||
let py = gil.python();
|
||||
let ctx = PyDict::new(py);
|
||||
|
||||
ctx.set_item(py, "CustomError", py.get_type::<CustomError>()).unwrap();
|
||||
ctx.set_item("CustomError", py.get_type::<CustomError>()).unwrap();
|
||||
|
||||
py.run("assert str(CustomError) == \"<class 'mymodule.CustomError'>\"", None, Some(&ctx)).unwrap();
|
||||
py.run("assert CustomError('oops').args == ('oops',)", None, Some(&ctx)).unwrap();
|
||||
|
@ -46,7 +47,7 @@ macro_rules! py_exception {
|
|||
($module: ident, $name: ident, $base: ty) => {
|
||||
pub struct $name;
|
||||
|
||||
pyobject_newtype!($name);
|
||||
pyobject_nativetype!($name);
|
||||
|
||||
impl $name {
|
||||
pub fn new<'p, T: $crate::ToPyObject>(py: $crate::Python<'p>, args: T) -> $crate::PyErr {
|
||||
|
@ -56,11 +57,7 @@ macro_rules! py_exception {
|
|||
|
||||
impl $crate::PyTypeObject for $name {
|
||||
#[inline]
|
||||
fn type_name() -> &'static str {
|
||||
"$name"
|
||||
}
|
||||
#[inline]
|
||||
fn type_object(py: $crate::Python) -> $crate::PyType {
|
||||
fn type_object<'p>(py: $crate::Python<'p>) -> $crate::PyType<'p> {
|
||||
unsafe {
|
||||
static mut type_object: *mut $crate::ffi::PyTypeObject = 0 as *mut $crate::ffi::PyTypeObject;
|
||||
|
||||
|
@ -68,8 +65,7 @@ macro_rules! py_exception {
|
|||
type_object = $crate::PyErr::new_type(
|
||||
py,
|
||||
concat!(stringify!($module), ".", stringify!($name)),
|
||||
Some($crate::PythonObject::into_object(py.get_type::<$base>())),
|
||||
None).as_type_ptr();
|
||||
Some(py.get_type::<$base>()), None);
|
||||
}
|
||||
|
||||
$crate::PyType::from_type_ptr(py, type_object)
|
||||
|
@ -136,25 +132,26 @@ 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(py: Python, name: &str,
|
||||
base: Option<PyObject>, dict: Option<PyObject>) -> PyType {
|
||||
pub fn new_type<'p>(py: Python<'p>, name: &str,
|
||||
base: Option<PyObject<'p>>, dict: Option<PyObject<'p>>) -> PyType<'p> {
|
||||
let base: *mut ffi::PyObject = match base {
|
||||
None => ptr::null_mut(),
|
||||
Some(obj) => obj.steal_ptr()
|
||||
None => std::ptr::null_mut(),
|
||||
Some(obj) => obj.into_ptr()
|
||||
};
|
||||
|
||||
let dict: *mut ffi::PyObject = match dict {
|
||||
None => ptr::null_mut(),
|
||||
None => std::ptr::null_mut(),
|
||||
Some(obj) => obj.into_ptr(),
|
||||
};
|
||||
|
||||
unsafe {
|
||||
let null_terminated_name = CString::new(name).unwrap();
|
||||
let ptr: *mut ffi::PyObject = ffi::PyErr_NewException(
|
||||
null_terminated_name.as_ptr() as *mut c_char, base, dict);
|
||||
PyObject::from_borrowed_ptr(py, ptr).unchecked_cast_into::<PyType>()
|
||||
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)
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
/// Retrieves the current error from the Python interpreter's global state.
|
||||
/// The error is cleared from the Python interpreter.
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
// Copyright (c) 2017-present PyO3 Project and Contributors
|
||||
|
||||
use ffi;
|
||||
use ppptr::pptr;
|
||||
use pyptr::PyPtr;
|
||||
use token::PyObjectMarker;
|
||||
use typeob::PyTypeInfo;
|
||||
use objects::PyObject;
|
||||
use python::ToPythonPointer;
|
||||
|
||||
pub trait PyBaseObject : PyTypeInfo + Sized {}
|
||||
|
||||
|
|
|
@ -105,7 +105,7 @@ impl<'p> PyDict<'p> {
|
|||
//}
|
||||
|
||||
/// Returns the list of (key, value) pairs in this dictionary.
|
||||
pub fn items(&self) -> Vec<(&PyObject, &PyObject)> {
|
||||
pub fn items(&self) -> Vec<(PyObject<'p>, PyObject<'p>)> {
|
||||
// Note that we don't provide an iterator because
|
||||
// PyDict_Next() is unsafe to use when the dictionary might be changed
|
||||
// by other python code.
|
||||
|
@ -116,7 +116,8 @@ impl<'p> PyDict<'p> {
|
|||
let mut key: *mut ffi::PyObject = mem::uninitialized();
|
||||
let mut value: *mut ffi::PyObject = mem::uninitialized();
|
||||
while ffi::PyDict_Next(self.as_ptr(), &mut pos, &mut key, &mut value) != 0 {
|
||||
vec.push((token.from_owned_ptr(key), token.from_owned_ptr(value)));
|
||||
vec.push((PyObject::from_owned_ptr(token, key),
|
||||
PyObject::from_owned_ptr(token, value)));
|
||||
}
|
||||
}
|
||||
vec
|
||||
|
@ -273,7 +274,7 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn test_items() {
|
||||
let gil = Python::acquire_gil();
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let mut v = HashMap::new();
|
||||
v.insert(7, 32);
|
||||
|
|
|
@ -8,10 +8,11 @@ use std::os::raw::c_char;
|
|||
use std::ffi::{CStr, CString};
|
||||
|
||||
use ::pptr;
|
||||
use conversion::ToPyTuple;
|
||||
use pyptr::PyPtr;
|
||||
use python::{ToPythonPointer, Python};
|
||||
use token::PythonObjectWithGilToken;
|
||||
use objects::{PyDict, PyType, exc};
|
||||
use objects::{PyObject, PyDict, PyType, exc};
|
||||
use objectprotocol::ObjectProtocol;
|
||||
use err::{PyResult, PyErr};
|
||||
|
||||
|
@ -79,6 +80,15 @@ impl<'p> PyModule<'p> {
|
|||
unsafe { self.str_from_ptr(ffi::PyModule_GetFilename(self.as_ptr())) }
|
||||
}
|
||||
|
||||
/// Calls a function in the module.
|
||||
/// This is equivalent to the Python expression: `getattr(module, name)(*args, **kwargs)`
|
||||
pub fn call<A>(&self, name: &str, args: A, kwargs: Option<&PyDict>)
|
||||
-> PyResult<PyObject<'p>>
|
||||
where A: ToPyTuple
|
||||
{
|
||||
self.getattr(name)?.call(args, kwargs)
|
||||
}
|
||||
|
||||
/// Adds a new extension type to the module.
|
||||
///
|
||||
/// This is a convenience function that initializes the `class`,
|
||||
|
|
|
@ -162,6 +162,7 @@ tuple_conversion!(9, (ref0, 0, A), (ref1, 1, B), (ref2, 2, C), (ref3, 3, D),
|
|||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// use pyo3::ObjectProtocol;
|
||||
/// let gil = pyo3::Python::acquire_gil();
|
||||
/// let py = gil.python();
|
||||
/// let os = py.import("os").unwrap();
|
||||
|
|
10
src/pyptr.rs
10
src/pyptr.rs
|
@ -499,11 +499,11 @@ impl<'p, T> Py<'p, T> where T: PyTypeInfo
|
|||
}
|
||||
}
|
||||
|
||||
//impl<'p, T> PythonObjectWithGilToken<'p> for Py<'p, T> {
|
||||
// fn gil(&self) -> Python<'p> {
|
||||
// self.py
|
||||
// }
|
||||
//}
|
||||
impl<'p, T> PythonObjectWithGilToken<'p> for Py<'p, T> {
|
||||
fn gil(&self) -> Python<'p> {
|
||||
self.py
|
||||
}
|
||||
}
|
||||
|
||||
impl<'p, T> ToPythonPointer for Py<'p, T> {
|
||||
/// Gets the underlying FFI pointer, returns a borrowed pointer.
|
||||
|
|
|
@ -9,7 +9,7 @@ use std::os::raw::c_int;
|
|||
|
||||
use ffi;
|
||||
use typeob::{PyTypeInfo, PyTypeObject, PyObjectAlloc};
|
||||
use token::{PyObjectMarker, PythonToken, PythonObjectWithGilToken};
|
||||
use token::{PyObjectMarker, PythonToken};
|
||||
use objects::{PyObject, PyType, PyBool, PyDict, PyModule};
|
||||
use err::{PyErr, PyResult, PyDowncastError};
|
||||
use pyptr::{Py, PyPtr};
|
||||
|
@ -254,33 +254,6 @@ impl<'p> Python<'p> {
|
|||
{
|
||||
f(Python(PhantomData))
|
||||
}
|
||||
|
||||
/// Convert raw pointer into referece
|
||||
#[inline]
|
||||
pub unsafe fn from_owned_ptr<P>(self, ptr: *mut ffi::PyObject) -> &'p P
|
||||
{
|
||||
std::mem::transmute(ptr)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn from_owned_ptr_opt<P>(self, ptr: *mut ffi::PyObject) -> Option<&'p P>
|
||||
{
|
||||
if ptr.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(std::mem::transmute(ptr))
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn from_owned_ptr_or_panic<P>(self, ptr: *mut ffi::PyObject) -> &'p P
|
||||
{
|
||||
if ptr.is_null() {
|
||||
::err::panic_after_error();
|
||||
} else {
|
||||
std::mem::transmute(ptr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -96,6 +96,7 @@ pub struct GILGuard {
|
|||
/// The Drop implementation for GILGuard will release the GIL.
|
||||
impl Drop for GILGuard {
|
||||
fn drop(&mut self) {
|
||||
println!("RELEASE");
|
||||
unsafe { ffi::PyGILState_Release(self.gstate) }
|
||||
}
|
||||
}
|
||||
|
@ -107,6 +108,7 @@ impl GILGuard {
|
|||
/// See [prepare_freethreaded_python()](fn.prepare_freethreaded_python.html) for details.
|
||||
pub fn acquire() -> GILGuard {
|
||||
::pythonrun::prepare_freethreaded_python();
|
||||
println!("ACQUIRE");
|
||||
let gstate = unsafe { ffi::PyGILState_Ensure() }; // acquire GIL
|
||||
GILGuard { gstate: gstate, no_send: marker::PhantomData }
|
||||
}
|
||||
|
|
|
@ -248,7 +248,7 @@ pub fn initialize_type<'p, T>(py: Python<'p>, module_name: Option<&str>, type_na
|
|||
}
|
||||
|
||||
// buffer protocol
|
||||
if let Some(meth) = ffi::PyBufferProcs::new::<T>() {
|
||||
if let Some(meth) = <T as class::buffer::PyBufferProtocolImpl>::tp_as_buffer() {
|
||||
static mut BUFFER_PROCS: ffi::PyBufferProcs = ffi::PyBufferProcs_INIT;
|
||||
*(unsafe { &mut BUFFER_PROCS }) = meth;
|
||||
type_object.tp_as_buffer = unsafe { &mut BUFFER_PROCS };
|
||||
|
|
|
@ -19,7 +19,6 @@ struct TestClass {
|
|||
impl class::PyBufferProtocol for TestClass {
|
||||
|
||||
fn bf_getbuffer(&self, py: Python, view: *mut ffi::Py_buffer, flags: c_int) -> PyResult<()> {
|
||||
|
||||
if view == ptr::null_mut() {
|
||||
return Err(PyErr::new::<exc::BufferError, _>(py, "View is null"))
|
||||
}
|
||||
|
@ -75,6 +74,5 @@ fn test_buffer() {
|
|||
|
||||
let d = PyDict::new(py);
|
||||
let _ = d.set_item("ob", t);
|
||||
|
||||
py.run("assert bytes(ob) == b' 23'", None, Some(&d)).unwrap();
|
||||
}
|
||||
|
|
|
@ -477,7 +477,9 @@ fn comparisons() {
|
|||
|
||||
|
||||
#[py::class]
|
||||
struct Sequence {token: PythonToken<Sequence>}
|
||||
struct Sequence {
|
||||
#[token]
|
||||
token: PythonToken<Sequence>}
|
||||
|
||||
#[py::proto]
|
||||
impl PySequenceProtocol for Sequence {
|
||||
|
@ -619,7 +621,6 @@ struct Reversed {token: PythonToken<Reversed>}
|
|||
#[py::proto]
|
||||
impl PyMappingProtocol for Reversed{
|
||||
fn __reversed__(&self, py: Python) -> PyResult<&'static str> {
|
||||
println!("__reversed__");
|
||||
Ok("I am reversed")
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue