introduce ToPyTuple trait, that simplifies ObjectProtoco.call method
This commit is contained in:
parent
f651b442ba
commit
8d728663d7
|
@ -21,7 +21,7 @@ use std::cmp::Ordering;
|
|||
use ffi;
|
||||
use libc;
|
||||
use python::{Python, PythonObject, ToPythonPointer};
|
||||
use objects::{PyObject, PyTuple, PyDict, PyString};
|
||||
use objects::{PyObject, PyTuple, PyDict, PyString, ToPyTuple};
|
||||
use conversion::ToPyObject;
|
||||
use err::{PyErr, PyResult, self};
|
||||
|
||||
|
@ -182,7 +182,7 @@ pub trait ObjectProtocol : PythonObject {
|
|||
/// This is equivalent to the Python expression: 'self(*args, **kwargs)'
|
||||
#[inline]
|
||||
fn call<A>(&self, py: Python, args: A, kwargs: Option<&PyDict>) -> PyResult<PyObject>
|
||||
where A: ToPyObject<ObjectType=PyTuple>
|
||||
where A: ToPyTuple
|
||||
{
|
||||
args.with_borrowed_ptr(py, |args| unsafe {
|
||||
err::result_from_owned_ptr(py, ffi::PyObject_Call(self.as_ptr(), args, kwargs.as_ptr()))
|
||||
|
@ -193,7 +193,7 @@ pub trait ObjectProtocol : PythonObject {
|
|||
/// This is equivalent to the Python expression: 'self.name(*args, **kwargs)'
|
||||
#[inline]
|
||||
fn call_method<A>(&self, py: Python, name: &str, args: A, kwargs: Option<&PyDict>) -> PyResult<PyObject>
|
||||
where A: ToPyObject<ObjectType=PyTuple>
|
||||
where A: ToPyTuple
|
||||
{
|
||||
try!(self.getattr(py, name)).call(py, args, kwargs)
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ pub use self::string::PyString as PyUnicode;
|
|||
pub use self::iterator::PyIterator;
|
||||
pub use self::boolobject::PyBool;
|
||||
pub use self::bytearray::PyByteArray;
|
||||
pub use self::tuple::{PyTuple, NoArgs};
|
||||
pub use self::tuple::{PyTuple, NoArgs, ToPyTuple};
|
||||
pub use self::dict::PyDict;
|
||||
pub use self::list::PyList;
|
||||
#[cfg(feature="python27-sys")]
|
||||
|
|
|
@ -22,7 +22,7 @@ use libc::c_char;
|
|||
use python::{Python, PythonObject, PyDrop};
|
||||
use objectprotocol::ObjectProtocol;
|
||||
use conversion::ToPyObject;
|
||||
use objects::{PyObject, PyTuple, PyDict, exc};
|
||||
use objects::{PyObject, PyTuple, PyDict, ToPyTuple, exc};
|
||||
use py_class::PythonObjectFromPyClassMacro;
|
||||
use err::{self, PyResult, PyErr};
|
||||
use std::ffi::{CStr, CString};
|
||||
|
@ -93,7 +93,7 @@ impl PyModule {
|
|||
/// Calls a function in the module.
|
||||
/// This is equivalent to the Python expression: `getattr(module, name)(*args, **kwargs)`
|
||||
pub fn call<A>(&self, py: Python, name: &str, args: A, kwargs: Option<&PyDict>) -> PyResult<PyObject>
|
||||
where A: ToPyObject<ObjectType=PyTuple>
|
||||
where A: ToPyTuple
|
||||
{
|
||||
try!(self.as_object().getattr(py, name)).call(py, args, kwargs)
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
use python::{Python, PythonObject, ToPythonPointer, PyDrop};
|
||||
use python::{Python, PythonObject, ToPythonPointer, PyClone, PyDrop};
|
||||
use err::{self, PyErr, PyResult};
|
||||
use super::object::PyObject;
|
||||
use super::exc;
|
||||
|
@ -24,6 +24,23 @@ use ffi::{self, Py_ssize_t};
|
|||
use conversion::{FromPyObject, ToPyObject};
|
||||
use std::slice;
|
||||
|
||||
/// Conversion trait that allows various objects to be converted into PyTuple object.
|
||||
pub trait ToPyTuple {
|
||||
|
||||
/// Converts self into a PyTuple object.
|
||||
fn to_py_tuple(&self, py: Python) -> 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<F, R>(&self, py: Python, f: F) -> R
|
||||
where F: FnOnce(*mut ffi::PyObject) -> R
|
||||
{
|
||||
let obj = self.to_py_tuple(py).into_object();
|
||||
f(obj.as_ptr())
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a Python tuple object.
|
||||
pub struct PyTuple(PyObject);
|
||||
|
||||
|
@ -92,6 +109,18 @@ impl PyTuple {
|
|||
}
|
||||
}
|
||||
|
||||
impl ToPyTuple for PyTuple {
|
||||
fn to_py_tuple(&self, py: Python) -> PyTuple {
|
||||
self.clone_ref(py)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ToPyTuple for &'a str {
|
||||
fn to_py_tuple(&self, py: Python) -> PyTuple {
|
||||
PyTuple::new(py, &[py_coerce_expr!(self.to_py_object(py)).into_object()])
|
||||
}
|
||||
}
|
||||
|
||||
fn wrong_tuple_length(py: Python, t: &PyTuple, expected_length: usize) -> PyErr {
|
||||
let msg = format!("Expected tuple of length {}, but got tuple of length {}.", expected_length, t.len(py));
|
||||
PyErr::new_lazy_init(py.get_type::<exc::ValueError>(), Some(msg.to_py_object(py).into_object()))
|
||||
|
@ -114,6 +143,15 @@ macro_rules! tuple_conversion ({$length:expr,$(($refN:ident, $n:tt, $T:ident)),+
|
|||
}
|
||||
}
|
||||
|
||||
impl <$($T: ToPyObject),+> ToPyTuple for ($($T,)+) {
|
||||
|
||||
fn to_py_tuple(&self, py: Python) -> PyTuple {
|
||||
PyTuple::new(py, &[
|
||||
$(py_coerce_expr!(self.$n.to_py_object(py)).into_object(),)+
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
impl <'s, $($T: FromPyObject<'s>),+> FromPyObject<'s> for ($($T,)+) {
|
||||
fn extract(py: Python, obj: &'s PyObject) -> PyResult<Self> {
|
||||
let t = try!(obj.cast_as::<PyTuple>(py));
|
||||
|
@ -168,6 +206,15 @@ impl ToPyObject for NoArgs {
|
|||
}
|
||||
}
|
||||
|
||||
/// Converts `NoArgs` to an empty Python tuple.
|
||||
impl ToPyTuple for NoArgs {
|
||||
|
||||
fn to_py_tuple(&self, py: Python) -> PyTuple {
|
||||
PyTuple::empty(py)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Returns `Ok(NoArgs)` if the input is an empty Python tuple.
|
||||
/// Otherwise, returns an error.
|
||||
extract!(obj to NoArgs; py => {
|
||||
|
@ -180,7 +227,6 @@ extract!(obj to NoArgs; py => {
|
|||
});
|
||||
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use python::{Python, PythonObject};
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
use python::{Python, PythonObject, ToPythonPointer};
|
||||
use conversion::ToPyObject;
|
||||
use objects::{PyObject, PyTuple, PyDict};
|
||||
use objects::{PyObject, PyTuple, PyDict, ToPyTuple};
|
||||
use err::{PyResult, result_from_owned_ptr};
|
||||
use ffi;
|
||||
use std::ffi::CStr;
|
||||
|
@ -67,7 +67,7 @@ impl PyType {
|
|||
/// This is equivalent to the Python expression: `self(*args, **kwargs)`
|
||||
#[inline]
|
||||
pub fn call<A>(&self, py: Python, args: A, kwargs: Option<&PyDict>) -> PyResult<PyObject>
|
||||
where A: ToPyObject<ObjectType=PyTuple>
|
||||
where A: ToPyTuple
|
||||
{
|
||||
args.with_borrowed_ptr(py, |args| unsafe {
|
||||
result_from_owned_ptr(py, ffi::PyObject_Call(self.0.as_ptr(), args, kwargs.as_ptr()))
|
||||
|
|
Loading…
Reference in New Issue