introduce python token system
This commit is contained in:
parent
bfb01f65d3
commit
6c87c9b77b
|
@ -6,15 +6,33 @@ use quote::Tokens;
|
|||
|
||||
pub fn build_py_class(ast: &mut syn::DeriveInput) -> Tokens {
|
||||
let base = syn::Ident::from("_pyo3::PyObject");
|
||||
let mut token: Option<syn::Ident> = None;
|
||||
|
||||
match ast.body {
|
||||
syn::Body::Struct(syn::VariantData::Struct(_)) => {
|
||||
syn::Body::Struct(syn::VariantData::Struct(ref mut fields)) => {
|
||||
for field in fields.iter_mut() {
|
||||
let mut attrs = vec![];
|
||||
for attr in field.attrs.iter() {
|
||||
match attr.value {
|
||||
syn::MetaItem::Word(ref a) => {
|
||||
if a.as_ref() == "token" {
|
||||
token = field.ident.clone();
|
||||
continue
|
||||
}
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
attrs.push(attr.clone());
|
||||
println!("FIELD: {:?}", attr);
|
||||
}
|
||||
field.attrs = attrs;
|
||||
}
|
||||
},
|
||||
_ => panic!("#[class] can only be used with notmal structs"),
|
||||
}
|
||||
|
||||
let dummy_const = syn::Ident::new(format!("_IMPL_PYO3_CLS_{}", ast.ident));
|
||||
let tokens = impl_class(&ast.ident, &base);
|
||||
let tokens = impl_class(&ast.ident, &base, token);
|
||||
|
||||
quote! {
|
||||
#[feature(specialization)]
|
||||
|
@ -23,16 +41,54 @@ pub fn build_py_class(ast: &mut syn::DeriveInput) -> Tokens {
|
|||
const #dummy_const: () = {
|
||||
extern crate pyo3 as _pyo3;
|
||||
use std;
|
||||
use pyo3::python::PythonObjectWithToken;
|
||||
|
||||
#tokens
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
fn impl_class(cls: &syn::Ident, base: &syn::Ident) -> Tokens {
|
||||
let token_name = syn::Ident::from("__py_token");
|
||||
fn impl_class(cls: &syn::Ident, base: &syn::Ident, token: Option<syn::Ident>) -> Tokens {
|
||||
let cls_name = quote! { #cls }.as_str().to_string();
|
||||
|
||||
let extra = if let Some(token) = token {
|
||||
Some(quote! {
|
||||
impl _pyo3::python::PythonObjectWithToken for #cls {
|
||||
fn token<'p>(&'p self) -> _pyo3::python::Token<'p> {
|
||||
self.#token.token()
|
||||
}
|
||||
}
|
||||
|
||||
/*impl std::fmt::Debug for #cls {
|
||||
fn fmt(&self, f : &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
|
||||
self.token().with(|py| {
|
||||
let ptr = <#cls as _pyo3::python::ToPythonPointer>::as_ptr(self);
|
||||
let repr = unsafe {
|
||||
_pyo3::Py::<_pyo3::PyString>::cast_from_owned_nullptr(
|
||||
py, _pyo3::ffi::PyObject_Repr(ptr))
|
||||
.map_err(|_| std::fmt::Error)? };
|
||||
f.write_str(&repr.to_string_lossy())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for #cls {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
|
||||
self.token().with(|py| {
|
||||
let ptr = <#cls as _pyo3::python::ToPythonPointer>::as_ptr(self);
|
||||
let s = unsafe {
|
||||
_pyo3::Py::<_pyo3::PyString>::cast_from_owned_nullptr(
|
||||
py, _pyo3::ffi::PyObject_Str(ptr)
|
||||
).map_err(|_| std::fmt::Error)?};
|
||||
f.write_str(&s.to_string_lossy())
|
||||
})
|
||||
}
|
||||
}*/
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
quote! {
|
||||
impl _pyo3::typeob::PyTypeInfo for #cls {
|
||||
type Type = #cls;
|
||||
|
@ -61,49 +117,6 @@ fn impl_class(cls: &syn::Ident, base: &syn::Ident) -> Tokens {
|
|||
}
|
||||
}
|
||||
|
||||
impl _pyo3::python::ToPythonPointer for #cls {
|
||||
#[inline]
|
||||
fn as_ptr(&self) -> *mut ffi::PyObject {
|
||||
let offset = <#cls as _pyo3::typeob::PyTypeInfo>::offset();
|
||||
unsafe {
|
||||
{self as *const _ as *mut u8}.offset(-offset) as *mut _pyo3::ffi::PyObject
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl _pyo3::python::PyClone for #cls {
|
||||
fn clone_ref(&self) -> PyPtr<#cls> {
|
||||
unsafe {
|
||||
let ptr = <#cls as _pyo3::python::ToPythonPointer>::as_ptr(self);
|
||||
_pyo3::PyPtr::from_borrowed_ptr(ptr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for #cls {
|
||||
fn fmt(&self, f : &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
|
||||
unsafe {
|
||||
let py = _pyo3::Python::assume_gil_acquired();
|
||||
let ptr = <#cls as _pyo3::python::ToPythonPointer>::as_ptr(self);
|
||||
let repr = try!(_pyo3::Py::<_pyo3::PyString>::cast_from_owned_nullptr(
|
||||
py, _pyo3::ffi::PyObject_Repr(ptr)).map_err(|_| std::fmt::Error));
|
||||
|
||||
f.write_str(&repr.to_string_lossy())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for #cls {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
|
||||
unsafe {
|
||||
let py = _pyo3::Python::assume_gil_acquired();
|
||||
let ptr = <#cls as _pyo3::python::ToPythonPointer>::as_ptr(self);
|
||||
let s = try!(_pyo3::Py::<_pyo3::PyString>::cast_from_owned_nullptr(
|
||||
py, _pyo3::ffi::PyObject_Str(ptr)).map_err(|_| std::fmt::Error));
|
||||
|
||||
f.write_str(&s.to_string_lossy())
|
||||
}
|
||||
}
|
||||
}
|
||||
#extra
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,9 +48,10 @@ 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 mut slf: Py<#cls> = Py::from_borrowed_ptr(py.token(), slf);
|
||||
|
||||
let args: _pyo3::Py<_pyo3::PyTuple> = _pyo3::Py::from_borrowed_ptr(py, args);
|
||||
let args: _pyo3::Py<_pyo3::PyTuple> =
|
||||
_pyo3::Py::from_borrowed_ptr(py.token(), args);
|
||||
let kwargs: Option<_pyo3::Py<_pyo3::PyDict>> =
|
||||
_pyo3::argparse::get_kwargs(py, kwargs);
|
||||
|
||||
|
@ -77,9 +78,10 @@ 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 mut slf: Py<#cls> = Py::from_borrowed_ptr(py.token(), slf);
|
||||
|
||||
let args: _pyo3::Py<_pyo3::PyTuple> = _pyo3::Py::from_borrowed_ptr(py, args);
|
||||
let args: _pyo3::Py<_pyo3::PyTuple> =
|
||||
_pyo3::Py::from_borrowed_ptr(py.token(), args);
|
||||
let kwargs: Option<_pyo3::Py<_pyo3::PyDict>> =
|
||||
_pyo3::argparse::get_kwargs(py, kwargs);
|
||||
|
||||
|
@ -109,8 +111,9 @@ pub fn impl_wrap_new(cls: &Box<syn::Ty>, name: &syn::Ident, spec: &FnSpec) -> To
|
|||
|
||||
_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);
|
||||
py.token(), cls as *mut _pyo3::ffi::PyObject);
|
||||
let args: _pyo3::Py<_pyo3::PyTuple> =
|
||||
_pyo3::Py::from_borrowed_ptr(py.token(), args);
|
||||
let kwargs: Option<_pyo3::Py<_pyo3::PyDict>> =
|
||||
_pyo3::argparse::get_kwargs(py, kwargs);
|
||||
|
||||
|
@ -158,8 +161,8 @@ fn impl_wrap_setter(cls: &Box<syn::Ty>, name: &syn::Ident, spec: &FnSpec) -> Tok
|
|||
const LOCATION: &'static str = concat!(
|
||||
stringify!(#cls), ".setter", stringify!(#name), "()");
|
||||
_pyo3::callback::cb_setter(LOCATION, |py| {
|
||||
let mut slf = _pyo3::Py::<#cls>::from_borrowed_ptr(py, slf);
|
||||
let value = _pyo3::PyObject::from_borrowed_ptr(py, value);
|
||||
let mut slf = _pyo3::Py::<#cls>::from_borrowed_ptr(py.token(), slf);
|
||||
let value = _pyo3::PyObject::from_borrowed_ptr(py.token(), value);
|
||||
|
||||
let result = match <#val_ty as _pyo3::FromPyObject>::extract(&value) {
|
||||
Ok(val) => slf.#name(py, val),
|
||||
|
|
|
@ -21,9 +21,9 @@
|
|||
|
||||
use ffi;
|
||||
use pyptr::{Py};
|
||||
use python::Python;
|
||||
use python::{Python, PythonObjectWithToken};
|
||||
use objects::{PyObject, PyTuple, PyDict, PyString, exc};
|
||||
//use conversion::RefFromPyObject;
|
||||
use conversion::RefFromPyObject;
|
||||
use err::{self, PyResult};
|
||||
|
||||
/// Description of a python parameter; used for `parse_args()`.
|
||||
|
@ -44,17 +44,17 @@ 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: &Py<'p, PyTuple>, kwargs: Option<&'p Py<'p, PyDict>>,
|
||||
args: &'p PyTuple, kwargs: Option<&'p PyDict>,
|
||||
accept_args: bool, accept_kwargs: bool,
|
||||
output: &mut[Option<Py<'p, PyObject>>]) -> PyResult<()>
|
||||
output: &mut[Option<&'p PyObject>]) -> PyResult<()>
|
||||
{
|
||||
assert!(params.len() == output.len());
|
||||
|
||||
let nargs = args.len()?;
|
||||
let nkeywords = kwargs.map_or(0, |d| d.len().unwrap_or(0));
|
||||
let nargs = args.len();
|
||||
let nkeywords = kwargs.map_or(0, |d| d.len());
|
||||
if !accept_args && (nargs + nkeywords > params.len()) {
|
||||
return Err(err::PyErr::new::<exc::TypeError, _>(
|
||||
py,
|
||||
py.token(),
|
||||
format!("{}{} takes at most {} argument{} ({} given)",
|
||||
fname.unwrap_or("function"),
|
||||
if fname.is_some() { "()" } else { "" },
|
||||
|
@ -66,25 +66,27 @@ pub fn parse_args<'p>(py: Python<'p>,
|
|||
let mut used_keywords = 0;
|
||||
// Iterate through the parameters and assign values to output:
|
||||
for (i, (p, out)) in params.iter().zip(output).enumerate() {
|
||||
match kwargs.and_then(|d| d.as_ref().get_item(p.name)) {
|
||||
match kwargs.and_then(|d| d.get_item(p.name)) {
|
||||
Some(kwarg) => {
|
||||
*out = Some(kwarg);
|
||||
used_keywords += 1;
|
||||
if i < nargs {
|
||||
return Err(err::PyErr::new::<exc::TypeError, _>(py,
|
||||
return Err(err::PyErr::new::<exc::TypeError, _>(
|
||||
py.token(),
|
||||
format!("Argument given by name ('{}') and position ({})",
|
||||
p.name, i+1)));
|
||||
}
|
||||
},
|
||||
None => {
|
||||
if i < nargs {
|
||||
*out = Some(args.as_ref().get_item(i));
|
||||
*out = Some(args.get_item(i));
|
||||
} else {
|
||||
*out = None;
|
||||
if !p.is_optional {
|
||||
return Err(err::PyErr::new::<exc::TypeError, _>(
|
||||
py, format!("Required argument ('{}') (pos {}) not found",
|
||||
p.name, i+1)));
|
||||
py.token(),
|
||||
format!("Required argument ('{}') (pos {}) not found",
|
||||
p.name, i+1)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -95,7 +97,8 @@ pub fn parse_args<'p>(py: Python<'p>,
|
|||
for (key, _value) in kwargs.unwrap().items() {
|
||||
let key = try!(try!(key.cast_as::<PyString>()).to_string());
|
||||
if !params.iter().any(|p| p.name == key) {
|
||||
return Err(err::PyErr::new::<exc::TypeError, _>(py,
|
||||
return Err(err::PyErr::new::<exc::TypeError, _>(
|
||||
py.token(),
|
||||
format!("'{}' is an invalid keyword argument for this function",
|
||||
key)));
|
||||
}
|
||||
|
@ -103,7 +106,7 @@ pub fn parse_args<'p>(py: Python<'p>,
|
|||
}
|
||||
Ok(())
|
||||
}
|
||||
/*
|
||||
|
||||
/// This macro is used to parse a parameter list into a set of variables.
|
||||
///
|
||||
/// Syntax: `py_argparse!(py, fname, args, kwargs, (parameter-list) { body })`
|
||||
|
@ -335,7 +338,7 @@ macro_rules! py_argparse_impl {
|
|||
Err(e) => Err(e)
|
||||
}
|
||||
}};
|
||||
}*/
|
||||
}
|
||||
|
||||
// Like py_argparse_impl!(), but accepts `*mut ffi::PyObject` for $args and $kwargs.
|
||||
#[macro_export]
|
||||
|
@ -357,7 +360,7 @@ pub unsafe fn get_kwargs<'p>(py: Python<'p>, ptr: *mut ffi::PyObject) -> Option<
|
|||
if ptr.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(Py::<PyDict>::from_borrowed_ptr(py, ptr))
|
||||
Some(Py::<PyDict>::from_borrowed_ptr(py.token(), ptr))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -143,7 +143,7 @@ impl PyBuffer {
|
|||
unsafe {
|
||||
let mut buf = Box::new(mem::zeroed::<ffi::Py_buffer>());
|
||||
err::error_on_minusone(
|
||||
obj.py(),
|
||||
obj.token(),
|
||||
ffi::PyObject_GetBuffer(obj.as_ptr(), &mut *buf, ffi::PyBUF_FULL_RO))?;
|
||||
validate(&buf);
|
||||
Ok(PyBuffer(buf))
|
||||
|
@ -401,7 +401,7 @@ impl PyBuffer {
|
|||
return incompatible_format_error(py);
|
||||
}
|
||||
unsafe {
|
||||
err::error_on_minusone(py, ffi::PyBuffer_ToContiguous(
|
||||
err::error_on_minusone(py.token(), ffi::PyBuffer_ToContiguous(
|
||||
target.as_ptr() as *mut raw::c_void,
|
||||
&*self.0 as *const ffi::Py_buffer as *mut ffi::Py_buffer,
|
||||
self.0.len,
|
||||
|
@ -436,7 +436,7 @@ impl PyBuffer {
|
|||
unsafe {
|
||||
// Copy the buffer into the uninitialized space in the vector.
|
||||
// Due to T:Copy, we don't need to be concerned with Drop impls.
|
||||
err::error_on_minusone(py, ffi::PyBuffer_ToContiguous(
|
||||
err::error_on_minusone(py.token(), ffi::PyBuffer_ToContiguous(
|
||||
vec.as_mut_ptr() as *mut raw::c_void,
|
||||
&*self.0 as *const ffi::Py_buffer as *mut ffi::Py_buffer,
|
||||
self.0.len,
|
||||
|
@ -487,7 +487,7 @@ impl PyBuffer {
|
|||
return incompatible_format_error(py);
|
||||
}
|
||||
unsafe {
|
||||
err::error_on_minusone(py, ffi::PyBuffer_FromContiguous(
|
||||
err::error_on_minusone(py.token(), ffi::PyBuffer_FromContiguous(
|
||||
&*self.0 as *const ffi::Py_buffer as *mut ffi::Py_buffer,
|
||||
source.as_ptr() as *mut raw::c_void,
|
||||
self.0.len,
|
||||
|
@ -498,15 +498,18 @@ impl PyBuffer {
|
|||
}
|
||||
|
||||
fn slice_length_error(py: Python) -> PyResult<()> {
|
||||
Err(err::PyErr::new::<exc::BufferError, _>(py, "Slice length does not match buffer length."))
|
||||
Err(err::PyErr::new::<exc::BufferError, _>(
|
||||
py.token(), "Slice length does not match buffer length."))
|
||||
}
|
||||
|
||||
fn incompatible_format_error(py: Python) -> PyResult<()> {
|
||||
Err(err::PyErr::new::<exc::BufferError, _>(py, "Slice type is incompatible with buffer format."))
|
||||
Err(err::PyErr::new::<exc::BufferError, _>(
|
||||
py.token(), "Slice type is incompatible with buffer format."))
|
||||
}
|
||||
|
||||
fn buffer_readonly_error(py: Python) -> PyResult<()> {
|
||||
Err(err::PyErr::new::<exc::BufferError, _>(py, "Cannot write to read-only buffer."))
|
||||
Err(err::PyErr::new::<exc::BufferError, _>(
|
||||
py.token(), "Cannot write to read-only buffer."))
|
||||
}
|
||||
|
||||
impl Drop for PyBuffer {
|
||||
|
|
|
@ -5,7 +5,7 @@ use std::{any, mem, ptr, isize, io, panic};
|
|||
use libc;
|
||||
|
||||
use pyptr::Py;
|
||||
use python::{Python, IntoPythonPointer};
|
||||
use python::{Python, IntoPythonPointer, PythonObjectWithToken};
|
||||
use objects::exc;
|
||||
use conversion::IntoPyObject;
|
||||
use ffi::{self, Py_hash_t};
|
||||
|
@ -27,7 +27,7 @@ impl<S> CallbackConverter<S> for PyObjectCallbackConverter
|
|||
type R = *mut ffi::PyObject;
|
||||
|
||||
fn convert(val: S, py: Python) -> *mut ffi::PyObject {
|
||||
val.into_object(py).into_ptr()
|
||||
val.into_object(py.token()).into_ptr()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -62,7 +62,8 @@ impl CallbackConverter<usize> for LenResultConverter {
|
|||
if val <= (isize::MAX as usize) {
|
||||
val as isize
|
||||
} else {
|
||||
PyErr::new_lazy_init(py.get_ptype::<exc::OverflowError>(), None).restore(py);
|
||||
PyErr::new_lazy_init(
|
||||
py.get_type::<exc::OverflowError>(), None).restore(py.token());
|
||||
-1
|
||||
}
|
||||
}
|
||||
|
@ -176,7 +177,7 @@ pub unsafe fn handle<'p, F, T, C>(location: &str, _c: C, f: F) -> C::R
|
|||
C::convert(val, py)
|
||||
}
|
||||
Err(e) => {
|
||||
e.restore(py);
|
||||
e.restore(py.token());
|
||||
C::error_value()
|
||||
}
|
||||
}
|
||||
|
@ -203,14 +204,14 @@ pub unsafe fn cb_unary<Slf, F, T, C>(location: &str,
|
|||
let guard = AbortOnDrop(location);
|
||||
let ret = panic::catch_unwind(|| {
|
||||
let py = Python::assume_gil_acquired();
|
||||
let mut slf: Py<Slf> = Py::from_borrowed_ptr(py, slf);
|
||||
let mut slf: Py<Slf> = Py::from_borrowed_ptr(py.token(), slf);
|
||||
|
||||
match f(py, slf.as_mut()) {
|
||||
Ok(val) => {
|
||||
C::convert(val, py)
|
||||
}
|
||||
Err(e) => {
|
||||
e.restore(py);
|
||||
e.restore(py.token());
|
||||
C::error_value()
|
||||
}
|
||||
}
|
||||
|
@ -235,7 +236,7 @@ pub unsafe fn cb_unary_unit<Slf, F>(location: &str, slf: *mut ffi::PyObject, f:
|
|||
let guard = AbortOnDrop(location);
|
||||
let ret = panic::catch_unwind(|| {
|
||||
let py = Python::assume_gil_acquired();
|
||||
let mut slf: Py<Slf> = Py::from_borrowed_ptr(py, slf);
|
||||
let mut slf: Py<Slf> = Py::from_borrowed_ptr(py.token(), slf);
|
||||
|
||||
f(py, slf.as_mut())
|
||||
});
|
||||
|
@ -297,7 +298,7 @@ pub unsafe fn cb_convert<C, T>(_c: C, py: Python, value: PyResult<T>) -> C::R
|
|||
match value {
|
||||
Ok(val) => C::convert(val, py),
|
||||
Err(e) => {
|
||||
e.restore(py);
|
||||
e.restore(py.token());
|
||||
C::error_value()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
use ffi;
|
||||
use err::PyResult;
|
||||
use python::Python;
|
||||
use python::{Python, PythonObjectWithToken};
|
||||
use callback::PyObjectCallbackConverter;
|
||||
use typeob::PyTypeInfo;
|
||||
use class::methods::PyMethodDef;
|
||||
|
|
|
@ -11,7 +11,7 @@ use std::os::raw::c_int;
|
|||
use ::{Py, CompareOp};
|
||||
use ffi;
|
||||
use err::{PyErr, PyResult};
|
||||
use python::{Python, IntoPythonPointer};
|
||||
use python::{Python, IntoPythonPointer, PythonObjectWithToken};
|
||||
use objects::{exc, PyObject};
|
||||
use typeob::PyTypeInfo;
|
||||
use conversion::{ToPyObject, FromPyObject, IntoPyObject};
|
||||
|
@ -345,8 +345,8 @@ impl<T> PyObjectRichcmpProtocolImpl for T where T: for<'p> PyObjectRichcmpProtoc
|
|||
let guard = ::callback::AbortOnDrop(LOCATION);
|
||||
let ret = std::panic::catch_unwind(|| {
|
||||
let py = Python::assume_gil_acquired();
|
||||
let slf = Py::<T>::from_borrowed_ptr(py, slf);
|
||||
let arg = PyObject::from_borrowed_ptr(py, arg);
|
||||
let slf = Py::<T>::from_borrowed_ptr(py.token(), slf);
|
||||
let arg = PyObject::from_borrowed_ptr(py.token(), arg);
|
||||
|
||||
let res = match extract_op(py, op) {
|
||||
Ok(op) => {
|
||||
|
@ -361,10 +361,10 @@ impl<T> PyObjectRichcmpProtocolImpl for T where T: for<'p> PyObjectRichcmpProtoc
|
|||
};
|
||||
match res {
|
||||
Ok(val) => {
|
||||
val.into_object(py).into_ptr()
|
||||
val.into_object(py.token()).into_ptr()
|
||||
}
|
||||
Err(e) => {
|
||||
e.restore(py);
|
||||
e.restore(py.token());
|
||||
std::ptr::null_mut()
|
||||
}
|
||||
}
|
||||
|
@ -394,8 +394,8 @@ fn extract_op(py: Python, op: c_int) -> PyResult<CompareOp> {
|
|||
ffi::Py_GT => Ok(CompareOp::Gt),
|
||||
ffi::Py_GE => Ok(CompareOp::Ge),
|
||||
_ => Err(PyErr::new_lazy_init(
|
||||
py.get_ptype::<exc::ValueError>(),
|
||||
py.get_type::<exc::ValueError>(),
|
||||
Some("tp_richcompare called with invalid comparison operator"
|
||||
.to_object(py).into_pptr())))
|
||||
.to_object(py.token()))))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ use std::os::raw::c_int;
|
|||
|
||||
use ffi;
|
||||
use err::PyResult;
|
||||
use python::Python;
|
||||
use python::{Python, PythonObjectWithToken};
|
||||
use objects::PyObject;
|
||||
use typeob::PyTypeInfo;
|
||||
use callback::{handle, UnitCallbackConverter};
|
||||
|
@ -73,7 +73,7 @@ impl ffi::PyBufferProcs {
|
|||
{
|
||||
const LOCATION: &'static str = concat!(stringify!(T), ".buffer_get::<PyBufferProtocol>()");
|
||||
handle(LOCATION, UnitCallbackConverter, |py| {
|
||||
let slf = PyObject::from_borrowed_ptr(py, slf);
|
||||
let slf = PyObject::from_borrowed_ptr(py.token(), slf);
|
||||
slf.bf_getbuffer(py, arg1, arg2)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ use std::os::raw::c_int;
|
|||
|
||||
use ffi;
|
||||
use err::PyResult;
|
||||
use python::Python;
|
||||
use python::{Python, PythonObjectWithToken};
|
||||
use objects::{PyObject, PyType};
|
||||
use callback::{PyObjectCallbackConverter, UnitCallbackConverter};
|
||||
use typeob::PyTypeInfo;
|
||||
|
|
|
@ -8,7 +8,7 @@ use std::os::raw::{c_int, c_void};
|
|||
|
||||
use ffi;
|
||||
use pyptr::Py;
|
||||
use python::{Python, ToPythonPointer};
|
||||
use python::{Python, ToPythonPointer, PythonObjectWithToken};
|
||||
use callback::AbortOnDrop;
|
||||
use class::NO_METHODS;
|
||||
use typeob::PyTypeInfo;
|
||||
|
@ -90,7 +90,7 @@ unsafe extern "C" fn tp_traverse<T>(slf: *mut ffi::PyObject,
|
|||
let guard = AbortOnDrop(LOCATION);
|
||||
let py = Python::assume_gil_acquired();
|
||||
let visit = PyVisit { visit: visit, arg: arg, _py: py };
|
||||
let slf: Py<T> = Py::from_borrowed_ptr(py, slf);
|
||||
let slf: Py<T> = Py::from_borrowed_ptr(py.token(), slf);
|
||||
|
||||
let ret = match T::__traverse__(&slf, py, visit) {
|
||||
Ok(()) => 0,
|
||||
|
@ -107,7 +107,7 @@ unsafe extern "C" fn tp_clear<T>(slf: *mut ffi::PyObject) -> c_int
|
|||
|
||||
let guard = AbortOnDrop(LOCATION);
|
||||
let py = Python::assume_gil_acquired();
|
||||
let slf: Py<T> = Py::from_borrowed_ptr(py, slf);
|
||||
let slf: Py<T> = Py::from_borrowed_ptr(py.token(), slf);
|
||||
T::__clear__(slf.as_mut(), py);
|
||||
mem::forget(guard);
|
||||
0
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
use ffi;
|
||||
use err::PyResult;
|
||||
use python::Python;
|
||||
use python::{Python, PythonObjectWithToken};
|
||||
use typeob::PyTypeInfo;
|
||||
use callback::PyObjectCallbackConverter;
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ macro_rules! py_unary_func {
|
|||
let guard = $crate::callback::AbortOnDrop(LOCATION);
|
||||
let ret = $crate::std::panic::catch_unwind(|| {
|
||||
let py = $crate::Python::assume_gil_acquired();
|
||||
let mut slf = $crate::Py::<T>::from_borrowed_ptr(py, slf);
|
||||
let mut slf = $crate::Py::<T>::from_borrowed_ptr(py.token(), slf);
|
||||
let res = slf.as_mut().$f(py).into();
|
||||
|
||||
match res {
|
||||
|
@ -25,7 +25,7 @@ macro_rules! py_unary_func {
|
|||
::convert(val, py)
|
||||
}
|
||||
Err(e) => {
|
||||
e.restore(py);
|
||||
e.restore(py.token());
|
||||
<$conv as $crate::callback::CallbackConverter<$res_type>>
|
||||
::error_value()
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ macro_rules! py_unary_func_self {
|
|||
let guard = $crate::callback::AbortOnDrop(LOCATION);
|
||||
let ret = $crate::std::panic::catch_unwind(|| {
|
||||
let py = $crate::Python::assume_gil_acquired();
|
||||
let mut slf = $crate::Py::<T>::from_borrowed_ptr(py, slf);
|
||||
let mut slf = $crate::Py::<T>::from_borrowed_ptr(py.token(), slf);
|
||||
let res = slf.$f(py).into();
|
||||
|
||||
match res {
|
||||
|
@ -69,7 +69,7 @@ macro_rules! py_unary_func_self {
|
|||
::convert(val, py)
|
||||
}
|
||||
Err(e) => {
|
||||
e.restore(py);
|
||||
e.restore(py.token());
|
||||
<$conv as $crate::callback::CallbackConverter<$res_type>>
|
||||
::error_value()
|
||||
}
|
||||
|
@ -126,8 +126,8 @@ macro_rules! py_binary_func{
|
|||
let guard = $crate::callback::AbortOnDrop(LOCATION);
|
||||
let ret = $crate::std::panic::catch_unwind(|| {
|
||||
let py = $crate::Python::assume_gil_acquired();
|
||||
let mut slf = $crate::Py::<T>::from_borrowed_ptr(py, slf);
|
||||
let arg = $crate::PyObject::from_borrowed_ptr(py, arg);
|
||||
let mut slf = $crate::Py::<T>::from_borrowed_ptr(py.token(), slf);
|
||||
let arg = $crate::PyObject::from_borrowed_ptr(py.token(), arg);
|
||||
|
||||
let result = match arg.extract() {
|
||||
Ok(arg) => {
|
||||
|
@ -142,7 +142,7 @@ macro_rules! py_binary_func{
|
|||
::convert(val, py)
|
||||
}
|
||||
Err(e) => {
|
||||
e.restore(py);
|
||||
e.restore(py.token());
|
||||
<$conv as $crate::callback::CallbackConverter<$res_type>>
|
||||
::error_value()
|
||||
}
|
||||
|
@ -178,8 +178,8 @@ macro_rules! py_binary_self_func{
|
|||
let guard = $crate::callback::AbortOnDrop(LOCATION);
|
||||
let ret = $crate::std::panic::catch_unwind(|| {
|
||||
let py = $crate::Python::assume_gil_acquired();
|
||||
let mut slf1 = $crate::Py::<T>::from_borrowed_ptr(py, slf);
|
||||
let arg = $crate::PyObject::from_borrowed_ptr(py, arg);
|
||||
let mut slf1 = $crate::Py::<T>::from_borrowed_ptr(py.token(), slf);
|
||||
let arg = $crate::PyObject::from_borrowed_ptr(py.token(), arg);
|
||||
|
||||
let result = match arg.extract() {
|
||||
Ok(arg) => {
|
||||
|
@ -193,7 +193,7 @@ macro_rules! py_binary_self_func{
|
|||
slf
|
||||
}
|
||||
Err(e) => {
|
||||
e.restore(py);
|
||||
e.restore(py.token());
|
||||
$crate::std::ptr::null_mut()
|
||||
}
|
||||
}
|
||||
|
@ -228,7 +228,7 @@ macro_rules! py_ssizearg_func {
|
|||
let guard = $crate::callback::AbortOnDrop(LOCATION);
|
||||
let ret = $crate::std::panic::catch_unwind(|| {
|
||||
let py = $crate::Python::assume_gil_acquired();
|
||||
let mut slf = $crate::Py::<T>::from_borrowed_ptr(py, slf);
|
||||
let mut slf = $crate::Py::<T>::from_borrowed_ptr(py.token(), slf);
|
||||
|
||||
let result = slf.as_mut().$f(py, arg as isize).into();
|
||||
match result {
|
||||
|
@ -237,7 +237,7 @@ macro_rules! py_ssizearg_func {
|
|||
::convert(val, py)
|
||||
}
|
||||
Err(e) => {
|
||||
e.restore(py);
|
||||
e.restore(py.token());
|
||||
<$conv as $crate::callback::CallbackConverter<$res_type>>
|
||||
::error_value()
|
||||
}
|
||||
|
@ -276,9 +276,9 @@ macro_rules! py_ternary_func{
|
|||
let guard = $crate::callback::AbortOnDrop(LOCATION);
|
||||
let ret = $crate::std::panic::catch_unwind(|| {
|
||||
let py = $crate::Python::assume_gil_acquired();
|
||||
let mut slf = $crate::Py::<T>::from_borrowed_ptr(py, slf);
|
||||
let arg1 = $crate::PyObject::from_borrowed_ptr(py, arg1);
|
||||
let arg2 = $crate::PyObject::from_borrowed_ptr(py, arg2);
|
||||
let mut slf = $crate::Py::<T>::from_borrowed_ptr(py.token(), slf);
|
||||
let arg1 = $crate::PyObject::from_borrowed_ptr(py.token(), arg1);
|
||||
let arg2 = $crate::PyObject::from_borrowed_ptr(py.token(), arg2);
|
||||
|
||||
let result = match arg1.extract() {
|
||||
Ok(arg1) => match arg2.extract() {
|
||||
|
@ -294,7 +294,7 @@ macro_rules! py_ternary_func{
|
|||
::convert(val, py)
|
||||
}
|
||||
Err(e) => {
|
||||
e.restore(py);
|
||||
e.restore(py.token());
|
||||
<$conv as $crate::callback::CallbackConverter<$res_type>>
|
||||
::error_value()
|
||||
}
|
||||
|
@ -333,9 +333,9 @@ macro_rules! py_ternary_self_func{
|
|||
let guard = $crate::callback::AbortOnDrop(LOCATION);
|
||||
let ret = $crate::std::panic::catch_unwind(|| {
|
||||
let py = $crate::Python::assume_gil_acquired();
|
||||
let mut slf1 = $crate::Py::<T>::from_borrowed_ptr(py, slf);
|
||||
let arg1 = $crate::PyObject::from_borrowed_ptr(py, arg1);
|
||||
let arg2 = $crate::PyObject::from_borrowed_ptr(py, arg2);
|
||||
let mut slf1 = $crate::Py::<T>::from_borrowed_ptr(py.token(), slf);
|
||||
let arg1 = $crate::PyObject::from_borrowed_ptr(py.token(), arg1);
|
||||
let arg2 = $crate::PyObject::from_borrowed_ptr(py.token(), arg2);
|
||||
|
||||
let result = match arg1.extract() {
|
||||
Ok(arg1) => match arg2.extract() {
|
||||
|
@ -348,7 +348,7 @@ macro_rules! py_ternary_self_func{
|
|||
match result {
|
||||
Ok(_) => slf,
|
||||
Err(e) => {
|
||||
e.restore(py);
|
||||
e.restore(py.token());
|
||||
$crate::std::ptr::null_mut()
|
||||
}
|
||||
}
|
||||
|
@ -385,13 +385,13 @@ macro_rules! py_func_set{
|
|||
$crate::callback::cb_unary_unit::<T, _>(LOCATION, slf, |py, slf| {
|
||||
if value.is_null() {
|
||||
let e = PyErr::new::<exc::NotImplementedError, _>(
|
||||
py, format!("Subscript deletion not supported by {:?}",
|
||||
stringify!(T)));
|
||||
e.restore(py);
|
||||
py.token(), format!("Subscript deletion not supported by {:?}",
|
||||
stringify!(T)));
|
||||
e.restore(py.token());
|
||||
return -1
|
||||
} else {
|
||||
let name = ::PyObject::from_borrowed_ptr(py, name);
|
||||
let value = ::PyObject::from_borrowed_ptr(py, value);
|
||||
let name = ::PyObject::from_borrowed_ptr(py.token(), name);
|
||||
let value = ::PyObject::from_borrowed_ptr(py.token(), value);
|
||||
let result = match name.extract() {
|
||||
Ok(name) => match value.extract() {
|
||||
Ok(value) => {
|
||||
|
@ -405,7 +405,7 @@ macro_rules! py_func_set{
|
|||
Ok(_) =>
|
||||
0,
|
||||
Err(e) => {
|
||||
e.restore(py);
|
||||
e.restore(py.token());
|
||||
-1
|
||||
}
|
||||
}
|
||||
|
@ -432,10 +432,10 @@ macro_rules! py_func_del{
|
|||
let guard = $crate::callback::AbortOnDrop(LOCATION);
|
||||
let ret = $crate::std::panic::catch_unwind(|| {
|
||||
let py = $crate::Python::assume_gil_acquired();
|
||||
let mut slf = $crate::Py::<T>::from_borrowed_ptr(py, slf);
|
||||
let mut slf = $crate::Py::<T>::from_borrowed_ptr(py.token(), slf);
|
||||
|
||||
if value.is_null() {
|
||||
let name = PyObject::from_borrowed_ptr(py, name);
|
||||
let name = PyObject::from_borrowed_ptr(py.token(), name);
|
||||
let result = match name.extract() {
|
||||
Ok(name) =>
|
||||
slf.as_mut().$f(py, name).into(),
|
||||
|
@ -445,15 +445,15 @@ macro_rules! py_func_del{
|
|||
Ok(_) =>
|
||||
0,
|
||||
Err(e) => {
|
||||
e.restore(py);
|
||||
e.restore(py.token());
|
||||
-1
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let e = PyErr::new::<exc::NotImplementedError, _>(
|
||||
py, format!("Subscript assignment not supported by {:?}",
|
||||
stringify!(T)));
|
||||
e.restore(py);
|
||||
py.token(), format!("Subscript assignment not supported by {:?}",
|
||||
stringify!(T)));
|
||||
e.restore(py.token());
|
||||
return -1
|
||||
|
||||
}
|
||||
|
@ -490,8 +490,8 @@ macro_rules! py_func_set_del{
|
|||
let guard = $crate::callback::AbortOnDrop(LOCATION);
|
||||
let ret = $crate::std::panic::catch_unwind(|| {
|
||||
let py = $crate::Python::assume_gil_acquired();
|
||||
let mut slf = $crate::Py::<T>::from_borrowed_ptr(py, slf);
|
||||
let name = PyObject::from_borrowed_ptr(py, name);
|
||||
let mut slf = $crate::Py::<T>::from_borrowed_ptr(py.token(), slf);
|
||||
let name = PyObject::from_borrowed_ptr(py.token(), name);
|
||||
|
||||
if value.is_null() {
|
||||
let result = match name.extract() {
|
||||
|
@ -503,12 +503,12 @@ macro_rules! py_func_set_del{
|
|||
Ok(_) =>
|
||||
0,
|
||||
Err(e) => {
|
||||
e.restore(py);
|
||||
e.restore(py.token());
|
||||
-1
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let value = ::PyObject::from_borrowed_ptr(py, value);
|
||||
let value = ::PyObject::from_borrowed_ptr(py.token(), value);
|
||||
let result = match name.extract() {
|
||||
Ok(name) => match value.extract() {
|
||||
Ok(value) => {
|
||||
|
@ -522,7 +522,7 @@ macro_rules! py_func_set_del{
|
|||
Ok(_) =>
|
||||
0,
|
||||
Err(e) => {
|
||||
e.restore(py);
|
||||
e.restore(py.token());
|
||||
-1
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
use ffi;
|
||||
use err::{PyErr, PyResult};
|
||||
use python::Python;
|
||||
use python::{Python, PythonObjectWithToken};
|
||||
use objects::{exc, PyObject};
|
||||
use callback::{PyObjectCallbackConverter, LenResultConverter};
|
||||
use conversion::{ToPyObject, FromPyObject};
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
use ffi;
|
||||
use err::PyResult;
|
||||
use python::Python;
|
||||
use python::{Python, PythonObjectWithToken};
|
||||
use callback::PyObjectCallbackConverter;
|
||||
use typeob::PyTypeInfo;
|
||||
use class::methods::PyMethodDef;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
use std::os::raw::c_int;
|
||||
|
||||
use ffi;
|
||||
use python::Python;
|
||||
use python::{Python, PythonObjectWithToken};
|
||||
use err::{PyErr, PyResult};
|
||||
use objects::{exc, PyObject};
|
||||
use callback::{PyObjectCallbackConverter, LenResultConverter, BoolCallbackConverter};
|
||||
|
@ -195,11 +195,12 @@ impl<T> PySequenceSetItemProtocolImpl for T where T: for<'p> PySequenceSetItemPr
|
|||
::callback::cb_unary_unit::<T, _>(LOCATION, slf, |py, slf| {
|
||||
if value.is_null() {
|
||||
let e = PyErr::new::<exc::NotImplementedError, _>(
|
||||
py, format!("Item deletion not supported by {:?}", stringify!(T)));
|
||||
e.restore(py);
|
||||
py.token(),
|
||||
format!("Item deletion not supported by {:?}", stringify!(T)));
|
||||
e.restore(py.token());
|
||||
return -1
|
||||
} else {
|
||||
let value = PyObject::from_borrowed_ptr(py, value);
|
||||
let value = PyObject::from_borrowed_ptr(py.token(), value);
|
||||
let result = match value.extract() {
|
||||
Ok(value) => {
|
||||
slf.__setitem__(py, key as isize, value).into()
|
||||
|
@ -209,7 +210,7 @@ impl<T> PySequenceSetItemProtocolImpl for T where T: for<'p> PySequenceSetItemPr
|
|||
match result {
|
||||
Ok(_) => 0,
|
||||
Err(e) => {
|
||||
e.restore(py);
|
||||
e.restore(py.token());
|
||||
-1
|
||||
}
|
||||
}
|
||||
|
@ -247,15 +248,15 @@ impl<T> PySequenceDelItemProtocolImpl for T where T: for<'p> PySequenceDelItemPr
|
|||
match result {
|
||||
Ok(_) => 0,
|
||||
Err(e) => {
|
||||
e.restore(py);
|
||||
e.restore(py.token());
|
||||
-1
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let e = PyErr::new::<exc::NotImplementedError, _>(
|
||||
py, format!("Item assignment not supported by {:?}",
|
||||
stringify!(T)));
|
||||
e.restore(py);
|
||||
py.token(), format!("Item assignment not supported by {:?}",
|
||||
stringify!(T)));
|
||||
e.restore(py.token());
|
||||
return -1
|
||||
}
|
||||
})
|
||||
|
@ -281,12 +282,12 @@ impl<T> PySequenceDelItemProtocolImpl for T
|
|||
match result {
|
||||
Ok(_) => 0,
|
||||
Err(e) => {
|
||||
e.restore(py);
|
||||
e.restore(py.token());
|
||||
-1
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let value = ::PyObject::from_borrowed_ptr(py, value);
|
||||
let value = ::PyObject::from_borrowed_ptr(py.token(), value);
|
||||
let result = match value.extract() {
|
||||
Ok(value) => {
|
||||
slf.__setitem__(py, key as isize, value).into()
|
||||
|
@ -296,7 +297,7 @@ impl<T> PySequenceDelItemProtocolImpl for T
|
|||
match result {
|
||||
Ok(_) => 0,
|
||||
Err(e) => {
|
||||
e.restore(py);
|
||||
e.restore(py.token());
|
||||
-1
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use ffi;
|
||||
use err::PyResult;
|
||||
use pyptr::Py;
|
||||
use python::{Python, ToPythonPointer};
|
||||
use pyptr::{Py, PyPtr};
|
||||
use python::{Python, ToPythonPointer, Token};
|
||||
use objects::{PyObject, PyTuple};
|
||||
use typeob::{PyTypeInfo};
|
||||
|
||||
|
@ -10,7 +10,7 @@ use typeob::{PyTypeInfo};
|
|||
pub trait ToPyObject {
|
||||
|
||||
/// Converts self into a Python object.
|
||||
fn to_object<'p>(&self, py: Python<'p>) -> Py<'p, PyObject>;
|
||||
fn to_object(&self, py: Token) -> PyPtr<PyObject>;
|
||||
|
||||
/// Converts self into a Python object and calls the specified closure
|
||||
/// on the native FFI pointer underlying the Python object.
|
||||
|
@ -18,7 +18,7 @@ pub trait ToPyObject {
|
|||
/// May be more efficient than `to_py_object` because it does not need
|
||||
/// to touch any reference counts when the input object already is a Python object.
|
||||
#[inline]
|
||||
fn with_borrowed_ptr<F, R>(&self, py: Python, f: F) -> R
|
||||
fn with_borrowed_ptr<F, R>(&self, py: Token, f: F) -> R
|
||||
where F: FnOnce(*mut ffi::PyObject) -> R
|
||||
{
|
||||
let obj = self.to_object(py).into_object();
|
||||
|
@ -30,7 +30,7 @@ pub trait IntoPyObject {
|
|||
|
||||
/// Converts self into a Python object. (Consumes self)
|
||||
#[inline]
|
||||
fn into_object<'p>(self, py: Python<'p>) -> Py<'p, PyObject>
|
||||
fn into_object(self, py: Token) -> PyPtr<PyObject>
|
||||
where Self: Sized;
|
||||
}
|
||||
|
||||
|
@ -39,12 +39,12 @@ pub trait IntoPyObject {
|
|||
pub trait ToPyTuple {
|
||||
|
||||
/// Converts self into a PyTuple object.
|
||||
fn to_py_tuple<'p>(&self, py: Python<'p>) -> Py<'p, PyTuple>;
|
||||
fn to_py_tuple(&self, py: Token) -> PyPtr<PyTuple>;
|
||||
|
||||
/// Converts self into a PyTuple object and calls the specified closure
|
||||
/// on the native FFI pointer underlying the Python object.
|
||||
#[inline]
|
||||
fn with_borrowed_ptr<'p, F, R>(&self, py: Python<'p>, f: F) -> R
|
||||
fn with_borrowed_ptr<F, R>(&self, py: Token, f: F) -> R
|
||||
where F: FnOnce(*mut ffi::PyObject) -> R
|
||||
{
|
||||
let obj = self.to_py_tuple(py);
|
||||
|
@ -102,7 +102,7 @@ impl <'p, T: ?Sized> RefFromPyObject<'p> for T
|
|||
impl<T> IntoPyObject for T where T: ToPyObject
|
||||
{
|
||||
#[inline]
|
||||
default fn into_object<'p>(self, py: Python<'p>) -> Py<'p, PyObject> where Self: Sized
|
||||
default fn into_object(self, py: Token) -> PyPtr<PyObject> where Self: Sized
|
||||
{
|
||||
self.to_object(py)
|
||||
}
|
||||
|
@ -114,12 +114,12 @@ impl<T> IntoPyObject for T where T: ToPyObject
|
|||
impl <'a, T: ?Sized> ToPyObject for &'a T where T: ToPyObject {
|
||||
|
||||
#[inline]
|
||||
default fn to_object<'p>(&self, py: Python<'p>) -> Py<'p, PyObject> {
|
||||
default fn to_object(&self, py: Token) -> PyPtr<PyObject> {
|
||||
<T as ToPyObject>::to_object(*self, py)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn with_borrowed_ptr<F, R>(&self, py: Python, f: F) -> R
|
||||
fn with_borrowed_ptr<F, R>(&self, py: Token, f: F) -> R
|
||||
where F: FnOnce(*mut ffi::PyObject) -> R
|
||||
{
|
||||
<T as ToPyObject>::with_borrowed_ptr(*self, py, f)
|
||||
|
@ -130,7 +130,7 @@ impl <'a, T: ?Sized> ToPyObject for &'a T where T: ToPyObject {
|
|||
/// `Option::None` is converted to Python `None`.
|
||||
impl <T> ToPyObject for Option<T> where T: ToPyObject {
|
||||
|
||||
fn to_object<'p>(&self, py: Python<'p>) -> Py<'p, PyObject> {
|
||||
fn to_object(&self, py: Token) -> PyPtr<PyObject> {
|
||||
match *self {
|
||||
Some(ref val) => val.to_object(py),
|
||||
None => py.None()
|
||||
|
@ -140,7 +140,7 @@ impl <T> ToPyObject for Option<T> where T: ToPyObject {
|
|||
|
||||
impl<T> IntoPyObject for Option<T> where T: IntoPyObject {
|
||||
|
||||
fn into_object<'p>(self, py: Python<'p>) -> Py<'p, PyObject> {
|
||||
fn into_object(self, py: Token) -> PyPtr<PyObject> {
|
||||
match self {
|
||||
Some(val) => val.into_object(py),
|
||||
None => py.None()
|
||||
|
@ -151,7 +151,7 @@ impl<T> IntoPyObject for Option<T> where T: IntoPyObject {
|
|||
|
||||
/// `()` is converted to Python `None`.
|
||||
impl ToPyObject for () {
|
||||
fn to_object<'p>(&self, py: Python<'p>) -> Py<'p, PyObject> {
|
||||
fn to_object(&self, py: Token) -> PyPtr<PyObject> {
|
||||
py.None()
|
||||
}
|
||||
}
|
||||
|
|
73
src/err.rs
73
src/err.rs
|
@ -4,7 +4,7 @@ use libc;
|
|||
|
||||
use ffi;
|
||||
use pyptr::{Py, PyPtr};
|
||||
use python::{ToPythonPointer, Python, IntoPythonPointer};
|
||||
use python::{ToPythonPointer, Python, IntoPythonPointer, Token, PythonObjectWithToken};
|
||||
use objects::{PyObject, PyType, exc};
|
||||
use typeob::{PyTypeObject};
|
||||
use conversion::{ToPyObject, ToPyTuple};
|
||||
|
@ -102,7 +102,7 @@ pub type PyResult<T> = Result<T, PyErr>;
|
|||
|
||||
|
||||
// Marker type that indicates an error while downcasting
|
||||
pub struct PyDowncastError<'p>(pub Python<'p>, pub Option<&'p str>);
|
||||
pub struct PyDowncastError<'p>(pub Token<'p>, pub Option<&'p str>);
|
||||
|
||||
|
||||
impl PyErr {
|
||||
|
@ -117,15 +117,15 @@ impl PyErr {
|
|||
///
|
||||
/// Example:
|
||||
/// `return Err(PyErr::new::<exc::TypeError, _>(py, "Error message"));`
|
||||
pub fn new<T, V>(py: Python, value: V) -> PyErr
|
||||
pub fn new<T, V>(py: Token, value: V) -> PyErr
|
||||
where T: PyTypeObject, V: ToPyObject
|
||||
{
|
||||
PyErr::new_helper(py, py.get_ptype::<T>(), value.to_object(py).into_pptr())
|
||||
PyErr::new_helper(py, py.get_type::<T>(), value.to_object(py))
|
||||
}
|
||||
|
||||
/// Gets whether an error is present in the Python interpreter's global state.
|
||||
#[inline]
|
||||
pub fn occurred(_ : Python) -> bool {
|
||||
pub fn occurred(_ : Token) -> bool {
|
||||
unsafe { !ffi::PyErr_Occurred().is_null() }
|
||||
}
|
||||
|
||||
|
@ -157,7 +157,7 @@ impl PyErr {
|
|||
/// Retrieves the current error from the Python interpreter's global state.
|
||||
/// The error is cleared from the Python interpreter.
|
||||
/// If no error is set, returns a `SystemError`.
|
||||
pub fn fetch(py: Python) -> PyErr {
|
||||
pub fn fetch(py: Token) -> PyErr {
|
||||
unsafe {
|
||||
let mut ptype : *mut ffi::PyObject = std::mem::uninitialized();
|
||||
let mut pvalue : *mut ffi::PyObject = std::mem::uninitialized();
|
||||
|
@ -167,7 +167,7 @@ impl PyErr {
|
|||
}
|
||||
}
|
||||
|
||||
unsafe fn new_from_ffi_tuple(py: Python,
|
||||
unsafe fn new_from_ffi_tuple(py: Token,
|
||||
ptype: *mut ffi::PyObject,
|
||||
pvalue: *mut ffi::PyObject,
|
||||
ptraceback: *mut ffi::PyObject) -> PyErr {
|
||||
|
@ -175,16 +175,16 @@ impl PyErr {
|
|||
// and because we mustn't panic in normalize().
|
||||
PyErr {
|
||||
ptype: if ptype.is_null() {
|
||||
py.get_ptype::<exc::SystemError>()
|
||||
py.get_type::<exc::SystemError>()
|
||||
} else {
|
||||
Py::<PyType>::from_borrowed_ptr(py, ptype).into_pptr()
|
||||
PyPtr::from_borrowed_ptr(ptype)
|
||||
},
|
||||
pvalue: PyObject::from_borrowed_pptr_opt(py, pvalue),
|
||||
ptraceback: PyObject::from_borrowed_pptr_opt(py, ptraceback)
|
||||
pvalue: PyPtr::from_borrowed_ptr_opt(py, pvalue),
|
||||
ptraceback: PyPtr::from_borrowed_ptr_opt(py, ptraceback)
|
||||
}
|
||||
}
|
||||
|
||||
fn new_helper(_py: Python, ty: PyPtr<PyType>, value: PyPtr<PyObject>) -> PyErr {
|
||||
fn new_helper(_py: Token, ty: PyPtr<PyType>, value: PyPtr<PyObject>) -> PyErr {
|
||||
assert!(unsafe { ffi::PyExceptionClass_Check(ty.as_ptr()) } != 0);
|
||||
PyErr {
|
||||
ptype: ty,
|
||||
|
@ -198,28 +198,28 @@ impl PyErr {
|
|||
/// `obj` must be an Python exception instance, the PyErr will use that instance.
|
||||
/// If `obj` is a Python exception type object, the PyErr will (lazily) create a new instance of that type.
|
||||
/// Otherwise, a `TypeError` is created instead.
|
||||
pub fn from_instance<O>(py: Python, obj: O) -> PyErr where O: ToPyObject {
|
||||
pub fn from_instance<O>(py: Token, obj: O) -> PyErr where O: ToPyObject {
|
||||
PyErr::from_instance_helper(py, obj.to_object(py))
|
||||
}
|
||||
|
||||
fn from_instance_helper<'p>(py: Python<'p>, obj: Py<'p, PyObject>) -> PyErr {
|
||||
fn from_instance_helper<'p>(py: Token, obj: PyPtr<PyObject>) -> PyErr {
|
||||
if unsafe { ffi::PyExceptionInstance_Check(obj.as_ptr()) } != 0 {
|
||||
PyErr {
|
||||
ptype: unsafe { Py::<PyType>::from_borrowed_ptr(
|
||||
py, ffi::PyExceptionInstance_Class(obj.as_ptr())).into_pptr() },
|
||||
pvalue: Some(obj.into_pptr()),
|
||||
ptype: unsafe { PyPtr::<PyType>::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 { Py::<PyType>::unchecked_downcast_from(obj).into_pptr() },
|
||||
ptype: unsafe { PyPtr::<PyType>::unchecked_downcast_from(obj) },
|
||||
pvalue: None,
|
||||
ptraceback: None
|
||||
}
|
||||
} else {
|
||||
PyErr {
|
||||
ptype: py.get_ptype::<exc::TypeError>(),
|
||||
pvalue: Some("exceptions must derive from BaseException".to_object(py).into_pptr()),
|
||||
ptype: py.get_type::<exc::TypeError>(),
|
||||
pvalue: Some("exceptions must derive from BaseException".to_object(py)),
|
||||
ptraceback: None
|
||||
}
|
||||
}
|
||||
|
@ -241,26 +241,26 @@ 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<'p>, exc: Py<'p, PyType>, args: A) -> PyErr
|
||||
pub fn new_err<'p, A>(py: Token, exc: Py<'p, PyType>, 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().into_pptr()),
|
||||
pvalue: Some(pval.into_object()),
|
||||
ptraceback: None
|
||||
}
|
||||
}
|
||||
|
||||
/// Print a standard traceback to sys.stderr.
|
||||
pub fn print(self, py: Python) {
|
||||
pub fn print(self, py: Token) {
|
||||
self.restore(py);
|
||||
unsafe { ffi::PyErr_PrintEx(0) }
|
||||
}
|
||||
|
||||
/// Print a standard traceback to sys.stderr.
|
||||
pub fn print_and_set_sys_last_vars(self, py: Python) {
|
||||
pub fn print_and_set_sys_last_vars(self, py: Token) {
|
||||
self.restore(py);
|
||||
unsafe { ffi::PyErr_PrintEx(1) }
|
||||
}
|
||||
|
@ -268,7 +268,7 @@ impl PyErr {
|
|||
/// Return true if the current exception matches the exception in `exc`.
|
||||
/// If `exc` is a class object, this also returns `true` when `self` is an instance of a subclass.
|
||||
/// If `exc` is a tuple, all exceptions in the tuple (and recursively in subtuples) are searched for a match.
|
||||
pub fn matches<T>(&self, py: Python, exc: T) -> bool
|
||||
pub fn matches<T>(&self, py: Token, exc: T) -> bool
|
||||
where T: ToPyObject
|
||||
{
|
||||
exc.with_borrowed_ptr(py, |exc| unsafe {
|
||||
|
@ -277,7 +277,7 @@ impl PyErr {
|
|||
}
|
||||
|
||||
/// Normalizes the error. This ensures that the exception value is an instance of the exception type.
|
||||
pub fn normalize(&mut self, py: Python) {
|
||||
pub fn normalize(&mut self, py: Token) {
|
||||
// The normalization helper function involves temporarily moving out of the &mut self,
|
||||
// which requires some unsafe trickery:
|
||||
unsafe {
|
||||
|
@ -288,7 +288,7 @@ impl PyErr {
|
|||
|
||||
/// Helper function for normalizing the error by deconstructing and reconstructing the PyErr.
|
||||
/// Must not panic for safety in normalize()
|
||||
fn into_normalized(self, py: Python) -> PyErr {
|
||||
fn into_normalized(self, py: Token) -> PyErr {
|
||||
let PyErr { ptype, pvalue, ptraceback } = self;
|
||||
let mut ptype = ptype.into_ptr();
|
||||
let mut pvalue = pvalue.into_ptr();
|
||||
|
@ -300,25 +300,25 @@ impl PyErr {
|
|||
}
|
||||
|
||||
/// Retrieves the exception type.
|
||||
pub fn get_type<'p>(&self, py: Python<'p>) -> Py<'p, PyType> {
|
||||
pub fn get_type<'p>(&self, py: Token<'p>) -> Py<'p, PyType> {
|
||||
self.ptype.as_ref(py)
|
||||
}
|
||||
|
||||
/// Retrieves the exception instance for this error.
|
||||
/// This method takes `&mut self` because the error might need
|
||||
/// to be normalized in order to create the exception instance.
|
||||
pub fn instance<'p>(&mut self, py: Python<'p>) -> Py<'p, PyObject> {
|
||||
pub fn instance<'p>(&mut self, py: Token<'p>) -> Py<'p, PyObject> {
|
||||
self.normalize(py);
|
||||
match self.pvalue {
|
||||
Some(ref instance) => instance.as_ref(py),
|
||||
None => py.None()
|
||||
None => py.None().as_ref(py),
|
||||
}
|
||||
}
|
||||
|
||||
/// Writes the error back to the Python interpreter's global state.
|
||||
/// This is the opposite of `PyErr::fetch()`.
|
||||
#[inline]
|
||||
pub fn restore(self, _py: Python) {
|
||||
pub fn restore(self, _py: Token) {
|
||||
let PyErr { ptype, pvalue, ptraceback } = self;
|
||||
unsafe {
|
||||
ffi::PyErr_Restore(ptype.into_ptr(), pvalue.into_ptr(), ptraceback.into_ptr())
|
||||
|
@ -327,10 +327,11 @@ impl PyErr {
|
|||
|
||||
/// Issue a warning message.
|
||||
/// May return a PyErr if warnings-as-errors is enabled.
|
||||
pub fn warn(py: Python, category: &PyObject, message: &str, stacklevel: i32) -> PyResult<()> {
|
||||
pub fn warn(py: Token, category: &PyObject, message: &str, stacklevel: i32) -> PyResult<()> {
|
||||
let message = CString::new(message).unwrap();
|
||||
unsafe {
|
||||
error_on_minusone(py, ffi::PyErr_WarnEx(category.as_ptr(), message.as_ptr(), stacklevel as ffi::Py_ssize_t))
|
||||
error_on_minusone(py, ffi::PyErr_WarnEx(
|
||||
category.as_ptr(), message.as_ptr(), stacklevel as ffi::Py_ssize_t))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -349,7 +350,7 @@ impl PyErr {
|
|||
/// Converts `PyDowncastError` to Python `TypeError`.
|
||||
impl <'p> std::convert::From<PyDowncastError<'p>> for PyErr {
|
||||
fn from(err: PyDowncastError<'p>) -> PyErr {
|
||||
PyErr::new_lazy_init(err.0.get_ptype::<exc::TypeError>(), None)
|
||||
PyErr::new_lazy_init(err.0.get_type::<exc::TypeError>(), None)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -367,14 +368,14 @@ impl std::convert::From<PyErr> for std::io::Error {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn panic_after_error(_py: Python) -> ! {
|
||||
pub fn panic_after_error() -> ! {
|
||||
unsafe { ffi::PyErr_Print(); }
|
||||
panic!("Python API called failed");
|
||||
}
|
||||
|
||||
/// Returns Ok if the error code is not -1.
|
||||
#[inline]
|
||||
pub fn error_on_minusone(py: Python, result: libc::c_int) -> PyResult<()> {
|
||||
pub fn error_on_minusone(py: Token, result: libc::c_int) -> PyResult<()> {
|
||||
if result != -1 {
|
||||
Ok(())
|
||||
} else {
|
||||
|
|
|
@ -141,5 +141,5 @@ macro_rules! py_fn_impl {
|
|||
#[allow(dead_code)]
|
||||
pub unsafe fn py_fn_impl<'p>(py: Python<'p>,
|
||||
method_def: *mut ffi::PyMethodDef) -> Py<'p, PyObject> {
|
||||
Py::from_owned_ptr_or_panic(py, ffi::PyCFunction_New(method_def, ptr::null_mut()))
|
||||
Py::from_owned_ptr_or_panic(py.token(), ffi::PyCFunction_New(method_def, ptr::null_mut()))
|
||||
}
|
||||
|
|
|
@ -69,7 +69,7 @@ pub use pyptr::{Py, PyPtr};
|
|||
|
||||
pub use err::{PyErr, PyResult, PyDowncastError};
|
||||
pub use objects::*;
|
||||
pub use python::{AsPy, Python, PythonToken};
|
||||
pub use python::{Python, PythonToken, IntoPythonPointer, PythonObjectWithToken};
|
||||
pub use pythonrun::{GILGuard, GILProtected, prepare_freethreaded_python};
|
||||
pub use conversion::{FromPyObject, RefFromPyObject, ToPyObject, IntoPyObject, ToPyTuple};
|
||||
pub use class::{CompareOp};
|
||||
|
@ -192,7 +192,6 @@ macro_rules! py_module_init {
|
|||
}
|
||||
}
|
||||
|
||||
use python::IntoPythonPointer;
|
||||
|
||||
#[doc(hidden)]
|
||||
pub unsafe fn py_module_init_impl(
|
||||
|
@ -208,10 +207,10 @@ pub unsafe fn py_module_init_impl(
|
|||
return module;
|
||||
}
|
||||
|
||||
let module = match Py::<PyModule>::cast_from_owned_ptr(py, module) {
|
||||
let module = match Py::<PyModule>::cast_from_owned_ptr(py.token(), module) {
|
||||
Ok(m) => m,
|
||||
Err(e) => {
|
||||
PyErr::from(e).restore(py);
|
||||
PyErr::from(e).restore(py.token());
|
||||
mem::forget(guard);
|
||||
return ptr::null_mut();
|
||||
}
|
||||
|
@ -219,7 +218,7 @@ pub unsafe fn py_module_init_impl(
|
|||
let ret = match init(py, &module) {
|
||||
Ok(()) => module.into_ptr(),
|
||||
Err(e) => {
|
||||
e.restore(py);
|
||||
e.restore(py.token());
|
||||
ptr::null_mut()
|
||||
}
|
||||
};
|
||||
|
|
|
@ -7,7 +7,7 @@ use std::cmp::Ordering;
|
|||
use ffi;
|
||||
use libc;
|
||||
use pyptr::{Py, PyPtr};
|
||||
use python::{Python, ToPythonPointer};
|
||||
use python::{Python, ToPythonPointer, Token, PythonObjectWithToken};
|
||||
use objects::{PyObject, PyDict, PyString};
|
||||
use conversion::{ToPyObject, ToPyTuple};
|
||||
use err::{PyErr, PyResult, self};
|
||||
|
@ -19,7 +19,7 @@ impl<'p, T> Py<'p, T> {
|
|||
/// This is equivalent to the Python expression 'hasattr(self, attr_name)'.
|
||||
#[inline]
|
||||
pub fn hasattr<N>(&self, attr_name: N) -> PyResult<bool> where N: ToPyObject {
|
||||
attr_name.with_borrowed_ptr(self.py(), |attr_name| unsafe {
|
||||
attr_name.with_borrowed_ptr(self.token(), |attr_name| unsafe {
|
||||
Ok(ffi::PyObject_HasAttr(self.as_ptr(), attr_name) != 0)
|
||||
})
|
||||
}
|
||||
|
@ -27,10 +27,11 @@ impl<'p, T> Py<'p, T> {
|
|||
/// Retrieves an attribute value.
|
||||
/// This is equivalent to the Python expression 'self.attr_name'.
|
||||
#[inline]
|
||||
pub fn getattr<N>(&self, attr_name: N) -> PyResult<Py<'p, PyObject>> where N: ToPyObject
|
||||
pub fn getattr<N>(&self, attr_name: N) -> PyResult<PyPtr<PyObject>> where N: ToPyObject
|
||||
{
|
||||
attr_name.with_borrowed_ptr(self.py(), |attr_name| unsafe {
|
||||
Py::from_owned_ptr_or_err(self.py(), ffi::PyObject_GetAttr(self.as_ptr(), attr_name))
|
||||
attr_name.with_borrowed_ptr(self.token(), |attr_name| unsafe {
|
||||
PyPtr::from_owned_ptr_or_err(
|
||||
self.token(), ffi::PyObject_GetAttr(self.as_ptr(), attr_name))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -41,10 +42,10 @@ impl<'p, T> Py<'p, T> {
|
|||
where N: ToPyObject, V: ToPyObject
|
||||
{
|
||||
attr_name.with_borrowed_ptr(
|
||||
self.py(), move |attr_name|
|
||||
value.with_borrowed_ptr(self.py(), |value| unsafe {
|
||||
self.token(), move |attr_name|
|
||||
value.with_borrowed_ptr(self.token(), |value| unsafe {
|
||||
err::error_on_minusone(
|
||||
self.py(), ffi::PyObject_SetAttr(self.as_ptr(), attr_name, value))
|
||||
self.token(), ffi::PyObject_SetAttr(self.as_ptr(), attr_name, value))
|
||||
}))
|
||||
}
|
||||
|
||||
|
@ -52,8 +53,8 @@ impl<'p, T> Py<'p, T> {
|
|||
/// This is equivalent to the Python expression 'del self.attr_name'.
|
||||
#[inline]
|
||||
pub fn delattr<N>(&self, attr_name: N) -> PyResult<()> where N: ToPyObject {
|
||||
attr_name.with_borrowed_ptr(self.py(), |attr_name| unsafe {
|
||||
err::error_on_minusone(self.py(),
|
||||
attr_name.with_borrowed_ptr(self.token(), |attr_name| unsafe {
|
||||
err::error_on_minusone(self.token(),
|
||||
ffi::PyObject_DelAttr(self.as_ptr(), attr_name))
|
||||
})
|
||||
}
|
||||
|
@ -73,8 +74,8 @@ impl<'p, T> Py<'p, T> {
|
|||
/// else:
|
||||
/// raise TypeError("ObjectProtocol::compare(): All comparisons returned false")
|
||||
/// ```
|
||||
pub fn compare<O>(&self, other: O) -> PyResult<Ordering> where O: ToPyObject {
|
||||
unsafe fn do_compare(py: Python,
|
||||
/*pub fn compare<O>(&self, other: O) -> PyResult<Ordering> where O: ToPyObject {
|
||||
unsafe fn do_compare(py: Token,
|
||||
a: *mut ffi::PyObject,
|
||||
b: *mut ffi::PyObject) -> PyResult<Ordering> {
|
||||
let result = ffi::PyObject_RichCompareBool(a, b, ffi::Py_EQ);
|
||||
|
@ -99,9 +100,9 @@ impl<'p, T> Py<'p, T> {
|
|||
}
|
||||
|
||||
other.with_borrowed_ptr(self.py(), |other| unsafe {
|
||||
do_compare(self.py(), self.as_ptr(), other)
|
||||
do_compare(self.token(), self.as_ptr(), other)
|
||||
})
|
||||
}
|
||||
}*/
|
||||
|
||||
/// Compares two Python objects.
|
||||
///
|
||||
|
@ -112,29 +113,29 @@ impl<'p, T> Py<'p, T> {
|
|||
/// * CompareOp::Le: `self <= other`
|
||||
/// * CompareOp::Gt: `self > other`
|
||||
/// * CompareOp::Ge: `self >= other`
|
||||
pub fn rich_compare<O>(&self, other: O, compare_op: ::CompareOp)
|
||||
-> PyResult<Py<'p, PyObject>> where O: ToPyObject {
|
||||
/*pub fn rich_compare<O>(&self, other: O, compare_op: ::CompareOp)
|
||||
-> PyResult<PyPtr<PyObject>> where O: ToPyObject {
|
||||
unsafe {
|
||||
other.with_borrowed_ptr(self.py(), |other| {
|
||||
other.with_borrowed_ptr(self.token(), |other| {
|
||||
Py::cast_from_owned_nullptr(
|
||||
self.py(), ffi::PyObject_RichCompare(
|
||||
self.token(), ffi::PyObject_RichCompare(
|
||||
self.as_ptr(), other, compare_op as libc::c_int))
|
||||
})
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
/// Compute the string representation of self.
|
||||
/// This is equivalent to the Python expression 'repr(self)'.
|
||||
#[inline]
|
||||
pub fn repr(&'p self) -> PyResult<Py<'p, PyString>> {
|
||||
unsafe { Py::cast_from_owned_nullptr(self.py(), ffi::PyObject_Repr(self.as_ptr())) }
|
||||
unsafe { Py::cast_from_owned_nullptr(self.token(), ffi::PyObject_Repr(self.as_ptr())) }
|
||||
}
|
||||
|
||||
/// Compute the string representation of self.
|
||||
/// This is equivalent to the Python expression 'str(self)'.
|
||||
#[inline]
|
||||
pub fn str(&'p self) -> PyResult<Py<'p, PyString>> {
|
||||
unsafe { Py::cast_from_owned_nullptr(self.py(), ffi::PyObject_Str(self.as_ptr())) }
|
||||
unsafe { Py::cast_from_owned_nullptr(self.token(), ffi::PyObject_Str(self.as_ptr())) }
|
||||
}
|
||||
|
||||
/// Determines whether this object is callable.
|
||||
|
@ -145,13 +146,13 @@ impl<'p, T> Py<'p, T> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Calls the object.
|
||||
/* /// Calls the object.
|
||||
/// This is equivalent to the Python expression: 'self(*args, **kwargs)'
|
||||
#[inline]
|
||||
pub fn call<'a, A>(&self, args: A, kwargs: Option<&PyDict>) -> PyResult<Py<'p, PyObject>>
|
||||
where A: ToPyTuple
|
||||
{
|
||||
let t = args.to_py_tuple(self.py());
|
||||
let t = args.to_py_tuple(self.token());
|
||||
unsafe {
|
||||
Py::from_owned_ptr_or_err(
|
||||
self.py(), ffi::PyObject_Call(self.as_ptr(), t.as_ptr(), kwargs.as_ptr()))
|
||||
|
@ -167,7 +168,7 @@ impl<'p, T> Py<'p, T> {
|
|||
where A: ToPyTuple
|
||||
{
|
||||
self.getattr(name)?.call(args, kwargs)
|
||||
}
|
||||
}*/
|
||||
|
||||
/// Retrieves the hash code of the object.
|
||||
/// This is equivalent to the Python expression: 'hash(self)'
|
||||
|
@ -175,7 +176,7 @@ impl<'p, T> Py<'p, T> {
|
|||
pub fn hash(&self) -> PyResult<::Py_hash_t> {
|
||||
let v = unsafe { ffi::PyObject_Hash(self.as_ptr()) };
|
||||
if v == -1 {
|
||||
Err(PyErr::fetch(self.py()))
|
||||
Err(PyErr::fetch(self.token()))
|
||||
} else {
|
||||
Ok(v)
|
||||
}
|
||||
|
@ -187,7 +188,7 @@ impl<'p, T> Py<'p, T> {
|
|||
pub fn is_true(&self) -> PyResult<bool> {
|
||||
let v = unsafe { ffi::PyObject_IsTrue(self.as_ptr()) };
|
||||
if v == -1 {
|
||||
Err(PyErr::fetch(self.py()))
|
||||
Err(PyErr::fetch(self.token()))
|
||||
} else {
|
||||
Ok(v != 0)
|
||||
}
|
||||
|
@ -199,7 +200,7 @@ impl<'p, T> Py<'p, T> {
|
|||
pub fn len(&self) -> PyResult<usize> {
|
||||
let v = unsafe { ffi::PyObject_Size(self.as_ptr()) };
|
||||
if v == -1 {
|
||||
Err(PyErr::fetch(self.py()))
|
||||
Err(PyErr::fetch(self.token()))
|
||||
} else {
|
||||
Ok(v as usize)
|
||||
}
|
||||
|
@ -207,9 +208,10 @@ impl<'p, T> Py<'p, T> {
|
|||
|
||||
/// This is equivalent to the Python expression: 'self[key]'
|
||||
#[inline]
|
||||
pub fn get_item<K>(&self, key: K) -> PyResult<Py<'p, PyObject>> where K: ToPyObject {
|
||||
key.with_borrowed_ptr(self.py(), |key| unsafe {
|
||||
Py::from_owned_ptr_or_err(self.py(), ffi::PyObject_GetItem(self.as_ptr(), key))
|
||||
pub fn get_item<K>(&'p self, key: K) -> PyResult<Py<'p, PyObject>> where K: ToPyObject {
|
||||
key.with_borrowed_ptr(self.token(), |key| unsafe {
|
||||
Py::from_owned_ptr_or_err(
|
||||
self.token(), ffi::PyObject_GetItem(self.as_ptr(), key))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -220,9 +222,9 @@ impl<'p, T> Py<'p, T> {
|
|||
where K: ToPyObject, V: ToPyObject
|
||||
{
|
||||
key.with_borrowed_ptr(
|
||||
self.py(), move |key|
|
||||
value.with_borrowed_ptr(self.py(), |value| unsafe {
|
||||
err::error_on_minusone(self.py(),
|
||||
self.token(), move |key|
|
||||
value.with_borrowed_ptr(self.token(), |value| unsafe {
|
||||
err::error_on_minusone(self.token(),
|
||||
ffi::PyObject_SetItem(self.as_ptr(), key, value))
|
||||
}))
|
||||
}
|
||||
|
@ -230,9 +232,9 @@ impl<'p, T> Py<'p, T> {
|
|||
/// Deletes an item.
|
||||
/// This is equivalent to the Python expression 'del self[key]'.
|
||||
#[inline]
|
||||
pub fn del_item<K>(&self, py: Python, key: K) -> PyResult<()> where K: ToPyObject {
|
||||
key.with_borrowed_ptr(py, |key| unsafe {
|
||||
err::error_on_minusone(py,
|
||||
pub fn del_item<K>(&self, key: K) -> PyResult<()> where K: ToPyObject {
|
||||
key.with_borrowed_ptr(self.token(), |key| unsafe {
|
||||
err::error_on_minusone(self.token(),
|
||||
ffi::PyObject_DelItem(self.as_ptr(), key))
|
||||
})
|
||||
}
|
||||
|
@ -271,7 +273,7 @@ impl<T> fmt::Debug for PyPtr<T> {
|
|||
let py = gil.python();
|
||||
|
||||
// TODO: we shouldn't use fmt::Error when repr() fails
|
||||
let r = self.as_ref(py);
|
||||
let r = self.as_ref(py.token());
|
||||
let repr_obj = try!(r.repr().map_err(|_| fmt::Error));
|
||||
f.write_str(&repr_obj.to_string_lossy())
|
||||
}
|
||||
|
@ -283,7 +285,7 @@ impl<T> fmt::Display for PyPtr<T> {
|
|||
let py = gil.python();
|
||||
|
||||
// TODO: we shouldn't use fmt::Error when repr() fails
|
||||
let r = self.as_ref(py);
|
||||
let r = self.as_ref(py.token());
|
||||
let repr_obj = try!(r.str().map_err(|_| fmt::Error));
|
||||
f.write_str(&repr_obj.to_string_lossy())
|
||||
}
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
use ::{Py, PyObject};
|
||||
use ::{Py, PyPtr, PyObject};
|
||||
use ffi;
|
||||
use python::{Python, ToPythonPointer};
|
||||
use python::{Python, PythonToken, ToPythonPointer, Token};
|
||||
use conversion::{ToPyObject};
|
||||
|
||||
/// Represents a Python `bool`.
|
||||
pub struct PyBool;
|
||||
pub struct PyBool(PythonToken<PyBool>);
|
||||
|
||||
pyobject_newtype!(PyBool, PyBool_Check, PyBool_Type);
|
||||
|
||||
impl PyBool {
|
||||
/// Depending on `val`, returns `py.True()` or `py.False()`.
|
||||
#[inline]
|
||||
pub fn get<'p>(py: Python<'p>, val: bool) -> Py<'p, PyBool> {
|
||||
pub fn get(py: Token, val: bool) -> PyPtr<PyBool> {
|
||||
if val { py.True() } else { py.False() }
|
||||
}
|
||||
|
||||
|
@ -25,12 +25,12 @@ impl PyBool {
|
|||
/// Converts a rust `bool` to a Python `bool`.
|
||||
impl ToPyObject for bool {
|
||||
#[inline]
|
||||
fn to_object<'p>(&self, py: Python<'p>) -> Py<'p, PyObject> {
|
||||
fn to_object(&self, py: Token) -> PyPtr<PyObject> {
|
||||
PyBool::get(py, *self).into_object()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn with_borrowed_ptr<F, R>(&self, _py: Python, f: F) -> R
|
||||
fn with_borrowed_ptr<F, R>(&self, _py: Token, f: F) -> R
|
||||
where F: FnOnce(*mut ffi::PyObject) -> R
|
||||
{
|
||||
// Avoid unnecessary Py_INCREF/Py_DECREF pair
|
||||
|
|
|
@ -4,13 +4,13 @@ use std;
|
|||
use std::ptr;
|
||||
use std::os::raw::c_char;
|
||||
use ffi;
|
||||
use python::{Python, ToPythonPointer, AsPy};
|
||||
use python::{Python, PythonToken, ToPythonPointer, Token};
|
||||
use objects::PyObject;
|
||||
use err::{PyResult, PyErr};
|
||||
use pyptr::Py;
|
||||
|
||||
/// Represents a Python bytearray.
|
||||
pub struct PyByteArray;
|
||||
pub struct PyByteArray(PythonToken<PyByteArray>);
|
||||
|
||||
pyobject_newtype!(PyByteArray, PyByteArray_Check, PyByteArray_Type);
|
||||
|
||||
|
@ -20,7 +20,7 @@ impl PyByteArray {
|
|||
/// The byte string is initialized by copying the data from the `&[u8]`.
|
||||
///
|
||||
/// Panics if out of memory.
|
||||
pub fn new<'p>(py: Python<'p>, src: &[u8]) -> Py<'p, PyByteArray> {
|
||||
pub fn new<'p>(py: Token<'p>, src: &[u8]) -> Py<'p, PyByteArray> {
|
||||
let ptr = src.as_ptr() as *const c_char;
|
||||
let len = src.len() as ffi::Py_ssize_t;
|
||||
let ptr = unsafe {ffi::PyByteArray_FromStringAndSize(ptr, len)};
|
||||
|
|
|
@ -3,15 +3,15 @@
|
|||
// based on Daniel Grunwald's https://github.com/dgrunwald/rust-cpython
|
||||
|
||||
use ffi;
|
||||
use pyptr::Py;
|
||||
use python::{AsPy, Python, ToPythonPointer};
|
||||
use pyptr::{Py, PyPtr};
|
||||
use python::{Python, Token, PythonToken, ToPythonPointer, PythonObjectWithToken};
|
||||
use conversion::ToPyObject;
|
||||
use objects::{PyObject, PyList};
|
||||
use objects::{PyObject}; //, PyList};
|
||||
use err::{self, PyResult, PyErr};
|
||||
use std::{mem, collections, hash, cmp};
|
||||
|
||||
/// Represents a Python `dict`.
|
||||
pub struct PyDict;
|
||||
pub struct PyDict(PythonToken<PyDict>);
|
||||
|
||||
pyobject_newtype!(PyDict, PyDict_Check, PyDict_Type);
|
||||
|
||||
|
@ -20,15 +20,15 @@ impl PyDict {
|
|||
/// Creates a new empty dictionary.
|
||||
///
|
||||
/// May panic when running out of memory.
|
||||
pub fn new<'p>(py: Python<'p>) -> Py<'p, PyDict> {
|
||||
unsafe { Py::<PyDict>::cast_from_owned_ptr_or_panic(py, ffi::PyDict_New()) }
|
||||
pub fn new(py: Token) -> Py<PyDict> {
|
||||
unsafe { Py::from_owned_ptr_or_panic(py, ffi::PyDict_New()) }
|
||||
}
|
||||
|
||||
/// Return a new dictionary that contains the same key-value pairs as self.
|
||||
/// Corresponds to `dict(self)` in Python.
|
||||
pub fn copy<'p>(&'p self) -> PyResult<Py<'p, PyDict>> {
|
||||
pub fn copy<'p>(&'p self) -> PyResult<PyPtr<PyDict>> {
|
||||
unsafe {
|
||||
Py::from_owned_ptr_or_err(self.py(), ffi::PyDict_Copy(self.as_ptr()))
|
||||
PyPtr::from_owned_ptr_or_err(self.token(), ffi::PyDict_Copy(self.as_ptr()))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,20 +48,20 @@ impl PyDict {
|
|||
/// Determine if the dictionary contains the specified key.
|
||||
/// This is equivalent to the Python expression `key in self`.
|
||||
pub fn contains<K>(&self, key: K) -> PyResult<bool> where K: ToPyObject {
|
||||
key.with_borrowed_ptr(self.py(), |key| unsafe {
|
||||
key.with_borrowed_ptr(self.token(), |key| unsafe {
|
||||
match ffi::PyDict_Contains(self.as_ptr(), key) {
|
||||
1 => Ok(true),
|
||||
0 => Ok(false),
|
||||
_ => Err(PyErr::fetch(self.py()))
|
||||
_ => Err(PyErr::fetch(self.token()))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Gets an item from the dictionary.
|
||||
/// Returns None if the item is not present, or if an error occurs.
|
||||
pub fn get_item<'p, K>(&'p self, key: K) -> Option<Py<'p, PyObject>> where K: ToPyObject {
|
||||
key.with_borrowed_ptr(self.py(), |key| unsafe {
|
||||
Py::from_borrowed_ptr_opt(self.py(), ffi::PyDict_GetItem(self.as_ptr(), key))
|
||||
pub fn get_item<K>(&self, key: K) -> Option<&PyObject> where K: ToPyObject {
|
||||
key.with_borrowed_ptr(self.token(), |key| unsafe {
|
||||
self.token().from_owned_ptr_opt(ffi::PyDict_GetItem(self.as_ptr(), key))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -69,57 +69,55 @@ impl PyDict {
|
|||
/// This is equivalent to the Python expression `self[key] = value`.
|
||||
pub fn set_item<K, V>(&self, key: K, value: V)
|
||||
-> PyResult<()> where K: ToPyObject, V: ToPyObject {
|
||||
let py = self.py();
|
||||
key.with_borrowed_ptr(
|
||||
self.py(), move |key|
|
||||
value.with_borrowed_ptr(py, |value| unsafe {
|
||||
self.token(), move |key|
|
||||
value.with_borrowed_ptr(self.token(), |value| unsafe {
|
||||
err::error_on_minusone(
|
||||
py, ffi::PyDict_SetItem(self.as_ptr(), key, value))
|
||||
self.token(), ffi::PyDict_SetItem(self.as_ptr(), key, value))
|
||||
}))
|
||||
}
|
||||
|
||||
/// Deletes an item.
|
||||
/// This is equivalent to the Python expression `del self[key]`.
|
||||
pub fn del_item<K>(&self, py: Python, key: K) -> PyResult<()> where K: ToPyObject {
|
||||
key.with_borrowed_ptr(py, |key| unsafe {
|
||||
pub fn del_item<K>(&self, key: K) -> PyResult<()> where K: ToPyObject {
|
||||
key.with_borrowed_ptr(self.token(), |key| unsafe {
|
||||
err::error_on_minusone(
|
||||
py, ffi::PyDict_DelItem(self.as_ptr(), key))
|
||||
self.token(), ffi::PyDict_DelItem(self.as_ptr(), key))
|
||||
})
|
||||
}
|
||||
|
||||
// List of dict items.
|
||||
// This is equivalent to the python expression `list(dict.items())`.
|
||||
pub fn items_list(&self) -> Py<PyList> {
|
||||
unsafe {
|
||||
Py::from_owned_ptr_or_panic(self.py(), ffi::PyDict_Items(self.as_ptr()))
|
||||
}
|
||||
}
|
||||
//pub fn items_list(&self) -> Py<PyList> {
|
||||
// unsafe {
|
||||
// Py::from_owned_ptr_or_panic(self.py(), ffi::PyDict_Items(self.as_ptr()))
|
||||
// }
|
||||
//}
|
||||
|
||||
/// Returns the list of (key, value) pairs in this dictionary.
|
||||
pub fn items(&self) -> Vec<(Py<PyObject>, Py<PyObject>)> {
|
||||
pub fn items(&self) -> Vec<(&PyObject, &PyObject)> {
|
||||
// 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.
|
||||
let py = self.py();
|
||||
let token = self.token();
|
||||
let mut vec = Vec::with_capacity(self.len());
|
||||
unsafe {
|
||||
let mut pos = 0;
|
||||
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((PyObject::from_borrowed_ptr(py, key),
|
||||
PyObject::from_borrowed_ptr(py, value)));
|
||||
vec.push((token.from_owned_ptr(key), token.from_owned_ptr(value)));
|
||||
}
|
||||
}
|
||||
vec
|
||||
}
|
||||
}
|
||||
|
||||
impl <K, V> ToPyObject for collections::HashMap<K, V>
|
||||
/*impl <K, V> ToPyObject for collections::HashMap<K, V>
|
||||
where K: hash::Hash+cmp::Eq+ToPyObject,
|
||||
V: ToPyObject
|
||||
{
|
||||
fn to_object<'p>(&self, py: Python<'p>) -> Py<'p, PyObject> {
|
||||
fn to_object(&self, py: Token) -> PyPtr<PyObject> {
|
||||
let dict = PyDict::new(py);
|
||||
for (key, value) in self {
|
||||
dict.set_item(key, value).unwrap();
|
||||
|
@ -132,14 +130,14 @@ impl <K, V> ToPyObject for collections::BTreeMap<K, V>
|
|||
where K: cmp::Eq+ToPyObject,
|
||||
V: ToPyObject
|
||||
{
|
||||
fn to_object<'p>(&self, py: Python<'p>) -> Py<'p, PyObject> {
|
||||
fn to_object(&self, py: Token) -> PyPtr<PyObject> {
|
||||
let dict = PyDict::new(py);
|
||||
for (key, value) in self {
|
||||
dict.set_item(key, value).unwrap();
|
||||
};
|
||||
dict.into_object()
|
||||
dict.into_pptr().into_object()
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
|
|
|
@ -9,8 +9,8 @@ use std::{self, mem, ops};
|
|||
use std::ffi::CStr;
|
||||
|
||||
use ffi;
|
||||
use pyptr::Py;
|
||||
use python::{Python, ToPythonPointer};
|
||||
use pyptr::{Py, PyPtr};
|
||||
use python::{Python, ToPythonPointer, Token};
|
||||
use err::PyResult;
|
||||
use super::tuple::PyTuple;
|
||||
use super::typeobject::PyType;
|
||||
|
@ -23,7 +23,7 @@ macro_rules! exc_type(
|
|||
|
||||
impl $crate::PyTypeObject for $name {
|
||||
#[inline]
|
||||
fn type_object<'p>(py: $crate::Python<'p>) -> $crate::Py<'p, PyType> {
|
||||
fn type_object(py: $crate::python::Token) -> $crate::PyPtr<PyType> {
|
||||
unsafe { PyType::from_type_ptr(py, ffi::$exc_name as *mut ffi::PyTypeObject) }
|
||||
}
|
||||
}
|
||||
|
@ -84,12 +84,11 @@ exc_type!(UnicodeTranslateError, PyExc_UnicodeTranslateError);
|
|||
|
||||
impl UnicodeDecodeError {
|
||||
|
||||
pub fn new<'p>(py: Python<'p>, encoding: &CStr, input: &[u8],
|
||||
range: ops::Range<usize>, reason: &CStr)
|
||||
-> PyResult<Py<'p, UnicodeDecodeError>> {
|
||||
pub fn new(py: Token, encoding: &CStr, input: &[u8], range: ops::Range<usize>, reason: &CStr)
|
||||
-> PyResult<PyPtr<UnicodeDecodeError>> {
|
||||
unsafe {
|
||||
let input: &[c_char] = mem::transmute(input);
|
||||
Py::from_owned_ptr_or_err(
|
||||
PyPtr::from_owned_ptr_or_err(
|
||||
py, ffi::PyUnicodeDecodeError_Create(
|
||||
encoding.as_ptr(),
|
||||
input.as_ptr(),
|
||||
|
@ -100,9 +99,8 @@ impl UnicodeDecodeError {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn new_utf8<'p>(py: Python<'p>, input: &[u8],
|
||||
err: std::str::Utf8Error)
|
||||
-> PyResult<Py<'p, UnicodeDecodeError>>
|
||||
pub fn new_utf8<'p>(py: Token, input: &[u8], err: std::str::Utf8Error)
|
||||
-> PyResult<PyPtr<UnicodeDecodeError>>
|
||||
{
|
||||
let pos = err.valid_up_to();
|
||||
UnicodeDecodeError::new(py, cstr!("utf-8"), input, pos .. pos+1, cstr!("invalid utf-8"))
|
||||
|
|
|
@ -3,13 +3,14 @@
|
|||
// based on Daniel Grunwald's https://github.com/dgrunwald/rust-cpython
|
||||
|
||||
use pyptr::Py;
|
||||
use python::{AsPy, Python, ToPythonPointer, IntoPythonPointer};
|
||||
use python::{Python, ToPythonPointer, IntoPythonPointer,
|
||||
PythonToken, PythonObjectWithToken, PythonTokenApi};
|
||||
use objects::PyObject;
|
||||
use ffi::{self, Py_ssize_t};
|
||||
use conversion::{ToPyObject, IntoPyObject};
|
||||
|
||||
/// Represents a Python `list`.
|
||||
pub struct PyList;
|
||||
pub struct PyList(PythonToken<PyList>);
|
||||
|
||||
pyobject_newtype!(PyList, PyList_Check, PyList_Type);
|
||||
|
||||
|
@ -38,12 +39,12 @@ impl PyList {
|
|||
/// Gets the item at the specified index.
|
||||
///
|
||||
/// Panics if the index is out of range.
|
||||
pub fn get_item<'p>(&'p self, index: usize) -> Py<'p, PyObject> {
|
||||
pub fn get_item(&self, index: usize) -> &PyObject {
|
||||
// TODO: do we really want to panic here?
|
||||
assert!(index < self.len());
|
||||
unsafe {
|
||||
Py::from_borrowed_ptr(
|
||||
self.py(), ffi::PyList_GetItem(self.as_ptr(), index as Py_ssize_t))
|
||||
let ptr = ffi::PyList_GetItem(self.as_ptr(), index as Py_ssize_t);
|
||||
self.py_token().from_owned(ptr)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,13 +6,13 @@ pub use self::module::PyModule;
|
|||
pub use self::string::{PyBytes, PyString, PyStringData};
|
||||
//pub use self::iterator::PyIterator;
|
||||
pub use self::boolobject::PyBool;
|
||||
pub use self::bytearray::PyByteArray;
|
||||
//pub use self::bytearray::PyByteArray;
|
||||
pub use self::tuple::{PyTuple, NoArgs};
|
||||
pub use self::dict::PyDict;
|
||||
pub use self::list::PyList;
|
||||
//pub use self::list::PyList;
|
||||
pub use self::num::{PyLong, PyFloat};
|
||||
//pub use self::sequence::PySequence;
|
||||
pub use self::slice::PySlice;
|
||||
//pub use self::slice::PySlice;
|
||||
//pub use self::set::{PySet, PyFrozenSet};
|
||||
|
||||
|
||||
|
@ -20,27 +20,6 @@ pub use self::slice::PySlice;
|
|||
macro_rules! pyobject_newtype(
|
||||
($name: ident, $checkfunction: ident, $typeobject: ident) => (
|
||||
|
||||
impl<'p> $crate::python::AsPy<'p> for &'p $name {
|
||||
#[inline]
|
||||
fn py<'a>(&'a self) -> $crate::Python<'p> {
|
||||
unsafe { $crate::python::Python::assume_gil_acquired() }
|
||||
}
|
||||
}
|
||||
|
||||
impl $crate::python::ToPythonPointer for $name {
|
||||
#[inline]
|
||||
fn as_ptr(&self) -> *mut $crate::ffi::PyObject {
|
||||
self as *const _ as *mut $crate::ffi::PyObject
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> $crate::python::ToPythonPointer for &'a $name {
|
||||
#[inline]
|
||||
fn as_ptr(&self) -> *mut $crate::ffi::PyObject {
|
||||
self as *const _ as *mut $crate::ffi::PyObject
|
||||
}
|
||||
}
|
||||
|
||||
impl $crate::typeob::PyTypeInfo for $name {
|
||||
type Type = ();
|
||||
|
||||
|
@ -64,11 +43,17 @@ macro_rules! pyobject_newtype(
|
|||
}
|
||||
}
|
||||
|
||||
impl $crate::python::PythonObjectWithToken for $name {
|
||||
fn token<'p>(&'p self) -> $crate::python::Token<'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 = unsafe { $crate::python::Python::assume_gil_acquired() };
|
||||
let py = <$name as $crate::python::PythonObjectWithToken>::token(self);
|
||||
let s = unsafe { $crate::Py::<$crate::PyString>::cast_from_owned_nullptr(
|
||||
py, $crate::ffi::PyObject_Repr(
|
||||
$crate::python::ToPythonPointer::as_ptr(self))) };
|
||||
|
@ -81,7 +66,7 @@ macro_rules! pyobject_newtype(
|
|||
fn fmt(&self, f: &mut $crate::std::fmt::Formatter)
|
||||
-> Result<(), $crate::std::fmt::Error>
|
||||
{
|
||||
let py = unsafe { $crate::python::Python::assume_gil_acquired() };
|
||||
let py = <$name as $crate::python::PythonObjectWithToken>::token(self);
|
||||
let s = unsafe { $crate::Py::<$crate::PyString>::cast_from_owned_nullptr(
|
||||
py, $crate::ffi::PyObject_Str(
|
||||
$crate::python::ToPythonPointer::as_ptr(self))) };
|
||||
|
@ -113,12 +98,12 @@ mod string;
|
|||
mod dict;
|
||||
//mod iterator;
|
||||
mod boolobject;
|
||||
mod bytearray;
|
||||
//mod bytearray;
|
||||
mod tuple;
|
||||
mod list;
|
||||
//mod list;
|
||||
mod num;
|
||||
//mod sequence;
|
||||
mod slice;
|
||||
//mod slice;
|
||||
// mod set;
|
||||
mod object;
|
||||
pub mod exc;
|
||||
|
|
|
@ -7,19 +7,19 @@ use ffi;
|
|||
use std::os::raw::c_char;
|
||||
use std::ffi::{CStr, CString};
|
||||
|
||||
use pyptr::Py;
|
||||
use python::{AsPy, Python, ToPythonPointer};
|
||||
use pyptr::{Py, PyPtr};
|
||||
use python::{Python, PythonToken, ToPythonPointer, PythonObjectWithToken, Token};
|
||||
use objects::{PyObject, PyDict, PyType, exc};
|
||||
use err::{PyResult, PyErr};
|
||||
|
||||
/// Represents a Python module object.
|
||||
pub struct PyModule;
|
||||
pub struct PyModule(PythonToken<PyModule>);
|
||||
|
||||
pyobject_newtype!(PyModule, PyModule_Check, PyModule_Type);
|
||||
|
||||
impl PyModule {
|
||||
/// Create a new module object with the `__name__` attribute set to name.
|
||||
pub fn new<'p>(py: Python<'p>, name: &str) -> PyResult<Py<'p, PyModule>> {
|
||||
pub fn new<'p>(py: Token<'p>, name: &str) -> PyResult<Py<'p, PyModule>> {
|
||||
let name = CString::new(name).unwrap();
|
||||
unsafe {
|
||||
Py::cast_from_owned_nullptr(py, ffi::PyModule_New(name.as_ptr()))
|
||||
|
@ -27,7 +27,7 @@ impl PyModule {
|
|||
}
|
||||
|
||||
/// Import the Python module with the specified name.
|
||||
pub fn import<'p>(py: Python<'p>, name: &str) -> PyResult<Py<'p, PyModule>> {
|
||||
pub fn import<'p>(py: Token<'p>, name: &str) -> PyResult<Py<'p, PyModule>> {
|
||||
let name = CString::new(name).unwrap();
|
||||
unsafe {
|
||||
Py::cast_from_owned_nullptr(py, ffi::PyImport_ImportModule(name.as_ptr()))
|
||||
|
@ -36,21 +36,21 @@ impl PyModule {
|
|||
|
||||
/// Return the dictionary object that implements module's namespace;
|
||||
/// this object is the same as the `__dict__` attribute of the module object.
|
||||
pub fn dict(&self) -> Py<PyDict> {
|
||||
pub fn dict(&self) -> PyPtr<PyDict> {
|
||||
unsafe {
|
||||
Py::from_borrowed_ptr(self.py(), ffi::PyModule_GetDict(self.as_ptr()))
|
||||
PyPtr::from_borrowed_ptr(ffi::PyModule_GetDict(self.as_ptr()))
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn str_from_ptr<'a>(&'a self, ptr: *const c_char) -> PyResult<&'a str> {
|
||||
if ptr.is_null() {
|
||||
Err(PyErr::fetch(self.py()))
|
||||
Err(PyErr::fetch(self.token()))
|
||||
} else {
|
||||
let slice = CStr::from_ptr(ptr).to_bytes();
|
||||
match std::str::from_utf8(slice) {
|
||||
Ok(s) => Ok(s),
|
||||
Err(e) => Err(PyErr::from_instance(
|
||||
self.py(), try!(exc::UnicodeDecodeError::new_utf8(self.py(), slice, e))))
|
||||
self.token(), try!(exc::UnicodeDecodeError::new_utf8(self.token(), slice, e))))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -81,17 +81,18 @@ impl PyModule {
|
|||
let type_name = <T as ::typeob::PyTypeInfo>::type_name();
|
||||
|
||||
let ty = if (ty.tp_flags & ffi::Py_TPFLAGS_READY) != 0 {
|
||||
unsafe { PyType::from_type_ptr(self.py(), ty) }
|
||||
unsafe { PyType::from_type_ptr(self.token(), ty) }
|
||||
} else {
|
||||
// automatically initialize the class
|
||||
let name = self.name()?;
|
||||
::typeob::initialize_type::<T>(self.py(), Some(name), type_name, ty)
|
||||
::typeob::initialize_type::<T>(self.token(), Some(name), type_name, ty)
|
||||
.expect(
|
||||
format!("An error occurred while initializing class {}",
|
||||
<T as ::typeob::PyTypeInfo>::type_name()).as_ref());
|
||||
unsafe { PyType::from_type_ptr(self.py(), ty) }
|
||||
unsafe { PyType::from_type_ptr(self.token(), ty) }
|
||||
};
|
||||
|
||||
PyObject::from_borrowed_ptr(self.py(), self.as_ptr()).setattr(type_name, ty)
|
||||
// PyObject::from_borrowed_ptr(self.py(), self.as_ptr()).setattr(type_name, ty)
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,12 +7,12 @@ extern crate num_traits;
|
|||
use self::num_traits::cast::cast;
|
||||
use std::os::raw::{c_long, c_double};
|
||||
|
||||
use ::Py;
|
||||
use ::{Py, PyPtr};
|
||||
use ffi;
|
||||
use super::exc;
|
||||
use super::PyObject;
|
||||
use typeob::PyTypeInfo;
|
||||
use python::{Python, ToPythonPointer};
|
||||
use python::{Python, PythonToken, ToPythonPointer, PythonObjectWithToken, Token};
|
||||
use err::{PyResult, PyErr};
|
||||
use conversion::{ToPyObject, FromPyObject};
|
||||
|
||||
|
@ -22,7 +22,7 @@ use conversion::{ToPyObject, FromPyObject};
|
|||
/// by using [ToPyObject](trait.ToPyObject.html)
|
||||
/// and [extract](struct.PyObject.html#method.extract)
|
||||
/// with the primitive Rust integer types.
|
||||
pub struct PyLong;
|
||||
pub struct PyLong(PythonToken<PyLong>);
|
||||
pyobject_newtype!(PyLong, PyLong_Check, PyLong_Type);
|
||||
|
||||
/// Represents a Python `float` object.
|
||||
|
@ -31,15 +31,15 @@ pyobject_newtype!(PyLong, PyLong_Check, PyLong_Type);
|
|||
/// by using [ToPyObject](trait.ToPyObject.html)
|
||||
/// and [extract](struct.PyObject.html#method.extract)
|
||||
/// with `f32`/`f64`.
|
||||
pub struct PyFloat;
|
||||
pub struct PyFloat(PythonToken<PyFloat>);
|
||||
pyobject_newtype!(PyFloat, PyFloat_Check, PyFloat_Type);
|
||||
|
||||
|
||||
impl PyFloat {
|
||||
/// Creates a new Python `float` object.
|
||||
pub fn new<'p>(py: Python<'p>, val: c_double) -> Py<'p, PyFloat> {
|
||||
pub fn new(_py: Token, val: c_double) -> PyPtr<PyFloat> {
|
||||
unsafe {
|
||||
Py::from_owned_ptr_or_panic(py, ffi::PyFloat_FromDouble(val))
|
||||
PyPtr::from_owned_ptr_or_panic(ffi::PyFloat_FromDouble(val))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,21 +53,21 @@ impl PyFloat {
|
|||
macro_rules! int_fits_c_long(
|
||||
($rust_type:ty) => (
|
||||
impl ToPyObject for $rust_type {
|
||||
fn to_object<'p>(&self, py: Python<'p>) -> Py<'p, PyObject> {
|
||||
fn to_object(&self, py: Token) -> PyPtr<PyObject> {
|
||||
unsafe {
|
||||
Py::from_owned_ptr_or_panic(py, ffi::PyLong_FromLong(*self as c_long))
|
||||
PyPtr::from_owned_ptr_or_panic(ffi::PyLong_FromLong(*self as c_long))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pyobject_extract!(obj to $rust_type => {
|
||||
let val = unsafe { ffi::PyLong_AsLong(obj.as_ptr()) };
|
||||
if val == -1 && PyErr::occurred(obj.py()) {
|
||||
return Err(PyErr::fetch(obj.py()));
|
||||
if val == -1 && PyErr::occurred(obj.token()) {
|
||||
return Err(PyErr::fetch(obj.token()));
|
||||
}
|
||||
match cast::<c_long, $rust_type>(val) {
|
||||
Some(v) => Ok(v),
|
||||
None => Err(overflow_error(obj.py()))
|
||||
None => Err(overflow_error(obj.token()))
|
||||
}
|
||||
});
|
||||
)
|
||||
|
@ -78,13 +78,13 @@ macro_rules! int_fits_larger_int(
|
|||
($rust_type:ty, $larger_type:ty) => (
|
||||
impl ToPyObject for $rust_type {
|
||||
#[inline]
|
||||
fn to_object<'p>(&self, py: Python<'p>) -> Py<'p, PyObject> {
|
||||
fn to_object(&self, py: Token) -> PyPtr<PyObject> {
|
||||
(*self as $larger_type).to_object(py)
|
||||
}
|
||||
}
|
||||
|
||||
pyobject_extract!(obj to $rust_type => {
|
||||
let py = obj.py();
|
||||
let py = obj.token();
|
||||
let val = try!(obj.extract::<$larger_type>());
|
||||
match cast::<$larger_type, $rust_type>(val) {
|
||||
Some(v) => Ok(v),
|
||||
|
@ -96,7 +96,7 @@ macro_rules! int_fits_larger_int(
|
|||
|
||||
|
||||
fn err_if_invalid_value<'p, T: PartialEq>
|
||||
(py: Python, invalid_value: T, actual_value: T) -> PyResult<T>
|
||||
(py: Token, invalid_value: T, actual_value: T) -> PyResult<T>
|
||||
{
|
||||
if actual_value == invalid_value && PyErr::occurred(py) {
|
||||
Err(PyErr::fetch(py))
|
||||
|
@ -109,9 +109,9 @@ macro_rules! int_convert_u64_or_i64 (
|
|||
($rust_type:ty, $pylong_from_ll_or_ull:expr, $pylong_as_ull_or_ull:expr) => (
|
||||
impl ToPyObject for $rust_type {
|
||||
|
||||
fn to_object<'p>(&self, py: Python<'p>) -> Py<'p, PyObject> {
|
||||
fn to_object(&self, py: Token) -> PyPtr<PyObject> {
|
||||
unsafe {
|
||||
Py::from_owned_ptr_or_panic(py, $pylong_from_ll_or_ull(*self))
|
||||
PyPtr::from_owned_ptr_or_panic($pylong_from_ll_or_ull(*self))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -123,13 +123,13 @@ macro_rules! int_convert_u64_or_i64 (
|
|||
let ptr = py.as_ptr();
|
||||
unsafe {
|
||||
if ffi::PyLong_Check(ptr) != 0 {
|
||||
err_if_invalid_value(py.py(), !0, $pylong_as_ull_or_ull(ptr))
|
||||
err_if_invalid_value(py.token(), !0, $pylong_as_ull_or_ull(ptr))
|
||||
} else {
|
||||
let num = ffi::PyNumber_Long(ptr);
|
||||
if num.is_null() {
|
||||
Err(PyErr::fetch(py.py()))
|
||||
Err(PyErr::fetch(py.token()))
|
||||
} else {
|
||||
err_if_invalid_value(py.py(), !0, $pylong_as_ull_or_ull(num))
|
||||
err_if_invalid_value(py.token(), !0, $pylong_as_ull_or_ull(num))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -169,26 +169,26 @@ int_fits_larger_int!(usize, u64);
|
|||
int_convert_u64_or_i64!(u64, ffi::PyLong_FromUnsignedLongLong, ffi::PyLong_AsUnsignedLongLong);
|
||||
|
||||
impl ToPyObject for f64 {
|
||||
fn to_object<'p>(&self, py: Python<'p>) -> Py<'p, PyObject> {
|
||||
fn to_object(&self, py: Token) -> PyPtr<PyObject> {
|
||||
PyFloat::new(py, *self).into_object()
|
||||
}
|
||||
}
|
||||
|
||||
pyobject_extract!(obj to f64 => {
|
||||
let v = unsafe { ffi::PyFloat_AsDouble(obj.as_ptr()) };
|
||||
if v == -1.0 && PyErr::occurred(obj.py()) {
|
||||
Err(PyErr::fetch(obj.py()))
|
||||
if v == -1.0 && PyErr::occurred(obj.token()) {
|
||||
Err(PyErr::fetch(obj.token()))
|
||||
} else {
|
||||
Ok(v)
|
||||
}
|
||||
});
|
||||
|
||||
fn overflow_error(py: Python) -> PyErr {
|
||||
PyErr::new_lazy_init(py.get_ptype::<exc::OverflowError>(), None)
|
||||
fn overflow_error(py: Token) -> PyErr {
|
||||
PyErr::new_lazy_init(py.get_type::<exc::OverflowError>(), None)
|
||||
}
|
||||
|
||||
impl ToPyObject for f32 {
|
||||
fn to_object<'p>(&self, py: Python<'p>) -> Py<'p, PyObject> {
|
||||
fn to_object(&self, py: Token) -> PyPtr<PyObject> {
|
||||
PyFloat::new(py, *self as f64).into_object()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,21 +4,23 @@ use std;
|
|||
|
||||
use ffi;
|
||||
use pyptr::{Py, PyPtr};
|
||||
use python::Python;
|
||||
use err::{PyErr, PyResult, PyDowncastError};
|
||||
use python::{Python, PythonToken, Token, PythonObjectWithToken};
|
||||
use typeob::PyTypeInfo;
|
||||
|
||||
pub struct PyObject;
|
||||
pub struct PyObject(PythonToken<PyObject>);
|
||||
|
||||
pyobject_newtype!(PyObject, PyObject_Check, PyBaseObject_Type);
|
||||
|
||||
impl PyObject {
|
||||
|
||||
#[inline]
|
||||
pub fn from_owned_ptr(py: Python, ptr: *mut ffi::PyObject) -> Py<PyObject> {
|
||||
pub fn from_owned_ptr(py: Token, ptr: *mut ffi::PyObject) -> Py<PyObject> {
|
||||
unsafe { Py::from_owned_ptr(py, ptr) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn from_borrowed_ptr(py: Python, ptr: *mut ffi::PyObject) -> Py<PyObject> {
|
||||
pub fn from_borrowed_ptr(py: Token, ptr: *mut ffi::PyObject) -> Py<PyObject> {
|
||||
unsafe { Py::from_borrowed_ptr(py, ptr) }
|
||||
}
|
||||
|
||||
|
@ -26,7 +28,7 @@ impl PyObject {
|
|||
/// This moves ownership over the pointer into the PyObject.
|
||||
/// Returns None for null pointers; undefined behavior if the pointer is invalid.
|
||||
#[inline]
|
||||
pub unsafe fn from_owned_pptr_opt(py: Python, ptr: *mut ffi::PyObject)
|
||||
pub unsafe fn from_owned_pptr_opt(py: Token, ptr: *mut ffi::PyObject)
|
||||
-> Option<PyPtr<PyObject>> {
|
||||
if ptr.is_null() {
|
||||
None
|
||||
|
@ -37,7 +39,7 @@ impl PyObject {
|
|||
|
||||
/// Returns None for null pointers; undefined behavior if the pointer is invalid.
|
||||
#[inline]
|
||||
pub unsafe fn from_borrowed_pptr_opt(py: Python, ptr: *mut ffi::PyObject)
|
||||
pub unsafe fn from_borrowed_pptr_opt(py: Token, ptr: *mut ffi::PyObject)
|
||||
-> Option<PyPtr<PyObject>> {
|
||||
if ptr.is_null() {
|
||||
None
|
||||
|
@ -53,4 +55,25 @@ impl PyObject {
|
|||
-> &'a [Py<'a, PyObject>] {
|
||||
std::mem::transmute(ptr)
|
||||
}
|
||||
|
||||
/// 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_as<'p, D>(&'p self) -> Result<&'p D, PyDowncastError<'p>>
|
||||
where D: PyTypeInfo
|
||||
{
|
||||
unsafe {
|
||||
let ptr = self as *const _ as *mut _;
|
||||
let checked = unsafe { ffi::PyObject_TypeCheck(ptr, D::type_object()) != 0 };
|
||||
|
||||
if checked {
|
||||
Ok(
|
||||
unsafe {
|
||||
let ptr = ptr as *mut D;
|
||||
ptr.as_ref().unwrap() })
|
||||
} else {
|
||||
Err(PyDowncastError(self.token(), None))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
// Copyright (c) 2017-present PyO3 Project and Contributors
|
||||
|
||||
use std::os::raw::c_long;
|
||||
use pyptr::Py;
|
||||
use pyptr::PyPtr;
|
||||
use objects::PyObject;
|
||||
use python::{AsPy, Python, ToPythonPointer};
|
||||
use python::{Python, PythonToken, ToPythonPointer, Token};
|
||||
use err::{PyErr, PyResult};
|
||||
use ffi::{self, Py_ssize_t};
|
||||
use conversion::ToPyObject;
|
||||
|
@ -30,18 +30,18 @@ impl PySliceIndices {
|
|||
|
||||
/// Represents a Python `slice`. Only `c_long` indeces supprted
|
||||
/// at the moment by PySlice object.
|
||||
pub struct PySlice(PyObject);
|
||||
pub struct PySlice(PythonToken<PySlice>);
|
||||
|
||||
pyobject_newtype!(PySlice, PySlice_Check, PySlice_Type);
|
||||
|
||||
impl PySlice {
|
||||
/// Construct a new slice with the given elements.
|
||||
pub fn new<'p>(py: Python<'p>, start: isize, stop: isize, step: isize) -> Py<'p, PySlice> {
|
||||
pub fn new<'p>(py: Token, start: isize, stop: isize, step: isize) -> PyPtr<PySlice> {
|
||||
unsafe {
|
||||
let ptr = ffi::PySlice_New(ffi::PyLong_FromLong(start as i64),
|
||||
ffi::PyLong_FromLong(stop as i64),
|
||||
ffi::PyLong_FromLong(step as i64));
|
||||
Py::from_owned_ptr_or_panic(py, ptr)
|
||||
PyPtr::from_owned_ptr_or_panic(py, ptr)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,14 +68,14 @@ impl PySlice {
|
|||
slicelength: slicelen,
|
||||
})
|
||||
} else {
|
||||
Err(PyErr::fetch(self.py()))
|
||||
Err(PyErr::fetch(self.token()))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToPyObject for PySliceIndices {
|
||||
fn to_object<'p>(&self, py: Python<'p>) -> Py<'p, PyObject> {
|
||||
PySlice::new(py, self.start, self.stop, self.step).into_object()
|
||||
fn to_object<'p>(&self, py: Token) -> PyPtr<PyObject> {
|
||||
PySlice::new(py, self.start, self.stop, self.step)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,20 +8,20 @@ use std::ascii::AsciiExt;
|
|||
use std::borrow::Cow;
|
||||
use std::os::raw::c_char;
|
||||
|
||||
use ::Py;
|
||||
use ::{Py, PyPtr};
|
||||
use ffi;
|
||||
use python::{AsPy, Python, ToPythonPointer};
|
||||
use python::{Python, PythonToken, ToPythonPointer, Token, PythonObjectWithToken};
|
||||
use super::{exc, PyObject};
|
||||
use err::{PyResult, PyErr};
|
||||
use conversion::{ToPyObject, RefFromPyObject};
|
||||
|
||||
/// Represents a Python string.
|
||||
pub struct PyString;
|
||||
pub struct PyString(PythonToken<PyString>);
|
||||
|
||||
pyobject_newtype!(PyString, PyUnicode_Check, PyUnicode_Type);
|
||||
|
||||
/// Represents a Python byte string.
|
||||
pub struct PyBytes;
|
||||
pub struct PyBytes(PythonToken<PyBytes>);
|
||||
|
||||
pyobject_newtype!(PyBytes, PyBytes_Check, PyBytes_Type);
|
||||
|
||||
|
@ -63,7 +63,7 @@ impl <'a> PyStringData<'a> {
|
|||
/// For Latin-1, UTF-16 and UTF-32, returns an owned string.
|
||||
///
|
||||
/// Fails with UnicodeDecodeError if the string data isn't valid in its encoding.
|
||||
pub fn to_string(self, py: Python) -> PyResult<Cow<'a, str>> {
|
||||
pub fn to_string(self, py: Token) -> PyResult<Cow<'a, str>> {
|
||||
match self {
|
||||
PyStringData::Utf8(data) => {
|
||||
match str::from_utf8(data) {
|
||||
|
@ -141,20 +141,19 @@ impl PyString {
|
|||
/// Use `PyUnicode::new()` to always create a unicode string.
|
||||
///
|
||||
/// Panics if out of memory.
|
||||
pub fn new<'p>(py: Python<'p>, s: &str) -> Py<'p, PyString> {
|
||||
pub fn new<'p>(py: Token, s: &str) -> PyPtr<PyString> {
|
||||
let ptr = s.as_ptr() as *const c_char;
|
||||
let len = s.len() as ffi::Py_ssize_t;
|
||||
unsafe {
|
||||
Py::cast_from_owned_ptr_or_panic(
|
||||
py, ffi::PyUnicode_FromStringAndSize(ptr, len))
|
||||
PyPtr::from_owned_ptr_or_panic(ffi::PyUnicode_FromStringAndSize(ptr, len))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_object<'p>(src: &'p PyObject, encoding: &str, errors: &str)
|
||||
-> PyResult<Py<'p, PyString>> {
|
||||
pub fn from_object<'p>(src: &PyObject, encoding: &str, errors: &str)
|
||||
-> PyResult<PyPtr<PyString>> {
|
||||
unsafe {
|
||||
Py::cast_from_owned_ptr(
|
||||
src.py(), ffi::PyUnicode_FromEncodedObject(
|
||||
PyPtr::from_owned_ptr_or_err(
|
||||
src.token(), ffi::PyUnicode_FromEncodedObject(
|
||||
src.as_ptr(), encoding.as_ptr() as *const i8, errors.as_ptr() as *const i8))
|
||||
.map_err(|e| e.into())
|
||||
}
|
||||
|
@ -168,7 +167,7 @@ impl PyString {
|
|||
let mut size : ffi::Py_ssize_t = mem::uninitialized();
|
||||
let data = ffi::PyUnicode_AsUTF8AndSize(self.as_ptr(), &mut size) as *const u8;
|
||||
if data.is_null() {
|
||||
PyErr::fetch(self.py()).print(self.py());
|
||||
PyErr::fetch(self.token()).print(self.token());
|
||||
panic!("PyUnicode_AsUTF8AndSize failed");
|
||||
}
|
||||
PyStringData::Utf8(std::slice::from_raw_parts(data, size as usize))
|
||||
|
@ -180,7 +179,7 @@ impl PyString {
|
|||
/// Returns a `UnicodeDecodeError` if the input is not valid unicode
|
||||
/// (containing unpaired surrogates).
|
||||
pub fn to_string(&self) -> PyResult<Cow<str>> {
|
||||
self.data().to_string(self.py())
|
||||
self.data().to_string(self.token())
|
||||
}
|
||||
|
||||
/// Convert the `PyString` into a Rust string.
|
||||
|
@ -197,7 +196,7 @@ impl PyBytes {
|
|||
/// The byte string is initialized by copying the data from the `&[u8]`.
|
||||
///
|
||||
/// Panics if out of memory.
|
||||
pub fn new<'p>(py: Python<'p>, s: &[u8]) -> Py<'p, PyBytes> {
|
||||
pub fn new<'p>(py: Token<'p>, s: &[u8]) -> Py<'p, PyBytes> {
|
||||
let ptr = s.as_ptr() as *const c_char;
|
||||
let len = s.len() as ffi::Py_ssize_t;
|
||||
unsafe {
|
||||
|
@ -220,7 +219,7 @@ impl PyBytes {
|
|||
/// See `PyString::new` for details on the conversion.
|
||||
impl ToPyObject for str {
|
||||
#[inline]
|
||||
fn to_object<'p>(&self, py: Python<'p>) -> Py<'p, PyObject> {
|
||||
fn to_object(&self, py: Token) -> PyPtr<PyObject> {
|
||||
PyString::new(py, self).into_object()
|
||||
}
|
||||
}
|
||||
|
@ -229,7 +228,7 @@ impl ToPyObject for str {
|
|||
/// See `PyString::new` for details on the conversion.
|
||||
impl <'a> ToPyObject for Cow<'a, str> {
|
||||
#[inline]
|
||||
fn to_object<'p>(&self, py: Python<'p>) -> Py<'p, PyObject> {
|
||||
fn to_object(&self, py: Token) -> PyPtr<PyObject> {
|
||||
PyString::new(py, self).into_object()
|
||||
}
|
||||
}
|
||||
|
@ -238,7 +237,7 @@ impl <'a> ToPyObject for Cow<'a, str> {
|
|||
/// See `PyString::new` for details on the conversion.
|
||||
impl ToPyObject for String {
|
||||
#[inline]
|
||||
fn to_object<'p>(&self, py: Python<'p>) -> Py<'p, PyObject> {
|
||||
fn to_object(&self, py: Token) -> PyPtr<PyObject> {
|
||||
PyString::new(py, self).into_object()
|
||||
}
|
||||
}
|
||||
|
@ -262,7 +261,7 @@ impl<'p> RefFromPyObject<'p> for str {
|
|||
fn with_extracted<F, R>(obj: &'p Py<'p, PyObject>, f: F) -> PyResult<R>
|
||||
where F: FnOnce(&str) -> R
|
||||
{
|
||||
let p = PyObject::from_borrowed_ptr(obj.py(), obj.as_ptr());
|
||||
let p = PyObject::from_borrowed_ptr(obj.token(), obj.as_ptr());
|
||||
let s = try!(p.extract::<Cow<str>>());
|
||||
Ok(f(&s))
|
||||
}
|
||||
|
|
|
@ -4,26 +4,27 @@
|
|||
|
||||
use std::slice;
|
||||
|
||||
use ::Py;
|
||||
use ::{Py, PyPtr};
|
||||
use ffi::{self, Py_ssize_t};
|
||||
use python::{AsPy, Python, ToPythonPointer, IntoPythonPointer};
|
||||
use python::{Python, PythonToken, Token,
|
||||
ToPythonPointer, IntoPythonPointer, PythonObjectWithToken};
|
||||
use err::{PyErr, PyResult};
|
||||
use conversion::{FromPyObject, ToPyObject, ToPyTuple};
|
||||
use super::exc;
|
||||
use super::PyObject;
|
||||
|
||||
/// Represents a Python tuple object.
|
||||
pub struct PyTuple;
|
||||
pub struct PyTuple(PythonToken<PyTuple>);
|
||||
|
||||
pyobject_newtype!(PyTuple, PyTuple_Check, PyTuple_Type);
|
||||
|
||||
impl PyTuple {
|
||||
/// Construct a new tuple with the given elements.
|
||||
pub fn new<'p, T: ToPyObject>(py: Python<'p>, elements: &[T]) -> Py<'p, PyTuple> {
|
||||
pub fn new<'p, T: ToPyObject>(py: Token, elements: &[T]) -> PyPtr<PyTuple> {
|
||||
unsafe {
|
||||
let len = elements.len();
|
||||
let ptr = ffi::PyTuple_New(len as Py_ssize_t);
|
||||
let t = Py::from_owned_ptr_or_panic(py, ptr);
|
||||
let t = PyPtr::from_owned_ptr_or_panic(ptr);
|
||||
for (i, e) in elements.iter().enumerate() {
|
||||
ffi::PyTuple_SetItem(ptr, i as Py_ssize_t, e.to_object(py).into_ptr());
|
||||
}
|
||||
|
@ -32,9 +33,9 @@ impl PyTuple {
|
|||
}
|
||||
|
||||
/// Retrieves the empty tuple.
|
||||
pub fn empty<'p>(py: Python<'p>) -> Py<'p, PyTuple> {
|
||||
pub fn empty(py: Token) -> PyPtr<PyTuple> {
|
||||
unsafe {
|
||||
Py::from_owned_ptr_or_panic(py, ffi::PyTuple_New(0))
|
||||
PyPtr::from_owned_ptr_or_panic(ffi::PyTuple_New(0))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,14 +51,13 @@ impl PyTuple {
|
|||
/// Gets the item at the specified index.
|
||||
///
|
||||
/// Panics if the index is out of range.
|
||||
pub fn get_item<'p>(&self, index: usize) -> Py<'p, PyObject> {
|
||||
pub fn get_item<'p>(&self, index: usize) -> &PyObject {
|
||||
// TODO: reconsider whether we should panic
|
||||
// It's quite inconsistent that this method takes `Python` when `len()` does not.
|
||||
assert!(index < self.len());
|
||||
unsafe {
|
||||
std::mem::transmute(
|
||||
PyObject::from_borrowed_ptr(
|
||||
self.py(), ffi::PyTuple_GET_ITEM(self.as_ptr(), index as Py_ssize_t)))
|
||||
self.token().from_owned_ptr(
|
||||
ffi::PyTuple_GET_ITEM(self.as_ptr(), index as Py_ssize_t))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,27 +84,27 @@ impl PyTuple {
|
|||
use std;
|
||||
|
||||
impl<'a> ToPyTuple for Py<'a, PyTuple> {
|
||||
fn to_py_tuple<'p>(&self, _py: Python<'p>) -> Py<'p, PyTuple> {
|
||||
unsafe { std::mem::transmute(self.clone()) }
|
||||
fn to_py_tuple(&self, _py: Token) -> PyPtr<PyTuple> {
|
||||
self.as_pptr()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ToPyTuple for &'a str {
|
||||
fn to_py_tuple<'p>(&self, py: Python<'p>) -> Py<'p, PyTuple> {
|
||||
fn to_py_tuple(&self, py: Token) -> PyPtr<PyTuple> {
|
||||
PyTuple::new(py, &[py_coerce_expr!(self.to_object(py))])
|
||||
}
|
||||
}
|
||||
|
||||
fn wrong_tuple_length(py: Python, t: &PyTuple, expected_length: usize) -> PyErr {
|
||||
fn wrong_tuple_length(py: Token, t: &PyTuple, expected_length: usize) -> PyErr {
|
||||
let msg = format!("Expected tuple of length {}, but got tuple of length {}.",
|
||||
expected_length, t.len());
|
||||
PyErr::new_lazy_init(
|
||||
py.get_ptype::<exc::ValueError>(), Some(msg.to_object(py).into_pptr()))
|
||||
py.get_type::<exc::ValueError>(), Some(msg.to_object(py)))
|
||||
}
|
||||
|
||||
macro_rules! tuple_conversion ({$length:expr,$(($refN:ident, $n:tt, $T:ident)),+} => {
|
||||
impl <$($T: ToPyObject),+> ToPyObject for ($($T,)+) {
|
||||
fn to_object<'p>(&self, py: Python<'p>) -> Py<'p, PyObject> {
|
||||
fn to_object(&self, py: Token) -> PyPtr<PyObject> {
|
||||
PyTuple::new(py, &[
|
||||
$(py_coerce_expr!(self.$n.to_object(py)),)+
|
||||
]).into_object()
|
||||
|
@ -112,7 +112,7 @@ macro_rules! tuple_conversion ({$length:expr,$(($refN:ident, $n:tt, $T:ident)),+
|
|||
}
|
||||
|
||||
impl <$($T: ToPyObject),+> ToPyTuple for ($($T,)+) {
|
||||
fn to_py_tuple<'p>(&self, py: Python<'p>) -> Py<'p, PyTuple> {
|
||||
fn to_py_tuple(&self, py: Token) -> PyPtr<PyTuple> {
|
||||
PyTuple::new(py, &[
|
||||
$(py_coerce_expr!(self.$n.to_object(py)),)+
|
||||
])
|
||||
|
@ -130,7 +130,7 @@ macro_rules! tuple_conversion ({$length:expr,$(($refN:ident, $n:tt, $T:ident)),+
|
|||
$( try!(slice[$n].extract::<$T>()), )+
|
||||
))
|
||||
} else {
|
||||
Err(wrong_tuple_length(obj.py(), t, $length))
|
||||
Err(wrong_tuple_length(obj.token(), t, $length))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -169,7 +169,7 @@ pub struct NoArgs;
|
|||
/// Converts `NoArgs` to an empty Python tuple.
|
||||
impl ToPyObject for NoArgs {
|
||||
|
||||
fn to_object<'p>(&self, py: Python<'p>) -> Py<'p, PyObject> {
|
||||
fn to_object(&self, py: Token) -> PyPtr<PyObject> {
|
||||
PyTuple::empty(py).into_object()
|
||||
}
|
||||
}
|
||||
|
@ -177,7 +177,7 @@ impl ToPyObject for NoArgs {
|
|||
/// Converts `NoArgs` to an empty Python tuple.
|
||||
impl ToPyTuple for NoArgs {
|
||||
|
||||
fn to_py_tuple<'p>(&self, py: Python<'p>) -> Py<'p, PyTuple> {
|
||||
fn to_py_tuple(&self, py: Token) -> PyPtr<PyTuple> {
|
||||
PyTuple::empty(py)
|
||||
}
|
||||
}
|
||||
|
@ -185,7 +185,7 @@ impl ToPyTuple for NoArgs {
|
|||
/// Converts `()` to an empty Python tuple.
|
||||
impl ToPyTuple for () {
|
||||
|
||||
fn to_py_tuple<'p>(&self, py: Python<'p>) -> Py<'p, PyTuple> {
|
||||
fn to_py_tuple(&self, py: Token) -> PyPtr<PyTuple> {
|
||||
PyTuple::empty(py)
|
||||
}
|
||||
}
|
||||
|
@ -198,7 +198,7 @@ pyobject_extract!(obj to NoArgs => {
|
|||
if t.len() == 0 {
|
||||
Ok(NoArgs)
|
||||
} else {
|
||||
Err(wrong_tuple_length(obj.py(), t, 0))
|
||||
Err(wrong_tuple_length(obj.token(), t, 0))
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -6,14 +6,14 @@ use std::ffi::CStr;
|
|||
use std::borrow::Cow;
|
||||
|
||||
use ffi;
|
||||
use pyptr::Py;
|
||||
use python::{AsPy, Python, ToPythonPointer};
|
||||
use pyptr::{Py, PyPtr};
|
||||
use python::{Python, PythonToken, ToPythonPointer, Token, PythonObjectWithToken};
|
||||
use conversion::ToPyTuple;
|
||||
use objects::{PyObject, PyDict};
|
||||
use err::PyResult;
|
||||
|
||||
/// Represents a reference to a Python type object.
|
||||
pub struct PyType;
|
||||
pub struct PyType(PythonToken<PyType>);
|
||||
|
||||
pyobject_newtype!(PyType, PyType_Check, PyType_Type);
|
||||
|
||||
|
@ -28,8 +28,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) -> Py<PyType> {
|
||||
Py::from_borrowed_ptr(py, p as *mut ffi::PyObject)
|
||||
pub unsafe fn from_type_ptr(_py: Token, p: *mut ffi::PyTypeObject) -> PyPtr<PyType> {
|
||||
PyPtr::from_borrowed_ptr(p as *mut ffi::PyObject)
|
||||
}
|
||||
|
||||
/// Gets the name of the PyType.
|
||||
|
@ -54,13 +54,13 @@ impl PyType {
|
|||
// /// 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<Py<'p, PyObject>>
|
||||
pub fn call<'p, A>(&'p self, args: A, kwargs: Option<&PyDict>) -> PyResult<PyPtr<PyObject>>
|
||||
where A: ToPyTuple
|
||||
{
|
||||
let args = args.to_py_tuple(self.py());
|
||||
let args = args.to_py_tuple(self.token());
|
||||
unsafe {
|
||||
Py::from_owned_ptr_or_err(
|
||||
self.py(), ffi::PyObject_Call(self.as_ptr(), args.as_ptr(), kwargs.as_ptr()))
|
||||
PyPtr::from_owned_ptr_or_err(
|
||||
self.token(), ffi::PyObject_Call(self.as_ptr(), args.as_ptr(), kwargs.as_ptr()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
192
src/pyptr.rs
192
src/pyptr.rs
|
@ -8,7 +8,7 @@ use std::convert::{AsRef, AsMut};
|
|||
use ffi;
|
||||
use err::{PyErr, PyResult, PyDowncastError};
|
||||
use conversion::{ToPyObject, IntoPyObject};
|
||||
use python::{AsPy, Python, ToPythonPointer, IntoPythonPointer};
|
||||
use python::{Python, ToPythonPointer, IntoPythonPointer, Token, PythonObjectWithToken};
|
||||
use objects::PyObject;
|
||||
use typeob::{PyTypeInfo, PyObjectAlloc};
|
||||
|
||||
|
@ -29,10 +29,34 @@ impl<T> PyPtr<T> {
|
|||
PyPtr {inner: ptr, _t: PhantomData}
|
||||
}
|
||||
|
||||
/// Creates a PyPTr instance for the given FFI pointer.
|
||||
/// Construct PyPtr<PyObject> from the result of a Python FFI call that
|
||||
/// returns a new reference (owned pointer).
|
||||
/// Returns `Err(PyErr)` if the pointer is `null`.
|
||||
/// Unsafe because the pointer might be invalid.
|
||||
pub unsafe fn from_owned_ptr_or_err(py: Token, ptr: *mut ffi::PyObject) -> PyResult<PyPtr<T>>
|
||||
{
|
||||
if ptr.is_null() {
|
||||
Err(PyErr::fetch(py))
|
||||
} else {
|
||||
Ok(PyPtr::from_owned_ptr(ptr))
|
||||
}
|
||||
}
|
||||
|
||||
/// Cast from ffi::PyObject ptr to PyPtr pointer
|
||||
#[inline]
|
||||
pub unsafe fn from_owned_ptr_or_panic(ptr: *mut ffi::PyObject) -> PyPtr<T>
|
||||
{
|
||||
if ptr.is_null() {
|
||||
::err::panic_after_error();
|
||||
} else {
|
||||
PyPtr::from_owned_ptr(ptr)
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a PyPtr instance for the given FFI pointer.
|
||||
/// Calls Py_INCREF() on the ptr.
|
||||
/// Undefined behavior if the pointer is NULL or invalid.
|
||||
/// Caller of this method has to have valid Py object.
|
||||
/// Caller of this method has to have valid Python object.
|
||||
#[inline]
|
||||
pub unsafe fn from_borrowed_ptr(ptr: *mut ffi::PyObject) -> PyPtr<T> {
|
||||
debug_assert!(!ptr.is_null() && ffi::Py_REFCNT(ptr) > 0);
|
||||
|
@ -40,12 +64,35 @@ impl<T> PyPtr<T> {
|
|||
PyPtr {inner: ptr, _t: PhantomData}
|
||||
}
|
||||
|
||||
pub fn as_ref<'p>(&self, _py: Python<'p>) -> Py<'p, T> {
|
||||
Py{inner: self.inner, _t: PhantomData, _py: PhantomData}
|
||||
/// Creates a Py instance for the given FFI pointer.
|
||||
/// Calls Py_INCREF() on the ptr.
|
||||
#[inline]
|
||||
pub unsafe fn from_borrowed_ptr_opt(_py: Token,
|
||||
ptr: *mut ffi::PyObject) -> Option<PyPtr<T>> {
|
||||
if ptr.is_null() {
|
||||
None
|
||||
} else {
|
||||
debug_assert!(ffi::Py_REFCNT(ptr) > 0);
|
||||
ffi::Py_INCREF(ptr);
|
||||
Some(PyPtr{inner: ptr, _t: PhantomData})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn into_ref<'p>(self, _py: Python<'p>) -> Py<'p, T> {
|
||||
let p = Py{inner: self.inner, _t: PhantomData, _py: PhantomData};
|
||||
pub fn as_ref<'p>(&self, py: Token<'p>) -> Py<'p, T> {
|
||||
unsafe { Py::from_borrowed_ptr(py, self.inner) }
|
||||
}
|
||||
|
||||
pub fn into_ref<'p>(self, py: Token<'p>) -> Py<'p, T> {
|
||||
let p = Py{inner: self.inner, _t: PhantomData, py: py};
|
||||
std::mem::forget(self);
|
||||
p
|
||||
}
|
||||
|
||||
/// Converts PyPtr<T> -> PyPtr<PyObject>
|
||||
/// Consumes `self` without calling `Py_INCREF()`
|
||||
#[inline]
|
||||
pub fn into_object(self) -> PyPtr<PyObject> {
|
||||
let p = PyPtr {inner: self.inner, _t: PhantomData};
|
||||
std::mem::forget(self);
|
||||
p
|
||||
}
|
||||
|
@ -57,9 +104,19 @@ impl<T> PyPtr<T> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn clone_ref(&self, _py: Python) -> PyPtr<T> {
|
||||
pub fn clone_ref(&self) -> PyPtr<T> {
|
||||
PyPtr{inner: self.inner.clone(), _t: PhantomData}
|
||||
}
|
||||
|
||||
/// Unchecked downcast from other PyPtr<S> to PyPtr<S>.
|
||||
/// Undefined behavior if the input object does not have the expected type.
|
||||
#[inline]
|
||||
pub unsafe fn unchecked_downcast_from<S>(py: PyPtr<S>) -> PyPtr<T>
|
||||
{
|
||||
let res = PyPtr {inner: py.inner, _t: PhantomData};
|
||||
std::mem::forget(py);
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> ToPythonPointer for PyPtr<T> {
|
||||
|
@ -85,8 +142,8 @@ impl<T> IntoPythonPointer for PyPtr<T> {
|
|||
impl<T> IntoPyObject for PyPtr<T> {
|
||||
|
||||
#[inline]
|
||||
fn into_object<'a>(self, py: Python<'a>) -> Py<'a, PyObject> {
|
||||
self.into_ref(py).into_object()
|
||||
fn into_object<'a>(self, py: Token) -> PyPtr<PyObject> {
|
||||
self.into_object()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -111,7 +168,7 @@ impl<T> Drop for PyPtr<T> {
|
|||
pub struct Py<'p, T> {
|
||||
pub inner: *mut ffi::PyObject,
|
||||
_t: PhantomData<T>,
|
||||
_py: PhantomData<Python<'p>>,
|
||||
py: Token<'p>,
|
||||
}
|
||||
|
||||
impl<'p, T> Py<'p, T>
|
||||
|
@ -120,17 +177,17 @@ impl<'p, T> Py<'p, T>
|
|||
/// This moves ownership over the pointer into the Py.
|
||||
/// Undefined behavior if the pointer is NULL or invalid.
|
||||
#[inline]
|
||||
pub unsafe fn from_owned_ptr(_py: Python<'p>, ptr: *mut ffi::PyObject) -> Py<'p, T> {
|
||||
pub unsafe fn from_owned_ptr(py: Token<'p>, ptr: *mut ffi::PyObject) -> Py<'p, T> {
|
||||
debug_assert!(!ptr.is_null() && ffi::Py_REFCNT(ptr) > 0);
|
||||
Py {inner: ptr, _t: PhantomData, _py: PhantomData}
|
||||
Py {inner: ptr, _t: PhantomData, py: py}
|
||||
}
|
||||
|
||||
/// Cast from ffi::PyObject ptr to a concrete object.
|
||||
#[inline]
|
||||
pub unsafe fn from_owned_ptr_or_panic(py: Python<'p>, ptr: *mut ffi::PyObject) -> Py<'p, T>
|
||||
pub unsafe fn from_owned_ptr_or_panic(py: Token<'p>, ptr: *mut ffi::PyObject) -> Py<'p, T>
|
||||
{
|
||||
if ptr.is_null() {
|
||||
::err::panic_after_error(py);
|
||||
::err::panic_after_error();
|
||||
} else {
|
||||
Py::from_owned_ptr(py, ptr)
|
||||
}
|
||||
|
@ -140,7 +197,7 @@ impl<'p, T> Py<'p, T>
|
|||
/// returns a new reference (owned pointer).
|
||||
/// Returns `Err(PyErr)` if the pointer is `null`.
|
||||
/// Unsafe because the pointer might be invalid.
|
||||
pub unsafe fn from_owned_ptr_or_err(py: Python<'p>, ptr: *mut ffi::PyObject)
|
||||
pub unsafe fn from_owned_ptr_or_err(py: Token<'p>, ptr: *mut ffi::PyObject)
|
||||
-> PyResult<Py<'p, T>>
|
||||
{
|
||||
if ptr.is_null() {
|
||||
|
@ -154,33 +211,26 @@ impl<'p, T> Py<'p, T>
|
|||
/// Calls Py_INCREF() on the ptr.
|
||||
/// Undefined behavior if the pointer is NULL or invalid.
|
||||
#[inline]
|
||||
pub unsafe fn from_borrowed_ptr(_py: Python<'p>, ptr: *mut ffi::PyObject) -> Py<'p, T> {
|
||||
pub unsafe fn from_borrowed_ptr(py: Token<'p>, ptr: *mut ffi::PyObject) -> Py<'p, T> {
|
||||
debug_assert!(!ptr.is_null() && ffi::Py_REFCNT(ptr) > 0);
|
||||
ffi::Py_INCREF(ptr);
|
||||
Py {inner: ptr, _t: PhantomData, _py: PhantomData}
|
||||
Py {inner: ptr, _t: PhantomData, py: py}
|
||||
}
|
||||
|
||||
/// 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>,
|
||||
pub unsafe fn from_borrowed_ptr_opt(py: Token<'p>,
|
||||
ptr: *mut ffi::PyObject) -> Option<Py<'p, T>> {
|
||||
if ptr.is_null() {
|
||||
None
|
||||
} else {
|
||||
debug_assert!(ffi::Py_REFCNT(ptr) > 0);
|
||||
ffi::Py_INCREF(ptr);
|
||||
Some(Py {inner: ptr, _t: PhantomData, _py: PhantomData})
|
||||
Some(Py {inner: ptr, _t: PhantomData, py: py})
|
||||
}
|
||||
}
|
||||
|
||||
/// Retrieve Python instance, the GIL is already acquired and
|
||||
/// stays acquired for the lifetime `'p`.
|
||||
#[inline]
|
||||
pub fn py(&self) -> Python<'p> {
|
||||
unsafe { Python::assume_gil_acquired() }
|
||||
}
|
||||
|
||||
/// Gets the reference count of this Py object.
|
||||
#[inline]
|
||||
pub fn get_refcnt(&self) -> usize {
|
||||
|
@ -209,24 +259,28 @@ impl<'p, T> Py<'p, T>
|
|||
/// Consumes `self` without calling `Py_DECREF()`
|
||||
#[inline]
|
||||
pub fn into_object(self) -> Py<'p, PyObject> {
|
||||
let p = Py {inner: self.inner, _t: PhantomData, _py: PhantomData};
|
||||
let p = Py {inner: self.inner, _t: PhantomData, py: self.py};
|
||||
std::mem::forget(self);
|
||||
p
|
||||
}
|
||||
|
||||
/// Unchecked downcast from other Py<S> to Self<T.
|
||||
/// Unchecked downcast from other Py<S> to Py<S>.
|
||||
/// Undefined behavior if the input object does not have the expected type.
|
||||
#[inline]
|
||||
pub unsafe fn unchecked_downcast_from<'a, S>(py: Py<'a, S>) -> Py<'a, T>
|
||||
pub unsafe fn unchecked_downcast_from<'a, S>(ob: Py<'a, S>) -> Py<'a, T>
|
||||
{
|
||||
let res = Py {inner: py.inner, _t: PhantomData, _py: PhantomData};
|
||||
std::mem::forget(py);
|
||||
let res = Py {inner: ob.inner, _t: PhantomData, py: ob.py};
|
||||
std::mem::forget(ob);
|
||||
res
|
||||
}
|
||||
|
||||
pub fn clone_ref(&self) -> Py<'p, T> {
|
||||
unsafe { ffi::Py_INCREF(self.inner) };
|
||||
Py {inner: self.inner, _t: self._t, _py: self._py}
|
||||
Py {inner: self.inner, _t: self._t, py: self.py}
|
||||
}
|
||||
|
||||
pub fn token<'a>(&'a self) -> Token<'p> {
|
||||
self.py
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -234,17 +288,17 @@ impl<'p, T> Py<'p, T>
|
|||
impl<'p, T> Py<'p, T> where T: PyTypeInfo
|
||||
{
|
||||
/// Create new python object and move T instance under python management
|
||||
pub fn new(py: Python<'p>, value: T) -> PyResult<Py<'p, T>> where T: PyObjectAlloc<Type=T>
|
||||
pub fn new(py: Token<'p>, value: T) -> PyResult<Py<'p, T>> where T: PyObjectAlloc<Type=T>
|
||||
{
|
||||
let ob = unsafe {
|
||||
try!(<T as PyObjectAlloc>::alloc(py, value))
|
||||
};
|
||||
Ok(Py{inner: ob, _t: PhantomData, _py: PhantomData})
|
||||
Ok(Py{inner: ob, _t: PhantomData, py: py})
|
||||
}
|
||||
|
||||
/// Cast from ffi::PyObject ptr to a concrete object.
|
||||
#[inline]
|
||||
pub fn cast_from_borrowed_ptr(py: Python<'p>, ptr: *mut ffi::PyObject)
|
||||
pub fn cast_from_borrowed_ptr(py: Token<'p>, ptr: *mut ffi::PyObject)
|
||||
-> Result<Py<'p, T>, ::PyDowncastError<'p>>
|
||||
{
|
||||
let checked = unsafe { ffi::PyObject_TypeCheck(ptr, T::type_object()) != 0 };
|
||||
|
@ -258,7 +312,7 @@ impl<'p, T> Py<'p, T> where T: PyTypeInfo
|
|||
|
||||
/// Cast from ffi::PyObject ptr to a concrete object.
|
||||
#[inline]
|
||||
pub fn cast_from_owned_ptr(py: Python<'p>, ptr: *mut ffi::PyObject)
|
||||
pub fn cast_from_owned_ptr(py: Token<'p>, ptr: *mut ffi::PyObject)
|
||||
-> Result<Py<'p, T>, ::PyDowncastError<'p>>
|
||||
{
|
||||
let checked = unsafe { ffi::PyObject_TypeCheck(ptr, T::type_object()) != 0 };
|
||||
|
@ -272,17 +326,17 @@ impl<'p, T> Py<'p, T> where T: PyTypeInfo
|
|||
|
||||
/// Cast from ffi::PyObject ptr to a concrete object.
|
||||
#[inline]
|
||||
pub unsafe fn cast_from_owned_ptr_or_panic(py: Python<'p>,
|
||||
pub unsafe fn cast_from_owned_ptr_or_panic(py: Token<'p>,
|
||||
ptr: *mut ffi::PyObject) -> Py<'p, T>
|
||||
{
|
||||
if ffi::PyObject_TypeCheck(ptr, T::type_object()) != 0 {
|
||||
Py::from_owned_ptr(py, ptr)
|
||||
} else {
|
||||
::err::panic_after_error(py);
|
||||
::err::panic_after_error();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cast_from_owned_nullptr(py: Python<'p>, ptr: *mut ffi::PyObject)
|
||||
pub fn cast_from_owned_nullptr(py: Token<'p>, ptr: *mut ffi::PyObject)
|
||||
-> PyResult<Py<'p, T>>
|
||||
{
|
||||
if ptr.is_null() {
|
||||
|
@ -322,7 +376,7 @@ impl<'p, T> Py<'p, T> where T: PyTypeInfo
|
|||
if checked {
|
||||
Ok( unsafe { Py::<D>::unchecked_downcast_from(self.clone_ref()) })
|
||||
} else {
|
||||
Err(PyDowncastError(self.py(), None))
|
||||
Err(PyDowncastError(self.py, None))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -330,13 +384,13 @@ impl<'p, T> Py<'p, T> where T: PyTypeInfo
|
|||
/// Fails with `PyDowncastError` if the object is not of the expected type.
|
||||
#[inline]
|
||||
pub fn cast_into<D>(self) -> Result<Py<'p, D>, PyDowncastError<'p>>
|
||||
where D: PyTypeInfo
|
||||
where D: 'p + PyTypeInfo
|
||||
{
|
||||
let checked = unsafe { ffi::PyObject_TypeCheck(self.inner, D::type_object()) != 0 };
|
||||
if checked {
|
||||
Ok( unsafe { Py::<D>::unchecked_downcast_from(self) })
|
||||
} else {
|
||||
Err(PyDowncastError(self.py(), None))
|
||||
Err(PyDowncastError(self.py, None))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -355,7 +409,7 @@ impl<'p, T> Py<'p, T> where T: PyTypeInfo
|
|||
let ptr = (self.inner as *mut u8).offset(offset) as *mut D;
|
||||
ptr.as_ref().unwrap() })
|
||||
} else {
|
||||
Err(PyDowncastError(self.py(), None))
|
||||
Err(PyDowncastError(self.token(), None))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -378,14 +432,11 @@ impl<'p, T> Py<'p, T> where T: PyTypeInfo
|
|||
}
|
||||
}
|
||||
|
||||
impl<'p, T> AsPy<'p> for Py<'p, T> {
|
||||
/// Retrieve Python instance, the GIL is already acquired and
|
||||
/// stays acquired for the lifetime `'p`.
|
||||
#[inline]
|
||||
fn py<'a>(&'a self) -> Python<'p> {
|
||||
unsafe { Python::assume_gil_acquired() }
|
||||
}
|
||||
}
|
||||
//impl<'p, T> PythonObjectWithToken for Py<'p, T> {
|
||||
// fn token(&self) -> Token {
|
||||
// self.py.token()
|
||||
// }
|
||||
//}
|
||||
|
||||
impl<'p, T> ToPythonPointer for Py<'p, T> {
|
||||
/// Gets the underlying FFI pointer, returns a borrowed pointer.
|
||||
|
@ -412,7 +463,9 @@ impl<'p, T> IntoPythonPointer for Py<'p, T> {
|
|||
impl<'p, T> Drop for Py<'p, T> {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
println!("drop Py: {:?} {}", self.inner, ffi::Py_REFCNT(self.inner));
|
||||
println!("drop Py: {:?} {} {:?}",
|
||||
self.inner,
|
||||
ffi::Py_REFCNT(self.inner), &self as *const _);
|
||||
}
|
||||
unsafe { ffi::Py_DECREF(self.inner); }
|
||||
}
|
||||
|
@ -423,7 +476,7 @@ impl<'p, T> Clone for Py<'p, T> {
|
|||
unsafe {
|
||||
debug_assert!(!self.inner.is_null() && ffi::Py_REFCNT(self.inner) > 0);
|
||||
ffi::Py_INCREF(self.inner);
|
||||
Py {inner: self.inner, _t: PhantomData, _py: PhantomData}
|
||||
Py {inner: self.inner, _t: PhantomData, py: self.py}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -476,9 +529,9 @@ impl<'source, T> ::FromPyObject<'source> for Py<'source, T> where T: PyTypeInfo
|
|||
{
|
||||
let checked = unsafe { ffi::PyObject_TypeCheck(py.inner, T::type_object()) != 0 };
|
||||
if checked {
|
||||
Ok( unsafe { Py::<T>::from_borrowed_ptr(py.py(), py.as_ptr()) })
|
||||
Ok( unsafe { Py::<T>::from_borrowed_ptr(py.token(), py.as_ptr()) })
|
||||
} else {
|
||||
Err(PyDowncastError(py.py(), None).into())
|
||||
Err(PyDowncastError(py.token(), None).into())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -486,12 +539,27 @@ impl<'source, T> ::FromPyObject<'source> for Py<'source, T> where T: PyTypeInfo
|
|||
impl <'a, T> ToPyObject for Py<'a, T> {
|
||||
|
||||
#[inline]
|
||||
default fn to_object<'p>(&self, py: Python<'p>) -> Py<'p, PyObject> {
|
||||
PyObject::from_owned_ptr(py, self.inner)
|
||||
default fn to_object<'p>(&self, py: Token) -> PyPtr<PyObject> {
|
||||
unsafe { PyPtr::from_borrowed_ptr(self.inner) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn with_borrowed_ptr<F, R>(&self, _py: Python, f: F) -> R
|
||||
fn with_borrowed_ptr<F, R>(&self, py: Token, f: F) -> R
|
||||
where F: FnOnce(*mut ffi::PyObject) -> R
|
||||
{
|
||||
f(self.inner)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> ToPyObject for PyPtr<T> {
|
||||
|
||||
#[inline]
|
||||
default fn to_object(&self, py: Token) -> PyPtr<PyObject> {
|
||||
unsafe { PyPtr::from_borrowed_ptr(self.inner) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn with_borrowed_ptr<F, R>(&self, py: Token, f: F) -> R
|
||||
where F: FnOnce(*mut ffi::PyObject) -> R
|
||||
{
|
||||
f(self.inner)
|
||||
|
@ -501,8 +569,10 @@ impl <'a, T> ToPyObject for Py<'a, T> {
|
|||
impl<'p, T> IntoPyObject for Py<'p, T> {
|
||||
|
||||
#[inline]
|
||||
default fn into_object<'a>(self, py: Python<'a>) -> Py<'a, PyObject> {
|
||||
PyObject::from_borrowed_ptr(py, self.inner)
|
||||
default fn into_object(self, py: Token) -> PyPtr<PyObject> {
|
||||
let ptr = unsafe { PyPtr::from_owned_ptr(self.inner) };
|
||||
std::mem::forget(self);
|
||||
ptr
|
||||
}
|
||||
}
|
||||
|
||||
|
|
152
src/python.rs
152
src/python.rs
|
@ -28,23 +28,46 @@ use pythonrun::GILGuard;
|
|||
#[derive(Copy, Clone)]
|
||||
pub struct Python<'p>(PhantomData<&'p GILGuard>);
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Token<'p>(PhantomData<&'p GILGuard>);
|
||||
|
||||
pub struct PythonToken<T>(PhantomData<T>);
|
||||
|
||||
|
||||
pub trait AsPy<'p> {
|
||||
fn py<'a>(&'a self) -> Python<'p>;
|
||||
pub trait PythonObjectWithToken : Sized {
|
||||
fn token<'p>(&'p self) -> Token<'p>;
|
||||
}
|
||||
|
||||
|
||||
pub trait PyClone : Sized {
|
||||
fn clone_ref(&self) -> PyPtr<Self>;
|
||||
}
|
||||
|
||||
impl<T> PyClone for T where T: ToPythonPointer {
|
||||
#[inline]
|
||||
fn clone_ref(&self) -> PyPtr<T> {
|
||||
unsafe {
|
||||
let ptr = <T as ToPythonPointer>::as_ptr(self);
|
||||
PyPtr::from_borrowed_ptr(ptr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// This trait allows retrieving the underlying FFI pointer from Python objects.
|
||||
pub trait ToPythonPointer {
|
||||
/// Retrieves the underlying FFI pointer (as a borrowed pointer).
|
||||
fn as_ptr(&self) -> *mut ffi::PyObject;
|
||||
|
||||
}
|
||||
|
||||
impl<'p, T> ToPythonPointer for T where T: PyTypeInfo + PythonObjectWithToken {
|
||||
#[inline]
|
||||
default fn as_ptr(&self) -> *mut ffi::PyObject {
|
||||
let offset = <T as PyTypeInfo>::offset();
|
||||
unsafe {
|
||||
{self as *const _ as *mut u8}.offset(-offset) as *mut ffi::PyObject
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// This trait allows retrieving the underlying FFI pointer from Python objects.
|
||||
|
@ -56,7 +79,18 @@ pub trait IntoPythonPointer {
|
|||
|
||||
|
||||
/// Convert None into a null pointer.
|
||||
impl <T> ToPythonPointer for Option<T> where T: ToPythonPointer {
|
||||
/*impl <T> ToPythonPointer for Option<T> where T: ToPythonPointer {
|
||||
#[inline]
|
||||
fn as_ptr(&self) -> *mut ffi::PyObject {
|
||||
match *self {
|
||||
Some(ref t) => t.as_ptr(),
|
||||
None => std::ptr::null_mut()
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
/// Convert None into a null pointer.
|
||||
impl<'p, T> ToPythonPointer for Option<&'p T> where T: ToPythonPointer {
|
||||
#[inline]
|
||||
fn as_ptr(&self) -> *mut ffi::PyObject {
|
||||
match *self {
|
||||
|
@ -116,7 +150,7 @@ impl<'p> Python<'p> {
|
|||
/// If `globals` is `None`, it defaults to Python module `__main__`.
|
||||
/// If `locals` is `None`, it defaults to the value of `globals`.
|
||||
pub fn eval(self, code: &str, globals: Option<&PyDict>,
|
||||
locals: Option<&PyDict>) -> PyResult<Py<'p, PyObject>> {
|
||||
locals: Option<&PyDict>) -> PyResult<PyPtr<PyObject>> {
|
||||
self.run_code(code, ffi::Py_eval_input, globals, locals)
|
||||
}
|
||||
|
||||
|
@ -137,13 +171,13 @@ impl<'p> Python<'p> {
|
|||
/// If `globals` is `None`, it defaults to Python module `__main__`.
|
||||
/// If `locals` is `None`, it defaults to the value of `globals`.
|
||||
fn run_code(self, code: &str, start: c_int,
|
||||
globals: Option<&PyDict>, locals: Option<&PyDict>) -> PyResult<Py<'p, PyObject>> {
|
||||
globals: Option<&PyDict>, locals: Option<&PyDict>) -> PyResult<PyPtr<PyObject>> {
|
||||
let code = CString::new(code).unwrap();
|
||||
|
||||
unsafe {
|
||||
let mptr = ffi::PyImport_AddModule("__main__\0".as_ptr() as *const _);
|
||||
if mptr.is_null() {
|
||||
return Err(PyErr::fetch(self));
|
||||
return Err(PyErr::fetch(self.token()));
|
||||
}
|
||||
|
||||
let mdict = ffi::PyModule_GetDict(mptr);
|
||||
|
@ -161,75 +195,58 @@ impl<'p> Python<'p> {
|
|||
let res_ptr = ffi::PyRun_StringFlags(code.as_ptr(),
|
||||
start, globals, locals, 0 as *mut _);
|
||||
|
||||
Py::from_owned_ptr_or_err(self, res_ptr)
|
||||
PyPtr::from_owned_ptr_or_err(self.token(), res_ptr)
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets the Python builtin value `None`.
|
||||
#[allow(non_snake_case)] // the Python keyword starts with uppercase
|
||||
#[inline]
|
||||
pub fn None(self) -> Py<'p, PyObject> {
|
||||
unsafe { PyObject::from_borrowed_ptr(self, ffi::Py_None()) }
|
||||
}
|
||||
|
||||
/// Gets the Python builtin value `True`.
|
||||
#[allow(non_snake_case)] // the Python keyword starts with uppercase
|
||||
#[inline]
|
||||
pub fn True(self) -> Py<'p, PyBool> {
|
||||
unsafe { Py::from_borrowed_ptr(self, ffi::Py_True()) }
|
||||
}
|
||||
|
||||
/// Gets the Python builtin value `False`.
|
||||
#[allow(non_snake_case)] // the Python keyword starts with uppercase
|
||||
#[inline]
|
||||
pub fn False(self) -> Py<'p, PyBool> {
|
||||
unsafe { Py::from_borrowed_ptr(self, ffi::Py_False()) }
|
||||
}
|
||||
|
||||
/// Gets the Python builtin value `NotImplemented`.
|
||||
#[allow(non_snake_case)] // the Python keyword starts with uppercase
|
||||
#[inline]
|
||||
pub fn NotImplemented(self) -> Py<'p, PyObject> {
|
||||
unsafe { PyObject::from_borrowed_ptr(self, ffi::Py_NotImplemented()) }
|
||||
}
|
||||
|
||||
/// Gets the Python type object for type T.
|
||||
pub fn get_type<T>(self) -> Py<'p, PyType> where T: PyTypeObject {
|
||||
T::type_object(self)
|
||||
}
|
||||
|
||||
/// Gets the Python type object for type T.
|
||||
pub fn get_ptype<T>(self) -> PyPtr<PyType> where T: PyTypeObject {
|
||||
T::type_object(self).into_pptr()
|
||||
pub fn get_type<T>(self) -> PyPtr<PyType> where T: PyTypeObject {
|
||||
T::type_object(self.token())
|
||||
}
|
||||
|
||||
/// Import the Python module with the specified name.
|
||||
pub fn import(self, name : &str) -> PyResult<Py<'p, PyModule>> {
|
||||
PyModule::import(self, name)
|
||||
PyModule::import(self.token(), name)
|
||||
}
|
||||
|
||||
pub fn with_token<T, F>(self, f: F) -> Py<'p, T>
|
||||
pub fn with_token<T, F>(self, f: F) -> PyPtr<T>
|
||||
where F: FnOnce(PythonToken<T>) -> T,
|
||||
T: PyTypeInfo + PyObjectAlloc<Type=T>
|
||||
{
|
||||
let value = f(PythonToken(PhantomData));
|
||||
Py::new(self, value).unwrap()
|
||||
if let Ok(ob) = Py::new(self.token(), value) {
|
||||
println!("created: {:?}", &ob as *const _);
|
||||
ob.into_pptr()
|
||||
} else {
|
||||
::err::panic_after_error()
|
||||
}
|
||||
}
|
||||
//}
|
||||
|
||||
//impl<'p> PythonObjectWithToken<'p> for Python<'p> {
|
||||
pub fn token(self) -> Token<'p> {
|
||||
Token(PhantomData)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> PythonToken<T> {
|
||||
pub fn token(&self) -> Token {
|
||||
Token(PhantomData)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'p> Token<'p> {
|
||||
/// Gets the Python builtin value `None`.
|
||||
#[allow(non_snake_case)] // the Python keyword starts with uppercase
|
||||
#[inline]
|
||||
pub fn None(&self) -> PyPtr<PyObject> {
|
||||
pub fn None(self) -> PyPtr<PyObject> {
|
||||
unsafe { PyPtr::from_borrowed_ptr(ffi::Py_None()) }
|
||||
}
|
||||
|
||||
/// Gets the Python builtin value `True`.
|
||||
#[allow(non_snake_case)] // the Python keyword starts with uppercase
|
||||
#[inline]
|
||||
pub fn True(&self) -> PyPtr<PyBool> {
|
||||
pub fn True(self) -> PyPtr<PyBool> {
|
||||
unsafe { PyPtr::from_borrowed_ptr(ffi::Py_True()) }
|
||||
}
|
||||
|
||||
|
@ -243,33 +260,52 @@ impl<T> PythonToken<T> {
|
|||
/// Gets the Python builtin value `NotImplemented`.
|
||||
#[allow(non_snake_case)] // the Python keyword starts with uppercase
|
||||
#[inline]
|
||||
pub fn NotImplemented(&self) -> PyPtr<PyObject> {
|
||||
pub fn NotImplemented(self) -> PyPtr<PyObject> {
|
||||
unsafe { PyPtr::from_borrowed_ptr(ffi::Py_NotImplemented()) }
|
||||
}
|
||||
|
||||
/// Gets the Python type object for type T.
|
||||
pub fn get_type<U>(&self) -> PyPtr<PyType> where U: PyTypeObject {
|
||||
U::type_object(Python(PhantomData)).into_pptr()
|
||||
#[inline]
|
||||
pub fn get_type<U>(self) -> PyPtr<PyType> where U: PyTypeObject {
|
||||
U::type_object(self)
|
||||
}
|
||||
|
||||
/// Execute closure `F` with Python instance.
|
||||
/// Retrieve Python instance under the assumption that the GIL is already acquired
|
||||
/// at this point, and stays acquired during closure call.
|
||||
pub fn with<'p, F>(&self, f: F) where F: FnOnce(Python<'p>)
|
||||
pub fn with<F, R>(self, f: F) -> R where F: FnOnce(Python<'p>) -> R
|
||||
{
|
||||
f(Python(PhantomData))
|
||||
}
|
||||
|
||||
pub fn with_token<P, F>(&self, f: F) -> PyPtr<P>
|
||||
where F: FnOnce(PythonToken<P>) -> P,
|
||||
P: PyTypeInfo + PyObjectAlloc<Type=P>
|
||||
/// Convert raw pointer into referece
|
||||
#[inline]
|
||||
pub unsafe fn from_owned_ptr<P>(self, ptr: *mut ffi::PyObject) -> &'p P
|
||||
{
|
||||
let value = f(PythonToken(PhantomData));
|
||||
Py::new(Python(PhantomData), value).unwrap().into_pptr()
|
||||
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)]
|
||||
mod test {
|
||||
use {Python, PyDict};
|
||||
|
|
|
@ -7,8 +7,8 @@ use std::collections::HashMap;
|
|||
|
||||
use {ffi, class};
|
||||
use err::{PyErr, PyResult};
|
||||
use pyptr::Py;
|
||||
use python::Python;
|
||||
use pyptr::{Py, PyPtr};
|
||||
use python::{Python, PythonObjectWithToken, Token};
|
||||
use objects::PyType;
|
||||
use callback::AbortOnDrop;
|
||||
use class::methods::PyMethodDefType;
|
||||
|
@ -92,12 +92,12 @@ pub trait PyObjectAlloc {
|
|||
/// and initializes it using init_val.
|
||||
/// `ty` must be derived from the Self type, and the resulting object
|
||||
/// must be of type `ty`.
|
||||
unsafe fn alloc(_py: Python, value: Self::Type) -> PyResult<*mut ffi::PyObject>;
|
||||
unsafe fn alloc(py: Token, value: Self::Type) -> PyResult<*mut ffi::PyObject>;
|
||||
|
||||
/// Calls the rust destructor for the object and frees the memory
|
||||
/// (usually by calling ptr->ob_type->tp_free).
|
||||
/// This function is used as tp_dealloc implementation.
|
||||
unsafe fn dealloc(_py: Python, obj: *mut ffi::PyObject);
|
||||
unsafe fn dealloc(py: Token, obj: *mut ffi::PyObject);
|
||||
}
|
||||
|
||||
/// A PythonObject that is usable as a base type for #[class]
|
||||
|
@ -108,13 +108,16 @@ impl<T> PyObjectAlloc for T where T : PyTypeInfo {
|
|||
/// and initializes it using init_val.
|
||||
/// `ty` must be derived from the Self type, and the resulting object
|
||||
/// must be of type `ty`.
|
||||
unsafe fn alloc(_py: Python, value: T::Type) -> PyResult<*mut ffi::PyObject> {
|
||||
let _ = <T as PyTypeObject>::type_object(_py);
|
||||
unsafe fn alloc(py: Token, value: T::Type) -> PyResult<*mut ffi::PyObject> {
|
||||
let _ = <T as PyTypeObject>::type_object(py);
|
||||
|
||||
let obj = ffi::PyType_GenericAlloc(
|
||||
<Self as PyTypeInfo>::type_object(), 0);
|
||||
|
||||
let offset = <Self as PyTypeInfo>::offset();
|
||||
println!("alloc {} {:?} {} {}", offset, obj, <Self as PyTypeInfo>::size(),
|
||||
<Self as PyTypeInfo>::type_object().tp_basicsize);
|
||||
|
||||
let ptr = (obj as *mut u8).offset(offset) as *mut Self::Type;
|
||||
std::ptr::write(ptr, value);
|
||||
|
||||
|
@ -124,7 +127,7 @@ impl<T> PyObjectAlloc for T where T : PyTypeInfo {
|
|||
/// Calls the rust destructor for the object and frees the memory
|
||||
/// (usually by calling ptr->ob_type->tp_free).
|
||||
/// This function is used as tp_dealloc implementation.
|
||||
unsafe fn dealloc(_py: Python, obj: *mut ffi::PyObject) {
|
||||
unsafe fn dealloc(py: Token, obj: *mut ffi::PyObject) {
|
||||
let ptr = (obj as *mut u8).offset(
|
||||
<Self as PyTypeInfo>::offset() as isize) as *mut Self::Type;
|
||||
std::ptr::drop_in_place(ptr);
|
||||
|
@ -147,14 +150,14 @@ impl<T> PyObjectAlloc for T where T : PyTypeInfo {
|
|||
pub trait PyTypeObject {
|
||||
|
||||
/// Retrieves the type object for this Python object type.
|
||||
fn type_object<'p>(py: Python<'p>) -> Py<'p, PyType>;
|
||||
fn type_object(py: Token) -> PyPtr<PyType>;
|
||||
|
||||
}
|
||||
|
||||
impl<T> PyTypeObject for T where T: PyObjectAlloc + PyTypeInfo {
|
||||
|
||||
#[inline]
|
||||
fn type_object<'p>(py: Python<'p>) -> Py<'p, PyType> {
|
||||
fn type_object<'p>(py: Token) -> PyPtr<PyType> {
|
||||
let mut ty = <T as PyTypeInfo>::type_object();
|
||||
|
||||
if (ty.tp_flags & ffi::Py_TPFLAGS_READY) != 0 {
|
||||
|
@ -169,10 +172,11 @@ impl<T> PyTypeObject for T where T: PyObjectAlloc + PyTypeInfo {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn initialize_type<'p, T>(py: Python<'p>, module_name: Option<&str>, type_name: &str,
|
||||
type_object: &mut ffi::PyTypeObject) -> PyResult<Py<'p, PyType>>
|
||||
pub fn initialize_type<'p, T>(py: Token, module_name: Option<&str>, type_name: &str,
|
||||
type_object: &mut ffi::PyTypeObject) -> PyResult<PyPtr<PyType>>
|
||||
where T: PyObjectAlloc + PyTypeInfo
|
||||
{
|
||||
println!("=========== init type");
|
||||
// type name
|
||||
let name = match module_name {
|
||||
Some(module_name) => CString::new(format!("{}.{}", module_name, type_name)),
|
||||
|
@ -298,7 +302,7 @@ unsafe extern "C" fn tp_dealloc_callback<T>(obj: *mut ffi::PyObject)
|
|||
println!("DEALLOC: {:?}", obj);
|
||||
let guard = AbortOnDrop("Cannot unwind out of tp_dealloc");
|
||||
let py = Python::assume_gil_acquired();
|
||||
let r = <T as PyObjectAlloc>::dealloc(py, obj);
|
||||
let r = <T as PyObjectAlloc>::dealloc(py.token(), obj);
|
||||
mem::forget(guard);
|
||||
r
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue