Refactor implementation. Drop parameter from constructor
This commit is contained in:
parent
86252cda4c
commit
a120bbf15e
|
@ -1,13 +1,15 @@
|
|||
Changes
|
||||
-------
|
||||
|
||||
0.1.x (xx-xx-2017)
|
||||
0.2.x (xx-xx-2017)
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
* Added weakref support #56
|
||||
|
||||
* Allow to add gc support without implementing PyGCProtocol #57
|
||||
|
||||
* Refactor `PyErr` implementation. Drop `py` parameter from constructor.
|
||||
|
||||
|
||||
0.1.0 (07-23-2017)
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "pyo3"
|
||||
version = "0.1.1"
|
||||
version = "0.2.0"
|
||||
description = "Bindings to Python"
|
||||
authors = ["PyO3 Project and Contributors <https://github.com/PyO3"]
|
||||
readme = "README.md"
|
||||
|
|
|
@ -64,6 +64,8 @@ fn impl_class(cls: &syn::Ident, base: &syn::Ident,
|
|||
fn to_object<'p>(&self, py: _pyo3::Python<'p>) -> _pyo3::PyObject {
|
||||
unsafe { _pyo3::PyObject::from_borrowed_ptr(py, self.as_ptr()) }
|
||||
}
|
||||
}
|
||||
impl _pyo3::ToBorrowedObject for #cls {
|
||||
#[inline]
|
||||
fn with_borrowed_ptr<F, R>(&self, _py: _pyo3::Python, f: F) -> R
|
||||
where F: FnOnce(*mut ffi::PyObject) -> R
|
||||
|
@ -76,6 +78,8 @@ fn impl_class(cls: &syn::Ident, base: &syn::Ident,
|
|||
fn to_object<'p>(&self, py: _pyo3::Python<'p>) -> _pyo3::PyObject {
|
||||
unsafe { _pyo3::PyObject::from_borrowed_ptr(py, self.as_ptr()) }
|
||||
}
|
||||
}
|
||||
impl<'a> _pyo3::ToBorrowedObject for &'a mut #cls {
|
||||
#[inline]
|
||||
fn with_borrowed_ptr<F, R>(&self, _py: _pyo3::Python, f: F) -> R
|
||||
where F: FnOnce(*mut ffi::PyObject) -> R
|
||||
|
|
|
@ -358,7 +358,7 @@ pub fn impl_arg_params(spec: &FnSpec, body: Tokens) -> Tokens {
|
|||
];
|
||||
|
||||
let mut _output = [#(#placeholders),*];
|
||||
match _pyo3::argparse::parse_args(_py, Some(_LOCATION), _PARAMS, &_args,
|
||||
match _pyo3::argparse::parse_args(Some(_LOCATION), _PARAMS, &_args,
|
||||
_kwargs, #accept_args, #accept_kwargs, &mut _output)
|
||||
{
|
||||
Ok(_) => {
|
||||
|
|
|
@ -28,8 +28,7 @@ pub struct ParamDescription<'a> {
|
|||
/// * kwargs: Keyword arguments
|
||||
/// * output: Output array that receives the arguments.
|
||||
/// 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],
|
||||
pub fn parse_args<'p>(fname: Option<&str>, params: &[ParamDescription],
|
||||
args: &'p PyTuple, kwargs: Option<&'p PyDict>,
|
||||
accept_args: bool, accept_kwargs: bool,
|
||||
output: &mut[Option<&'p PyObjectRef>]) -> PyResult<()>
|
||||
|
@ -40,7 +39,6 @@ pub fn parse_args<'p>(py: Python<'p>,
|
|||
let nkeywords = kwargs.map_or(0, |d| d.len());
|
||||
if !accept_args && (nargs + nkeywords > params.len()) {
|
||||
return Err(err::PyErr::new::<exc::TypeError, _>(
|
||||
py,
|
||||
format!("{}{} takes at most {} argument{} ({} given)",
|
||||
fname.unwrap_or("function"),
|
||||
if fname.is_some() { "()" } else { "" },
|
||||
|
@ -58,7 +56,6 @@ pub fn parse_args<'p>(py: Python<'p>,
|
|||
used_keywords += 1;
|
||||
if i < nargs {
|
||||
return Err(err::PyErr::new::<exc::TypeError, _>(
|
||||
py,
|
||||
format!("Argument given by name ('{}') and position ({})", p.name, i+1)));
|
||||
}
|
||||
},
|
||||
|
@ -66,8 +63,7 @@ pub fn parse_args<'p>(py: Python<'p>,
|
|||
if p.kw_only {
|
||||
if !p.is_optional {
|
||||
return Err(err::PyErr::new::<exc::TypeError, _>(
|
||||
py, format!(
|
||||
"Required argument ('{}') is keyword only argument", p.name)));
|
||||
format!("Required argument ('{}') is keyword only argument", p.name)));
|
||||
}
|
||||
*out = None;
|
||||
}
|
||||
|
@ -77,9 +73,7 @@ pub fn parse_args<'p>(py: Python<'p>,
|
|||
*out = None;
|
||||
if !p.is_optional {
|
||||
return Err(err::PyErr::new::<exc::TypeError, _>(
|
||||
py,
|
||||
format!("Required argument ('{}') (pos {}) not found",
|
||||
p.name, i+1)));
|
||||
format!("Required argument ('{}') (pos {}) not found", p.name, i+1)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -92,7 +86,6 @@ pub fn parse_args<'p>(py: Python<'p>,
|
|||
let key = PyString::downcast_from(item.get_item(0))?.to_string()?;
|
||||
if !params.iter().any(|p| p.name == key) {
|
||||
return Err(err::PyErr::new::<exc::TypeError, _>(
|
||||
py,
|
||||
format!("'{}' is an invalid keyword argument for this function", key)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -394,10 +394,10 @@ impl PyBuffer {
|
|||
|
||||
fn copy_to_slice_impl<T: Element+Copy>(&self, py: Python, target: &mut [T], fort: u8) -> PyResult<()> {
|
||||
if mem::size_of_val(target) != self.len_bytes() {
|
||||
return slice_length_error(py);
|
||||
return slice_length_error();
|
||||
}
|
||||
if !T::is_compatible_format(self.format()) || mem::size_of::<T>() != self.item_size() {
|
||||
return incompatible_format_error(py);
|
||||
return incompatible_format_error();
|
||||
}
|
||||
unsafe {
|
||||
err::error_on_minusone(py, ffi::PyBuffer_ToContiguous(
|
||||
|
@ -427,7 +427,7 @@ impl PyBuffer {
|
|||
|
||||
fn to_vec_impl<T: Element+Copy>(&self, py: Python, fort: u8) -> PyResult<Vec<T>> {
|
||||
if !T::is_compatible_format(self.format()) || mem::size_of::<T>() != self.item_size() {
|
||||
incompatible_format_error(py)?;
|
||||
incompatible_format_error()?;
|
||||
unreachable!();
|
||||
}
|
||||
let item_count = self.item_count();
|
||||
|
@ -477,13 +477,13 @@ impl PyBuffer {
|
|||
|
||||
fn copy_from_slice_impl<T: Element+Copy>(&self, py: Python, source: &[T], fort: u8) -> PyResult<()> {
|
||||
if self.readonly() {
|
||||
return buffer_readonly_error(py);
|
||||
return buffer_readonly_error();
|
||||
}
|
||||
if mem::size_of_val(source) != self.len_bytes() {
|
||||
return slice_length_error(py);
|
||||
return slice_length_error();
|
||||
}
|
||||
if !T::is_compatible_format(self.format()) || mem::size_of::<T>() != self.item_size() {
|
||||
return incompatible_format_error(py);
|
||||
return incompatible_format_error();
|
||||
}
|
||||
unsafe {
|
||||
err::error_on_minusone(py, ffi::PyBuffer_FromContiguous(
|
||||
|
@ -504,19 +504,16 @@ impl PyBuffer {
|
|||
}
|
||||
}
|
||||
|
||||
fn slice_length_error(py: Python) -> PyResult<()> {
|
||||
Err(err::PyErr::new::<exc::BufferError, _>(
|
||||
py, "Slice length does not match buffer length."))
|
||||
fn slice_length_error() -> PyResult<()> {
|
||||
Err(err::PyErr::new::<exc::BufferError, _>("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."))
|
||||
fn incompatible_format_error() -> PyResult<()> {
|
||||
Err(err::PyErr::new::<exc::BufferError, _>("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."))
|
||||
fn buffer_readonly_error() -> PyResult<()> {
|
||||
Err(err::PyErr::new::<exc::BufferError, _>("Cannot write to read-only buffer."))
|
||||
}
|
||||
|
||||
impl Drop for PyBuffer {
|
||||
|
|
|
@ -5,11 +5,11 @@
|
|||
use std::os::raw::c_int;
|
||||
use std::{any, ptr, isize};
|
||||
|
||||
use python::{Python, IntoPyPointer};
|
||||
use objects::exc;
|
||||
use conversion::IntoPyObject;
|
||||
use err::PyResult;
|
||||
use ffi::{self, Py_hash_t};
|
||||
use err::{PyErr, PyResult};
|
||||
use python::{Python, IntoPyPointer};
|
||||
use objects::exc::OverflowError;
|
||||
use conversion::IntoPyObject;
|
||||
|
||||
|
||||
pub trait CallbackConverter<S> {
|
||||
|
@ -62,8 +62,7 @@ impl CallbackConverter<usize> for LenResultConverter {
|
|||
if val <= (isize::MAX as usize) {
|
||||
val as isize
|
||||
} else {
|
||||
PyErr::new_lazy_init(
|
||||
py.get_type::<exc::OverflowError>(), None).restore(py);
|
||||
OverflowError::new(()).restore(py);
|
||||
-1
|
||||
}
|
||||
}
|
||||
|
|
|
@ -365,7 +365,7 @@ impl<T> PyObjectRichcmpProtocolImpl for T
|
|||
let slf = py.cast_from_borrowed_ptr::<T>(slf);
|
||||
let arg = py.cast_from_borrowed_ptr::<PyObjectRef>(arg);
|
||||
|
||||
let res = match extract_op(py, op) {
|
||||
let res = match extract_op(op) {
|
||||
Ok(op) => match arg.extract() {
|
||||
Ok(arg) =>
|
||||
slf.__richcmp__(arg, op).into(),
|
||||
|
@ -388,7 +388,7 @@ impl<T> PyObjectRichcmpProtocolImpl for T
|
|||
}
|
||||
|
||||
|
||||
fn extract_op(py: Python, op: c_int) -> PyResult<CompareOp> {
|
||||
fn extract_op(op: c_int) -> PyResult<CompareOp> {
|
||||
match op {
|
||||
ffi::Py_LT => Ok(CompareOp::Lt),
|
||||
ffi::Py_LE => Ok(CompareOp::Le),
|
||||
|
@ -396,8 +396,7 @@ fn extract_op(py: Python, op: c_int) -> PyResult<CompareOp> {
|
|||
ffi::Py_NE => Ok(CompareOp::Ne),
|
||||
ffi::Py_GT => Ok(CompareOp::Gt),
|
||||
ffi::Py_GE => Ok(CompareOp::Ge),
|
||||
_ => Err(PyErr::new_lazy_init(
|
||||
py.get_type::<exc::ValueError>(),
|
||||
Some("tp_richcompare called with invalid comparison operator".into_object(py))))
|
||||
_ => Err(PyErr::new::<exc::ValueError, _>(
|
||||
"tp_richcompare called with invalid comparison operator"))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -294,7 +294,7 @@ macro_rules! py_func_set{
|
|||
|
||||
if value.is_null() {
|
||||
let e = $crate::PyErr::new::<exc::NotImplementedError, _>(
|
||||
py, format!("Subscript deletion not supported by {:?}", stringify!(T)));
|
||||
format!("Subscript deletion not supported by {:?}", stringify!(T)));
|
||||
e.restore(py);
|
||||
-1
|
||||
} else {
|
||||
|
@ -356,8 +356,7 @@ macro_rules! py_func_del{
|
|||
}
|
||||
} else {
|
||||
let e = PyErr::new::<exc::NotImplementedError, _>(
|
||||
py, format!("Subscript assignment not supported by {:?}",
|
||||
stringify!(T)));
|
||||
format!("Subscript assignment not supported by {:?}", stringify!(T)));
|
||||
e.restore(py);
|
||||
-1
|
||||
}
|
||||
|
|
|
@ -222,7 +222,6 @@ impl<T> PySequenceSetItemProtocolImpl for T
|
|||
|
||||
if value.is_null() {
|
||||
let e = PyErr::new::<exc::NotImplementedError, _>(
|
||||
py,
|
||||
format!("Item deletion not supported by {:?}", stringify!(T)));
|
||||
e.restore(py);
|
||||
-1
|
||||
|
@ -283,7 +282,7 @@ impl<T> PySequenceDelItemProtocolImpl for T
|
|||
}
|
||||
} else {
|
||||
let e = PyErr::new::<exc::NotImplementedError, _>(
|
||||
py, format!("Item assignment not supported by {:?}", stringify!(T)));
|
||||
format!("Item assignment not supported by {:?}", stringify!(T)));
|
||||
e.restore(py);
|
||||
-1
|
||||
}
|
||||
|
|
|
@ -16,13 +16,23 @@ pub trait ToPyObject {
|
|||
/// Converts self into a Python object.
|
||||
fn to_object(&self, py: Python) -> PyObject;
|
||||
|
||||
}
|
||||
|
||||
pub trait ToBorrowedObject: ToPyObject {
|
||||
|
||||
/// Converts self into a Python object and calls the specified closure
|
||||
/// on the native FFI pointer underlying the Python object.
|
||||
///
|
||||
/// May be more efficient than `to_py_object` because it does not need
|
||||
/// May be more efficient than `to_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
|
||||
where F: FnOnce(*mut ffi::PyObject) -> R;
|
||||
}
|
||||
|
||||
impl<T> ToBorrowedObject for T where T: ToPyObject {
|
||||
#[inline]
|
||||
default fn with_borrowed_ptr<F, R>(&self, py: Python, f: F) -> R
|
||||
where F: FnOnce(*mut ffi::PyObject) -> R
|
||||
{
|
||||
let obj = self.to_object(py);
|
||||
|
@ -38,14 +48,16 @@ pub trait IntoPyObject {
|
|||
|
||||
/// Converts self into a Python object. (Consumes self)
|
||||
#[inline]
|
||||
fn into_object(self, py: Python) -> PyObject
|
||||
where Self: Sized;
|
||||
fn into_object(self, py: Python) -> PyObject;
|
||||
}
|
||||
|
||||
|
||||
/// Conversion trait that allows various objects to be converted into `PyTuple` object.
|
||||
pub trait IntoPyTuple {
|
||||
|
||||
/// Converts self into a PyTuple object.
|
||||
fn to_tuple(&self, py: Python) -> Py<PyTuple>;
|
||||
|
||||
/// Converts self into a PyTuple object.
|
||||
fn into_tuple(self, py: Python) -> Py<PyTuple>;
|
||||
|
||||
|
@ -104,12 +116,15 @@ impl <'a, T: ?Sized> ToPyObject for &'a T where T: ToPyObject {
|
|||
fn to_object(&self, py: Python) -> PyObject {
|
||||
<T as ToPyObject>::to_object(*self, py)
|
||||
}
|
||||
}
|
||||
|
||||
impl <'a, T: ?Sized> ToBorrowedObject for &'a T where T: ToBorrowedObject {
|
||||
|
||||
#[inline]
|
||||
fn with_borrowed_ptr<F, R>(&self, py: Python, f: F) -> R
|
||||
where F: FnOnce(*mut ffi::PyObject) -> R
|
||||
{
|
||||
<T as ToPyObject>::with_borrowed_ptr(*self, py, f)
|
||||
<T as ToBorrowedObject>::with_borrowed_ptr(*self, py, f)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
295
src/err.rs
295
src/err.rs
|
@ -12,7 +12,7 @@ use PyObject;
|
|||
use objects::{PyObjectRef, PyType, exc};
|
||||
use instance::Py;
|
||||
use typeob::PyTypeObject;
|
||||
use conversion::{ToPyObject, IntoPyTuple, IntoPyObject};
|
||||
use conversion::{ToPyObject, ToBorrowedObject, IntoPyTuple};
|
||||
|
||||
/**
|
||||
Defines a new exception type.
|
||||
|
@ -49,11 +49,15 @@ macro_rules! py_exception {
|
|||
($module: ident, $name: ident, $base: ty) => {
|
||||
pub struct $name;
|
||||
|
||||
// pyobject_nativetype!($name);
|
||||
impl std::convert::From<$name> for $crate::PyErr {
|
||||
fn from(_err: $name) -> $crate::PyErr {
|
||||
$crate::PyErr::new::<$name, _>(())
|
||||
}
|
||||
}
|
||||
|
||||
impl $name {
|
||||
pub fn new<T: $crate::IntoPyObject>(py: $crate::Python, args: T) -> $crate::PyErr {
|
||||
$crate::PyErr::new::<$name, T>(py, args)
|
||||
pub fn new<T: $crate::ToPyObject + 'static>(args: T) -> $crate::PyErr {
|
||||
$crate::PyErr::new::<$name, T>(args)
|
||||
}
|
||||
#[inline(always)]
|
||||
fn type_object() -> *mut $crate::ffi::PyTypeObject {
|
||||
|
@ -95,8 +99,16 @@ macro_rules! py_exception {
|
|||
}
|
||||
}
|
||||
|
||||
/// Represents a PyErr value
|
||||
pub enum PyErrValue {
|
||||
None,
|
||||
Value(PyObject),
|
||||
ToErr(Box<ToPyErr>),
|
||||
ToObject(Box<ToPyObject>),
|
||||
ToTuple(Box<IntoPyTuple>),
|
||||
}
|
||||
|
||||
/// Represents a Python exception that was raised.
|
||||
#[derive(Debug)]
|
||||
pub struct PyErr {
|
||||
/// The type of the exception. This should be either a `PyClass` or a `PyType`.
|
||||
pub ptype: Py<PyType>,
|
||||
|
@ -106,7 +118,7 @@ pub struct PyErr {
|
|||
/// a tuple of arguments to be passed to `ptype`'s constructor,
|
||||
/// or a single argument to be passed to `ptype`'s constructor.
|
||||
/// Call `PyErr::instance()` to get the exception instance in all cases.
|
||||
pub pvalue: Option<PyObject>,
|
||||
pub pvalue: PyErrValue,
|
||||
/// The `PyTraceBack` object associated with the error.
|
||||
pub ptraceback: Option<PyObject>,
|
||||
}
|
||||
|
@ -117,7 +129,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;
|
||||
|
||||
|
||||
impl PyErr {
|
||||
|
@ -131,11 +143,46 @@ impl PyErr {
|
|||
/// Panics if `T` is not a python class derived from `BaseException`.
|
||||
///
|
||||
/// Example:
|
||||
/// `return Err(PyErr::new::<exc::TypeError, _>(py, "Error message"));`
|
||||
pub fn new<T, V>(py: Python, value: V) -> PyErr
|
||||
where T: PyTypeObject, V: IntoPyObject
|
||||
/// `return Err(PyErr::new::<exc::TypeError, _>("Error message"));`
|
||||
pub fn new<T, V>(value: V) -> PyErr
|
||||
where T: PyTypeObject, V: ToPyObject + 'static
|
||||
{
|
||||
PyErr::new_helper(py, py.get_type::<T>(), value.into_object(py))
|
||||
let ty = T::type_object();
|
||||
assert_ne!(unsafe { ffi::PyExceptionClass_Check(ty.as_ptr()) }, 0);
|
||||
|
||||
PyErr {
|
||||
ptype: ty,
|
||||
pvalue: PyErrValue::ToObject(Box::new(value)),
|
||||
ptraceback: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Construct a new error, with the usual lazy initialization of Python exceptions.
|
||||
/// `exc` is the exception type; usually one of the standard exceptions
|
||||
/// like `exc::RuntimeError::type_info()`.
|
||||
/// `args` is the a tuple of arguments to pass to the exception constructor.
|
||||
pub fn from_type<A>(exc: Py<PyType>, args: A) -> PyErr
|
||||
where A: IntoPyTuple + 'static
|
||||
{
|
||||
PyErr {
|
||||
ptype: exc,
|
||||
pvalue: PyErrValue::ToTuple(Box::new(args)),
|
||||
ptraceback: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new PyErr of type `T`.
|
||||
pub fn from_value<T>(value: PyErrValue) -> PyErr
|
||||
where T: PyTypeObject
|
||||
{
|
||||
let ty = T::type_object();
|
||||
assert_ne!(unsafe { ffi::PyExceptionClass_Check(ty.as_ptr()) }, 0);
|
||||
|
||||
PyErr {
|
||||
ptype: ty,
|
||||
pvalue: value,
|
||||
ptraceback: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets whether an error is present in the Python interpreter's global state.
|
||||
|
@ -173,39 +220,38 @@ 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(_: Python) -> PyErr {
|
||||
unsafe {
|
||||
let mut ptype : *mut ffi::PyObject = std::ptr::null_mut();
|
||||
let mut pvalue : *mut ffi::PyObject = std::ptr::null_mut();
|
||||
let mut ptraceback : *mut ffi::PyObject = std::ptr::null_mut();
|
||||
ffi::PyErr_Fetch(&mut ptype, &mut pvalue, &mut ptraceback);
|
||||
PyErr::new_from_ffi_tuple(py, ptype, pvalue, ptraceback)
|
||||
PyErr::new_from_ffi_tuple(ptype, pvalue, ptraceback)
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn new_from_ffi_tuple(py: Python,
|
||||
ptype: *mut ffi::PyObject,
|
||||
unsafe fn new_from_ffi_tuple(ptype: *mut ffi::PyObject,
|
||||
pvalue: *mut ffi::PyObject,
|
||||
ptraceback: *mut ffi::PyObject) -> PyErr {
|
||||
// Note: must not panic to ensure all owned pointers get acquired correctly,
|
||||
// and because we mustn't panic in normalize().
|
||||
|
||||
let pvalue = if let Some(obj) =
|
||||
PyObject::from_owned_ptr_or_opt(Python::assume_gil_acquired(), pvalue)
|
||||
{
|
||||
PyErrValue::Value(obj)
|
||||
} else {
|
||||
PyErrValue::None
|
||||
};
|
||||
|
||||
PyErr {
|
||||
ptype: if ptype.is_null() {
|
||||
py.get_type::<exc::SystemError>().into()
|
||||
<exc::SystemError as PyTypeObject>::type_object()
|
||||
} else {
|
||||
Py::from_owned_ptr(ptype)
|
||||
},
|
||||
pvalue: PyObject::from_owned_ptr_or_opt(py, pvalue),
|
||||
ptraceback: PyObject::from_owned_ptr_or_opt(py, ptraceback)
|
||||
}
|
||||
}
|
||||
|
||||
fn new_helper(_py: Python, ty: &PyType, value: PyObject) -> PyErr {
|
||||
assert_ne!(unsafe { ffi::PyExceptionClass_Check(ty.as_ptr()) }, 0);
|
||||
PyErr {
|
||||
ptype: ty.into(),
|
||||
pvalue: Some(value),
|
||||
ptraceback: None
|
||||
pvalue: pvalue,
|
||||
ptraceback: PyObject::from_owned_ptr_or_opt(Python::assume_gil_acquired(), ptraceback),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -215,60 +261,31 @@ impl PyErr {
|
|||
/// 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: IntoPyObject {
|
||||
PyErr::from_instance_helper(py, obj.into_object(py))
|
||||
}
|
||||
|
||||
fn from_instance_helper(py: Python, obj: PyObject) -> PyErr {
|
||||
pub fn from_instance(obj: &PyObjectRef) -> PyErr {
|
||||
let ptr = obj.as_ptr();
|
||||
|
||||
if unsafe { ffi::PyExceptionInstance_Check(ptr) } != 0 {
|
||||
PyErr {
|
||||
ptype: unsafe { Py::from_borrowed_ptr( ffi::PyExceptionInstance_Class(ptr)) },
|
||||
pvalue: Some(obj),
|
||||
ptraceback: None
|
||||
pvalue: PyErrValue::Value(obj.into()),
|
||||
ptraceback: None,
|
||||
}
|
||||
} else if unsafe { ffi::PyExceptionClass_Check(obj.as_ptr()) } != 0 {
|
||||
PyErr {
|
||||
ptype: unsafe { Py::from_borrowed_ptr(ptr) },
|
||||
pvalue: None,
|
||||
ptraceback: None
|
||||
pvalue: PyErrValue::None,
|
||||
ptraceback: None,
|
||||
}
|
||||
} else {
|
||||
PyErr {
|
||||
ptype: py.get_type::<exc::TypeError>().into(),
|
||||
pvalue: Some("exceptions must derive from BaseException".into_object(py)),
|
||||
ptraceback: None
|
||||
ptype: exc::TypeError::type_object(),
|
||||
pvalue: PyErrValue::ToObject(
|
||||
Box::new("exceptions must derive from BaseException")),
|
||||
ptraceback: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Construct a new error, with the usual lazy initialization of Python exceptions.
|
||||
/// `exc` is the exception type; usually one of the standard exceptions like `py.get_type::<exc::RuntimeError>()`.
|
||||
/// `value` is the exception instance, or a tuple of arguments to pass to the exception constructor.
|
||||
#[inline]
|
||||
pub fn new_lazy_init(exc: &PyType, value: Option<PyObject>) -> PyErr {
|
||||
PyErr {
|
||||
ptype: exc.into(),
|
||||
pvalue: value,
|
||||
ptraceback: None
|
||||
}
|
||||
}
|
||||
|
||||
/// Construct a new error, with the usual lazy initialization of Python exceptions.
|
||||
/// `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<A>(py: Python, exc: &PyType, args: A) -> PyErr
|
||||
where A: IntoPyTuple
|
||||
{
|
||||
PyErr {
|
||||
ptype: exc.into(),
|
||||
pvalue: Some(args.into_tuple(py).into()),
|
||||
ptraceback: None
|
||||
}
|
||||
}
|
||||
|
||||
/// Print a standard traceback to sys.stderr.
|
||||
pub fn print(self, py: Python) {
|
||||
self.restore(py);
|
||||
|
@ -285,7 +302,7 @@ impl PyErr {
|
|||
/// 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
|
||||
where T: ToPyObject
|
||||
where T: ToBorrowedObject
|
||||
{
|
||||
exc.with_borrowed_ptr(py, |exc| unsafe {
|
||||
ffi::PyErr_GivenExceptionMatches(self.ptype.as_ptr(), exc) != 0
|
||||
|
@ -306,12 +323,20 @@ impl PyErr {
|
|||
/// Must not panic for safety in normalize()
|
||||
fn into_normalized(self, py: Python) -> PyErr {
|
||||
let PyErr { ptype, pvalue, ptraceback } = self;
|
||||
|
||||
let mut pvalue = match pvalue {
|
||||
PyErrValue::None => std::ptr::null_mut(),
|
||||
PyErrValue::Value(ob) => ob.into_ptr(),
|
||||
PyErrValue::ToErr(ob) => ob.exc_arguments(py).into_ptr(),
|
||||
PyErrValue::ToObject(ob) => ob.to_object(py).into_ptr(),
|
||||
PyErrValue::ToTuple(ob) => ob.to_tuple(py).into_ptr(),
|
||||
};
|
||||
|
||||
let mut ptype = ptype.into_ptr();
|
||||
let mut pvalue = pvalue.into_ptr();
|
||||
let mut ptraceback = ptraceback.into_ptr();
|
||||
unsafe {
|
||||
ffi::PyErr_NormalizeException(&mut ptype, &mut pvalue, &mut ptraceback);
|
||||
PyErr::new_from_ffi_tuple(py, ptype, pvalue, ptraceback)
|
||||
PyErr::new_from_ffi_tuple(ptype, pvalue, ptraceback)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -321,38 +346,51 @@ impl PyErr {
|
|||
}
|
||||
|
||||
/// Retrieves the exception instance for this error.
|
||||
/// This method takes `&mut self` because the error might need
|
||||
/// This method takes `mut self` because the error might need
|
||||
/// to be normalized in order to create the exception instance.
|
||||
pub fn instance(&mut self, py: Python) -> PyObject {
|
||||
self.normalize(py);
|
||||
pub fn instance(mut self, py: Python) -> PyObject {
|
||||
&self.normalize(py);
|
||||
match self.pvalue {
|
||||
Some(ref instance) => instance.clone_ref(py),
|
||||
None => py.None(),
|
||||
PyErrValue::Value(ref instance) => instance.clone_ref(py),
|
||||
_ => py.None(),
|
||||
}
|
||||
}
|
||||
|
||||
/// 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: Python) {
|
||||
let PyErr { ptype, pvalue, ptraceback } = self;
|
||||
|
||||
let pvalue = match pvalue {
|
||||
PyErrValue::None => std::ptr::null_mut(),
|
||||
PyErrValue::Value(ob) => ob.into_ptr(),
|
||||
PyErrValue::ToErr(ob) => ob.exc_arguments(py).into_ptr(),
|
||||
PyErrValue::ToObject(ob) => ob.to_object(py).into_ptr(),
|
||||
PyErrValue::ToTuple(ob) => ob.to_tuple(py).into_ptr(),
|
||||
};
|
||||
unsafe {
|
||||
ffi::PyErr_Restore(ptype.into_ptr(), pvalue.into_ptr(), ptraceback.into_ptr())
|
||||
ffi::PyErr_Restore(ptype.into_ptr(), pvalue, ptraceback.into_ptr())
|
||||
}
|
||||
}
|
||||
|
||||
/// Issue a warning message.
|
||||
/// May return a PyErr if warnings-as-errors is enabled.
|
||||
pub fn warn(py: Python, category: &PyObjectRef, message: &str, stacklevel: i32) -> PyResult<()> {
|
||||
let message = CString::new(message).map_err(|e| e.to_pyerr(py))?;
|
||||
let message = CString::new(message)?;
|
||||
unsafe {
|
||||
error_on_minusone(py, ffi::PyErr_WarnEx(
|
||||
category.as_ptr(), message.as_ptr(), stacklevel as ffi::Py_ssize_t))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clone_ref(&self, py: Python) -> PyErr {
|
||||
let v = if let Some(ref val) = self.pvalue { Some(val.clone_ref(py))} else { None };
|
||||
pub fn clone_ref(&mut self, py: Python) -> PyErr {
|
||||
&self.normalize(py);
|
||||
let v = match self.pvalue {
|
||||
PyErrValue::Value(ref instance) => PyErrValue::Value(instance.clone_ref(py)),
|
||||
_ => PyErrValue::None,
|
||||
};
|
||||
|
||||
let t = if let Some(ref val) = self.ptraceback { Some(val.clone_ref(py))} else { None };
|
||||
PyErr {
|
||||
ptype: self.ptype.clone_ref(py),
|
||||
|
@ -362,21 +400,27 @@ impl PyErr {
|
|||
}
|
||||
|
||||
pub fn release(self, py: Python) {
|
||||
#[allow(unused_variables)]
|
||||
let PyErr { ptype, pvalue, ptraceback } = self;
|
||||
py.release(ptype);
|
||||
py.release(pvalue);
|
||||
py.release(ptraceback);
|
||||
}
|
||||
}
|
||||
|
||||
/// 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_type::<exc::TypeError>(), None)
|
||||
impl std::fmt::Debug for PyErr {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
|
||||
f.write_str(format!("PyErr {{ type: {:?} }}", self.ptype).as_str())
|
||||
}
|
||||
}
|
||||
|
||||
impl <'p> std::fmt::Debug for PyDowncastError<'p> {
|
||||
/// Converts `PyDowncastError` to Python `TypeError`.
|
||||
impl std::convert::From<PyDowncastError> for PyErr {
|
||||
fn from(_err: PyDowncastError) -> PyErr {
|
||||
PyErr::new::<exc::TypeError, _>(())
|
||||
}
|
||||
}
|
||||
|
||||
impl <'p> std::fmt::Debug for PyDowncastError {
|
||||
fn fmt(&self, f : &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
|
||||
f.write_str("PyDowncastError")
|
||||
}
|
||||
|
@ -392,14 +436,22 @@ impl std::convert::From<PyErr> for std::io::Error {
|
|||
|
||||
/// Converts into `PyErr`
|
||||
pub trait ToPyErr {
|
||||
fn to_pyerr(&self, Python) -> PyErr;
|
||||
fn exc_arguments(&self, Python) -> PyObject;
|
||||
}
|
||||
|
||||
macro_rules! impl_to_pyerr {
|
||||
($err: ty, $pyexc: ty) => {
|
||||
impl $crate::ToPyErr for $err {
|
||||
fn to_pyerr(&self, py: $crate::Python) -> PyErr {
|
||||
PyErr::new::<$pyexc, _>(py, self.description())
|
||||
fn exc_arguments(&self, py: $crate::Python) -> PyObject {
|
||||
self.description().to_object(py)
|
||||
}
|
||||
}
|
||||
|
||||
impl $crate::std::convert::From<$err> for $crate::PyErr {
|
||||
fn from(err: $err) -> $crate::PyErr {
|
||||
$crate::PyErr::from_value::<exc::ValueError>(
|
||||
$crate::err::PyErrValue::ToErr(Box::new(err))
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -407,43 +459,59 @@ macro_rules! impl_to_pyerr {
|
|||
|
||||
#[cfg(Py_3)]
|
||||
/// Create `OSError` from `io::Error`
|
||||
impl ToPyErr for io::Error {
|
||||
|
||||
fn to_pyerr(&self, py: Python) -> PyErr {
|
||||
let tp = match self.kind() {
|
||||
io::ErrorKind::BrokenPipe => py.get_type::<exc::BrokenPipeError>(),
|
||||
io::ErrorKind::ConnectionRefused => py.get_type::<exc::ConnectionRefusedError>(),
|
||||
io::ErrorKind::ConnectionAborted => py.get_type::<exc::ConnectionAbortedError>(),
|
||||
io::ErrorKind::ConnectionReset => py.get_type::<exc::ConnectionResetError>(),
|
||||
io::ErrorKind::Interrupted => py.get_type::<exc::InterruptedError>(),
|
||||
io::ErrorKind::NotFound => py.get_type::<exc::FileNotFoundError>(),
|
||||
io::ErrorKind::WouldBlock => py.get_type::<exc::BlockingIOError>(),
|
||||
io::ErrorKind::TimedOut => py.get_type::<exc::TimeoutError>(),
|
||||
_ => py.get_type::<exc::OSError>(),
|
||||
};
|
||||
|
||||
let errno = self.raw_os_error().unwrap_or(0);
|
||||
let errdesc = self.description();
|
||||
|
||||
PyErr::new_err(py, tp, (errno, errdesc))
|
||||
impl std::convert::From<io::Error> for PyErr {
|
||||
fn from(err: io::Error) -> PyErr {
|
||||
match err.kind() {
|
||||
io::ErrorKind::BrokenPipe =>
|
||||
PyErr::from_value::<exc::BrokenPipeError>(PyErrValue::ToErr(Box::new(err))),
|
||||
io::ErrorKind::ConnectionRefused =>
|
||||
PyErr::from_value::<exc::ConnectionRefusedError>(PyErrValue::ToErr(Box::new(err))),
|
||||
io::ErrorKind::ConnectionAborted =>
|
||||
PyErr::from_value::<exc::ConnectionAbortedError>(PyErrValue::ToErr(Box::new(err))),
|
||||
io::ErrorKind::ConnectionReset =>
|
||||
PyErr::from_value::<exc::ConnectionResetError>(PyErrValue::ToErr(Box::new(err))),
|
||||
io::ErrorKind::Interrupted =>
|
||||
PyErr::from_value::<exc::InterruptedError>(PyErrValue::ToErr(Box::new(err))),
|
||||
io::ErrorKind::NotFound =>
|
||||
PyErr::from_value::<exc::FileNotFoundError>(PyErrValue::ToErr(Box::new(err))),
|
||||
io::ErrorKind::WouldBlock =>
|
||||
PyErr::from_value::<exc::BlockingIOError>(PyErrValue::ToErr(Box::new(err))),
|
||||
io::ErrorKind::TimedOut =>
|
||||
PyErr::from_value::<exc::TimeoutError>(PyErrValue::ToErr(Box::new(err))),
|
||||
_ =>
|
||||
PyErr::from_value::<exc::OSError>(PyErrValue::ToErr(Box::new(err))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(Py_3))]
|
||||
/// Create `OSError` from `io::Error`
|
||||
impl std::convert::From<io::Error> for PyErr {
|
||||
fn from(err: io::Error) -> PyErr {
|
||||
PyErr::from_value::<exc::OSError>(PyErrValue::ToErr(Box::new(err)))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Extract `errno` and `errdesc` from from `io::Error`
|
||||
impl ToPyErr for io::Error {
|
||||
|
||||
fn to_pyerr(&self, py: Python) -> PyErr {
|
||||
fn exc_arguments(&self, py: Python) -> PyObject {
|
||||
let errno = self.raw_os_error().unwrap_or(0);
|
||||
let errdesc = self.description();
|
||||
let errdesc = self.description().to_owned();
|
||||
(errno, errdesc).to_object(py)
|
||||
}
|
||||
}
|
||||
|
||||
PyErr::new_err(py, &py.get_type::<exc::OSError>(), (errno, errdesc))
|
||||
impl<W: 'static + Send + std::fmt::Debug> std::convert::From<std::io::IntoInnerError<W>> for PyErr
|
||||
{
|
||||
fn from(err: std::io::IntoInnerError<W>) -> PyErr {
|
||||
PyErr::from_value::<exc::OSError>(PyErrValue::ToErr(Box::new(err)))
|
||||
}
|
||||
}
|
||||
|
||||
impl<W: Send + std::fmt::Debug> ToPyErr for std::io::IntoInnerError<W> {
|
||||
fn to_pyerr(&self, py: Python) -> PyErr {
|
||||
PyErr::new::<exc::OSError, _>(py, self.description())
|
||||
fn exc_arguments(&self, py: Python) -> PyObject {
|
||||
self.description().to_object(py)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -483,7 +551,8 @@ mod tests {
|
|||
fn set_typeerror() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
PyErr::new_lazy_init(py.get_type::<exc::TypeError>(), None).restore(py);
|
||||
let err: PyErr = exc::TypeError.into();
|
||||
err.restore(py);
|
||||
assert!(PyErr::occurred(py));
|
||||
drop(PyErr::fetch(py));
|
||||
}
|
||||
|
|
|
@ -325,8 +325,7 @@ impl<'a, T> std::convert::From<&'a mut T> for PyObject
|
|||
|
||||
impl<T> PyDowncastInto for Py<T> where T: PyTypeInfo
|
||||
{
|
||||
fn downcast_into<I>(py: Python, ob: I)
|
||||
-> Result<Self, PyDowncastError>
|
||||
fn downcast_into<I>(_py: Python, ob: I) -> Result<Self, PyDowncastError>
|
||||
where I: IntoPyPointer
|
||||
{
|
||||
unsafe{
|
||||
|
@ -335,20 +334,20 @@ impl<T> PyDowncastInto for Py<T> where T: PyTypeInfo
|
|||
Ok(Py::from_owned_ptr(ptr))
|
||||
} else {
|
||||
ffi::Py_DECREF(ptr);
|
||||
Err(PyDowncastError(py, None))
|
||||
Err(PyDowncastError)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn downcast_into_from_ptr(py: Python, ptr: *mut ffi::PyObject)
|
||||
-> Result<Self, PyDowncastError>
|
||||
fn downcast_into_from_ptr(_py: Python, ptr: *mut ffi::PyObject)
|
||||
-> Result<Self, PyDowncastError>
|
||||
{
|
||||
unsafe{
|
||||
if T::is_instance(ptr) {
|
||||
Ok(Py::from_owned_ptr(ptr))
|
||||
} else {
|
||||
ffi::Py_DECREF(ptr);
|
||||
Err(PyDowncastError(py, None))
|
||||
Err(PyDowncastError)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -150,7 +150,7 @@ pub mod ffi {
|
|||
pub use ffi3::*;
|
||||
}
|
||||
|
||||
pub use err::{PyErr, PyResult, PyDowncastError, ToPyErr};
|
||||
pub use err::{PyErr, PyErrValue, PyResult, PyDowncastError, ToPyErr};
|
||||
pub use objects::*;
|
||||
pub use objectprotocol::ObjectProtocol;
|
||||
pub use object::PyObject;
|
||||
|
@ -158,7 +158,8 @@ pub use python::{Python, ToPyPointer, IntoPyPointer,
|
|||
PyMutDowncastFrom, PyDowncastFrom, PyDowncastInto};
|
||||
pub use pythonrun::{GILGuard, GILPool, prepare_freethreaded_python, prepare_pyo3_library};
|
||||
pub use instance::{PyToken, PyObjectWithToken, AsPyRef, Py, PyNativeType};
|
||||
pub use conversion::{FromPyObject, RefFromPyObject, ToPyObject, IntoPyObject, IntoPyTuple};
|
||||
pub use conversion::{FromPyObject, RefFromPyObject,
|
||||
ToPyObject, ToBorrowedObject, IntoPyObject, IntoPyTuple};
|
||||
pub mod class;
|
||||
pub use class::*;
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ use pythonrun;
|
|||
use err::{PyErr, PyResult};
|
||||
use instance::{AsPyRef, PyObjectWithToken};
|
||||
use objects::{PyObjectRef, PyDict};
|
||||
use conversion::{ToPyObject, IntoPyObject, IntoPyTuple, FromPyObject};
|
||||
use conversion::{ToPyObject, ToBorrowedObject, IntoPyObject, IntoPyTuple, FromPyObject};
|
||||
use python::{Python, ToPyPointer, IntoPyPointer};
|
||||
|
||||
|
||||
|
@ -230,7 +230,9 @@ impl ToPyObject for PyObject
|
|||
fn to_object<'p>(&self, py: Python<'p>) -> PyObject {
|
||||
unsafe {PyObject::from_borrowed_ptr(py, self.as_ptr())}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToBorrowedObject for PyObject {
|
||||
#[inline]
|
||||
fn with_borrowed_ptr<F, R>(&self, _py: Python, f: F) -> R
|
||||
where F: FnOnce(*mut ffi::PyObject) -> R
|
||||
|
|
|
@ -9,7 +9,7 @@ use err::{self, PyErr, PyResult};
|
|||
use python::{Python, ToPyPointer, PyDowncastFrom};
|
||||
use object::PyObject;
|
||||
use objects::{PyObjectRef, PyDict, PyString, PyIterator, PyType};
|
||||
use conversion::{ToPyObject, IntoPyTuple, FromPyObject};
|
||||
use conversion::{ToPyObject, ToBorrowedObject, IntoPyTuple, FromPyObject};
|
||||
use instance::PyObjectWithToken;
|
||||
|
||||
|
||||
|
@ -27,7 +27,7 @@ pub trait ObjectProtocol {
|
|||
/// Sets an attribute value.
|
||||
/// This is equivalent to the Python expression 'self.attr_name = value'.
|
||||
fn setattr<N, V>(&self, attr_name: N, value: V) -> PyResult<()>
|
||||
where N: ToPyObject, V: ToPyObject;
|
||||
where N: ToBorrowedObject, V: ToBorrowedObject;
|
||||
|
||||
/// Deletes an attribute.
|
||||
/// This is equivalent to the Python expression 'del self.attr_name'.
|
||||
|
@ -102,16 +102,16 @@ pub trait ObjectProtocol {
|
|||
fn len(&self) -> PyResult<usize>;
|
||||
|
||||
/// This is equivalent to the Python expression: 'self[key]'
|
||||
fn get_item<K>(&self, key: K) -> PyResult<&PyObjectRef> where K: ToPyObject;
|
||||
fn get_item<K>(&self, key: K) -> PyResult<&PyObjectRef> where K: ToBorrowedObject;
|
||||
|
||||
/// Sets an item value.
|
||||
/// This is equivalent to the Python expression 'self[key] = value'.
|
||||
fn set_item<K, V>(&self, key: K, value: V) -> PyResult<()>
|
||||
where K: ToPyObject, V: ToPyObject;
|
||||
where K: ToBorrowedObject, V: ToBorrowedObject;
|
||||
|
||||
/// Deletes an item.
|
||||
/// This is equivalent to the Python expression 'del self[key]'.
|
||||
fn del_item<K>(&self, key: K) -> PyResult<()> where K: ToPyObject;
|
||||
fn del_item<K>(&self, key: K) -> PyResult<()> where K: ToBorrowedObject;
|
||||
|
||||
/// Takes an object and returns an iterator for it.
|
||||
/// This is typically a new iterator but if the argument
|
||||
|
@ -163,7 +163,7 @@ impl<T> ObjectProtocol for T where T: PyObjectWithToken + ToPyPointer {
|
|||
|
||||
#[inline]
|
||||
fn setattr<N, V>(&self, attr_name: N, value: V) -> PyResult<()>
|
||||
where N: ToPyObject, V: ToPyObject
|
||||
where N: ToBorrowedObject, V: ToBorrowedObject
|
||||
{
|
||||
attr_name.with_borrowed_ptr(
|
||||
self.py(), move |attr_name|
|
||||
|
@ -203,7 +203,8 @@ impl<T> ObjectProtocol for T where T: PyObjectWithToken + ToPyPointer {
|
|||
} else if result < 0 {
|
||||
return Err(PyErr::fetch(py));
|
||||
}
|
||||
Err(PyErr::new::<::exc::TypeError, _>(py, "ObjectProtocol::compare(): All comparisons returned false"))
|
||||
Err(::exc::TypeError::new(
|
||||
"ObjectProtocol::compare(): All comparisons returned false"))
|
||||
}
|
||||
|
||||
other.with_borrowed_ptr(self.py(), |other| unsafe {
|
||||
|
@ -308,7 +309,7 @@ impl<T> ObjectProtocol for T where T: PyObjectWithToken + ToPyPointer {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn get_item<K>(&self, key: K) -> PyResult<&PyObjectRef> where K: ToPyObject {
|
||||
fn get_item<K>(&self, key: K) -> PyResult<&PyObjectRef> where K: ToBorrowedObject {
|
||||
key.with_borrowed_ptr(self.py(), |key| unsafe {
|
||||
self.py().cast_from_ptr_or_err(
|
||||
ffi::PyObject_GetItem(self.as_ptr(), key))
|
||||
|
@ -317,7 +318,7 @@ impl<T> ObjectProtocol for T where T: PyObjectWithToken + ToPyPointer {
|
|||
|
||||
#[inline]
|
||||
fn set_item<K, V>(&self, key: K, value: V) -> PyResult<()>
|
||||
where K: ToPyObject, V: ToPyObject
|
||||
where K: ToBorrowedObject, V: ToBorrowedObject
|
||||
{
|
||||
key.with_borrowed_ptr(
|
||||
self.py(), move |key|
|
||||
|
@ -328,7 +329,7 @@ impl<T> ObjectProtocol for T where T: PyObjectWithToken + ToPyPointer {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn del_item<K>(&self, key: K) -> PyResult<()> where K: ToPyObject {
|
||||
fn del_item<K>(&self, key: K) -> PyResult<()> where K: ToBorrowedObject {
|
||||
key.with_borrowed_ptr(self.py(), |key| unsafe {
|
||||
err::error_on_minusone(
|
||||
self.py(), ffi::PyObject_DelItem(self.as_ptr(), key))
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
use ffi;
|
||||
use object::PyObject;
|
||||
use python::{ToPyPointer, Python, PyDowncastFrom};
|
||||
use conversion::{ToPyObject, IntoPyObject};
|
||||
use conversion::{ToPyObject, IntoPyObject, ToBorrowedObject};
|
||||
|
||||
/// Represents a Python `bool`.
|
||||
pub struct PyBool(PyObject);
|
||||
|
@ -36,7 +36,9 @@ impl ToPyObject for bool {
|
|||
py, if *self { ffi::Py_True() } else { ffi::Py_False() })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToBorrowedObject for bool {
|
||||
#[inline]
|
||||
fn with_borrowed_ptr<F, R>(&self, _py: Python, f: F) -> R
|
||||
where F: FnOnce(*mut ffi::PyObject) -> R
|
||||
|
|
|
@ -98,7 +98,7 @@ mod test {
|
|||
assert_eq!(20, bytearray.len());
|
||||
|
||||
let none = py.None();
|
||||
if let Err(mut err) = PyByteArray::from(py, &none) {
|
||||
if let Err(err) = PyByteArray::from(py, &none) {
|
||||
assert!(py.is_instance::<exc::TypeError, _>(&err.instance(py)).unwrap())
|
||||
} else {
|
||||
panic!("error");
|
||||
|
|
|
@ -8,7 +8,7 @@ use ffi;
|
|||
use object::PyObject;
|
||||
use instance::PyObjectWithToken;
|
||||
use python::{Python, ToPyPointer};
|
||||
use conversion::ToPyObject;
|
||||
use conversion::{ToPyObject, ToBorrowedObject};
|
||||
use objects::{PyObjectRef, PyList};
|
||||
use err::{self, PyResult, PyErr};
|
||||
|
||||
|
@ -52,7 +52,7 @@ 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 {
|
||||
pub fn contains<K>(&self, key: K) -> PyResult<bool> where K: ToBorrowedObject {
|
||||
key.with_borrowed_ptr(self.py(), |key| unsafe {
|
||||
match ffi::PyDict_Contains(self.as_ptr(), key) {
|
||||
1 => Ok(true),
|
||||
|
@ -64,7 +64,7 @@ impl PyDict {
|
|||
|
||||
/// Gets an item from the dictionary.
|
||||
/// Returns None if the item is not present, or if an error occurs.
|
||||
pub fn get_item<K>(&self, key: K) -> Option<&PyObjectRef> where K: ToPyObject {
|
||||
pub fn get_item<K>(&self, key: K) -> Option<&PyObjectRef> where K: ToBorrowedObject {
|
||||
key.with_borrowed_ptr(self.py(), |key| unsafe {
|
||||
self.py().cast_from_borrowed_ptr_or_opt(
|
||||
ffi::PyDict_GetItem(self.as_ptr(), key))
|
||||
|
@ -86,7 +86,7 @@ impl PyDict {
|
|||
|
||||
/// Deletes an item.
|
||||
/// This is equivalent to the Python expression `del self[key]`.
|
||||
pub fn del_item<K>(&self, key: K) -> PyResult<()> where K: ToPyObject
|
||||
pub fn del_item<K>(&self, key: K) -> PyResult<()> where K: ToBorrowedObject
|
||||
{
|
||||
key.with_borrowed_ptr(self.py(), |key| unsafe {
|
||||
err::error_on_minusone(
|
||||
|
|
|
@ -9,7 +9,7 @@ use std::{self, mem, ops};
|
|||
use std::ffi::CStr;
|
||||
|
||||
use ffi;
|
||||
use object::PyObject;
|
||||
use objects::PyObjectRef;
|
||||
use python::{Python, ToPyPointer};
|
||||
use err::PyResult;
|
||||
use super::PyTuple;
|
||||
|
@ -18,8 +18,16 @@ macro_rules! exc_type(
|
|||
($name:ident, $exc_name:ident) => (
|
||||
pub struct $name;
|
||||
|
||||
// pyobject_newtype!($name);
|
||||
|
||||
impl std::convert::From<$name> for $crate::PyErr {
|
||||
fn from(_err: $name) -> $crate::PyErr {
|
||||
$crate::PyErr::new::<$name, _>(())
|
||||
}
|
||||
}
|
||||
impl $name {
|
||||
pub fn new<V: $crate::ToPyObject + 'static>(value: V) -> $crate::PyErr {
|
||||
$crate::PyErr::new::<$name, V>(value)
|
||||
}
|
||||
}
|
||||
impl $crate::typeob::PyTypeObject for $name {
|
||||
#[inline(always)]
|
||||
fn init_type() {}
|
||||
|
@ -116,12 +124,12 @@ exc_type!(WindowsError, PyExc_WindowsError);
|
|||
|
||||
impl UnicodeDecodeError {
|
||||
|
||||
pub fn new(py: Python, encoding: &CStr, input: &[u8],
|
||||
range: ops::Range<usize>, reason: &CStr) -> PyResult<PyObject> {
|
||||
pub fn new_err<'p>(py: Python<'p>, encoding: &CStr, input: &[u8],
|
||||
range: ops::Range<usize>, reason: &CStr) -> PyResult<&'p PyObjectRef> {
|
||||
unsafe {
|
||||
let input: &[c_char] = mem::transmute(input);
|
||||
PyObject::from_owned_ptr_or_err(
|
||||
py, ffi::PyUnicodeDecodeError_Create(
|
||||
py.cast_from_ptr_or_err(
|
||||
ffi::PyUnicodeDecodeError_Create(
|
||||
encoding.as_ptr(),
|
||||
input.as_ptr(),
|
||||
input.len() as ffi::Py_ssize_t,
|
||||
|
@ -131,11 +139,12 @@ impl UnicodeDecodeError {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn new_utf8(py: Python, input: &[u8], err: std::str::Utf8Error)
|
||||
-> PyResult<PyObject>
|
||||
pub fn new_utf8<'p>(py: Python<'p>, input: &[u8], err: std::str::Utf8Error)
|
||||
-> PyResult<&'p PyObjectRef>
|
||||
{
|
||||
let pos = err.valid_up_to();
|
||||
UnicodeDecodeError::new(py, cstr!("utf-8"), input, pos .. pos+1, cstr!("invalid utf-8"))
|
||||
UnicodeDecodeError::new_err(
|
||||
py, cstr!("utf-8"), input, pos .. pos+1, cstr!("invalid utf-8"))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,8 +17,7 @@ pub struct PyIterator<'p>(&'p PyObjectRef);
|
|||
|
||||
impl <'p> PyIterator<'p> {
|
||||
/// Constructs a `PyIterator` from a Python iterator object.
|
||||
pub fn from_object<T>(py: Python<'p>, obj: T)
|
||||
-> Result<PyIterator<'p>, PyDowncastError<'p>>
|
||||
pub fn from_object<T>(py: Python<'p>, obj: T) -> Result<PyIterator<'p>, PyDowncastError>
|
||||
where T: IntoPyPointer
|
||||
{
|
||||
unsafe {
|
||||
|
@ -27,7 +26,7 @@ impl <'p> PyIterator<'p> {
|
|||
Ok(PyIterator(py.cast_from_ptr(ptr)))
|
||||
} else {
|
||||
ffi::Py_DECREF(ptr);
|
||||
Err(PyDowncastError(py, None))
|
||||
Err(PyDowncastError)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ use instance::PyObjectWithToken;
|
|||
use object::PyObject;
|
||||
use objects::PyObjectRef;
|
||||
use python::{Python, ToPyPointer, IntoPyPointer};
|
||||
use conversion::{ToPyObject, IntoPyObject};
|
||||
use conversion::{ToPyObject, IntoPyObject, ToBorrowedObject};
|
||||
|
||||
/// Represents a Python `list`.
|
||||
pub struct PyList(PyObject);
|
||||
|
@ -77,7 +77,7 @@ impl PyList {
|
|||
}
|
||||
|
||||
/// Appends an item at the list.
|
||||
pub fn append<I>(&self, item: I) -> PyResult<()> where I: ToPyObject
|
||||
pub fn append<I>(&self, item: I) -> PyResult<()> where I: ToBorrowedObject
|
||||
{
|
||||
item.with_borrowed_ptr(self.py(), |item| unsafe {
|
||||
err::error_on_minusone(
|
||||
|
@ -88,7 +88,7 @@ impl PyList {
|
|||
/// Inserts an item at the specified index.
|
||||
///
|
||||
/// Panics if the index is out of range.
|
||||
pub fn insert<I>(&self, index: isize, item: I) -> PyResult<()> where I: ToPyObject
|
||||
pub fn insert<I>(&self, index: isize, item: I) -> PyResult<()> where I: ToBorrowedObject
|
||||
{
|
||||
item.with_borrowed_ptr(self.py(), |item| unsafe {
|
||||
err::error_on_minusone(
|
||||
|
@ -148,7 +148,7 @@ impl <T> ToPyObject for Vec<T> where T: ToPyObject {
|
|||
|
||||
}
|
||||
|
||||
impl <T> IntoPyObject for Vec<T> where T: IntoPyObject {
|
||||
impl <T> IntoPyObject for Vec<T> where T: IntoPyObject + ToPyObject {
|
||||
|
||||
fn into_object(self, py: Python) -> PyObject {
|
||||
unsafe {
|
||||
|
|
|
@ -61,12 +61,11 @@ macro_rules! pyobject_downcast(
|
|||
/// Extracts `Self` from the source `PyObject`.
|
||||
fn extract(ob: &'a $crate::PyObjectRef) -> $crate::PyResult<Self>
|
||||
{
|
||||
use instance::PyObjectWithToken;
|
||||
unsafe {
|
||||
if $crate::ffi::$checkfunction(ob.as_ptr()) != 0 {
|
||||
Ok($crate::std::mem::transmute(ob))
|
||||
} else {
|
||||
Err($crate::PyDowncastError(ob.py(), None).into())
|
||||
Err($crate::PyDowncastError.into())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -168,7 +167,10 @@ macro_rules! pyobject_nativetype(
|
|||
fn to_object(&self, py: $crate::Python) -> $crate::PyObject {
|
||||
unsafe {$crate::PyObject::from_borrowed_ptr(py, self.0.as_ptr())}
|
||||
}
|
||||
}
|
||||
|
||||
impl $crate::ToBorrowedObject for $name
|
||||
{
|
||||
#[inline]
|
||||
fn with_borrowed_ptr<F, R>(&self, _py: $crate::Python, f: F) -> R
|
||||
where F: FnOnce(*mut $crate::ffi::PyObject) -> R
|
||||
|
|
|
@ -14,7 +14,7 @@ use python::{Python, ToPyPointer};
|
|||
use objects::{PyObjectRef, PyDict, PyType, exc};
|
||||
use objectprotocol::ObjectProtocol;
|
||||
use instance::PyObjectWithToken;
|
||||
use err::{PyResult, PyErr, ToPyErr};
|
||||
use err::{PyResult, PyErr};
|
||||
|
||||
|
||||
/// Represents a Python `module` object.
|
||||
|
@ -27,7 +27,7 @@ pyobject_nativetype!(PyModule, PyModule_Type, PyModule_Check);
|
|||
impl PyModule {
|
||||
/// Create a new module object with the `__name__` attribute set to name.
|
||||
pub fn new<'p>(py: Python<'p>, name: &str) -> PyResult<&'p PyModule> {
|
||||
let name = CString::new(name).map_err(|e| e.to_pyerr(py))?;
|
||||
let name = CString::new(name)?;
|
||||
unsafe {
|
||||
py.cast_from_ptr_or_err(
|
||||
ffi::PyModule_New(name.as_ptr()))
|
||||
|
@ -36,7 +36,7 @@ impl PyModule {
|
|||
|
||||
/// Import the Python module with the specified name.
|
||||
pub fn import<'p>(py: Python<'p>, name: &str) -> PyResult<&'p PyModule> {
|
||||
let name = CString::new(name).map_err(|e| e.to_pyerr(py))?;
|
||||
let name = CString::new(name)?;
|
||||
unsafe {
|
||||
py.cast_from_ptr_or_err(
|
||||
ffi::PyImport_ImportModule(name.as_ptr()))
|
||||
|
@ -60,8 +60,7 @@ impl PyModule {
|
|||
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))))
|
||||
exc::UnicodeDecodeError::new_utf8(self.py(), slice, e)?))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@ macro_rules! int_fits_c_long(
|
|||
}
|
||||
match cast::<c_long, $rust_type>(val) {
|
||||
Some(v) => Ok(v),
|
||||
None => Err(overflow_error(obj.py()))
|
||||
None => Err(exc::OverflowError.into())
|
||||
}
|
||||
});
|
||||
)
|
||||
|
@ -110,7 +110,7 @@ macro_rules! int_fits_larger_int(
|
|||
let val = try!(obj.extract::<$larger_type>());
|
||||
match cast::<$larger_type, $rust_type>(val) {
|
||||
Some(v) => Ok(v),
|
||||
None => Err(overflow_error(obj.py()))
|
||||
None => Err(exc::OverflowError.into())
|
||||
}
|
||||
});
|
||||
)
|
||||
|
@ -162,7 +162,7 @@ macro_rules! int_convert_u64_or_i64 (
|
|||
} else if ffi::PyInt_Check(ptr) != 0 {
|
||||
match cast::<c_long, $rust_type>(ffi::PyInt_AS_LONG(ptr)) {
|
||||
Some(v) => Ok(v),
|
||||
None => Err(overflow_error(obj.py()))
|
||||
None => Err(exc::OverflowError.into())
|
||||
}
|
||||
} else {
|
||||
let num = PyObject::from_owned_ptr_or_err(
|
||||
|
@ -206,10 +206,6 @@ int_fits_larger_int!(usize, u64);
|
|||
// u64 has a manual implementation as it never fits into signed long
|
||||
int_convert_u64_or_i64!(u64, ffi::PyLong_FromUnsignedLongLong, ffi::PyLong_AsUnsignedLongLong);
|
||||
|
||||
fn overflow_error(py: Python) -> PyErr {
|
||||
PyErr::new_lazy_init(py.get_type::<exc::OverflowError>(), None)
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
|
|
|
@ -50,7 +50,7 @@ macro_rules! int_fits_c_long(
|
|||
}
|
||||
match cast::<c_long, $rust_type>(val) {
|
||||
Some(v) => Ok(v),
|
||||
None => Err(overflow_error(obj.py()))
|
||||
None => Err(exc::OverflowError.into())
|
||||
}
|
||||
});
|
||||
)
|
||||
|
@ -62,7 +62,7 @@ macro_rules! int_fits_larger_int(
|
|||
impl ToPyObject for $rust_type {
|
||||
#[inline]
|
||||
fn to_object(&self, py: Python) -> PyObject {
|
||||
(*self as $larger_type).to_object(py)
|
||||
(*self as $larger_type).into_object(py)
|
||||
}
|
||||
}
|
||||
impl IntoPyObject for $rust_type {
|
||||
|
@ -74,7 +74,7 @@ macro_rules! int_fits_larger_int(
|
|||
let val = try!(obj.extract::<$larger_type>());
|
||||
match cast::<$larger_type, $rust_type>(val) {
|
||||
Some(v) => Ok(v),
|
||||
None => Err(overflow_error(obj.py()))
|
||||
None => Err(exc::OverflowError.into())
|
||||
}
|
||||
});
|
||||
)
|
||||
|
@ -160,9 +160,6 @@ int_fits_larger_int!(usize, u64);
|
|||
// u64 has a manual implementation as it never fits into signed long
|
||||
int_convert_u64_or_i64!(u64, ffi::PyLong_FromUnsignedLongLong, ffi::PyLong_AsUnsignedLongLong);
|
||||
|
||||
fn overflow_error(py: Python) -> PyErr {
|
||||
PyErr::new_lazy_init(py.get_type::<exc::OverflowError>(), None)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
|
|
|
@ -6,7 +6,7 @@ use err::{self, PyErr, PyResult};
|
|||
use object::PyObject;
|
||||
use instance::PyObjectWithToken;
|
||||
use python::{ToPyPointer, PyDowncastFrom};
|
||||
use conversion::{FromPyObject, ToPyObject};
|
||||
use conversion::{FromPyObject, ToBorrowedObject};
|
||||
use objects::{PyObjectRef, PyList, PyTuple};
|
||||
use objectprotocol::ObjectProtocol;
|
||||
|
||||
|
@ -101,7 +101,7 @@ impl PySequence {
|
|||
/// Assign object v to the ith element of o.
|
||||
/// Equivalent to Python statement `o[i] = v`
|
||||
#[inline]
|
||||
pub fn set_item<I>(&self, i: isize, item: I) -> PyResult<()> where I: ToPyObject {
|
||||
pub fn set_item<I>(&self, i: isize, item: I) -> PyResult<()> where I: ToBorrowedObject {
|
||||
unsafe {
|
||||
item.with_borrowed_ptr(self.py(), |item| {
|
||||
err::error_on_minusone(
|
||||
|
@ -145,7 +145,7 @@ impl PySequence {
|
|||
/// Return the number of occurrences of value in o, that is, return the number of keys for
|
||||
/// which `o[key] == value`
|
||||
#[inline]
|
||||
pub fn count<V>(&self, value: V) -> PyResult<usize> where V: ToPyObject
|
||||
pub fn count<V>(&self, value: V) -> PyResult<usize> where V: ToBorrowedObject
|
||||
{
|
||||
let r = value.with_borrowed_ptr(self.py(), |ptr| unsafe {
|
||||
ffi::PySequence_Count(self.as_ptr(), ptr)
|
||||
|
@ -157,9 +157,9 @@ impl PySequence {
|
|||
}
|
||||
}
|
||||
|
||||
/// Determine if o contains value. this is equivalent to the Python expression `value in o`
|
||||
/// Determine if o contains value. this is equivalent to the Python expression `value in o`
|
||||
#[inline]
|
||||
pub fn contains<V>(&self, value: V) -> PyResult<bool> where V: ToPyObject
|
||||
pub fn contains<V>(&self, value: V) -> PyResult<bool> where V: ToBorrowedObject
|
||||
{
|
||||
let r = value.with_borrowed_ptr(self.py(), |ptr| unsafe {
|
||||
ffi::PySequence_Contains(self.as_ptr(), ptr)
|
||||
|
@ -174,7 +174,7 @@ impl PySequence {
|
|||
/// Return the first index i for which o[i] == value.
|
||||
/// This is equivalent to the Python expression `o.index(value)`
|
||||
#[inline]
|
||||
pub fn index<V>(&self, value: V) -> PyResult<usize> where V: ToPyObject
|
||||
pub fn index<V>(&self, value: V) -> PyResult<usize> where V: ToBorrowedObject
|
||||
{
|
||||
let r = value.with_borrowed_ptr(self.py(), |ptr| unsafe {
|
||||
ffi::PySequence_Index(self.as_ptr(), ptr)
|
||||
|
|
|
@ -5,7 +5,7 @@ use std::{hash, collections};
|
|||
use ffi;
|
||||
use python::{Python, ToPyPointer};
|
||||
use object::PyObject;
|
||||
use conversion::ToPyObject;
|
||||
use conversion::{ToPyObject, ToBorrowedObject};
|
||||
use instance::{AsPyRef, Py, PyObjectWithToken};
|
||||
use err::{self, PyResult, PyErr};
|
||||
|
||||
|
@ -129,7 +129,7 @@ impl PyFrozenSet {
|
|||
|
||||
/// Determine if the set 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 {
|
||||
pub fn contains<K>(&self, key: K) -> PyResult<bool> where K: ToBorrowedObject {
|
||||
key.with_borrowed_ptr(self.py(), |key| unsafe {
|
||||
match ffi::PySet_Contains(self.as_ptr(), key) {
|
||||
1 => Ok(true),
|
||||
|
|
|
@ -52,7 +52,8 @@ impl <'a> PyStringData<'a> {
|
|||
PyStringData::Utf8(data) => {
|
||||
match str::from_utf8(data) {
|
||||
Ok(s) => Ok(Cow::Borrowed(s)),
|
||||
Err(e) => Err(PyErr::from_instance(py, try!(exc::UnicodeDecodeError::new_utf8(py, data, e))))
|
||||
Err(e) => Err(PyErr::from_instance(
|
||||
exc::UnicodeDecodeError::new_utf8(py, data, e)?))
|
||||
}
|
||||
}
|
||||
PyStringData::Latin1(data) => {
|
||||
|
@ -69,10 +70,10 @@ impl <'a> PyStringData<'a> {
|
|||
match String::from_utf16(data) {
|
||||
Ok(s) => Ok(Cow::Owned(s)),
|
||||
Err(_) => Err(PyErr::from_instance(
|
||||
py, try!(exc::UnicodeDecodeError::new(
|
||||
exc::UnicodeDecodeError::new_err(
|
||||
py, cstr!("utf-16"),
|
||||
utf16_bytes(data), 0 .. 2*data.len(), cstr!("invalid utf-16")))
|
||||
))
|
||||
utf16_bytes(data), 0 .. 2*data.len(), cstr!("invalid utf-16"))?)
|
||||
)
|
||||
}
|
||||
},
|
||||
PyStringData::Utf32(data) => {
|
||||
|
@ -82,10 +83,10 @@ impl <'a> PyStringData<'a> {
|
|||
match data.iter().map(|&u| char::from_u32(u)).collect() {
|
||||
Some(s) => Ok(Cow::Owned(s)),
|
||||
None => Err(PyErr::from_instance(
|
||||
py, try!(exc::UnicodeDecodeError::new(
|
||||
exc::UnicodeDecodeError::new_err(
|
||||
py, cstr!("utf-32"),
|
||||
utf32_bytes(data), 0 .. 4*data.len(), cstr!("invalid utf-32")))
|
||||
))
|
||||
utf32_bytes(data), 0 .. 4*data.len(), cstr!("invalid utf-32"))?)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -101,18 +101,32 @@ impl PyTuple {
|
|||
}
|
||||
|
||||
impl<'a> IntoPyTuple for &'a PyTuple {
|
||||
fn to_tuple(&self, _py: Python) -> Py<PyTuple> {
|
||||
let t: Py<PyTuple> = (*self).into();
|
||||
t
|
||||
}
|
||||
fn into_tuple(self, _py: Python) -> Py<PyTuple> {
|
||||
self.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoPyTuple for Py<PyTuple> {
|
||||
fn to_tuple(&self, py: Python) -> Py<PyTuple> {
|
||||
self.clone_ref(py)
|
||||
}
|
||||
fn into_tuple(self, _py: Python) -> Py<PyTuple> {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoPyTuple for &'a str {
|
||||
fn to_tuple(&self, py: Python) -> Py<PyTuple> {
|
||||
unsafe {
|
||||
let ptr = ffi::PyTuple_New(1);
|
||||
ffi::PyTuple_SetItem(ptr, 0, ToPyObject::to_object(self, py).into_ptr());
|
||||
Py::from_owned_ptr_or_panic(ptr)
|
||||
}
|
||||
}
|
||||
fn into_tuple(self, py: Python) -> Py<PyTuple> {
|
||||
unsafe {
|
||||
let ptr = ffi::PyTuple_New(1);
|
||||
|
@ -122,11 +136,10 @@ impl<'a> IntoPyTuple for &'a str {
|
|||
}
|
||||
}
|
||||
|
||||
fn wrong_tuple_length(py: Python, t: &PyTuple, expected_length: usize) -> PyErr {
|
||||
fn wrong_tuple_length(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_type::<exc::ValueError>(), Some(msg.into_object(py)))
|
||||
exc::ValueError::new(msg)
|
||||
}
|
||||
|
||||
macro_rules! tuple_conversion ({$length:expr,$(($refN:ident, $n:tt, $T:ident)),+} => {
|
||||
|
@ -149,7 +162,14 @@ macro_rules! tuple_conversion ({$length:expr,$(($refN:ident, $n:tt, $T:ident)),+
|
|||
}
|
||||
}
|
||||
|
||||
impl <$($T: IntoPyObject),+> IntoPyTuple for ($($T,)+) {
|
||||
impl <$($T: ToPyObject + IntoPyObject),+> IntoPyTuple for ($($T,)+) {
|
||||
fn to_tuple(&self, py: Python) -> Py<PyTuple> {
|
||||
unsafe {
|
||||
let ptr = ffi::PyTuple_New($length);
|
||||
$(ffi::PyTuple_SetItem(ptr, $n, ToPyObject::to_object(&self.$n, py).into_ptr());)+;
|
||||
Py::from_owned_ptr_or_panic(ptr)
|
||||
}
|
||||
}
|
||||
fn into_tuple(self, py: Python) -> Py<PyTuple> {
|
||||
unsafe {
|
||||
let ptr = ffi::PyTuple_New($length);
|
||||
|
@ -169,7 +189,7 @@ macro_rules! tuple_conversion ({$length:expr,$(($refN:ident, $n:tt, $T:ident)),+
|
|||
$( try!(slice[$n].extract::<$T>(obj.py())), )+
|
||||
))
|
||||
} else {
|
||||
Err(wrong_tuple_length(obj.py(), t, $length))
|
||||
Err(wrong_tuple_length(t, $length))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -213,8 +233,8 @@ impl ToPyObject for NoArgs {
|
|||
}
|
||||
}
|
||||
|
||||
impl IntoPyObject for NoArgs
|
||||
{
|
||||
impl IntoPyObject for NoArgs {
|
||||
|
||||
fn into_object(self, py: Python) -> PyObject {
|
||||
PyTuple::empty(py).into()
|
||||
}
|
||||
|
@ -223,6 +243,10 @@ impl IntoPyObject for NoArgs
|
|||
/// Converts `NoArgs` to an empty Python tuple.
|
||||
impl IntoPyTuple for NoArgs {
|
||||
|
||||
fn to_tuple(&self, py: Python) -> Py<PyTuple> {
|
||||
PyTuple::empty(py)
|
||||
}
|
||||
|
||||
fn into_tuple(self, py: Python) -> Py<PyTuple> {
|
||||
PyTuple::empty(py)
|
||||
}
|
||||
|
@ -231,6 +255,10 @@ impl IntoPyTuple for NoArgs {
|
|||
/// Converts `()` to an empty Python tuple.
|
||||
impl IntoPyTuple for () {
|
||||
|
||||
fn to_tuple(&self, py: Python) -> Py<PyTuple> {
|
||||
PyTuple::empty(py)
|
||||
}
|
||||
|
||||
fn into_tuple(self, py: Python) -> Py<PyTuple> {
|
||||
PyTuple::empty(py)
|
||||
}
|
||||
|
@ -244,7 +272,7 @@ pyobject_extract!(py, obj to NoArgs => {
|
|||
if t.len() == 0 {
|
||||
Ok(NoArgs)
|
||||
} else {
|
||||
Err(wrong_tuple_length(obj.py(), t, 0))
|
||||
Err(wrong_tuple_length(t, 0))
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -9,10 +9,10 @@ use std::os::raw::c_int;
|
|||
|
||||
use ffi;
|
||||
use typeob::{PyTypeInfo, PyTypeObject, PyObjectAlloc};
|
||||
use instance::{Py, PyToken, PyObjectWithToken, AsPyRef};
|
||||
use instance::{Py, PyToken, AsPyRef};
|
||||
use object::PyObject;
|
||||
use objects::{PyObjectRef, PyType, PyDict, PyModule};
|
||||
use err::{PyErr, PyResult, PyDowncastError, ToPyErr};
|
||||
use err::{PyErr, PyResult, PyDowncastError};
|
||||
use pythonrun::{self, GILGuard};
|
||||
|
||||
|
||||
|
@ -46,7 +46,7 @@ pub trait PyDowncastFrom : Sized {
|
|||
if let Some(ob) = Self::try_downcast_from(ob) {
|
||||
Ok(ob)
|
||||
} else {
|
||||
Err(PyDowncastError(ob.py(), None))
|
||||
Err(PyDowncastError)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,7 +55,7 @@ pub trait PyDowncastFrom : Sized {
|
|||
if let Some(ob) = Self::try_exact_downcast_from(ob) {
|
||||
Ok(ob)
|
||||
} else {
|
||||
Err(PyDowncastError(ob.py(), None))
|
||||
Err(PyDowncastError)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,8 +82,7 @@ pub trait PyMutDowncastFrom : Sized {
|
|||
if let Some(o) = Self::try_mut_downcast_from(ob) {
|
||||
return Ok(o)
|
||||
} else {
|
||||
let py = unsafe { Python::assume_gil_acquired() };
|
||||
Err(PyDowncastError(py, None))
|
||||
Err(PyDowncastError)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -92,8 +91,7 @@ pub trait PyMutDowncastFrom : Sized {
|
|||
if let Some(ob) = Self::try_mut_exact_downcast_from(ob) {
|
||||
Ok(ob)
|
||||
} else {
|
||||
let py = unsafe { Python::assume_gil_acquired() };
|
||||
Err(PyDowncastError(py, None))
|
||||
Err(PyDowncastError)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -107,7 +105,7 @@ pub trait PyDowncastInto : Sized {
|
|||
|
||||
/// Cast from ffi::PyObject to a concrete Python object type.
|
||||
fn downcast_into_from_ptr(py: Python, ptr: *mut ffi::PyObject)
|
||||
-> Result<Self, PyDowncastError>;
|
||||
-> Result<Self, PyDowncastError>;
|
||||
|
||||
/// Cast from ffi::PyObject to a concrete Python object type.
|
||||
fn unchecked_downcast_into<I>(I) -> Self where I: IntoPyPointer;
|
||||
|
@ -210,7 +208,7 @@ impl<'p> Python<'p> {
|
|||
/// 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<&'p PyObjectRef> {
|
||||
let code = CString::new(code).map_err(|e| e.to_pyerr(self))?;
|
||||
let code = CString::new(code)?;
|
||||
|
||||
unsafe {
|
||||
let mptr = ffi::PyImport_AddModule("__main__\0".as_ptr() as *const _);
|
||||
|
@ -303,7 +301,7 @@ impl<'p> Python<'p> {
|
|||
impl<'p> Python<'p> {
|
||||
|
||||
/// Register object in release pool, and try to downcast to specific type.
|
||||
pub fn checked_cast_as<T>(self, obj: PyObject) -> Result<&'p T, PyDowncastError<'p>>
|
||||
pub fn checked_cast_as<T>(self, obj: PyObject) -> Result<&'p T, PyDowncastError>
|
||||
where T: PyDowncastFrom
|
||||
{
|
||||
unsafe {
|
||||
|
|
|
@ -20,7 +20,7 @@ impl class::PyBufferProtocol for TestClass {
|
|||
|
||||
fn bf_getbuffer(&self, view: *mut ffi::Py_buffer, flags: c_int) -> PyResult<()> {
|
||||
if view.is_null() {
|
||||
return Err(PyErr::new::<exc::BufferError, _>(self.py(), "View is null"))
|
||||
return Err(PyErr::new::<exc::BufferError, _>("View is null"))
|
||||
}
|
||||
|
||||
unsafe {
|
||||
|
@ -28,7 +28,7 @@ impl class::PyBufferProtocol for TestClass {
|
|||
}
|
||||
|
||||
if (flags & ffi::PyBUF_WRITABLE) == ffi::PyBUF_WRITABLE {
|
||||
return Err(PyErr::new::<exc::BufferError, _>(self.py(), "Object is not writable"))
|
||||
return Err(PyErr::new::<exc::BufferError, _>("Object is not writable"))
|
||||
}
|
||||
|
||||
let bytes = &self.vec;
|
||||
|
|
|
@ -656,7 +656,7 @@ impl PySequenceProtocol for Sequence {
|
|||
|
||||
fn __getitem__(&self, key: isize) -> PyResult<isize> {
|
||||
if key == 5 {
|
||||
return Err(PyErr::new::<exc::IndexError, NoArgs>(self.py(), NoArgs));
|
||||
return Err(PyErr::new::<exc::IndexError, NoArgs>(NoArgs));
|
||||
}
|
||||
Ok(key)
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ impl<'p> PyMappingProtocol<'p> for Test
|
|||
return Ok("int".into_object(self.py()))
|
||||
}
|
||||
}
|
||||
Err(PyErr::new::<exc::ValueError, _>(self.py(), "error"))
|
||||
Err(PyErr::new::<exc::ValueError, _>("error"))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue