special treatment for native python objects
This commit is contained in:
parent
55d0d58734
commit
ea8ccf190a
|
@ -40,9 +40,6 @@ pub fn build_py_class(ast: &mut syn::DeriveInput) -> Tokens {
|
|||
unused_qualifications, unused_variables, non_camel_case_types)]
|
||||
const #dummy_const: () = {
|
||||
extern crate pyo3 as _pyo3;
|
||||
use std;
|
||||
use pyo3::PythonObjectWithToken;
|
||||
use pyo3::python::PythonObjectWithCheckedDowncast;
|
||||
|
||||
#tokens
|
||||
};
|
||||
|
@ -116,6 +113,26 @@ fn impl_class(cls: &syn::Ident, base: &syn::Ident, token: Option<syn::Ident>) ->
|
|||
}
|
||||
}
|
||||
|
||||
impl<'p> _pyo3::python::PyDowncastFrom<'p> for #cls
|
||||
{
|
||||
fn downcast_from(py: &'p _pyo3::PyObject<'p>)
|
||||
-> Result<&'p #cls, _pyo3::PyDowncastError<'p>>
|
||||
{
|
||||
unsafe {
|
||||
let checked = ffi::PyObject_TypeCheck(
|
||||
py.as_ptr(), <#cls as _pyo3::typeob::PyTypeInfo>::type_object()) != 0;
|
||||
|
||||
if checked {
|
||||
let offset = <#cls as _pyo3::typeob::PyTypeInfo>::offset();
|
||||
let ptr = (py.as_ptr() as *mut u8).offset(offset) as *mut #cls;
|
||||
Ok(ptr.as_ref().unwrap())
|
||||
} else {
|
||||
Err(_pyo3::PyDowncastError(py.token(), None))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#extra
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,7 +58,6 @@ fn impl_methods(ty: &Box<syn::Ty>, impls: &mut Vec<syn::ImplItem>) -> Tokens {
|
|||
unused_qualifications, unused_variables)]
|
||||
const #dummy_const: () = {
|
||||
extern crate pyo3 as _pyo3;
|
||||
use pyo3::callback::CallbackConverter;
|
||||
|
||||
#tokens
|
||||
};
|
||||
|
|
|
@ -49,11 +49,8 @@ pub fn impl_wrap(cls: &Box<syn::Ty>, name: &syn::Ident, spec: &FnSpec) -> Tokens
|
|||
const LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#name),"()");
|
||||
_pyo3::callback::cb_meth(LOCATION, |py| {
|
||||
let mut slf: Py<#cls> = Py::from_borrowed_ptr(py, slf);
|
||||
|
||||
let args: _pyo3::Py<_pyo3::PyTuple> =
|
||||
_pyo3::Py::from_borrowed_ptr(py, args);
|
||||
let kwargs: Option<_pyo3::Py<_pyo3::PyDict>> =
|
||||
_pyo3::argparse::get_kwargs(py, kwargs);
|
||||
let args = _pyo3::PyTuple::from_borrowed_ptr(py, args);
|
||||
let kwargs = _pyo3::argparse::get_kwargs(py, kwargs);
|
||||
|
||||
let result: #output = {
|
||||
#body
|
||||
|
@ -79,11 +76,8 @@ pub fn impl_proto_wrap(cls: &Box<syn::Ty>, name: &syn::Ident, spec: &FnSpec) ->
|
|||
const LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#name),"()");
|
||||
_pyo3::callback::cb_meth(LOCATION, |py| {
|
||||
let mut slf: Py<#cls> = Py::from_borrowed_ptr(py, slf);
|
||||
|
||||
let args: _pyo3::Py<_pyo3::PyTuple> =
|
||||
_pyo3::Py::from_borrowed_ptr(py, args);
|
||||
let kwargs: Option<_pyo3::Py<_pyo3::PyDict>> =
|
||||
_pyo3::argparse::get_kwargs(py, kwargs);
|
||||
let args = _pyo3::PyTuple::from_borrowed_ptr(py, args);
|
||||
let kwargs = _pyo3::argparse::get_kwargs(py, kwargs);
|
||||
|
||||
let result = {
|
||||
#body
|
||||
|
@ -110,12 +104,9 @@ pub fn impl_wrap_new(cls: &Box<syn::Ty>, name: &syn::Ident, spec: &FnSpec) -> To
|
|||
const LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#name), "()");
|
||||
|
||||
_pyo3::callback::cb_meth(LOCATION, |py| {
|
||||
let cls: _pyo3::Py<_pyo3::PyType> = _pyo3::Py::from_borrowed_ptr(
|
||||
py, cls as *mut _pyo3::ffi::PyObject);
|
||||
let args: _pyo3::Py<_pyo3::PyTuple> =
|
||||
_pyo3::Py::from_borrowed_ptr(py, args);
|
||||
let kwargs: Option<_pyo3::Py<_pyo3::PyDict>> =
|
||||
_pyo3::argparse::get_kwargs(py, kwargs);
|
||||
let cls = _pyo3::PyType::from_type_ptr(py, cls);
|
||||
let args = _pyo3::PyTuple::from_borrowed_ptr(py, args);
|
||||
let kwargs = _pyo3::argparse::get_kwargs(py, kwargs);
|
||||
|
||||
let result: #output = {
|
||||
#body
|
||||
|
@ -184,7 +175,7 @@ fn impl_wrap_setter(cls: &Box<syn::Ty>, name: &syn::Ident, spec: &FnSpec) -> Tok
|
|||
fn impl_call(_cls: &Box<syn::Ty>, fname: &syn::Ident, spec: &FnSpec) -> Tokens {
|
||||
let names: Vec<&syn::Ident> = spec.args.iter().map(|item| item.name).collect();
|
||||
quote! {{
|
||||
slf.as_mut().#fname(py, #(#names),*)
|
||||
slf.#fname(py, #(#names),*)
|
||||
}}
|
||||
}
|
||||
|
||||
|
@ -297,7 +288,7 @@ fn impl_arg_param(arg: &FnArg, spec: &FnSpec, body: &Tokens) -> Tokens {
|
|||
match
|
||||
match _iter.next().unwrap().as_ref() {
|
||||
Some(obj) => {
|
||||
if obj == &py.None() {
|
||||
if obj.is_none() {
|
||||
Ok(#default)
|
||||
} else {
|
||||
match obj.extract() {
|
||||
|
@ -317,7 +308,7 @@ fn impl_arg_param(arg: &FnArg, spec: &FnSpec, body: &Tokens) -> Tokens {
|
|||
quote! {
|
||||
match match _iter.next().unwrap().as_ref() {
|
||||
Some(obj) => {
|
||||
if obj == &py.None() {
|
||||
if obj.is_none() {
|
||||
Ok(#default)
|
||||
} else {
|
||||
match obj.extract() {
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
//! See also the macros `py_argparse!`, `py_fn!` and `py_method!`.
|
||||
|
||||
use ffi;
|
||||
use pyptr::Py;
|
||||
use python::Python;
|
||||
use objects::{PyObject, PyTuple, PyDict, PyString, exc};
|
||||
use conversion::RefFromPyObject;
|
||||
|
@ -44,7 +43,7 @@ pub struct ParamDescription<'a> {
|
|||
/// Must have same length as `params` and must be initialized to `None`.
|
||||
pub fn parse_args<'p>(py: Python<'p>,
|
||||
fname: Option<&str>, params: &[ParamDescription],
|
||||
args: &'p PyTuple, kwargs: Option<&'p Py<'p, PyDict>>,
|
||||
args: &'p PyTuple<'p>, kwargs: Option<&'p PyDict<'p>>,
|
||||
accept_args: bool, accept_kwargs: bool,
|
||||
output: &mut[Option<PyObject<'p>>]) -> PyResult<()>
|
||||
{
|
||||
|
@ -356,11 +355,11 @@ macro_rules! py_argparse_raw {
|
|||
|
||||
#[inline]
|
||||
#[doc(hidden)]
|
||||
pub unsafe fn get_kwargs<'p>(py: Python<'p>, ptr: *mut ffi::PyObject) -> Option<Py<'p, PyDict>> {
|
||||
pub unsafe fn get_kwargs<'p>(py: Python<'p>, ptr: *mut ffi::PyObject) -> Option<PyDict<'p>> {
|
||||
if ptr.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(Py::<PyDict>::from_borrowed_ptr(py, ptr))
|
||||
Some(PyDict::from_borrowed_ptr(py, ptr))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
46
src/err.rs
46
src/err.rs
|
@ -3,12 +3,13 @@ use std::ffi::CString;
|
|||
use libc;
|
||||
|
||||
use ffi;
|
||||
use pyptr::{Py, PyPtr};
|
||||
use pyptr::{PyPtr};
|
||||
use python::{ToPythonPointer, IntoPythonPointer, Python};
|
||||
use objects::{PyObject, PyType, exc};
|
||||
use native::PyNativeObject;
|
||||
use token::PyObjectMarker;
|
||||
use typeob::{PyTypeObject};
|
||||
use conversion::{ToPyObject, ToPyTuple, IntoPyObject};
|
||||
use conversion::{ToPyObject, ToPyTuple};
|
||||
|
||||
/**
|
||||
Defines a new exception type.
|
||||
|
@ -85,7 +86,7 @@ macro_rules! py_exception {
|
|||
#[derive(Debug)]
|
||||
pub struct PyErr {
|
||||
/// The type of the exception. This should be either a `PyClass` or a `PyType`.
|
||||
pub ptype: PyPtr<PyType>,
|
||||
pub ptype: PyPtr<PyObjectMarker>,
|
||||
/// The value of the exception.
|
||||
///
|
||||
/// This can be either an instance of `ptype`,
|
||||
|
@ -121,7 +122,7 @@ impl PyErr {
|
|||
pub fn new<T, V>(py: Python, value: V) -> PyErr
|
||||
where T: PyTypeObject, V: ToPyObject
|
||||
{
|
||||
PyErr::new_helper(py, py.get_type::<T>(), value.to_object(py))
|
||||
PyErr::new_helper(py, py.get_type::<T>().into_object(), value.to_object(py))
|
||||
}
|
||||
|
||||
/// Gets whether an error is present in the Python interpreter's global state.
|
||||
|
@ -160,9 +161,9 @@ impl PyErr {
|
|||
/// If no error is set, returns a `SystemError`.
|
||||
pub fn fetch(py: Python) -> PyErr {
|
||||
unsafe {
|
||||
let mut ptype : *mut ffi::PyObject = std::mem::uninitialized();
|
||||
let mut pvalue : *mut ffi::PyObject = std::mem::uninitialized();
|
||||
let mut ptraceback : *mut ffi::PyObject = std::mem::uninitialized();
|
||||
let mut ptype : *mut ffi::PyObject = std::ptr::null_mut();
|
||||
let mut pvalue : *mut ffi::PyObject = std::ptr::null_mut();
|
||||
let mut ptraceback : *mut ffi::PyObject = std::ptr::null_mut();
|
||||
ffi::PyErr_Fetch(&mut ptype, &mut pvalue, &mut ptraceback);
|
||||
PyErr::new_from_ffi_tuple(py, ptype, pvalue, ptraceback)
|
||||
}
|
||||
|
@ -176,16 +177,16 @@ impl PyErr {
|
|||
// and because we mustn't panic in normalize().
|
||||
PyErr {
|
||||
ptype: if ptype.is_null() {
|
||||
py.get_type::<exc::SystemError>()
|
||||
py.get_type::<exc::SystemError>().into_object()
|
||||
} else {
|
||||
PyPtr::from_borrowed_ptr(ptype)
|
||||
PyPtr::<PyObjectMarker>::from_owned_ptr(ptype).into_object()
|
||||
},
|
||||
pvalue: PyPtr::from_borrowed_ptr_opt(py, pvalue),
|
||||
ptraceback: PyPtr::from_borrowed_ptr_opt(py, ptraceback)
|
||||
pvalue: PyPtr::from_owned_ptr_or_opt(py, pvalue),
|
||||
ptraceback: PyPtr::from_owned_ptr_or_opt(py, ptraceback)
|
||||
}
|
||||
}
|
||||
|
||||
fn new_helper(_py: Python, ty: PyPtr<PyType>, value: PyPtr<PyObjectMarker>) -> PyErr {
|
||||
fn new_helper(_py: Python, ty: PyPtr<PyObjectMarker>, value: PyPtr<PyObjectMarker>) -> PyErr {
|
||||
assert!(unsafe { ffi::PyExceptionClass_Check(ty.as_ptr()) } != 0);
|
||||
PyErr {
|
||||
ptype: ty,
|
||||
|
@ -206,20 +207,20 @@ impl PyErr {
|
|||
fn from_instance_helper<'p>(py: Python, obj: PyPtr<PyObjectMarker>) -> PyErr {
|
||||
if unsafe { ffi::PyExceptionInstance_Check(obj.as_ptr()) } != 0 {
|
||||
PyErr {
|
||||
ptype: unsafe { PyPtr::<PyType>::from_borrowed_ptr(
|
||||
ptype: unsafe { PyPtr::<PyObjectMarker>::from_borrowed_ptr(
|
||||
ffi::PyExceptionInstance_Class(obj.as_ptr())) },
|
||||
pvalue: Some(obj),
|
||||
ptraceback: None
|
||||
}
|
||||
} else if unsafe { ffi::PyExceptionClass_Check(obj.as_ptr()) } != 0 {
|
||||
PyErr {
|
||||
ptype: unsafe { PyPtr::<PyType>::unchecked_downcast_from(obj) },
|
||||
ptype: unsafe { PyPtr::<PyObjectMarker>::unchecked_downcast_from(obj) },
|
||||
pvalue: None,
|
||||
ptraceback: None
|
||||
}
|
||||
} else {
|
||||
PyErr {
|
||||
ptype: py.get_type::<exc::TypeError>(),
|
||||
ptype: py.get_type::<exc::TypeError>().into_object(),
|
||||
pvalue: Some("exceptions must derive from BaseException".to_object(py)),
|
||||
ptraceback: None
|
||||
}
|
||||
|
@ -230,9 +231,9 @@ impl PyErr {
|
|||
/// `exc` is the exception type; usually one of the standard exceptions like `py.get_type::<exc::RuntimeError>()`.
|
||||
/// `value` is the exception instance, or a tuple of arguments to pass to the exception constructor.
|
||||
#[inline]
|
||||
pub fn new_lazy_init(exc: PyPtr<PyType>, value: Option<PyPtr<PyObjectMarker>>) -> PyErr {
|
||||
pub fn new_lazy_init<'p>(exc: PyType<'p>, value: Option<PyPtr<PyObjectMarker>>) -> PyErr {
|
||||
PyErr {
|
||||
ptype: exc,
|
||||
ptype: exc.into_object(),
|
||||
pvalue: value,
|
||||
ptraceback: None
|
||||
}
|
||||
|
@ -242,14 +243,13 @@ impl PyErr {
|
|||
/// `exc` is the exception type; usually one of the standard exceptions like `py.get_type::<exc::RuntimeError>()`.
|
||||
/// `args` is the a tuple of arguments to pass to the exception constructor.
|
||||
#[inline]
|
||||
pub fn new_err<'p, A>(py: Python, exc: Py<'p, PyType>, args: A) -> PyErr
|
||||
pub fn new_err<'p, A>(py: Python, exc: PyType<'p>, args: A) -> PyErr
|
||||
where A: 'p + ToPyTuple
|
||||
{
|
||||
let exc = exc.clone_ref();
|
||||
let pval = args.to_py_tuple(py);
|
||||
PyErr {
|
||||
ptype: exc.into_pptr(),
|
||||
pvalue: Some(pval.into_object(py)),
|
||||
ptype: exc.into_object(),
|
||||
pvalue: Some(pval.into_object()),
|
||||
ptraceback: None
|
||||
}
|
||||
}
|
||||
|
@ -301,8 +301,8 @@ impl PyErr {
|
|||
}
|
||||
|
||||
/// Retrieves the exception type.
|
||||
pub fn get_type<'p>(&self, py: Python<'p>) -> Py<'p, PyType> {
|
||||
self.ptype.as_ref(py)
|
||||
pub fn get_type<'p>(&self, py: Python<'p>) -> PyType<'p> {
|
||||
self.ptype.clone_ref(py).cast_into(py).unwrap()
|
||||
}
|
||||
|
||||
/// Retrieves the exception instance for this error.
|
||||
|
|
|
@ -76,7 +76,7 @@ pub use token::{PyObjectMarker, PythonToken, PythonObjectWithToken};
|
|||
pub use err::{PyErr, PyResult, PyDowncastError};
|
||||
pub use objects::*;
|
||||
pub use objectprotocol::ObjectProtocol;
|
||||
pub use python::{Python, IntoPythonPointer};
|
||||
pub use python::{Python, ToPythonPointer, IntoPythonPointer, PyDowncastFrom, PyDowncastInto};
|
||||
pub use pythonrun::{GILGuard, GILProtected, prepare_freethreaded_python};
|
||||
pub use conversion::{FromPyObject, RefFromPyObject, ToPyObject, IntoPyObject, ToPyTuple};
|
||||
pub use class::{CompareOp};
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
|
||||
// use python::{Python, ToPythonPointer, PythonObjectWithCheckedDowncast};
|
||||
// use err::{PyErr, PyResult};
|
||||
// use ppptr::pptr;
|
||||
// use pyptr::Py;
|
||||
use pyptr::PyPtr;
|
||||
use token::PyObjectMarker;
|
||||
use typeob::PyTypeInfo;
|
||||
// use conversion::{ToPyObject, FromPyObject};
|
||||
|
||||
|
||||
pub trait PyNativeObject : PyTypeInfo {}
|
||||
pub trait PyNativeObject : PyTypeInfo {
|
||||
|
||||
fn into_object(self) -> PyPtr<PyObjectMarker>;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*impl<'a, T: Sized> FromPyObject<'a> for T
|
||||
|
|
|
@ -94,6 +94,11 @@ pub trait ObjectProtocol {
|
|||
/// This is equivalent to the Python expression: 'not not self'
|
||||
fn is_true(&self) -> PyResult<bool>;
|
||||
|
||||
/// Returns whether the object is considered to be None.
|
||||
/// This is equivalent to the Python expression: 'is None'
|
||||
#[inline]
|
||||
fn is_none(&self) -> bool;
|
||||
|
||||
/// Returns the length of the sequence or mapping.
|
||||
/// This is equivalent to the Python expression: 'len(self)'
|
||||
fn len(&self) -> PyResult<usize>;
|
||||
|
@ -305,6 +310,13 @@ impl<T> ObjectProtocol for T where T: PythonObjectWithToken + ToPythonPointer {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns whether the object is considered to be None.
|
||||
/// This is equivalent to the Python expression: 'is None'
|
||||
#[inline]
|
||||
fn is_none(&self) -> bool {
|
||||
unsafe { ffi::Py_None() == self.as_ptr() }
|
||||
}
|
||||
|
||||
/// Returns the length of the sequence or mapping.
|
||||
/// This is equivalent to the Python expression: 'len(self)'
|
||||
#[inline]
|
||||
|
|
|
@ -2,7 +2,8 @@ use ::{pptr, PyPtr};
|
|||
use ffi;
|
||||
use token::PyObjectMarker;
|
||||
use python::{ToPythonPointer, Python};
|
||||
use conversion::{ToPyObject, IntoPyObject};
|
||||
use native::PyNativeObject;
|
||||
use conversion::ToPyObject;
|
||||
|
||||
/// Represents a Python `bool`.
|
||||
pub struct PyBool<'p>(pptr<'p>);
|
||||
|
@ -12,8 +13,10 @@ pyobject_nativetype!(PyBool, PyBool_Check, PyBool_Type);
|
|||
impl<'p> PyBool<'p> {
|
||||
/// Depending on `val`, returns `py.True()` or `py.False()`.
|
||||
#[inline]
|
||||
pub fn get(py: Python<'p>, val: bool) -> PyBool<'p> {
|
||||
if val { py.True() } else { py.False() }
|
||||
pub fn new(py: Python<'p>, val: bool) -> PyBool<'p> {
|
||||
unsafe { PyBool(
|
||||
pptr::from_borrowed_ptr(py, if val { ffi::Py_True() } else { ffi::Py_False() })
|
||||
)}
|
||||
}
|
||||
|
||||
/// Gets whether this boolean is `true`.
|
||||
|
@ -27,7 +30,7 @@ impl<'p> PyBool<'p> {
|
|||
impl ToPyObject for bool {
|
||||
#[inline]
|
||||
fn to_object(&self, py: Python) -> PyPtr<PyObjectMarker> {
|
||||
PyBool::get(py, *self).into_object(py)
|
||||
PyBool::new(py, *self).into_object()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
@ -26,6 +26,11 @@ impl<'p> PyDict<'p> {
|
|||
unsafe { PyDict(pptr::from_owned_ptr_or_panic(py, ffi::PyDict_New())) }
|
||||
}
|
||||
|
||||
/// Construct a new dict with the given raw pointer
|
||||
pub fn from_borrowed_ptr(py: Python<'p>, ptr: *mut ffi::PyObject) -> PyDict<'p> {
|
||||
unsafe { PyDict(pptr::from_borrowed_ptr(py, ptr)) }
|
||||
}
|
||||
|
||||
/// Return a new dictionary that contains the same key-value pairs as self.
|
||||
/// Corresponds to `dict(self)` in Python.
|
||||
pub fn copy(&'p self) -> PyResult<PyDict<'p>> {
|
||||
|
@ -65,7 +70,7 @@ impl<'p> PyDict<'p> {
|
|||
/// Returns None if the item is not present, or if an error occurs.
|
||||
pub fn get_item<K>(&self, key: K) -> Option<PyObject> where K: ToPyObject {
|
||||
key.with_borrowed_ptr(self.token(), |key| unsafe {
|
||||
PyObject::from_owned_ptr_or_opt(
|
||||
PyObject::from_borrowed_ptr_or_opt(
|
||||
self.token(), ffi::PyDict_GetItem(self.as_ptr(), key))
|
||||
})
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ macro_rules! exc_type(
|
|||
|
||||
impl $crate::PyTypeObject for $name {
|
||||
#[inline]
|
||||
fn type_object(py: $crate::python::Python) -> $crate::PyPtr<PyType> {
|
||||
fn type_object<'p>(py: $crate::python::Python<'p>) -> $crate::PyType<'p> {
|
||||
unsafe { PyType::from_type_ptr(py, ffi::$exc_name as *mut ffi::PyTypeObject) }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,72 +16,15 @@ pub use self::slice::PySlice;
|
|||
//pub use self::set::{PySet, PyFrozenSet};
|
||||
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! pyobject_newtype(
|
||||
($name: ident, $checkfunction: ident, $typeobject: ident) => (
|
||||
|
||||
impl $crate::typeob::PyTypeInfo for $name {
|
||||
type Type = ();
|
||||
|
||||
#[inline]
|
||||
fn size() -> usize {
|
||||
$crate::std::mem::size_of::<ffi::PyObject>()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn offset() -> isize {
|
||||
0
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn type_name() -> &'static str {
|
||||
stringify!($name)
|
||||
}
|
||||
#[inline]
|
||||
fn type_object() -> &'static mut $crate::ffi::PyTypeObject {
|
||||
unsafe { &mut $crate::ffi::$typeobject }
|
||||
}
|
||||
}
|
||||
|
||||
impl $crate::token::PythonObjectWithToken for $name {
|
||||
fn token<'p>(&'p self) -> $crate::python::Python<'p> {
|
||||
self.0.token()
|
||||
}
|
||||
}
|
||||
|
||||
impl $crate::std::fmt::Debug for $name {
|
||||
default fn fmt(&self, f: &mut $crate::std::fmt::Formatter)
|
||||
-> Result<(), $crate::std::fmt::Error>
|
||||
{
|
||||
let py = <$name as $crate::token::PythonObjectWithToken>::token(self);
|
||||
let s = unsafe { $crate::Py::<$crate::PyString>::cast_from_owned_or_err(
|
||||
py, $crate::ffi::PyObject_Repr(
|
||||
$crate::python::ToPythonPointer::as_ptr(self))) };
|
||||
let repr_obj = try!(s.map_err(|_| $crate::std::fmt::Error));
|
||||
f.write_str(&repr_obj.to_string_lossy())
|
||||
}
|
||||
}
|
||||
|
||||
impl $crate::std::fmt::Display for $name {
|
||||
fn fmt(&self, f: &mut $crate::std::fmt::Formatter)
|
||||
-> Result<(), $crate::std::fmt::Error>
|
||||
{
|
||||
let py = <$name as $crate::token::PythonObjectWithToken>::token(self);
|
||||
let s = unsafe { $crate::Py::<$crate::PyString>::cast_from_owned_or_err(
|
||||
py, $crate::ffi::PyObject_Str(
|
||||
$crate::python::ToPythonPointer::as_ptr(self))) };
|
||||
let str_obj = try!(s.map_err(|_| $crate::std::fmt::Error));
|
||||
f.write_str(&str_obj.to_string_lossy())
|
||||
}
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! pyobject_nativetype(
|
||||
($name: ident, $checkfunction: ident, $typeobject: ident) => (
|
||||
|
||||
impl<'p> $crate::native::PyNativeObject for $name<'p> {}
|
||||
impl<'p> $crate::native::PyNativeObject for $name<'p> {
|
||||
fn into_object(self) -> $crate::PyPtr<$crate::PyObjectMarker> {
|
||||
unsafe { $crate::std::mem::transmute(self) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'p> $crate::typeob::PyTypeInfo for $name<'p> {
|
||||
type Type = ();
|
||||
|
@ -112,14 +55,36 @@ macro_rules! pyobject_nativetype(
|
|||
}
|
||||
}
|
||||
|
||||
impl<'p> $crate::python::PythonObjectWithCheckedDowncast<'p> for $name<'p>
|
||||
impl<'p> $crate::python::PyDowncastFrom<'p> for $name<'p>
|
||||
{
|
||||
fn downcast_from(py: $crate::Py<'p, $crate::PyObject>)
|
||||
fn downcast_from(py: &'p $crate::PyObject<'p>)
|
||||
-> Result<&'p $name<'p>, $crate::PyDowncastError<'p>>
|
||||
{
|
||||
use $crate::{ToPythonPointer, PythonObjectWithToken};
|
||||
|
||||
unsafe {
|
||||
if $crate::ffi::$checkfunction(py.as_ptr()) > 0 {
|
||||
let ptr = py as *const _ as *mut u8 as *mut $name;
|
||||
Ok(ptr.as_ref().unwrap())
|
||||
} else {
|
||||
Err($crate::PyDowncastError(py.token(), None))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'p> $crate::python::PyDowncastInto<'p> for $name<'p>
|
||||
{
|
||||
fn downcast_into(py: $crate::Python<'p>, ob: $crate::PyObject)
|
||||
-> Result<$name<'p>, $crate::PyDowncastError<'p>>
|
||||
{
|
||||
let inst = $name(
|
||||
$crate::pptr::cast_from_borrowed_ptr::<$name>(py.token(), py.as_ptr())?);
|
||||
Ok(inst)
|
||||
match $crate::pptr::cast_from_owned_ptr::<$name>(py, ob.as_ptr()) {
|
||||
Ok(ptr) => {
|
||||
$crate::std::mem::forget(ob);
|
||||
Ok($name(ptr))
|
||||
},
|
||||
Err(e) => Err(e)
|
||||
}
|
||||
}
|
||||
|
||||
fn downcast_from_owned_ptr(py: $crate::Python<'p>, ptr: *mut $crate::ffi::PyObject)
|
||||
|
@ -137,6 +102,16 @@ macro_rules! pyobject_nativetype(
|
|||
}
|
||||
}
|
||||
|
||||
impl<'p> $crate::python::IntoPythonPointer for $name<'p> {
|
||||
/// Gets the underlying FFI pointer, returns a owned pointer.
|
||||
#[inline]
|
||||
fn into_ptr(self) -> *mut $crate::ffi::PyObject {
|
||||
let ptr = self.0.as_ptr();
|
||||
$crate::std::mem::forget(self);
|
||||
ptr
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> $crate::FromPyObject<'a> for $name<'a>
|
||||
{
|
||||
/// Extracts `Self` from the source `Py<PyObject>`.
|
||||
|
@ -196,10 +171,9 @@ macro_rules! pyobject_nativetype(
|
|||
default fn fmt(&self, f: &mut $crate::std::fmt::Formatter)
|
||||
-> Result<(), $crate::std::fmt::Error>
|
||||
{
|
||||
use python::PythonObjectWithCheckedDowncast;
|
||||
use $crate::python::PyDowncastInto;
|
||||
|
||||
let py = <$name as $crate::token::PythonObjectWithToken>::token(self);
|
||||
println!("DEBUG {:?}", self.as_ptr());
|
||||
let s = unsafe { $crate::PyString::downcast_from_owned_ptr(
|
||||
py, $crate::ffi::PyObject_Repr(
|
||||
$crate::python::ToPythonPointer::as_ptr(self))) };
|
||||
|
@ -212,8 +186,10 @@ macro_rules! pyobject_nativetype(
|
|||
fn fmt(&self, f: &mut $crate::std::fmt::Formatter)
|
||||
-> Result<(), $crate::std::fmt::Error>
|
||||
{
|
||||
use $crate::python::PyDowncastInto;
|
||||
|
||||
let py = <$name as $crate::token::PythonObjectWithToken>::token(self);
|
||||
let s = unsafe { $crate::Py::<$crate::PyString>::cast_from_owned_or_err(
|
||||
let s = unsafe { $crate::PyString::downcast_from_owned_ptr(
|
||||
py, $crate::ffi::PyObject_Str(
|
||||
$crate::python::ToPythonPointer::as_ptr(self))) };
|
||||
let str_obj = try!(s.map_err(|_| $crate::std::fmt::Error));
|
||||
|
|
|
@ -45,6 +45,18 @@ impl<'p> PyObject<'p> {
|
|||
unsafe { PyObject(pptr::from_borrowed_ptr(py, ptr)) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn from_borrowed_ptr_or_opt(py: Python<'p>, ptr: *mut ffi::PyObject)
|
||||
-> Option<PyObject<'p>> {
|
||||
unsafe {
|
||||
if let Some(ptr) = pptr::from_borrowed_ptr_or_opt(py, ptr) {
|
||||
Some(PyObject(ptr))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Transmutes a slice of owned FFI pointers to `&[Py<'p, PyObject>]`.
|
||||
/// Undefined behavior if any pointer in the slice is NULL or invalid.
|
||||
#[inline]
|
||||
|
@ -57,19 +69,20 @@ impl<'p> PyObject<'p> {
|
|||
/// Fails with `PyDowncastError` if the object is not of the expected type.
|
||||
#[inline]
|
||||
pub fn cast_as<D>(&'p self) -> Result<&'p D, PyDowncastError<'p>>
|
||||
where D: PyTypeInfo
|
||||
//where D: PyTypeInfo
|
||||
//{
|
||||
where D: ::PyDowncastFrom<'p>
|
||||
{
|
||||
unsafe {
|
||||
let ptr = self as *const _ as *mut _;
|
||||
let checked = ffi::PyObject_TypeCheck(ptr, D::type_object()) != 0;
|
||||
<D as ::PyDowncastFrom>::downcast_from(&self)
|
||||
}
|
||||
|
||||
if checked {
|
||||
let ptr = ptr as *mut D;
|
||||
Ok(ptr.as_ref().unwrap())
|
||||
} else {
|
||||
Err(PyDowncastError(self.token(), None))
|
||||
}
|
||||
}
|
||||
/// Casts the PyObject to a concrete Python object type.
|
||||
/// Fails with `PyDowncastError` if the object is not of the expected type.
|
||||
#[inline]
|
||||
pub fn cast_into<D>(self, py: Python<'p>) -> Result<D, PyDowncastError<'p>>
|
||||
where D: ::PyDowncastInto<'p>
|
||||
{
|
||||
<D as ::PyDowncastInto>::downcast_into(py, self)
|
||||
}
|
||||
|
||||
/// Extracts some type from the Python object.
|
||||
|
@ -80,3 +93,10 @@ impl<'p> PyObject<'p> {
|
|||
::conversion::FromPyObject::extract(&self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'p> PartialEq for PyObject<'p> {
|
||||
#[inline]
|
||||
fn eq(&self, other: &PyObject) -> bool {
|
||||
self.as_ptr() == other.as_ptr()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -166,7 +166,7 @@ impl<'p> PyString<'p> {
|
|||
// of forcing the UTF-8 representation to be created.
|
||||
unsafe {
|
||||
let mut size : ffi::Py_ssize_t = mem::uninitialized();
|
||||
let data = ffi::PyUnicode_AsUTF8AndSize(self.as_ptr(), &mut size) as *const u8;
|
||||
let data = ffi::PyUnicode_AsUTF8AndSize(self.0.as_ptr(), &mut size) as *const u8;
|
||||
if data.is_null() {
|
||||
PyErr::fetch(self.token()).print(self.token());
|
||||
panic!("PyUnicode_AsUTF8AndSize failed");
|
||||
|
|
|
@ -33,6 +33,11 @@ impl<'p> PyTuple<'p> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Construct a new tuple with the given raw pointer
|
||||
pub unsafe fn from_borrowed_ptr(py: Python<'p>, ptr: *mut ffi::PyObject) -> PyTuple<'p> {
|
||||
PyTuple(pptr::from_borrowed_ptr(py, ptr))
|
||||
}
|
||||
|
||||
/// Retrieves the empty tuple.
|
||||
pub fn empty(py: Python<'p>) -> PyTuple<'p> {
|
||||
unsafe {
|
||||
|
@ -122,7 +127,7 @@ macro_rules! tuple_conversion ({$length:expr,$(($refN:ident, $n:tt, $T:ident)),+
|
|||
fn extract(obj: &'s PyObject<'s>) -> PyResult<Self>
|
||||
//where S: ::typeob::PyTypeInfo
|
||||
{
|
||||
let t = try!(obj.cast_as::<&PyTuple>());
|
||||
let t = try!(obj.cast_as::<PyTuple>());
|
||||
let slice = t.as_slice();
|
||||
if t.len() == $length {
|
||||
Ok((
|
||||
|
|
|
@ -5,20 +5,21 @@
|
|||
use std::ffi::CStr;
|
||||
use std::borrow::Cow;
|
||||
|
||||
use ::pptr;
|
||||
use ffi;
|
||||
use pyptr::{PyPtr};
|
||||
use token::{PythonToken, PythonObjectWithToken};
|
||||
use token::PythonObjectWithToken;
|
||||
use python::{Python, ToPythonPointer};
|
||||
use conversion::ToPyTuple;
|
||||
use objects::{PyObject, PyDict};
|
||||
use err::PyResult;
|
||||
|
||||
/// Represents a reference to a Python type object.
|
||||
pub struct PyType(PythonToken<PyType>);
|
||||
pub struct PyType<'p>(pptr<'p>);
|
||||
|
||||
pyobject_newtype!(PyType, PyType_Check, PyType_Type);
|
||||
pyobject_nativetype!(PyType, PyType_Check, PyType_Type);
|
||||
|
||||
impl PyType {
|
||||
|
||||
impl<'p> PyType<'p> {
|
||||
/// Retrieves the underlying FFI pointer associated with this Python object.
|
||||
#[inline]
|
||||
pub fn as_type_ptr(&self) -> *mut ffi::PyTypeObject {
|
||||
|
@ -29,8 +30,8 @@ impl PyType {
|
|||
/// This increments the reference count on the type object.
|
||||
/// Undefined behavior if the pointer is NULL or invalid.
|
||||
#[inline]
|
||||
pub unsafe fn from_type_ptr(_py: Python, p: *mut ffi::PyTypeObject) -> PyPtr<PyType> {
|
||||
PyPtr::from_borrowed_ptr(p as *mut ffi::PyObject)
|
||||
pub unsafe fn from_type_ptr(py: Python<'p>, p: *mut ffi::PyTypeObject) -> PyType<'p> {
|
||||
PyType(pptr::from_borrowed_ptr(py, p as *mut ffi::PyObject))
|
||||
}
|
||||
|
||||
/// Gets the name of the PyType.
|
||||
|
@ -48,28 +49,28 @@ impl PyType {
|
|||
|
||||
/// Return true if `obj` is an instance of `self`.
|
||||
#[inline]
|
||||
pub fn is_instance(&self, _: Python, obj: &PyObject) -> bool {
|
||||
pub fn is_instance<T: ToPythonPointer>(&self, obj: &T) -> bool {
|
||||
unsafe { ffi::PyObject_TypeCheck(obj.as_ptr(), self.as_type_ptr()) != 0 }
|
||||
}
|
||||
|
||||
// /// Calls the type object, thus creating a new instance.
|
||||
// /// This is equivalent to the Python expression: `self(*args, **kwargs)`
|
||||
#[inline]
|
||||
pub fn call<'p, A>(&'p self, args: A, kwargs: Option<&PyDict>) -> PyResult<PyPtr<PyObject>>
|
||||
pub fn call<A>(&'p self, args: A, kwargs: Option<&PyDict>) -> PyResult<PyObject<'p>>
|
||||
where A: ToPyTuple
|
||||
{
|
||||
let args = args.to_py_tuple(self.token());
|
||||
unsafe {
|
||||
PyPtr::from_owned_ptr_or_err(
|
||||
PyObject::from_owned_ptr_or_err(
|
||||
self.token(), ffi::PyObject_Call(self.as_ptr(), args.as_ptr(), kwargs.as_ptr()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for PyType {
|
||||
impl<'p> PartialEq for PyType<'p> {
|
||||
#[inline]
|
||||
fn eq(&self, o : &PyType) -> bool {
|
||||
self.as_type_ptr() == o.as_type_ptr()
|
||||
fn eq(&self, other: &PyType) -> bool {
|
||||
self.as_type_ptr() == other.as_type_ptr()
|
||||
}
|
||||
}
|
||||
impl Eq for PyType { }
|
||||
impl<'p> Eq for PyType<'p> { }
|
||||
|
|
|
@ -58,7 +58,7 @@ impl<'p> pptr<'p> {
|
|||
/// This moves ownership over the pointer into the pptr<'p>.
|
||||
/// Returns None for null pointers; undefined behavior if the pointer is invalid.
|
||||
#[inline]
|
||||
pub unsafe fn from_owned_ptr_or_opt(py: Python<'p>, ptr: *mut ffi::PyObject)
|
||||
pub unsafe fn from_owned_ptr_or_opt(py: Python<'p>, ptr: *mut ffi::PyObject)
|
||||
-> Option<pptr<'p>> {
|
||||
if ptr.is_null() {
|
||||
None
|
||||
|
@ -80,8 +80,8 @@ impl<'p> pptr<'p> {
|
|||
/// Creates a Py instance for the given FFI pointer.
|
||||
/// Calls Py_INCREF() on the ptr.
|
||||
#[inline]
|
||||
pub unsafe fn from_borrowed_ptr_opt(py: Python<'p>,
|
||||
ptr: *mut ffi::PyObject) -> Option<pptr<'p>> {
|
||||
pub unsafe fn from_borrowed_ptr_or_opt(py: Python<'p>, ptr: *mut ffi::PyObject)
|
||||
-> Option<pptr<'p>> {
|
||||
if ptr.is_null() {
|
||||
None
|
||||
} else {
|
||||
|
|
22
src/pyptr.rs
22
src/pyptr.rs
|
@ -117,8 +117,8 @@ impl<T> PyPtr<T> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn clone_ref(&self) -> PyPtr<T> {
|
||||
PyPtr{inner: self.inner.clone(), _t: PhantomData}
|
||||
pub fn clone_ref(&self, _py: Python) -> PyPtr<T> {
|
||||
unsafe { PyPtr::from_borrowed_ptr(self.inner) }
|
||||
}
|
||||
|
||||
/// Unchecked downcast from other PyPtr<S> to PyPtr<S>.
|
||||
|
@ -130,6 +130,21 @@ impl<T> PyPtr<T> {
|
|||
std::mem::forget(py);
|
||||
res
|
||||
}
|
||||
|
||||
/// Casts the PyPtr to a concrete Python object type.
|
||||
/// Fails with `PyDowncastError` if the object is not of the expected type.
|
||||
#[inline]
|
||||
pub fn cast_into<'p, D>(self, py: Python<'p>) -> Result<D, PyDowncastError<'p>>
|
||||
where D: ::PyDowncastInto<'p>
|
||||
{
|
||||
match <D as ::PyDowncastInto>::downcast_from_owned_ptr(py, self.inner) {
|
||||
Ok(ptr) => {
|
||||
std::mem::forget(self);
|
||||
Ok(ptr)
|
||||
}
|
||||
Err(e) => Err(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> ToPythonPointer for PyPtr<T> {
|
||||
|
@ -547,11 +562,10 @@ impl<'p, T> AsMut<T> for Py<'p, T> where T: PyTypeInfo {
|
|||
}
|
||||
|
||||
impl<'source, T> ::FromPyObject<'source> for &'source T
|
||||
where T: PyTypeInfo
|
||||
where T: PyTypeInfo + ::PyDowncastFrom<'source>
|
||||
{
|
||||
#[inline]
|
||||
default fn extract(py: &'source PyObject<'source>) -> PyResult<&'source T>
|
||||
//where S: PyTypeInfo
|
||||
{
|
||||
Ok(py.cast_as()?)
|
||||
}
|
||||
|
|
|
@ -31,9 +31,19 @@ pub struct Python<'p>(PhantomData<&'p GILGuard>);
|
|||
|
||||
|
||||
/// Trait implemented by Python object types that allow a checked downcast.
|
||||
pub trait PythonObjectWithCheckedDowncast<'p> : Sized {
|
||||
pub trait PyDowncastFrom<'p> : Sized {
|
||||
|
||||
/// Cast from PyObject to a concrete Python object type.
|
||||
fn downcast_from(Py<'p, PyObject>) -> Result<Self, PyDowncastError<'p>>;
|
||||
fn downcast_from(&'p PyObject<'p>) -> Result<&'p Self, PyDowncastError<'p>>;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Trait implemented by Python object types that allow a checked downcast.
|
||||
pub trait PyDowncastInto<'p> : Sized {
|
||||
|
||||
/// Cast from PyObject to a concrete Python object type.
|
||||
fn downcast_into(Python<'p>, PyObject) -> Result<Self, PyDowncastError<'p>>;
|
||||
|
||||
/// Cast from ffi::PyObject to a concrete Python object type.
|
||||
fn downcast_from_owned_ptr(py: Python<'p>, ptr: *mut ffi::PyObject)
|
||||
|
@ -203,7 +213,7 @@ impl<'p> Python<'p> {
|
|||
}
|
||||
|
||||
/// Gets the Python type object for type T.
|
||||
pub fn get_type<T>(self) -> PyPtr<PyType> where T: PyTypeObject {
|
||||
pub fn get_type<T>(self) -> PyType<'p> where T: PyTypeObject {
|
||||
T::type_object(self)
|
||||
}
|
||||
|
||||
|
@ -230,14 +240,14 @@ impl<'p> Python<'p> {
|
|||
#[allow(non_snake_case)] // the Python keyword starts with uppercase
|
||||
#[inline]
|
||||
pub fn True(self) -> PyBool<'p> {
|
||||
PyBool::get(self, true)
|
||||
PyBool::new(self, true)
|
||||
}
|
||||
|
||||
/// Gets the Python builtin value `False`.
|
||||
#[allow(non_snake_case)] // the Python keyword starts with uppercase
|
||||
#[inline]
|
||||
pub fn False(self) -> PyBool<'p> {
|
||||
PyBool::get(self, false)
|
||||
PyBool::new(self, false)
|
||||
}
|
||||
|
||||
/// Gets the Python builtin value `NotImplemented`.
|
||||
|
|
|
@ -6,7 +6,7 @@ use std::marker::PhantomData;
|
|||
use ffi;
|
||||
use pyptr::{Py, PyPtr};
|
||||
use err::{PyResult};
|
||||
use python::{Python, ToPythonPointer, PythonObjectWithCheckedDowncast};
|
||||
use python::{Python, ToPythonPointer, PyDowncastInto};
|
||||
use objects::PyString;
|
||||
use typeob::{PyTypeInfo, PyObjectAlloc};
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ use std::collections::HashMap;
|
|||
|
||||
use {ffi, class};
|
||||
use err::{PyErr, PyResult};
|
||||
use pyptr::{Py, PyPtr};
|
||||
use pyptr::{Py};
|
||||
use python::{Python};
|
||||
use objects::PyType;
|
||||
use callback::AbortOnDrop;
|
||||
|
@ -153,14 +153,14 @@ impl<T> PyObjectAlloc for T where T : PyTypeInfo {
|
|||
pub trait PyTypeObject {
|
||||
|
||||
/// Retrieves the type object for this Python object type.
|
||||
fn type_object(py: Python) -> PyPtr<PyType>;
|
||||
fn type_object<'p>(py: Python<'p>) -> PyType<'p>;
|
||||
|
||||
}
|
||||
|
||||
impl<T> PyTypeObject for T where T: PyObjectAlloc + PyTypeInfo {
|
||||
|
||||
#[inline]
|
||||
fn type_object<'p>(py: Python) -> PyPtr<PyType> {
|
||||
fn type_object<'p>(py: Python<'p>) -> PyType<'p> {
|
||||
let mut ty = <T as PyTypeInfo>::type_object();
|
||||
|
||||
if (ty.tp_flags & ffi::Py_TPFLAGS_READY) != 0 {
|
||||
|
@ -175,11 +175,10 @@ impl<T> PyTypeObject for T where T: PyObjectAlloc + PyTypeInfo {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn initialize_type<'p, T>(py: Python, module_name: Option<&str>, type_name: &str,
|
||||
type_object: &mut ffi::PyTypeObject) -> PyResult<PyPtr<PyType>>
|
||||
pub fn initialize_type<'p, T>(py: Python<'p>, module_name: Option<&str>, type_name: &str,
|
||||
type_object: &mut ffi::PyTypeObject) -> PyResult<PyType<'p>>
|
||||
where T: PyObjectAlloc + PyTypeInfo
|
||||
{
|
||||
println!("=========== init type");
|
||||
// type name
|
||||
let name = match module_name {
|
||||
Some(module_name) => CString::new(format!("{}.{}", module_name, type_name)),
|
||||
|
|
|
@ -17,6 +17,7 @@ struct TestClass {
|
|||
|
||||
#[py::proto]
|
||||
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() {
|
||||
|
@ -31,7 +32,7 @@ impl class::PyBufferProtocol for TestClass {
|
|||
return Err(PyErr::new::<exc::BufferError, _>(py, "Object is not writable"))
|
||||
}
|
||||
|
||||
let bytes = self.vec(py);
|
||||
let bytes = &self.vec;
|
||||
|
||||
unsafe {
|
||||
(*view).buf = bytes.as_ptr() as *mut c_void;
|
||||
|
@ -70,10 +71,10 @@ fn test_buffer() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let t = TestClass::create_instance(py, vec![b' ', b'2', b'3']).unwrap();
|
||||
let t = py.with_token(|e| TestClass{vec: vec![b' ', b'2', b'3']});
|
||||
|
||||
let d = PyDict::new(py);
|
||||
let _ = d.set_item(py, "ob", t);
|
||||
let _ = d.set_item("ob", t);
|
||||
|
||||
py.run("assert bytes(ob) == b' 23'", None, Some(&d)).unwrap();
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ use pyo3::python::ToPythonPointer;
|
|||
|
||||
macro_rules! py_run {
|
||||
($py:expr, $val:ident, $code:expr) => {{
|
||||
let d = PyDict::new($py.token());
|
||||
let d = PyDict::new($py);
|
||||
d.set_item(stringify!($val), &$val).unwrap();
|
||||
//$py.run($code, None, Some(&d)).map_err(|e| e.print($py)).expect($code);
|
||||
$py.run($code, None, Some(&d)).expect($code);
|
||||
|
@ -27,11 +27,11 @@ macro_rules! py_assert {
|
|||
|
||||
macro_rules! py_expect_exception {
|
||||
($py:expr, $val:ident, $code:expr, $err:ident) => {{
|
||||
let d = PyDict::new($py.token());
|
||||
let d = PyDict::new($py);
|
||||
d.set_item(stringify!($val), &$val).unwrap();
|
||||
let res = $py.run($code, None, Some(&d));
|
||||
let err = res.unwrap_err();
|
||||
if !err.matches($py.token(), $py.token().get_type::<exc::$err>()) {
|
||||
if !err.matches($py, $py.get_type::<exc::$err>()) {
|
||||
panic!(format!("Expected {} but got {:?}", stringify!($err), err))
|
||||
}
|
||||
}}
|
||||
|
@ -46,9 +46,8 @@ fn empty_class() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let typeobj = py.get_type::<EmptyClass>();
|
||||
let to = typeobj.as_ref(py.token());
|
||||
// By default, don't allow creating instances from python.
|
||||
assert!(to.call(NoArgs, None).is_err());
|
||||
assert!(typeobj.call(NoArgs, None).is_err());
|
||||
|
||||
py_assert!(py, typeobj, "typeobj.__name__ == 'EmptyClass'");
|
||||
}
|
||||
|
@ -56,11 +55,11 @@ fn empty_class() {
|
|||
#[py::class]
|
||||
struct EmptyClassInModule { }
|
||||
|
||||
#[test]
|
||||
//#[test]
|
||||
fn empty_class_in_module() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let module = PyModule::new(py.token(), "test_module.nested").unwrap();
|
||||
let module = PyModule::new(py, "test_module.nested").unwrap();
|
||||
module.add_class::<EmptyClassInModule>().unwrap();
|
||||
|
||||
let ty = module.getattr("EmptyClassInModule").unwrap();
|
||||
|
@ -84,8 +83,7 @@ fn empty_class_with_new() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let typeobj = py.get_type::<EmptyClassWithNew>();
|
||||
let to = typeobj.as_ref(py.token());
|
||||
assert!(to.call(NoArgs, None).unwrap().cast_into::<EmptyClassWithNew>().is_ok());
|
||||
assert!(typeobj.call(NoArgs, None).unwrap().cast_as::<EmptyClassWithNew>().is_ok());
|
||||
}
|
||||
|
||||
#[py::class]
|
||||
|
@ -107,7 +105,8 @@ fn new_with_one_arg() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let typeobj = py.get_type::<NewWithOneArg>();
|
||||
let obj = typeobj.call((42,), None).unwrap().cast_into::<NewWithOneArg>().unwrap();
|
||||
let wrp = typeobj.call((42,), None).unwrap();
|
||||
let obj = wrp.cast_as::<NewWithOneArg>().unwrap();
|
||||
assert_eq!(obj._data, 42);
|
||||
}
|
||||
|
||||
|
@ -132,7 +131,8 @@ fn new_with_two_args() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let typeobj = py.get_type::<NewWithTwoArgs>();
|
||||
let obj = typeobj.call((10, 20), None).unwrap().cast_into::<NewWithTwoArgs>().unwrap();
|
||||
let wrp = typeobj.call((10, 20), None).unwrap();
|
||||
let obj = wrp.cast_as::<NewWithTwoArgs>().unwrap();
|
||||
assert_eq!(obj._data1, 10);
|
||||
assert_eq!(obj._data2, 20);
|
||||
}
|
||||
|
@ -316,7 +316,7 @@ impl StaticMethod {
|
|||
|
||||
#[py::class]
|
||||
struct GCIntegration {
|
||||
self_ref: RefCell<PyPtr<PyObject>>,
|
||||
self_ref: RefCell<PyPtr<PyObjectMarker>>,
|
||||
dropped: TestDropCall,
|
||||
token: PythonToken<GCIntegration>,
|
||||
}
|
||||
|
@ -328,7 +328,7 @@ impl PyGCProtocol for GCIntegration {
|
|||
}
|
||||
|
||||
fn __clear__(&mut self, py: Python) {
|
||||
*self.self_ref.borrow_mut() = self.token.None();
|
||||
*self.self_ref.borrow_mut() = py.None();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -339,7 +339,7 @@ fn gc_integration() {
|
|||
|
||||
let drop_called = Arc::new(AtomicBool::new(false));
|
||||
let mut inst = py.with_token(|t| GCIntegration{
|
||||
self_ref: RefCell::new(t.None()),
|
||||
self_ref: RefCell::new(py.None()),
|
||||
dropped: TestDropCall { drop_called: drop_called.clone() },
|
||||
token: t});
|
||||
|
||||
|
@ -422,7 +422,7 @@ impl<'p> PyObjectProtocol<'p> for StringMethods {
|
|||
// Ok(PyString::new(py, "unicode"))
|
||||
//}
|
||||
|
||||
fn __bytes__(&self, py: Python) -> PyResult<Py<PyBytes>> {
|
||||
fn __bytes__(&self, py: Python) -> PyResult<PyBytes<'p>> {
|
||||
Ok(PyBytes::new(py, b"bytes"))
|
||||
}
|
||||
}
|
||||
|
@ -707,35 +707,35 @@ impl PyObjectProtocol for BinaryArithmetic {
|
|||
|
||||
#[py::proto]
|
||||
impl PyNumberProtocol for BinaryArithmetic {
|
||||
fn __add__(&self, py: Python, rhs: &PyObject) -> PyResult<String> {
|
||||
fn __add__(&self, py: Python, rhs: &PyObject<'p>) -> PyResult<String> {
|
||||
Ok(format!("{:?} + {:?}", self, rhs))
|
||||
}
|
||||
|
||||
fn __sub__(&self, py: Python, rhs: &PyObject) -> PyResult<String> {
|
||||
fn __sub__(&self, py: Python, rhs: &PyObject<'p>) -> PyResult<String> {
|
||||
Ok(format!("{:?} - {:?}", self, rhs))
|
||||
}
|
||||
|
||||
fn __mul__(&self, py: Python, rhs: &PyObject) -> PyResult<String> {
|
||||
fn __mul__(&self, py: Python, rhs: &PyObject<'p>) -> PyResult<String> {
|
||||
Ok(format!("{:?} * {:?}", self, rhs))
|
||||
}
|
||||
|
||||
fn __lshift__(&self, py: Python, rhs: &PyObject) -> PyResult<String> {
|
||||
fn __lshift__(&self, py: Python, rhs: &PyObject<'p>) -> PyResult<String> {
|
||||
Ok(format!("{:?} << {:?}", self, rhs))
|
||||
}
|
||||
|
||||
fn __rshift__(&self, py: Python, rhs: &PyObject) -> PyResult<String> {
|
||||
fn __rshift__(&self, py: Python, rhs: &PyObject<'p>) -> PyResult<String> {
|
||||
Ok(format!("{:?} >> {:?}", self, rhs))
|
||||
}
|
||||
|
||||
fn __and__(&self, py: Python, rhs: &PyObject) -> PyResult<String> {
|
||||
fn __and__(&self, py: Python, rhs: &PyObject<'p>) -> PyResult<String> {
|
||||
Ok(format!("{:?} & {:?}", self, rhs))
|
||||
}
|
||||
|
||||
fn __xor__(&self, py: Python, rhs: &PyObject) -> PyResult<String> {
|
||||
fn __xor__(&self, py: Python, rhs: &PyObject<'p>) -> PyResult<String> {
|
||||
Ok(format!("{:?} ^ {:?}", self, rhs))
|
||||
}
|
||||
|
||||
fn __or__(&self, py: Python, rhs: &PyObject) -> PyResult<String> {
|
||||
fn __or__(&self, py: Python, rhs: &PyObject<'p>) -> PyResult<String> {
|
||||
Ok(format!("{:?} | {:?}", self, rhs))
|
||||
}
|
||||
}
|
||||
|
@ -778,7 +778,7 @@ impl PyObjectProtocol for RichComparisons {
|
|||
Ok("RC")
|
||||
}
|
||||
|
||||
fn __richcmp__(&self, py: Python, other: &PyObject, op: CompareOp) -> PyResult<String> {
|
||||
fn __richcmp__(&self, py: Python, other: &PyObject<'p>, op: CompareOp) -> PyResult<String> {
|
||||
match op {
|
||||
CompareOp::Lt => Ok(format!("{:?} < {:?}", self.__repr__(py), other)),
|
||||
CompareOp::Le => Ok(format!("{:?} <= {:?}", self.__repr__(py), other)),
|
||||
|
@ -802,11 +802,11 @@ impl PyObjectProtocol for RichComparisons2 {
|
|||
}
|
||||
|
||||
fn __richcmp__(&self, py: Python,
|
||||
other: &PyObject, op: CompareOp) -> PyResult<PyPtr<PyObject>> {
|
||||
other: &'p PyObject<'p>, op: CompareOp) -> PyResult<PyPtr<PyObjectMarker>> {
|
||||
match op {
|
||||
CompareOp::Eq => Ok(true.to_object(py.token()).into_object()),
|
||||
CompareOp::Ne => Ok(false.to_object(py.token()).into_object()),
|
||||
_ => Ok(py.token().NotImplemented())
|
||||
CompareOp::Eq => Ok(true.to_object(py).into_object()),
|
||||
CompareOp::Ne => Ok(false.to_object(py).into_object()),
|
||||
_ => Ok(py.NotImplemented())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -952,10 +952,12 @@ fn inplace_operations() {
|
|||
#[py::class]
|
||||
struct ContextManager {
|
||||
exit_called: bool,
|
||||
|
||||
#[token]
|
||||
token: PythonToken<ContextManager>,
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
#[py::proto]
|
||||
impl<'p> PyContextProtocol<'p> for ContextManager {
|
||||
|
||||
|
@ -964,19 +966,19 @@ impl<'p> PyContextProtocol<'p> for ContextManager {
|
|||
}
|
||||
|
||||
fn __exit__(&mut self, py: Python,
|
||||
ty: Option<&'p PyType>,
|
||||
value: Option<&'p PyObject>,
|
||||
traceback: Option<&'p PyObject>) -> PyResult<bool> {
|
||||
ty: Option<PyType<'p>>,
|
||||
value: Option<PyObject<'p>>,
|
||||
traceback: Option<PyObject<'p>>) -> PyResult<bool> {
|
||||
self.exit_called = true;
|
||||
if ty == Some(py.get_type::<exc::ValueError>()) {
|
||||
Ok(true)
|
||||
} else {
|
||||
Ok(false)
|
||||
Ok(false)
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
/*#[test]
|
||||
#[test]
|
||||
fn context_manager() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
@ -994,7 +996,7 @@ fn context_manager() {
|
|||
py, c, "with c as x:\n raise NotImplementedError",
|
||||
NotImplementedError);
|
||||
assert!(c.exit_called);
|
||||
}*/
|
||||
}
|
||||
|
||||
|
||||
#[py::class]
|
||||
|
|
|
@ -24,19 +24,18 @@ fn test_basics() {
|
|||
struct Test {}
|
||||
|
||||
#[py::proto]
|
||||
impl<'p> PyMappingProtocol<'p> for Test {
|
||||
fn __getitem__(&self, idx: Py<'p, PyObject>) -> PyResult<Py<'p, PyObject>> {
|
||||
let py = self.py();
|
||||
|
||||
impl<'p> PyMappingProtocol<'p> for Test
|
||||
{
|
||||
fn __getitem__(&self, py: Python, idx: PyObject<'p>) -> PyResult<PyPtr<PyObjectMarker>> {
|
||||
if let Ok(slice) = idx.cast_as::<PySlice>() {
|
||||
let indices = slice.indices(1000)?;
|
||||
if indices.start == 100 && indices.stop == 200 && indices.step == 1 {
|
||||
return Ok("slice".to_object(py).into_object())
|
||||
return Ok("slice".to_object(py))
|
||||
}
|
||||
}
|
||||
else if let Ok(idx) = idx.extract::<isize>() {
|
||||
if idx == 1 {
|
||||
return Ok("int".to_object(py).into_object())
|
||||
return Ok("int".to_object(py))
|
||||
}
|
||||
}
|
||||
Err(PyErr::new::<exc::ValueError, _>(py, "error"))
|
||||
|
@ -48,7 +47,7 @@ fn test_cls_impl() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let ob = py.init(Test{});
|
||||
let ob = py.with_token(|e| Test{});
|
||||
let d = PyDict::new(py);
|
||||
d.set_item("ob", ob).unwrap();
|
||||
|
||||
|
|
Loading…
Reference in New Issue