parent
44611991c3
commit
0a270a0583
|
@ -8,11 +8,11 @@ fn main() {
|
|||
let py = gil.python();
|
||||
|
||||
let sys = py.import("sys").unwrap();
|
||||
let version: String = sys.get("version", py).unwrap().extract(py).unwrap();
|
||||
let version: String = sys.get(py, "version").unwrap().extract(py).unwrap();
|
||||
|
||||
let os = py.import("os").unwrap();
|
||||
let getenv = os.get("getenv", py).unwrap();
|
||||
let user: String = getenv.call(("USER",), None, py).unwrap().extract(py).unwrap();
|
||||
let getenv = os.get(py, "getenv").unwrap();
|
||||
let user: String = getenv.call(py, ("USER",), None).unwrap().extract(py).unwrap();
|
||||
|
||||
println!("Hello {}, I'm Python {}", user, version);
|
||||
}
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
use cpython::{Python, PyObject, PyRustObject, PyResult};
|
||||
|
||||
py_module_initializer!(custom_type, |py, m| {
|
||||
try!(m.add("__doc__", "Module documentation string", py));
|
||||
try!(m.add_type::<i32>("MyType", py)
|
||||
try!(m.add(py, "__doc__", "Module documentation string"));
|
||||
try!(m.add_type::<i32>(py, "MyType")
|
||||
.add("a", py_method!(a()))
|
||||
.finish());
|
||||
Ok(())
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
use cpython::{PyObject, PyResult, Python, PyTuple, PyDict};
|
||||
|
||||
py_module_initializer!(hello, |py, m| {
|
||||
try!(m.add("__doc__", "Module documentation string", py));
|
||||
try!(m.add("run", py_fn!(run), py));
|
||||
try!(m.add("val", py_fn!(val()), py));
|
||||
try!(m.add(py, "__doc__", "Module documentation string"));
|
||||
try!(m.add(py, "run", py_fn!(run)));
|
||||
try!(m.add(py, "val", py_fn!(val())));
|
||||
Ok(())
|
||||
});
|
||||
|
||||
|
|
|
@ -5,14 +5,14 @@
|
|||
#[macro_use] extern crate cpython;
|
||||
|
||||
py_module_initializer!(inheritance, |py, m| {
|
||||
try!(m.add("__doc__", "Module documentation string", py));
|
||||
try!(m.add(py, "__doc__", "Module documentation string"));
|
||||
let base_class = try!(
|
||||
m.add_type::<()>("BaseClass", py)
|
||||
m.add_type::<()>(py, "BaseClass")
|
||||
.doc("Type doc string")
|
||||
.finish());
|
||||
for i in 1..10 {
|
||||
try!(
|
||||
m.add_type::<()>(&format!("C{}", i), py)
|
||||
m.add_type::<()>(py, &format!("C{}", i))
|
||||
.base(&base_class)
|
||||
.doc(&format!("Derived class #{}", i))
|
||||
.finish());
|
||||
|
|
|
@ -43,10 +43,10 @@ pub struct ParamDescription<'a> {
|
|||
/// * output: Output array that receives the arguments.
|
||||
/// Must have same length as `params` and must be initialized to `None`.
|
||||
pub fn parse_args(
|
||||
py: Python,
|
||||
fname: Option<&str>, params: &[ParamDescription],
|
||||
args: &PyTuple, kwargs: Option<&PyDict>,
|
||||
output: &mut[Option<PyObject>],
|
||||
py: Python
|
||||
output: &mut[Option<PyObject>]
|
||||
) -> PyResult<()>
|
||||
{
|
||||
assert!(params.len() == output.len());
|
||||
|
@ -65,7 +65,7 @@ pub fn parse_args(
|
|||
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.get_item(p.name, py)) {
|
||||
match kwargs.and_then(|d| d.get_item(py, p.name)) {
|
||||
Some(kwarg) => {
|
||||
*out = Some(kwarg);
|
||||
used_keywords += 1;
|
||||
|
@ -77,7 +77,7 @@ pub fn parse_args(
|
|||
},
|
||||
None => {
|
||||
if i < nargs {
|
||||
*out = Some(args.get_item(i, py));
|
||||
*out = Some(args.get_item(py, i));
|
||||
} else {
|
||||
*out = None;
|
||||
if !p.is_optional {
|
||||
|
@ -92,7 +92,7 @@ pub fn parse_args(
|
|||
if used_keywords != nkeywords {
|
||||
// check for extraneous keyword arguments
|
||||
for (key, _value) in kwargs.unwrap().items(py) {
|
||||
let key = try!(PyString::extract(&key, py));
|
||||
let key = try!(PyString::extract(py, &key));
|
||||
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",
|
||||
|
@ -106,11 +106,11 @@ pub fn parse_args(
|
|||
#[doc(hidden)]
|
||||
#[macro_export]
|
||||
macro_rules! py_argparse_extract {
|
||||
( $iter:expr, $py:ident, ( ) $body:block ) => { $body };
|
||||
( $iter:expr, $py:ident, ( $pname:ident : $ptype:ty ) $body:block) => {
|
||||
match <$ptype as $crate::ExtractPyObject>::prepare_extract($iter.next().unwrap().as_ref().unwrap(), $py) {
|
||||
( $py:ident, $iter:expr, ( ) $body:block ) => { $body };
|
||||
( $py:ident, $iter:expr, ( $pname:ident : $ptype:ty ) $body:block) => {
|
||||
match <$ptype as $crate::ExtractPyObject>::prepare_extract($py, $iter.next().unwrap().as_ref().unwrap()) {
|
||||
Ok(prepared) => {
|
||||
match <$ptype as $crate::ExtractPyObject>::extract(&prepared, $py) {
|
||||
match <$ptype as $crate::ExtractPyObject>::extract($py, &prepared) {
|
||||
Ok($pname) => $body,
|
||||
Err(e) => Err(e)
|
||||
}
|
||||
|
@ -118,9 +118,9 @@ macro_rules! py_argparse_extract {
|
|||
Err(e) => Err(e)
|
||||
}
|
||||
};
|
||||
( $iter:expr, $py: ident, ( $pname:ident : $ptype:ty , $($r:tt)+ ) $body:block) => {
|
||||
py_argparse_extract!($iter, $py, ($pname: $ptype) {
|
||||
py_argparse_extract!( $iter, $py, ( $($r)* ) $body)
|
||||
( $py: ident, $iter:expr, ( $pname:ident : $ptype:ty , $($r:tt)+ ) $body:block) => {
|
||||
py_argparse_extract!($py, $iter, ($pname: $ptype) {
|
||||
py_argparse_extract!( $py, $iter, ( $($r)* ) $body)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -133,8 +133,9 @@ macro_rules! py_argparse_snd {
|
|||
|
||||
/// This macro is used to parse a parameter list into a set of variables.
|
||||
///
|
||||
/// Syntax: `py_argparse!(fname, args, kwargs, (parameter-list) { body })`
|
||||
/// Syntax: `py_argparse!(py, fname, args, kwargs, (parameter-list) { body })`
|
||||
///
|
||||
/// * `py`: the `Python` token
|
||||
/// * `fname`: expression of type `Option<&str>`: Name of the function used in error messages.
|
||||
/// * `args`: expression of type `&PyTuple`: The position arguments
|
||||
/// * `kwargs`: expression of type `Option<&PyDict>`: The named arguments
|
||||
|
@ -149,7 +150,7 @@ macro_rules! py_argparse_snd {
|
|||
/// If extraction fails, `py_argparse!()` returns a failed `PyResult` without evaluating `body`.
|
||||
#[macro_export]
|
||||
macro_rules! py_argparse {
|
||||
($fname:expr, $args:expr, $kwargs:expr, $py:expr, ($( $pname:ident : $ptype:ty ),*) $body:block) => {{
|
||||
($py:expr, $fname:expr, $args:expr, $kwargs:expr, ($( $pname:ident : $ptype:ty ),*) $body:block) => {{
|
||||
const PARAMS: &'static [$crate::argparse::ParamDescription<'static>] = &[
|
||||
$(
|
||||
$crate::argparse::ParamDescription {
|
||||
|
@ -160,12 +161,12 @@ macro_rules! py_argparse {
|
|||
];
|
||||
let py: $crate::Python = $py;
|
||||
let mut output = [$( py_argparse_snd!($pname, None) ),*];
|
||||
match $crate::argparse::parse_args($fname, PARAMS, $args, $kwargs, &mut output, py) {
|
||||
match $crate::argparse::parse_args(py, $fname, PARAMS, $args, $kwargs, &mut output) {
|
||||
Ok(()) => {
|
||||
// We can't use experimental slice pattern syntax in macros
|
||||
//let &[$(ref $pname),*] = &output;
|
||||
let mut iter = output.iter();
|
||||
let ret = py_argparse_extract!( iter, py, ( $( $pname : $ptype ),* ) $body );
|
||||
let ret = py_argparse_extract!( py, iter, ( $( $pname : $ptype ),* ) $body );
|
||||
assert!(iter.next() == None);
|
||||
ret
|
||||
},
|
||||
|
@ -185,7 +186,7 @@ mod test {
|
|||
let py = gil_guard.python();
|
||||
let mut called = false;
|
||||
let tuple = ("abc", 42).to_py_object(py);
|
||||
py_argparse!(None, &tuple, None, py, (x: &str, y: i32) {
|
||||
py_argparse!(py, None, &tuple, None, (x: &str, y: i32) {
|
||||
assert_eq!(x, "abc");
|
||||
assert_eq!(y, 42);
|
||||
called = true;
|
||||
|
|
|
@ -94,9 +94,9 @@ pub trait ToPyObject {
|
|||
pub trait ExtractPyObject<'prepared> : Sized {
|
||||
type Prepared : 'static;
|
||||
|
||||
fn prepare_extract<'a, 'p>(obj: &'a PyObject, py: Python<'p>) -> PyResult<Self::Prepared>;
|
||||
fn prepare_extract<'a, 'p>(py: Python<'p>, obj: &'a PyObject) -> PyResult<Self::Prepared>;
|
||||
|
||||
fn extract<'p>(prepared: &'prepared Self::Prepared, py: Python<'p>) -> PyResult<Self>;
|
||||
fn extract<'p>(py: Python<'p>, prepared: &'prepared Self::Prepared) -> PyResult<Self>;
|
||||
}
|
||||
|
||||
impl <'prepared, T> ExtractPyObject<'prepared> for T
|
||||
|
@ -105,12 +105,12 @@ where T: PythonObjectWithCheckedDowncast
|
|||
type Prepared = PyObject;
|
||||
|
||||
#[inline]
|
||||
fn prepare_extract(obj: &PyObject, py: Python) -> PyResult<Self::Prepared> {
|
||||
fn prepare_extract(py: Python, obj: &PyObject) -> PyResult<Self::Prepared> {
|
||||
Ok(obj.clone_ref(py))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn extract(obj: &'prepared Self::Prepared, py: Python) -> PyResult<T> {
|
||||
fn extract(py: Python, obj: &'prepared Self::Prepared) -> PyResult<T> {
|
||||
Ok(try!(obj.clone_ref(py).cast_into(py)))
|
||||
}
|
||||
}
|
||||
|
|
14
src/err.rs
14
src/err.rs
|
@ -91,10 +91,10 @@ impl PyErr {
|
|||
pub fn new<T, V>(py: Python, value: V) -> PyErr
|
||||
where T: PythonObjectWithTypeObject, V: ToPyObject
|
||||
{
|
||||
PyErr::new_helper(py.get_type::<T>(), value.to_py_object(py).into_object())
|
||||
PyErr::new_helper(py, py.get_type::<T>(), value.to_py_object(py).into_object())
|
||||
}
|
||||
|
||||
fn new_helper(ty: PyType, value: PyObject) -> PyErr {
|
||||
fn new_helper(_py: Python, ty: PyType, value: PyObject) -> PyErr {
|
||||
assert!(unsafe { ffi::PyExceptionClass_Check(ty.as_object().as_ptr()) } != 0);
|
||||
PyErr {
|
||||
ptype: ty.into_object(),
|
||||
|
@ -108,11 +108,11 @@ 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>(obj: O, py: Python) -> PyErr where O: PythonObject {
|
||||
PyErr::from_instance_helper(obj.into_object(), py)
|
||||
pub fn from_instance<O>(py: Python, obj: O) -> PyErr where O: PythonObject {
|
||||
PyErr::from_instance_helper(py, obj.into_object())
|
||||
}
|
||||
|
||||
fn from_instance_helper(obj: PyObject, py: Python) -> PyErr {
|
||||
fn from_instance_helper(py: Python, obj: PyObject) -> PyErr {
|
||||
if unsafe { ffi::PyExceptionInstance_Check(obj.as_ptr()) } != 0 {
|
||||
PyErr {
|
||||
ptype: unsafe { PyObject::from_borrowed_ptr(py, ffi::PyExceptionInstance_Class(obj.as_ptr())) },
|
||||
|
@ -162,7 +162,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.
|
||||
#[inline]
|
||||
pub fn matches(&self, exc: &PyObject, _py: Python) -> bool {
|
||||
pub fn matches(&self, _py: Python, exc: &PyObject) -> bool {
|
||||
unsafe { ffi::PyErr_GivenExceptionMatches(self.ptype.as_ptr(), exc.as_ptr()) != 0 }
|
||||
}
|
||||
|
||||
|
@ -175,7 +175,7 @@ impl PyErr {
|
|||
}
|
||||
// This is safe as long as normalized() doesn't unwind due to a panic.
|
||||
}
|
||||
|
||||
|
||||
/// 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 {
|
||||
|
|
|
@ -91,7 +91,7 @@ macro_rules! py_fn {
|
|||
Some(kwargs) => Some(<$crate::PyDict as $crate::PythonObject>::unchecked_downcast_from(kwargs)),
|
||||
None => None
|
||||
};
|
||||
match py_argparse!(Some(stringify!($f)), &args, kwargs.as_ref(), py,
|
||||
match py_argparse!(py, Some(stringify!($f)), &args, kwargs.as_ref(),
|
||||
( $($pname : $ptype),* ) { $f( py, $($pname),* ) })
|
||||
{
|
||||
Ok(val) => {
|
||||
|
|
48
src/lib.rs
48
src/lib.rs
|
@ -20,7 +20,6 @@
|
|||
#![feature(filling_drop)] // necessary to avoid segfault with unsafe_no_drop_flag
|
||||
#![feature(optin_builtin_traits)] // for opting out of Sync/Send
|
||||
#![feature(slice_patterns)] // for tuple_conversion macros
|
||||
#![feature(utf8_error)] // for translating Utf8Error to Python exception
|
||||
#![feature(plugin)]
|
||||
#![plugin(interpolate_idents)]
|
||||
#![allow(unused_imports)] // because some imports are only necessary with python 2.x or 3.x
|
||||
|
@ -31,28 +30,25 @@
|
|||
//! In Python, all objects are implicitly reference counted.
|
||||
//! In rust, we will use the `PyObject` type to represent a reference to a Python object.
|
||||
//!
|
||||
//! The method `clone_ref()` (from trait `PyClone`) can be used to create additional
|
||||
//! references to the same Python object.
|
||||
//!
|
||||
//! Because all Python objects potentially have multiple owners, the concept
|
||||
//! concept of rust mutability does not apply to Python objects.
|
||||
//! concept of Rust mutability does not apply to Python objects.
|
||||
//! As a result, this API will allow mutating Python objects even if they are not stored
|
||||
//! in a mutable rust variable.
|
||||
//! in a mutable Rust variable.
|
||||
//!
|
||||
//! The Python interpreter uses a global interpreter lock (GIL)
|
||||
//! to ensure thread-safety.
|
||||
//! This API uses the lifetime parameter `PyObject<'p>` to ensure that Python objects cannot
|
||||
//! be accessed without holding the GIL.
|
||||
//! Throughout this library, the lifetime `'p` always refers to the lifetime of the Python interpreter.
|
||||
//! This API uses a zero-sized `struct Python<'p>` as a token to indicate
|
||||
//! that a function can assume that the GIL is held.
|
||||
//!
|
||||
//! When accessing existing objects, the lifetime on `PyObject<'p>` is sufficient to ensure that the GIL
|
||||
//! is held by the current code. But we also need to ensure that the GIL is held when creating new objects.
|
||||
//! For this purpose, this library uses the marker type `Python<'p>`,
|
||||
//! which acts like a reference to the whole Python interpreter.
|
||||
//!
|
||||
//! You can obtain a `Python<'p>` instance by acquiring the GIL, or by calling `Python()`
|
||||
//! on any existing Python object.
|
||||
//! You obtain a `Python` instance by acquiring the GIL,
|
||||
//! and have to pass it into all operations that call into the Python runtime.
|
||||
//!
|
||||
//! # Error Handling
|
||||
//! The vast majority of operations in this library will return `PyResult<'p, ...>`.
|
||||
//! This is an alias for the type `Result<..., PyErr<'p>>`.
|
||||
//! The vast majority of operations in this library will return `PyResult<...>`.
|
||||
//! This is an alias for the type `Result<..., PyErr>`.
|
||||
//!
|
||||
//! A `PyErr` represents a Python exception. Errors within the rust-cpython library are
|
||||
//! also exposed as Python exceptions.
|
||||
|
@ -66,14 +62,14 @@
|
|||
//!
|
||||
//! fn main() {
|
||||
//! let gil = Python::acquire_gil();
|
||||
//! let py = gil.python();
|
||||
//! let py = gil.python(); // obtain `Python` token
|
||||
//!
|
||||
//! let sys = py.import("sys").unwrap();
|
||||
//! let version: String = sys.get("version", py).unwrap().extract(py).unwrap();
|
||||
//! let version: String = sys.get(py, "version").unwrap().extract(py).unwrap();
|
||||
//!
|
||||
//! let os = py.import("os").unwrap();
|
||||
//! let getenv = os.get("getenv", py).unwrap();
|
||||
//! let user: String = getenv.call(("USER",), None, py).unwrap().extract(py).unwrap();
|
||||
//! let getenv = os.get(py, "getenv").unwrap();
|
||||
//! let user: String = getenv.call(py, ("USER",), None).unwrap().extract(py).unwrap();
|
||||
//!
|
||||
//! println!("Hello {}, I'm Python {}", user, version);
|
||||
//! }
|
||||
|
@ -142,7 +138,7 @@ pub mod _detail {
|
|||
|
||||
/// assume_gil_acquired(), but the returned Python<'p> is bounded by the scope
|
||||
/// of the referenced variable.
|
||||
/// This is useful in macros to ensure that type inference doesn't set 'p == 'static.
|
||||
/// This is useful in macros to ensure that type inference doesn't set `'p` == `'static`.
|
||||
#[inline]
|
||||
pub unsafe fn bounded_assume_gil_acquired<'p, T>(_bound: &'p T) -> super::Python<'p> {
|
||||
super::Python::assume_gil_acquired()
|
||||
|
@ -154,12 +150,8 @@ pub mod _detail {
|
|||
///
|
||||
/// Macro syntax: `py_module_initializer!($name, |$py, $m| $body)`
|
||||
///
|
||||
/// 1. The module name as a string literal.
|
||||
/// 2. The name of the init function as an identifier.
|
||||
/// The function must be named `init$module_name` so that Python 2.7 can load the module.
|
||||
/// Note: this parameter will be removed in a future version
|
||||
/// (once Rust supports `concat_ident!` as function name).
|
||||
/// 3. A function or lambda of type `Fn(Python<'p>, &PyModule<'p>) -> PyResult<'p, ()>`.
|
||||
/// 1. `name`: The module name as a Rust identifier.
|
||||
/// 2. A lambda of type `Fn(Python, &PyModule) -> PyResult<()>`.
|
||||
/// This function will be called when the module is imported, and is responsible
|
||||
/// for adding the module's members.
|
||||
///
|
||||
|
@ -172,8 +164,8 @@ pub mod _detail {
|
|||
/// use cpython::{Python, PyResult, PyObject};
|
||||
///
|
||||
/// py_module_initializer!(example, |py, m| {
|
||||
/// try!(m.add("__doc__", "Module documentation string", py));
|
||||
/// try!(m.add("run", py_fn!(run()), py));
|
||||
/// try!(m.add(py, "__doc__", "Module documentation string"));
|
||||
/// try!(m.add(py, "run", py_fn!(run())));
|
||||
/// Ok(())
|
||||
/// });
|
||||
///
|
||||
|
|
|
@ -30,7 +30,7 @@ pub trait ObjectProtocol : PythonObject {
|
|||
/// Determines whether this object has the given attribute.
|
||||
/// This is equivalent to the Python expression 'hasattr(self, attr_name)'.
|
||||
#[inline]
|
||||
fn hasattr<N>(&self, attr_name: N, py: Python) -> PyResult<bool> where N: ToPyObject {
|
||||
fn hasattr<N>(&self, py: Python, attr_name: N) -> PyResult<bool> where N: ToPyObject {
|
||||
attr_name.with_borrowed_ptr(py, |attr_name| unsafe {
|
||||
Ok(ffi::PyObject_HasAttr(self.as_ptr(), attr_name) != 0)
|
||||
})
|
||||
|
@ -39,7 +39,7 @@ pub trait ObjectProtocol : PythonObject {
|
|||
/// Retrieves an attribute value.
|
||||
/// This is equivalent to the Python expression 'self.attr_name'.
|
||||
#[inline]
|
||||
fn getattr<N>(&self, attr_name: N, py: Python) -> PyResult<PyObject> where N: ToPyObject {
|
||||
fn getattr<N>(&self, py: Python, attr_name: N) -> PyResult<PyObject> where N: ToPyObject {
|
||||
attr_name.with_borrowed_ptr(py, |attr_name| unsafe {
|
||||
err::result_from_owned_ptr(py,
|
||||
ffi::PyObject_GetAttr(self.as_ptr(), attr_name))
|
||||
|
@ -49,7 +49,7 @@ pub trait ObjectProtocol : PythonObject {
|
|||
/// Sets an attribute value.
|
||||
/// This is equivalent to the Python expression 'self.attr_name = value'.
|
||||
#[inline]
|
||||
fn setattr<N, V>(&self, attr_name: N, value: V, py: Python) -> PyResult<()>
|
||||
fn setattr<N, V>(&self, py: Python, attr_name: N, value: V) -> PyResult<()>
|
||||
where N: ToPyObject, V: ToPyObject
|
||||
{
|
||||
attr_name.with_borrowed_ptr(py, move |attr_name|
|
||||
|
@ -62,7 +62,7 @@ pub trait ObjectProtocol : PythonObject {
|
|||
/// Deletes an attribute.
|
||||
/// This is equivalent to the Python expression 'del self.attr_name'.
|
||||
#[inline]
|
||||
fn delattr<N>(&self, attr_name: N, py: Python) -> PyResult<()> where N: ToPyObject {
|
||||
fn delattr<N>(&self, py: Python, attr_name: N) -> PyResult<()> where N: ToPyObject {
|
||||
attr_name.with_borrowed_ptr(py, |attr_name| unsafe {
|
||||
err::error_on_minusone(py,
|
||||
ffi::PyObject_DelAttr(self.as_ptr(), attr_name))
|
||||
|
@ -72,7 +72,7 @@ pub trait ObjectProtocol : PythonObject {
|
|||
/// Compares two Python objects.
|
||||
/// This is equivalent to the Python expression 'cmp(self, other)'.
|
||||
#[cfg(feature="python27-sys")]
|
||||
fn compare<O>(&self, other: O, py: Python) -> PyResult<Ordering> where O: ToPyObject {
|
||||
fn compare<O>(&self, py: Python, other: O) -> PyResult<Ordering> where O: ToPyObject {
|
||||
other.with_borrowed_ptr(py, |other| unsafe {
|
||||
let mut result : libc::c_int = -1;
|
||||
try!(err::error_on_minusone(py,
|
||||
|
@ -126,7 +126,7 @@ pub trait ObjectProtocol : PythonObject {
|
|||
/// Calls the object.
|
||||
/// This is equivalent to the Python expression: 'self(*args, **kwargs)'
|
||||
#[inline]
|
||||
fn call<A>(&self, args: A, kwargs: Option<&PyDict>, py: Python) -> PyResult<PyObject>
|
||||
fn call<A>(&self, py: Python, args: A, kwargs: Option<&PyDict>) -> PyResult<PyObject>
|
||||
where A: ToPyObject<ObjectType=PyTuple>
|
||||
{
|
||||
args.with_borrowed_ptr(py, |args| unsafe {
|
||||
|
@ -137,10 +137,10 @@ pub trait ObjectProtocol : PythonObject {
|
|||
/// Calls a method on the object.
|
||||
/// This is equivalent to the Python expression: 'self.name(*args, **kwargs)'
|
||||
#[inline]
|
||||
fn call_method<A>(&self, name: &str, args: A, kwargs: Option<&PyDict>, py: Python) -> PyResult<PyObject>
|
||||
fn call_method<A>(&self, py: Python, name: &str, args: A, kwargs: Option<&PyDict>) -> PyResult<PyObject>
|
||||
where A: ToPyObject<ObjectType=PyTuple>
|
||||
{
|
||||
try!(self.getattr(name, py)).call(args, kwargs, py)
|
||||
try!(self.getattr(py, name)).call(py, args, kwargs)
|
||||
}
|
||||
|
||||
/// Retrieves the hash code of the object.
|
||||
|
@ -181,7 +181,7 @@ pub trait ObjectProtocol : PythonObject {
|
|||
|
||||
/// This is equivalent to the Python expression: 'self[key]'
|
||||
#[inline]
|
||||
fn get_item<K>(&self, key: K, py: Python) -> PyResult<PyObject> where K: ToPyObject {
|
||||
fn get_item<K>(&self, py: Python, key: K) -> PyResult<PyObject> where K: ToPyObject {
|
||||
key.with_borrowed_ptr(py, |key| unsafe {
|
||||
err::result_from_owned_ptr(py,
|
||||
ffi::PyObject_GetItem(self.as_ptr(), key))
|
||||
|
@ -191,7 +191,7 @@ pub trait ObjectProtocol : PythonObject {
|
|||
/// Sets an item value.
|
||||
/// This is equivalent to the Python expression 'self[key] = value'.
|
||||
#[inline]
|
||||
fn set_item<K, V>(&self, key: K, value: V, py: Python) -> PyResult<()> where K: ToPyObject, V: ToPyObject {
|
||||
fn set_item<K, V>(&self, py: Python, key: K, value: V) -> PyResult<()> where K: ToPyObject, V: ToPyObject {
|
||||
key.with_borrowed_ptr(py, move |key|
|
||||
value.with_borrowed_ptr(py, |value| unsafe {
|
||||
err::error_on_minusone(py,
|
||||
|
@ -202,14 +202,14 @@ pub trait ObjectProtocol : PythonObject {
|
|||
/// Deletes an item.
|
||||
/// This is equivalent to the Python expression 'del self[key]'.
|
||||
#[inline]
|
||||
fn del_item<K>(&self, key: K, py: Python) -> PyResult<()> where K: ToPyObject {
|
||||
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,
|
||||
ffi::PyObject_DelItem(self.as_ptr(), key))
|
||||
})
|
||||
}
|
||||
|
||||
/* /// Takes an object and returns an iterator for it.
|
||||
/* TODO /// Takes an object and returns an iterator for it.
|
||||
/// This is typically a new iterator but if the argument
|
||||
/// is an iterator, this returns itself.
|
||||
#[cfg(feature="python27-sys")]
|
||||
|
@ -248,7 +248,7 @@ mod test {
|
|||
use std;
|
||||
use python::{Python, PythonObject};
|
||||
use conversion::ToPyObject;
|
||||
use objects::{/*PySequence, */PyList, PyTuple};
|
||||
use objects::{PyList, PyTuple};
|
||||
|
||||
#[test]
|
||||
fn test_debug_string() {
|
||||
|
|
|
@ -48,3 +48,5 @@ extract!(obj to bool; py => {
|
|||
Ok(try!(obj.cast_as::<PyBool>(py)).is_true())
|
||||
});
|
||||
|
||||
// TODO: mod tests
|
||||
|
||||
|
|
|
@ -61,7 +61,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, py: Python) -> PyResult<bool> where K: ToPyObject {
|
||||
pub fn contains<K>(&self, py: Python, key: K) -> PyResult<bool> where K: ToPyObject {
|
||||
key.with_borrowed_ptr(py, |key| unsafe {
|
||||
match ffi::PyDict_Contains(self.0.as_ptr(), key) {
|
||||
1 => Ok(true),
|
||||
|
@ -73,7 +73,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, py: Python) -> Option<PyObject> where K: ToPyObject {
|
||||
pub fn get_item<K>(&self, py: Python, key: K) -> Option<PyObject> where K: ToPyObject {
|
||||
key.with_borrowed_ptr(py, |key| unsafe {
|
||||
PyObject::from_borrowed_ptr_opt(py,
|
||||
ffi::PyDict_GetItem(self.0.as_ptr(), key))
|
||||
|
@ -82,7 +82,7 @@ impl PyDict {
|
|||
|
||||
/// Sets an item value.
|
||||
/// This is equivalent to the Python expression `self[key] = value`.
|
||||
pub fn set_item<K, V>(&self, key: K, value: V, py: Python) -> PyResult<()> where K: ToPyObject, V: ToPyObject {
|
||||
pub fn set_item<K, V>(&self, py: Python, key: K, value: V) -> PyResult<()> where K: ToPyObject, V: ToPyObject {
|
||||
key.with_borrowed_ptr(py, move |key|
|
||||
value.with_borrowed_ptr(py, |value| unsafe {
|
||||
err::error_on_minusone(py,
|
||||
|
@ -92,7 +92,7 @@ impl PyDict {
|
|||
|
||||
/// Deletes an item.
|
||||
/// This is equivalent to the Python expression `del self[key]`.
|
||||
pub fn del_item<K>(&self, key: K, py: Python) -> PyResult<()> where K: ToPyObject {
|
||||
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,
|
||||
ffi::PyDict_DelItem(self.0.as_ptr(), key))
|
||||
|
@ -135,7 +135,7 @@ impl <K, V> ToPyObject for collections::HashMap<K, V>
|
|||
fn to_py_object(&self, py: Python) -> PyDict {
|
||||
let dict = PyDict::new(py);
|
||||
for (key, value) in self {
|
||||
dict.set_item(key, value, py).unwrap();
|
||||
dict.set_item(py, key, value).unwrap();
|
||||
};
|
||||
dict
|
||||
}
|
||||
|
@ -150,7 +150,7 @@ impl <K, V> ToPyObject for collections::BTreeMap<K, V>
|
|||
fn to_py_object(&self, py: Python) -> PyDict {
|
||||
let dict = PyDict::new(py);
|
||||
for (key, value) in self {
|
||||
dict.set_item(key, value, py).unwrap();
|
||||
dict.set_item(py, key, value).unwrap();
|
||||
};
|
||||
dict
|
||||
}
|
||||
|
@ -183,8 +183,8 @@ mod test {
|
|||
let mut v = HashMap::new();
|
||||
v.insert(7, 32);
|
||||
let dict = v.to_py_object(py);
|
||||
assert_eq!(true, dict.contains(7i32, py).unwrap());
|
||||
assert_eq!(false, dict.contains(8i32, py).unwrap());
|
||||
assert_eq!(true, dict.contains(py, 7i32).unwrap());
|
||||
assert_eq!(false, dict.contains(py, 8i32).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -194,8 +194,8 @@ mod test {
|
|||
let mut v = HashMap::new();
|
||||
v.insert(7, 32);
|
||||
let dict = v.to_py_object(py);
|
||||
assert_eq!(32, dict.get_item(7i32, py).unwrap().extract::<i32>(py).unwrap());
|
||||
assert_eq!(None, dict.get_item(8i32, py));
|
||||
assert_eq!(32, dict.get_item(py, 7i32).unwrap().extract::<i32>(py).unwrap());
|
||||
assert_eq!(None, dict.get_item(py, 8i32));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -205,10 +205,10 @@ mod test {
|
|||
let mut v = HashMap::new();
|
||||
v.insert(7, 32);
|
||||
let dict = v.to_py_object(py);
|
||||
assert!(dict.set_item(7i32, 42i32, py).is_ok()); // change
|
||||
assert!(dict.set_item(8i32, 123i32, py).is_ok()); // insert
|
||||
assert_eq!(42i32, dict.get_item(7i32, py).unwrap().extract::<i32>(py).unwrap());
|
||||
assert_eq!(123i32, dict.get_item(8i32, py).unwrap().extract::<i32>(py).unwrap());
|
||||
assert!(dict.set_item(py, 7i32, 42i32).is_ok()); // change
|
||||
assert!(dict.set_item(py, 8i32, 123i32).is_ok()); // insert
|
||||
assert_eq!(42i32, dict.get_item(py, 7i32).unwrap().extract::<i32>(py).unwrap());
|
||||
assert_eq!(123i32, dict.get_item(py, 8i32).unwrap().extract::<i32>(py).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -218,8 +218,8 @@ mod test {
|
|||
let mut v = HashMap::new();
|
||||
v.insert(7, 32);
|
||||
let dict = v.to_py_object(py);
|
||||
assert!(dict.set_item(7i32, 42i32, py).is_ok()); // change
|
||||
assert!(dict.set_item(8i32, 123i32, py).is_ok()); // insert
|
||||
assert!(dict.set_item(py, 7i32, 42i32).is_ok()); // change
|
||||
assert!(dict.set_item(py, 8i32, 123i32).is_ok()); // insert
|
||||
assert_eq!(32i32, *v.get(&7i32).unwrap()); // not updated!
|
||||
assert_eq!(None, v.get(&8i32));
|
||||
}
|
||||
|
@ -232,9 +232,9 @@ mod test {
|
|||
let mut v = HashMap::new();
|
||||
v.insert(7, 32);
|
||||
let dict = v.to_py_object(py);
|
||||
assert!(dict.del_item(7i32, py).is_ok());
|
||||
assert!(dict.del_item(py, 7i32).is_ok());
|
||||
assert_eq!(0, dict.len(py));
|
||||
assert_eq!(None, dict.get_item(7i32, py));
|
||||
assert_eq!(None, dict.get_item(py, 7i32));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -244,13 +244,13 @@ mod test {
|
|||
let mut v = HashMap::new();
|
||||
v.insert(7, 32);
|
||||
let dict = v.to_py_object(py);
|
||||
assert!(dict.del_item(7i32, py).is_ok()); // change
|
||||
assert!(dict.del_item(py, 7i32).is_ok()); // change
|
||||
assert_eq!(32i32, *v.get(&7i32).unwrap()); // not updated!
|
||||
}
|
||||
|
||||
/*
|
||||
#[test]
|
||||
fn test_items_list() {
|
||||
TODO fn test_items_list() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let mut v = HashMap::new();
|
||||
|
|
|
@ -37,7 +37,7 @@ macro_rules! exc_type(
|
|||
|
||||
impl PythonObjectWithCheckedDowncast for $name {
|
||||
#[inline]
|
||||
fn downcast_from<'p>(obj : PyObject, py: Python<'p>)
|
||||
fn downcast_from<'p>(py: Python<'p>, obj : PyObject)
|
||||
-> Result<$name, PythonObjectDowncastError<'p>>
|
||||
{
|
||||
unsafe {
|
||||
|
@ -50,7 +50,7 @@ macro_rules! exc_type(
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn downcast_borrow_from<'a, 'p>(obj: &'a PyObject, py: Python<'p>)
|
||||
fn downcast_borrow_from<'a, 'p>(py: Python<'p>, obj: &'a PyObject)
|
||||
-> Result<&'a $name, PythonObjectDowncastError<'p>>
|
||||
{
|
||||
unsafe {
|
||||
|
|
|
@ -52,7 +52,8 @@ impl PyList {
|
|||
/// Gets the item at the specified index.
|
||||
///
|
||||
/// Panics if the index is out of range.
|
||||
pub fn get_item(&self, index: usize, py: Python) -> PyObject {
|
||||
pub fn get_item(&self, py: Python, index: usize) -> PyObject {
|
||||
// TODO: do we really want to panic here?
|
||||
assert!(index < self.len(py));
|
||||
unsafe {
|
||||
PyObject::from_borrowed_ptr(py, ffi::PyList_GetItem(self.0.as_ptr(), index as Py_ssize_t))
|
||||
|
@ -62,7 +63,7 @@ impl PyList {
|
|||
/// Sets the item at the specified index.
|
||||
///
|
||||
/// Panics if the index is out of range.
|
||||
pub fn set_item(&self, index: usize, item: PyObject, _py: Python) {
|
||||
pub fn set_item(&self, _py: Python, index: usize, item: PyObject) {
|
||||
let r = unsafe { ffi::PyList_SetItem(self.0.as_ptr(), index as Py_ssize_t, item.steal_ptr()) };
|
||||
assert!(r == 0);
|
||||
}
|
||||
|
@ -70,7 +71,7 @@ impl PyList {
|
|||
/// Inserts an item at the specified index.
|
||||
///
|
||||
/// Panics if the index is out of range.
|
||||
pub fn insert_item(&self, index: usize, item: PyObject, _py: Python) {
|
||||
pub fn insert_item(&self, _py: Python, index: usize, item: PyObject) {
|
||||
let r = unsafe { ffi::PyList_Insert(self.0.as_ptr(), index as Py_ssize_t, item.as_ptr()) };
|
||||
assert!(r == 0);
|
||||
}
|
||||
|
@ -98,7 +99,7 @@ impl <'a, 'p> IntoIterator for &'a PyList {
|
|||
}
|
||||
|
||||
/// Used by `impl IntoIterator for &PyList`.
|
||||
pub struct PyListIterator<'p> {
|
||||
TODO pub struct PyListIterator<'p> {
|
||||
list: PyList,
|
||||
index: usize
|
||||
}
|
||||
|
@ -143,20 +144,20 @@ impl <'prepared, T> ExtractPyObject<'prepared> for Vec<T>
|
|||
{
|
||||
type Prepared = Vec<T::Prepared>;
|
||||
|
||||
fn prepare_extract(obj: &PyObject, py: Python) -> PyResult<Self::Prepared> {
|
||||
fn prepare_extract(py: Python, obj: &PyObject) -> PyResult<Self::Prepared> {
|
||||
let list = try!(obj.cast_as::<PyList>(py));
|
||||
let len = list.len(py);
|
||||
let mut v = Vec::with_capacity(len);
|
||||
for i in 0 .. len {
|
||||
v.push(try!(T::prepare_extract(&list.get_item(i, py), py)));
|
||||
v.push(try!(T::prepare_extract(py, &list.get_item(py, i))));
|
||||
}
|
||||
Ok(v)
|
||||
}
|
||||
|
||||
fn extract(prepared: &'prepared Self::Prepared, py: Python) -> PyResult<Vec<T>> {
|
||||
fn extract(py: Python, prepared: &'prepared Self::Prepared) -> PyResult<Vec<T>> {
|
||||
let mut v = Vec::with_capacity(prepared.len());
|
||||
for prepared_elem in prepared {
|
||||
v.push(try!(T::extract(prepared_elem, py)));
|
||||
v.push(try!(T::extract(py, prepared_elem)));
|
||||
}
|
||||
Ok(v)
|
||||
}
|
||||
|
@ -184,10 +185,10 @@ mod test {
|
|||
let py = gil.python();
|
||||
let v = vec![2, 3, 5, 7];
|
||||
let list = v.to_py_object(py);
|
||||
assert_eq!(2, list.get_item(0, py).extract::<i32>(py).unwrap());
|
||||
assert_eq!(3, list.get_item(1, py).extract::<i32>(py).unwrap());
|
||||
assert_eq!(5, list.get_item(2, py).extract::<i32>(py).unwrap());
|
||||
assert_eq!(7, list.get_item(3, py).extract::<i32>(py).unwrap());
|
||||
assert_eq!(2, list.get_item(py, 0).extract::<i32>(py).unwrap());
|
||||
assert_eq!(3, list.get_item(py, 1).extract::<i32>(py).unwrap());
|
||||
assert_eq!(5, list.get_item(py, 2).extract::<i32>(py).unwrap());
|
||||
assert_eq!(7, list.get_item(py, 3).extract::<i32>(py).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -197,9 +198,9 @@ mod test {
|
|||
let v = vec![2, 3, 5, 7];
|
||||
let list = v.to_py_object(py);
|
||||
let val = 42i32.to_py_object(py).into_object();
|
||||
assert_eq!(2, list.get_item(0, py).extract::<i32>(py).unwrap());
|
||||
list.set_item(0, val, py);
|
||||
assert_eq!(42, list.get_item(0, py).extract::<i32>(py).unwrap());
|
||||
assert_eq!(2, list.get_item(py, 0).extract::<i32>(py).unwrap());
|
||||
list.set_item(py, 0, val);
|
||||
assert_eq!(42, list.get_item(py, 0).extract::<i32>(py).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -210,16 +211,16 @@ mod test {
|
|||
let list = v.to_py_object(py);
|
||||
let val = 42i32.to_py_object(py).into_object();
|
||||
assert_eq!(4, list.len(py));
|
||||
assert_eq!(2, list.get_item(0, py).extract::<i32>(py).unwrap());
|
||||
list.insert_item(0, val, py);
|
||||
assert_eq!(2, list.get_item(py, 0).extract::<i32>(py).unwrap());
|
||||
list.insert_item(py, 0, val);
|
||||
assert_eq!(5, list.len(py));
|
||||
assert_eq!(42, list.get_item(0, py).extract::<i32>(py).unwrap());
|
||||
assert_eq!(2, list.get_item(1, py).extract::<i32>(py).unwrap());
|
||||
assert_eq!(42, list.get_item(py, 0).extract::<i32>(py).unwrap());
|
||||
assert_eq!(2, list.get_item(py, 1).extract::<i32>(py).unwrap());
|
||||
}
|
||||
|
||||
/*
|
||||
#[test]
|
||||
fn test_iter() {
|
||||
fn test_iter() { TODO
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let v = vec![2, 3, 5, 7];
|
||||
|
@ -246,14 +247,14 @@ mod test {
|
|||
assert_eq!(idx, v.len());
|
||||
}
|
||||
*/
|
||||
|
||||
/*#[test]
|
||||
|
||||
#[test]
|
||||
fn test_extract() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let v = vec![2, 3, 5, 7];
|
||||
let list = v.to_py_object(py);
|
||||
let v2 = list.into_object().extract::<Vec<i32>>().unwrap();
|
||||
let v2 = list.into_object().extract::<Vec<i32>>(py).unwrap();
|
||||
assert_eq!(v, v2);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
|
|
@ -102,7 +102,7 @@ macro_rules! pyobject_newtype(
|
|||
|
||||
impl ::python::PythonObjectWithCheckedDowncast for $name {
|
||||
#[inline]
|
||||
fn downcast_from<'p>(obj: ::objects::object::PyObject, py: ::python::Python<'p>) -> Result<$name, ::python::PythonObjectDowncastError<'p>> {
|
||||
fn downcast_from<'p>(py: ::python::Python<'p>, obj: ::objects::object::PyObject) -> Result<$name, ::python::PythonObjectDowncastError<'p>> {
|
||||
unsafe {
|
||||
if ::ffi::$checkfunction(obj.as_ptr()) != 0 {
|
||||
Ok($name(obj))
|
||||
|
@ -113,7 +113,7 @@ macro_rules! pyobject_newtype(
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn downcast_borrow_from<'a, 'p>(obj: &'a ::objects::object::PyObject, py: ::python::Python<'p>) -> Result<&'a $name, ::python::PythonObjectDowncastError<'p>> {
|
||||
fn downcast_borrow_from<'a, 'p>(py: ::python::Python<'p>, obj: &'a ::objects::object::PyObject) -> Result<&'a $name, ::python::PythonObjectDowncastError<'p>> {
|
||||
unsafe {
|
||||
if ::ffi::$checkfunction(obj.as_ptr()) != 0 {
|
||||
Ok(::std::mem::transmute(obj))
|
||||
|
@ -144,11 +144,11 @@ macro_rules! extract(
|
|||
type Prepared = PyObject;
|
||||
|
||||
#[inline]
|
||||
fn prepare_extract(obj: &PyObject, py: Python) -> PyResult<Self::Prepared> {
|
||||
fn prepare_extract(py: Python, obj: &PyObject) -> PyResult<Self::Prepared> {
|
||||
Ok(::python::PyClone::clone_ref(obj, py))
|
||||
}
|
||||
|
||||
fn extract($obj: &'prepared PyObject, $py: Python) -> PyResult<Self> {
|
||||
fn extract($py: Python, $obj: &'prepared PyObject) -> PyResult<Self> {
|
||||
$body
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,14 +57,14 @@ impl PyModule {
|
|||
}
|
||||
}
|
||||
|
||||
unsafe fn str_from_ptr<'a>(&'a self, ptr: *const c_char, py: Python) -> PyResult<&'a str> {
|
||||
if ptr == std::ptr::null() {
|
||||
unsafe fn str_from_ptr<'a>(&'a self, py: Python, ptr: *const c_char) -> PyResult<&'a str> {
|
||||
if ptr.is_null() {
|
||||
Err(PyErr::fetch(py))
|
||||
} 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(try!(exc::UnicodeDecodeError::new_utf8(py, slice, e)), py))
|
||||
Err(e) => Err(PyErr::from_instance(py, try!(exc::UnicodeDecodeError::new_utf8(py, slice, e))))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -73,35 +73,35 @@ impl PyModule {
|
|||
///
|
||||
/// May fail if the module does not have a `__name__` attribute.
|
||||
pub fn name<'a>(&'a self, py: Python) -> PyResult<&'a str> {
|
||||
unsafe { self.str_from_ptr(ffi::PyModule_GetName(self.0.as_ptr()), py) }
|
||||
unsafe { self.str_from_ptr(py, ffi::PyModule_GetName(self.0.as_ptr())) }
|
||||
}
|
||||
|
||||
/// Gets the module filename.
|
||||
///
|
||||
/// May fail if the module does not have a `__file__` attribute.
|
||||
pub fn filename<'a>(&'a self, py: Python) -> PyResult<&'a str> {
|
||||
unsafe { self.str_from_ptr(ffi::PyModule_GetFilename(self.0.as_ptr()), py) }
|
||||
unsafe { self.str_from_ptr(py, ffi::PyModule_GetFilename(self.0.as_ptr())) }
|
||||
}
|
||||
|
||||
/// Gets a member from the module.
|
||||
/// This is equivalent to the Python expression: `getattr(module, name)`
|
||||
pub fn get(&self, name: &str, py: Python) -> PyResult<PyObject> {
|
||||
self.as_object().getattr(name, py)
|
||||
pub fn get(&self, py: Python, name: &str) -> PyResult<PyObject> {
|
||||
self.as_object().getattr(py, name)
|
||||
}
|
||||
|
||||
/// Calls a function in the module.
|
||||
/// This is equivalent to the Python expression: `getattr(module, name)(*args, **kwargs)`
|
||||
pub fn call<A>(&self, name: &str, args: A, kwargs: Option<&PyDict>, py: Python) -> PyResult<PyObject>
|
||||
pub fn call<A>(&self, py: Python, name: &str, args: A, kwargs: Option<&PyDict>) -> PyResult<PyObject>
|
||||
where A: ToPyObject<ObjectType=PyTuple>
|
||||
{
|
||||
try!(self.as_object().getattr(name, py)).call(args, kwargs, py)
|
||||
try!(self.as_object().getattr(py, name)).call(py, args, kwargs)
|
||||
}
|
||||
|
||||
/// Adds a member to the module.
|
||||
///
|
||||
/// This is a convenience function which can be used from the module's initialization function.
|
||||
pub fn add<V>(&self, name: &str, value: V, py: Python) -> PyResult<()> where V: ToPyObject {
|
||||
self.as_object().setattr(name, value, py)
|
||||
pub fn add<V>(&self, py: Python, name: &str, value: V) -> PyResult<()> where V: ToPyObject {
|
||||
self.as_object().setattr(py, name, value)
|
||||
}
|
||||
|
||||
/// Adds a new extension type to the module.
|
||||
|
@ -109,9 +109,9 @@ impl PyModule {
|
|||
/// This is a convenience function that creates a new `PyRustTypeBuilder` and
|
||||
/// sets `new_type.__module__` to this module's name.
|
||||
/// The new type will be added to this module when `finish()` is called on the builder.
|
||||
pub fn add_type<'p, T>(&self, name: &str, py: Python<'p>) -> ::rustobject::typebuilder::PyRustTypeBuilder<'p, T>
|
||||
pub fn add_type<'p, T>(&self, py: Python<'p>, name: &str) -> ::rustobject::typebuilder::PyRustTypeBuilder<'p, T>
|
||||
where T: 'static + Send {
|
||||
::rustobject::typebuilder::new_typebuilder_for_module(self, name, py)
|
||||
::rustobject::typebuilder::new_typebuilder_for_module(py, self, name)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -196,12 +196,12 @@ macro_rules! int_convert_u64_or_i64 (
|
|||
type Prepared = PyObject;
|
||||
|
||||
#[inline]
|
||||
fn prepare_extract(obj: &PyObject, py: Python) -> PyResult<Self::Prepared> {
|
||||
fn prepare_extract(py: Python, obj: &PyObject) -> PyResult<Self::Prepared> {
|
||||
Ok(obj.clone_ref(py))
|
||||
}
|
||||
|
||||
#[cfg(feature="python27-sys")]
|
||||
fn extract(obj: &'prepared PyObject, py: Python) -> PyResult<$rust_type> {
|
||||
fn extract(py: Python, obj: &'prepared PyObject) -> PyResult<$rust_type> {
|
||||
let ptr = obj.as_ptr();
|
||||
|
||||
unsafe {
|
||||
|
@ -220,7 +220,7 @@ macro_rules! int_convert_u64_or_i64 (
|
|||
}
|
||||
|
||||
#[cfg(feature="python3-sys")]
|
||||
fn extract(obj: &'prepared PyObject, py: Python) -> PyResult<$rust_type> {
|
||||
fn extract(py: Python, obj: &'prepared PyObject) -> PyResult<$rust_type> {
|
||||
let ptr = obj.as_ptr();
|
||||
unsafe {
|
||||
if ffi::PyLong_Check(ptr) != 0 {
|
||||
|
|
|
@ -25,17 +25,20 @@ use err::PyResult;
|
|||
/// Represents a reference to a Python object.
|
||||
///
|
||||
/// Python objects are reference counted.
|
||||
/// Calling `clone()` on a `PyObject` will return a new reference to the same object
|
||||
/// Calling `clone_ref()` on a `PyObject` will return a new reference to the same object
|
||||
/// (thus incrementing the reference count).
|
||||
/// The `Drop` implementation will decrement the reference count.
|
||||
/// The `Drop` implementation will automatically decrement the reference count.
|
||||
/// You can also call `release_ref()` to explicitly decrement the reference count.
|
||||
/// This is slightly faster than relying on automatic drop, because `release_ref`
|
||||
/// does not need to check whether the GIL needs to be acquired.
|
||||
///
|
||||
/// `PyObject` can be used with all Python objects, since all python types
|
||||
/// derive from `object`. This crate also contains other, more specific types
|
||||
/// that serve as references to Python objects (e.g. `PyTuple` for Python tuples, etc.).
|
||||
///
|
||||
/// You can convert from any Python object to `PyObject` by calling `as_object()` or `into_object`
|
||||
/// You can convert from any Python object to `PyObject` by calling `as_object()` or `into_object()`
|
||||
/// from the [PythonObject trait](trait.PythonObject.html).
|
||||
/// In the other direction, you can call `cast_as` or `cast_into`
|
||||
/// In the other direction, you can call `cast_as()` or `cast_into()`
|
||||
/// on `PyObject` to convert to more specific object types.
|
||||
///
|
||||
/// Most of the interesting methods are provided by the [ObjectProtocol trait](trait.ObjectProtocol.html).
|
||||
|
@ -85,12 +88,12 @@ impl PythonObject for PyObject {
|
|||
|
||||
impl PythonObjectWithCheckedDowncast for PyObject {
|
||||
#[inline]
|
||||
fn downcast_from<'p>(obj: PyObject, _py: Python<'p>) -> Result<PyObject, PythonObjectDowncastError<'p>> {
|
||||
fn downcast_from<'p>(_py: Python<'p>, obj: PyObject) -> Result<PyObject, PythonObjectDowncastError<'p>> {
|
||||
Ok(obj)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn downcast_borrow_from<'a, 'p>(obj: &'a PyObject, _py: Python<'p>) -> Result<&'a PyObject, PythonObjectDowncastError<'p>> {
|
||||
fn downcast_borrow_from<'a, 'p>(_py: Python<'p>, obj: &'a PyObject) -> Result<&'a PyObject, PythonObjectDowncastError<'p>> {
|
||||
Ok(obj)
|
||||
}
|
||||
}
|
||||
|
@ -209,7 +212,7 @@ impl PyObject {
|
|||
pub fn cast_into<'p, T>(self, py: Python<'p>) -> Result<T, PythonObjectDowncastError<'p>>
|
||||
where T: PythonObjectWithCheckedDowncast
|
||||
{
|
||||
PythonObjectWithCheckedDowncast::downcast_from(self, py)
|
||||
PythonObjectWithCheckedDowncast::downcast_from(py, self)
|
||||
}
|
||||
|
||||
/// Casts the PyObject to a concrete Python object type.
|
||||
|
@ -229,7 +232,7 @@ impl PyObject {
|
|||
pub fn cast_as<'s, 'p, T>(&'s self, py: Python<'p>) -> Result<&'s T, PythonObjectDowncastError<'p>>
|
||||
where T: PythonObjectWithCheckedDowncast
|
||||
{
|
||||
PythonObjectWithCheckedDowncast::downcast_borrow_from(self, py)
|
||||
PythonObjectWithCheckedDowncast::downcast_borrow_from(py, self)
|
||||
}
|
||||
|
||||
/// Extracts some type from the Python object.
|
||||
|
@ -238,8 +241,8 @@ impl PyObject {
|
|||
pub fn extract<T>(&self, py: Python) -> PyResult<T>
|
||||
where T: for<'prep> ::conversion::ExtractPyObject<'prep>
|
||||
{
|
||||
let prepared = try!(<T as ::conversion::ExtractPyObject>::prepare_extract(self, py));
|
||||
<T as ::conversion::ExtractPyObject>::extract(&prepared, py)
|
||||
let prepared = try!(<T as ::conversion::ExtractPyObject>::prepare_extract(py, self));
|
||||
<T as ::conversion::ExtractPyObject>::extract(py, &prepared)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -40,13 +40,13 @@ pyobject_newtype!(PyInstance, PyInstance_Check, PyInstance_Type);
|
|||
|
||||
impl PyClass {
|
||||
/// Return true if self is a subclass of base.
|
||||
pub fn is_subclass_of(&self, base: &PyClass, _py: Python) -> bool {
|
||||
pub fn is_subclass_of(&self, _py: Python, base: &PyClass) -> bool {
|
||||
unsafe { ffi::PyClass_IsSubclass(self.as_ptr(), base.as_ptr()) != 0 }
|
||||
}
|
||||
|
||||
/// Create a new instance of the class.
|
||||
/// The parameters args and kw are used as the positional and keyword parameters to the object’s constructor.
|
||||
pub fn create_instance<T>(&self, args: T, kw: Option<&PyDict>, py: Python) -> PyResult<PyInstance>
|
||||
pub fn create_instance<T>(&self, py: Python, args: T, kw: Option<&PyDict>) -> PyResult<PyInstance>
|
||||
where T: ToPyObject<ObjectType=PyTuple>
|
||||
{
|
||||
args.with_borrowed_ptr(py, |args| unsafe {
|
||||
|
@ -57,7 +57,7 @@ impl PyClass {
|
|||
|
||||
/// Create a new instance of a specific class without calling its constructor.
|
||||
/// The dict parameter will be used as the object’s __dict__.
|
||||
pub fn create_instance_raw(&self, dict: &PyDict, py: Python) -> PyResult<PyInstance> {
|
||||
pub fn create_instance_raw(&self, py: Python, dict: &PyDict) -> PyResult<PyInstance> {
|
||||
unsafe {
|
||||
err::result_cast_from_owned_ptr(py,
|
||||
ffi::PyInstance_NewRaw(self.as_ptr(), dict.as_object().as_ptr()))
|
||||
|
|
|
@ -43,7 +43,7 @@ impl PySequence {
|
|||
|
||||
/// Return the concatenation of o1 and o2. Equivalent to python `o1 + o2`
|
||||
#[inline]
|
||||
pub fn concat(&self, other: &PySequence, py: Python) -> PyResult<PyObject> {
|
||||
pub fn concat(&self, py: Python, other: &PySequence) -> PyResult<PyObject> {
|
||||
unsafe {
|
||||
err::result_from_owned_ptr(py, ffi::PySequence_Concat(self.as_ptr(), other.as_ptr()))
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ impl PySequence {
|
|||
/// Equivalent to python `o * count`
|
||||
/// NB: Python accepts negative counts; it returns an empty Sequence.
|
||||
#[inline]
|
||||
pub fn repeat(&self, count: isize, py: Python) -> PyResult<PyObject> {
|
||||
pub fn repeat(&self, py: Python, count: isize) -> PyResult<PyObject> {
|
||||
unsafe {
|
||||
err::result_from_owned_ptr(py, ffi::PySequence_Repeat(self.as_ptr(), count as Py_ssize_t))
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ impl PySequence {
|
|||
|
||||
/// Return the concatenation of o1 and o2 on success. Equivalent to python `o1 += o2`
|
||||
#[inline]
|
||||
pub fn in_place_concat(&self, other: &PySequence, py: Python) -> PyResult<PyObject> {
|
||||
pub fn in_place_concat(&self, py: Python, other: &PySequence) -> PyResult<PyObject> {
|
||||
unsafe {
|
||||
result_from_owned_ptr(py, ffi::PySequence_InPlaceConcat(self.as_ptr(), other.as_ptr()))
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ impl PySequence {
|
|||
/// Equivalent to python `o *= count`
|
||||
/// NB: Python accepts negative counts; it empties the Sequence.
|
||||
#[inline]
|
||||
pub fn in_place_repeat(&self, count: isize, py: Python) -> PyResult<PyObject> {
|
||||
pub fn in_place_repeat(&self, py: Python, count: isize) -> PyResult<PyObject> {
|
||||
unsafe {
|
||||
result_from_owned_ptr(py,
|
||||
ffi::PySequence_InPlaceRepeat(self.as_ptr(), count as Py_ssize_t))
|
||||
|
@ -80,7 +80,7 @@ impl PySequence {
|
|||
|
||||
/// Return the ith element of the Sequence. Equivalent to python `o[index]`
|
||||
#[inline]
|
||||
pub fn get_item(&self, index: isize, py: Python) -> PyResult<PyObject> {
|
||||
pub fn get_item(&self, py: Python, index: isize) -> PyResult<PyObject> {
|
||||
unsafe {
|
||||
result_from_owned_ptr(py,
|
||||
ffi::PySequence_GetItem(self.as_ptr(), index as Py_ssize_t))
|
||||
|
@ -90,7 +90,7 @@ impl PySequence {
|
|||
/// Return the slice of sequence object o between begin and end.
|
||||
/// This is the equivalent of the Python expression `o[begin:end]`
|
||||
#[inline]
|
||||
pub fn get_slice(&self, begin : isize, end : isize, py: Python) -> PyResult<PyObject> {
|
||||
pub fn get_slice(&self, py: Python, begin : isize, end : isize) -> PyResult<PyObject> {
|
||||
unsafe {
|
||||
result_from_owned_ptr(py,
|
||||
ffi::PySequence_GetSlice(self.as_ptr(), begin as Py_ssize_t, end as Py_ssize_t))
|
||||
|
@ -100,7 +100,7 @@ impl PySequence {
|
|||
/// Assign object v to the ith element of o.
|
||||
/// Equivalent to Python statement `o[i] = v`
|
||||
#[inline]
|
||||
pub fn set_item(&self, i: isize, v: &PyObject, py: Python) -> PyResult<()> {
|
||||
pub fn set_item(&self, py: Python, i: isize, v: &PyObject) -> PyResult<()> {
|
||||
unsafe {
|
||||
err::error_on_minusone(py,
|
||||
ffi::PySequence_SetItem(self.as_ptr(), i as Py_ssize_t, v.as_ptr()))
|
||||
|
@ -110,7 +110,7 @@ impl PySequence {
|
|||
/// Delete the ith element of object o.
|
||||
/// Python statement `del o[i]`
|
||||
#[inline]
|
||||
pub fn del_item(&self, i: isize, py: Python) -> PyResult<()> {
|
||||
pub fn del_item(&self, py: Python, i: isize) -> PyResult<()> {
|
||||
unsafe {
|
||||
err::error_on_minusone(py,
|
||||
ffi::PySequence_DelItem(self.as_ptr(), i as Py_ssize_t))
|
||||
|
@ -120,7 +120,7 @@ impl PySequence {
|
|||
/// Assign the sequence object v to the slice in sequence object o from i1 to i2.
|
||||
/// This is the equivalent of the Python statement `o[i1:i2] = v`
|
||||
#[inline]
|
||||
pub fn set_slice(&self, i1: isize, i2: isize, v: &PyObject, py: Python) -> PyResult<()> {
|
||||
pub fn set_slice(&self, py: Python, i1: isize, i2: isize, v: &PyObject) -> PyResult<()> {
|
||||
unsafe {
|
||||
err::error_on_minusone(py,
|
||||
ffi::PySequence_SetSlice(self.as_ptr(), i1 as Py_ssize_t, i2 as Py_ssize_t, v.as_ptr()))
|
||||
|
@ -130,7 +130,7 @@ impl PySequence {
|
|||
/// Delete the slice in sequence object o from i1 to i2.
|
||||
/// equivalent of the Python statement `del o[i1:i2]`
|
||||
#[inline]
|
||||
pub fn del_slice(&self, i1: isize, i2: isize, py: Python) -> PyResult<()> {
|
||||
pub fn del_slice(&self, py: Python, i1: isize, i2: isize) -> PyResult<()> {
|
||||
unsafe {
|
||||
err::error_on_minusone(py,
|
||||
ffi::PySequence_DelSlice(self.as_ptr(), i1 as Py_ssize_t, i2 as Py_ssize_t))
|
||||
|
@ -140,7 +140,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, py: Python) -> PyResult<usize>
|
||||
pub fn count<V>(&self, py: Python, value: V) -> PyResult<usize>
|
||||
where V: ToPyObject
|
||||
{
|
||||
let r = value.with_borrowed_ptr(py, |ptr| unsafe {
|
||||
|
@ -155,7 +155,7 @@ impl PySequence {
|
|||
|
||||
/// Determine if o contains value. this is equivalent to the Python expression `value in o`
|
||||
#[inline]
|
||||
pub fn contains<V>(&self, value: V, py: Python) -> PyResult<bool>
|
||||
pub fn contains<V>(&self, py: Python, value: V) -> PyResult<bool>
|
||||
where V: ToPyObject
|
||||
{
|
||||
let r = value.with_borrowed_ptr(py, |ptr| unsafe {
|
||||
|
@ -171,7 +171,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, py: Python) -> PyResult<usize>
|
||||
pub fn index<V>(&self, py: Python, value: V) -> PyResult<usize>
|
||||
where V: ToPyObject
|
||||
{
|
||||
let r = value.with_borrowed_ptr(py, |ptr| unsafe {
|
||||
|
@ -233,7 +233,7 @@ impl <'p> Iterator for PySequenceIterator<'p> {
|
|||
// can't report any errors in underlying size check so we panic.
|
||||
let len = self.sequence.len(self.py).unwrap();
|
||||
if self.index < len {
|
||||
match self.sequence.get_item(self.index, self.py) {
|
||||
match self.sequence.get_item(self.py, self.index) {
|
||||
Ok(item) => {
|
||||
self.index += 1;
|
||||
Some(item)
|
||||
|
@ -277,7 +277,7 @@ mod test {
|
|||
assert_eq!(0, seq.len(py).unwrap());
|
||||
|
||||
let needle = 7i32.to_py_object(py).into_object();
|
||||
assert_eq!(false, seq.contains(&needle, py).unwrap());
|
||||
assert_eq!(false, seq.contains(py, &needle).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -289,13 +289,13 @@ mod test {
|
|||
assert_eq!(6, seq.len(py).unwrap());
|
||||
|
||||
let bad_needle = 7i32.to_py_object(py).into_object();
|
||||
assert_eq!(false, seq.contains(&bad_needle, py).unwrap());
|
||||
assert_eq!(false, seq.contains(py, &bad_needle).unwrap());
|
||||
|
||||
let good_needle = 8i32.to_py_object(py).into_object();
|
||||
assert_eq!(true, seq.contains(&good_needle, py).unwrap());
|
||||
assert_eq!(true, seq.contains(py, &good_needle).unwrap());
|
||||
|
||||
let type_coerced_needle = 8f32.to_py_object(py).into_object();
|
||||
assert_eq!(true, seq.contains(&type_coerced_needle, py).unwrap());
|
||||
assert_eq!(true, seq.contains(py, &type_coerced_needle).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -304,18 +304,18 @@ mod test {
|
|||
let py = gil.python();
|
||||
let v : Vec<i32> = vec![1, 1, 2, 3, 5, 8];
|
||||
let seq = v.to_py_object(py).into_object().cast_into::<PySequence>(py).unwrap();
|
||||
assert_eq!(1, seq.get_item(0, py).unwrap().extract::<i32>(py).unwrap());
|
||||
assert_eq!(1, seq.get_item(1, py).unwrap().extract::<i32>(py).unwrap());
|
||||
assert_eq!(2, seq.get_item(2, py).unwrap().extract::<i32>(py).unwrap());
|
||||
assert_eq!(3, seq.get_item(3, py).unwrap().extract::<i32>(py).unwrap());
|
||||
assert_eq!(5, seq.get_item(4, py).unwrap().extract::<i32>(py).unwrap());
|
||||
assert_eq!(8, seq.get_item(5, py).unwrap().extract::<i32>(py).unwrap());
|
||||
assert_eq!(8, seq.get_item(-1, py).unwrap().extract::<i32>(py).unwrap());
|
||||
assert_eq!(5, seq.get_item(-2, py).unwrap().extract::<i32>(py).unwrap());
|
||||
assert_eq!(3, seq.get_item(-3, py).unwrap().extract::<i32>(py).unwrap());
|
||||
assert_eq!(2, seq.get_item(-4, py).unwrap().extract::<i32>(py).unwrap());
|
||||
assert_eq!(1, seq.get_item(-5, py).unwrap().extract::<i32>(py).unwrap());
|
||||
assert!(seq.get_item(10, py).is_err());
|
||||
assert_eq!(1, seq.get_item(py, 0).unwrap().extract::<i32>(py).unwrap());
|
||||
assert_eq!(1, seq.get_item(py, 1).unwrap().extract::<i32>(py).unwrap());
|
||||
assert_eq!(2, seq.get_item(py, 2).unwrap().extract::<i32>(py).unwrap());
|
||||
assert_eq!(3, seq.get_item(py, 3).unwrap().extract::<i32>(py).unwrap());
|
||||
assert_eq!(5, seq.get_item(py, 4).unwrap().extract::<i32>(py).unwrap());
|
||||
assert_eq!(8, seq.get_item(py, 5).unwrap().extract::<i32>(py).unwrap());
|
||||
assert_eq!(8, seq.get_item(py, -1).unwrap().extract::<i32>(py).unwrap());
|
||||
assert_eq!(5, seq.get_item(py, -2).unwrap().extract::<i32>(py).unwrap());
|
||||
assert_eq!(3, seq.get_item(py, -3).unwrap().extract::<i32>(py).unwrap());
|
||||
assert_eq!(2, seq.get_item(py, -4).unwrap().extract::<i32>(py).unwrap());
|
||||
assert_eq!(1, seq.get_item(py, -5).unwrap().extract::<i32>(py).unwrap());
|
||||
assert!(seq.get_item(py, 10).is_err());
|
||||
}
|
||||
|
||||
// fn test_get_slice() {}
|
||||
|
@ -328,21 +328,21 @@ mod test {
|
|||
let py = gil.python();
|
||||
let v : Vec<i32> = vec![1, 1, 2, 3, 5, 8];
|
||||
let seq = v.to_py_object(py).into_object().cast_into::<PySequence>(py).unwrap();
|
||||
assert!(seq.del_item(10, py).is_err());
|
||||
assert_eq!(1, seq.get_item(0, py).unwrap().extract::<i32>(py).unwrap());
|
||||
assert!(seq.del_item(0, py).is_ok());
|
||||
assert_eq!(1, seq.get_item(0, py).unwrap().extract::<i32>(py).unwrap());
|
||||
assert!(seq.del_item(0, py).is_ok());
|
||||
assert_eq!(2, seq.get_item(0, py).unwrap().extract::<i32>(py).unwrap());
|
||||
assert!(seq.del_item(0, py).is_ok());
|
||||
assert_eq!(3, seq.get_item(0, py).unwrap().extract::<i32>(py).unwrap());
|
||||
assert!(seq.del_item(0, py).is_ok());
|
||||
assert_eq!(5, seq.get_item(0, py).unwrap().extract::<i32>(py).unwrap());
|
||||
assert!(seq.del_item(0, py).is_ok());
|
||||
assert_eq!(8, seq.get_item(0, py).unwrap().extract::<i32>(py).unwrap());
|
||||
assert!(seq.del_item(0, py).is_ok());
|
||||
assert!(seq.del_item(py, 10).is_err());
|
||||
assert_eq!(1, seq.get_item(py, 0).unwrap().extract::<i32>(py).unwrap());
|
||||
assert!(seq.del_item(py, 0).is_ok());
|
||||
assert_eq!(1, seq.get_item(py, 0).unwrap().extract::<i32>(py).unwrap());
|
||||
assert!(seq.del_item(py, 0).is_ok());
|
||||
assert_eq!(2, seq.get_item(py, 0).unwrap().extract::<i32>(py).unwrap());
|
||||
assert!(seq.del_item(py, 0).is_ok());
|
||||
assert_eq!(3, seq.get_item(py, 0).unwrap().extract::<i32>(py).unwrap());
|
||||
assert!(seq.del_item(py, 0).is_ok());
|
||||
assert_eq!(5, seq.get_item(py, 0).unwrap().extract::<i32>(py).unwrap());
|
||||
assert!(seq.del_item(py, 0).is_ok());
|
||||
assert_eq!(8, seq.get_item(py, 0).unwrap().extract::<i32>(py).unwrap());
|
||||
assert!(seq.del_item(py, 0).is_ok());
|
||||
assert_eq!(0, seq.len(py).unwrap());
|
||||
assert!(seq.del_item(0, py).is_err());
|
||||
assert!(seq.del_item(py, 0).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -351,12 +351,12 @@ mod test {
|
|||
let py = gil.python();
|
||||
let v : Vec<i32> = vec![1, 1, 2, 3, 5, 8];
|
||||
let seq = v.to_py_object(py).into_object().cast_into::<PySequence>(py).unwrap();
|
||||
assert_eq!(0, seq.index(1i32, py).unwrap());
|
||||
assert_eq!(2, seq.index(2i32, py).unwrap());
|
||||
assert_eq!(3, seq.index(3i32, py).unwrap());
|
||||
assert_eq!(4, seq.index(5i32, py).unwrap());
|
||||
assert_eq!(5, seq.index(8i32, py).unwrap());
|
||||
assert!(seq.index(42i32, py).is_err());
|
||||
assert_eq!(0, seq.index(py, 1i32).unwrap());
|
||||
assert_eq!(2, seq.index(py, 2i32).unwrap());
|
||||
assert_eq!(3, seq.index(py, 3i32).unwrap());
|
||||
assert_eq!(4, seq.index(py, 5i32).unwrap());
|
||||
assert_eq!(5, seq.index(py, 8i32).unwrap());
|
||||
assert!(seq.index(py, 42i32).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -365,17 +365,17 @@ mod test {
|
|||
let py = gil.python();
|
||||
let v : Vec<i32> = vec![1, 1, 2, 3, 5, 8];
|
||||
let seq = v.to_py_object(py).into_object().cast_into::<PySequence>(py).unwrap();
|
||||
assert_eq!(2, seq.count(1i32, py).unwrap());
|
||||
assert_eq!(1, seq.count(2i32, py).unwrap());
|
||||
assert_eq!(1, seq.count(3i32, py).unwrap());
|
||||
assert_eq!(1, seq.count(5i32, py).unwrap());
|
||||
assert_eq!(1, seq.count(8i32, py).unwrap());
|
||||
assert_eq!(0, seq.count(42i32, py).unwrap());
|
||||
assert_eq!(2, seq.count(py, 1i32).unwrap());
|
||||
assert_eq!(1, seq.count(py, 2i32).unwrap());
|
||||
assert_eq!(1, seq.count(py, 3i32).unwrap());
|
||||
assert_eq!(1, seq.count(py, 5i32).unwrap());
|
||||
assert_eq!(1, seq.count(py, 8i32).unwrap());
|
||||
assert_eq!(0, seq.count(py, 42i32).unwrap());
|
||||
}
|
||||
|
||||
/*
|
||||
#[test]
|
||||
fn test_seq_iter() {
|
||||
fn test_seq_iter() { TODO
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let v : Vec<i32> = vec![1, 1, 2, 3, 5, 8];
|
||||
|
@ -411,10 +411,10 @@ mod test {
|
|||
let seq = v.to_py_object(py).into_object().cast_into::<PySequence>(py).unwrap();
|
||||
|
||||
let bad_needle = "blurst".to_py_object(py);
|
||||
assert_eq!(false, seq.contains(bad_needle, py).unwrap());
|
||||
assert_eq!(false, seq.contains(py, bad_needle).unwrap());
|
||||
|
||||
let good_needle = "worst".to_py_object(py);
|
||||
assert_eq!(true, seq.contains(good_needle, py).unwrap());
|
||||
assert_eq!(true, seq.contains(py, good_needle).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -423,7 +423,7 @@ mod test {
|
|||
let py = gil.python();
|
||||
let v : Vec<i32> = vec![1, 2, 3];
|
||||
let seq = v.to_py_object(py).into_object().cast_into::<PySequence>(py).unwrap();
|
||||
let concat_seq = seq.concat(&seq, py).unwrap().cast_into::<PySequence>(py).unwrap();
|
||||
let concat_seq = seq.concat(py, &seq).unwrap().cast_into::<PySequence>(py).unwrap();
|
||||
assert_eq!(6, concat_seq.len(py).unwrap());
|
||||
let concat_v : Vec<i32> = vec![1, 2, 3, 1, 2, 3];
|
||||
for (el, cc) in seq.into_iter(py).zip(concat_v) {
|
||||
|
@ -437,7 +437,7 @@ mod test {
|
|||
let py = gil.python();
|
||||
let v = "string";
|
||||
let seq = v.to_py_object(py).into_object().cast_into::<PySequence>(py).unwrap();
|
||||
let concat_seq = seq.concat(&seq, py).unwrap().cast_into::<PySequence>(py).unwrap();
|
||||
let concat_seq = seq.concat(py, &seq).unwrap().cast_into::<PySequence>(py).unwrap();
|
||||
assert_eq!(12, concat_seq.len(py).unwrap());
|
||||
/*let concat_v = "stringstring".to_owned();
|
||||
for (el, cc) in seq.into_iter(py).zip(concat_v.chars()) {
|
||||
|
@ -451,7 +451,7 @@ mod test {
|
|||
let py = gil.python();
|
||||
let v = vec!["foo", "bar"];
|
||||
let seq = v.to_py_object(py).into_object().cast_into::<PySequence>(py).unwrap();
|
||||
let repeat_seq = seq.repeat(3, py).unwrap().cast_into::<PySequence>(py).unwrap();
|
||||
let repeat_seq = seq.repeat(py, 3).unwrap().cast_into::<PySequence>(py).unwrap();
|
||||
assert_eq!(6, repeat_seq.len(py).unwrap());
|
||||
let repeated = vec!["foo", "bar", "foo", "bar", "foo", "bar"];
|
||||
for (el, rpt) in seq.into_iter(py).zip(repeated.iter()) {
|
||||
|
|
|
@ -99,7 +99,7 @@ impl PyUnicode {
|
|||
};
|
||||
match str::from_utf8(bytes.as_slice(py)) {
|
||||
Ok(s) => Ok(Cow::Owned(s.to_owned())),
|
||||
Err(e) => Err(PyErr::from_instance(try!(exc::UnicodeDecodeError::new_utf8(py, bytes.as_slice(py), e)), py))
|
||||
Err(e) => Err(PyErr::from_instance(py, try!(exc::UnicodeDecodeError::new_utf8(py, bytes.as_slice(py), e))))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -137,7 +137,7 @@ impl PyUnicode {
|
|||
let bytes = try!(self.to_utf8_bytes(py));
|
||||
match str::from_utf8(bytes) {
|
||||
Ok(s) => Ok(Cow::Borrowed(s)),
|
||||
Err(e) => Err(PyErr::from_instance(try!(exc::UnicodeDecodeError::new_utf8(py, bytes, e)), py))
|
||||
Err(e) => Err(PyErr::from_instance(py, try!(exc::UnicodeDecodeError::new_utf8(py, bytes, e))))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -164,7 +164,7 @@ impl PyString {
|
|||
/// Returns `TypeError` if the input is not one of the accepted types.
|
||||
/// Returns `UnicodeDecodeError` if the input is not valid unicode.
|
||||
#[cfg(feature="python27-sys")]
|
||||
pub fn extract<'a>(o: &'a PyObject, py: Python) -> PyResult<Cow<'a, str>> {
|
||||
pub fn extract<'a>(py: Python, o: &'a PyObject) -> PyResult<Cow<'a, str>> {
|
||||
if let Ok(s) = o.cast_as::<PyBytes>(py) {
|
||||
s.to_string(py)
|
||||
} else if let Ok(u) = o.cast_as::<PyUnicode>(py) {
|
||||
|
@ -184,7 +184,7 @@ impl PyString {
|
|||
/// Returns `TypeError` if the input is not one of the accepted types.
|
||||
/// Any invalid code points are replaced with U+FFFD REPLACEMENT CHARACTER.
|
||||
#[cfg(feature="python27-sys")]
|
||||
pub fn extract_lossy<'a>(o: &'a PyObject, py: Python) -> PyResult<Cow<'a, str>> {
|
||||
pub fn extract_lossy<'a>(py: Python, o: &'a PyObject) -> PyResult<Cow<'a, str>> {
|
||||
if let Ok(s) = o.cast_as::<PyBytes>(py) {
|
||||
Ok(s.to_string_lossy(py))
|
||||
} else if let Ok(u) = o.cast_as::<PyUnicode>(py) {
|
||||
|
@ -204,7 +204,7 @@ impl PyString {
|
|||
/// Returns `TypeError` if the input is not one of the accepted types.
|
||||
/// Returns `UnicodeDecodeError` if the input is not valid unicode.
|
||||
#[cfg(feature="python3-sys")]
|
||||
pub fn extract<'a>(o: &'a PyObject, py: Python) -> PyResult<Cow<'a, str>> {
|
||||
pub fn extract<'a>(py: Python, o: &'a PyObject) -> PyResult<Cow<'a, str>> {
|
||||
if let Ok(u) = o.cast_as::<PyUnicode>(py) {
|
||||
u.to_string(py)
|
||||
} else {
|
||||
|
@ -222,7 +222,7 @@ impl PyString {
|
|||
/// Returns `TypeError` if the input is not one of the accepted types.
|
||||
/// Any invalid code points are replaced with U+FFFD REPLACEMENT CHARACTER.
|
||||
#[cfg(feature="python3-sys")]
|
||||
pub fn extract_lossy<'a>(o: &'a PyObject, py: Python) -> PyResult<Cow<'a, str>> {
|
||||
pub fn extract_lossy<'a>(py: Python, o: &'a PyObject) -> PyResult<Cow<'a, str>> {
|
||||
if let Ok(u) = o.cast_as::<PyUnicode>(py) {
|
||||
Ok(u.to_string_lossy(py))
|
||||
} else {
|
||||
|
@ -243,7 +243,7 @@ impl PyString {
|
|||
pub fn to_string(&self, py: Python) -> PyResult<Cow<str>> {
|
||||
match str::from_utf8(self.as_slice(py)) {
|
||||
Ok(s) => Ok(Cow::Borrowed(s)),
|
||||
Err(e) => Err(PyErr::from_instance(try!(exc::UnicodeDecodeError::new_utf8(py, self.as_slice(py), e)), py))
|
||||
Err(e) => Err(PyErr::from_instance(py, try!(exc::UnicodeDecodeError::new_utf8(py, self.as_slice(py), e))))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -312,14 +312,14 @@ impl ToPyObject for String {
|
|||
/// Accepts Python `str` and `unicode` objects.
|
||||
/// In Python 2.7, `str` is expected to be UTF-8 encoded.
|
||||
extract!(obj to String; py => {
|
||||
PyString::extract(obj, py).map(|s| s.into_owned())
|
||||
PyString::extract(py, obj).map(|s| s.into_owned())
|
||||
});
|
||||
|
||||
/// Allows extracting strings from Python objects.
|
||||
/// Accepts Python `str` and `unicode` objects.
|
||||
/// In Python 2.7, `str` is expected to be UTF-8 encoded.
|
||||
extract!(obj to Cow<'prepared, str>; py => {
|
||||
PyString::extract(obj, py)
|
||||
PyString::extract(py, obj)
|
||||
});
|
||||
|
||||
enum PreparedString {
|
||||
|
@ -330,18 +330,18 @@ enum PreparedString {
|
|||
impl <'prepared> ExtractPyObject<'prepared> for &'prepared str {
|
||||
type Prepared = PreparedString;
|
||||
|
||||
fn prepare_extract(obj: &PyObject, py: Python) -> PyResult<Self::Prepared> {
|
||||
match try!(PyString::extract(obj, py)) {
|
||||
fn prepare_extract(py: Python, obj: &PyObject) -> PyResult<Self::Prepared> {
|
||||
match try!(PyString::extract(py, obj)) {
|
||||
Cow::Owned(s) => Ok(PreparedString::Extracted(s)),
|
||||
Cow::Borrowed(_) => Ok(PreparedString::BorrowFrom(obj.clone_ref(py)))
|
||||
}
|
||||
}
|
||||
|
||||
fn extract(prepared: &'prepared PreparedString, py: Python) -> PyResult<Self> {
|
||||
fn extract(py: Python, prepared: &'prepared PreparedString) -> PyResult<Self> {
|
||||
match *prepared {
|
||||
PreparedString::Extracted(ref s) => Ok(s),
|
||||
PreparedString::BorrowFrom(ref obj) => {
|
||||
match try!(PyString::extract(obj, py)) {
|
||||
match try!(PyString::extract(py, obj)) {
|
||||
Cow::Owned(_) => panic!("Failed to borrow from python object"),
|
||||
Cow::Borrowed(s) => Ok(s)
|
||||
}
|
||||
|
@ -370,8 +370,8 @@ mod test {
|
|||
let py = gil.python();
|
||||
let s = "Hello Python";
|
||||
let py_string = s.to_py_object(py).into_object();
|
||||
let prepared = <&str>::prepare_extract(&py_string, py).unwrap();
|
||||
assert_eq!(s, <&str>::extract(&prepared, py).unwrap());
|
||||
let prepared = <&str>::prepare_extract(py, &py_string).unwrap();
|
||||
assert_eq!(s, <&str>::extract(py, &prepared).unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
use {Python, PyDict, ToPyObject, PyInt};
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
|
||||
// TODO: move these tests into the dict module
|
||||
#[test]
|
||||
fn test_hashmap_to_python() {
|
||||
let gil = Python::acquire_gil();
|
||||
|
@ -30,7 +31,7 @@ fn test_hashmap_to_python() {
|
|||
let py_map = map.to_py_object(py);
|
||||
|
||||
assert!(py_map.len(py) == 1);
|
||||
assert!( py_map.get_item(1, py).unwrap().extract::<i32>(py).unwrap() == 1);
|
||||
assert!( py_map.get_item(py, 1).unwrap().extract::<i32>(py).unwrap() == 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -44,6 +45,6 @@ fn test_btreemap_to_python() {
|
|||
let py_map = map.to_py_object(py);
|
||||
|
||||
assert!(py_map.len(py) == 1);
|
||||
assert!( py_map.get_item(1, py).unwrap().extract::<i32>(py).unwrap() == 1);
|
||||
assert!( py_map.get_item(py, 1).unwrap().extract::<i32>(py).unwrap() == 1);
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ impl PyTuple {
|
|||
/// Gets the length of the tuple.
|
||||
#[inline]
|
||||
pub fn len(&self) -> usize {
|
||||
// Safe despite not taking a `Python`, because tuples are immutable.
|
||||
// Safe despite not taking a `Python` token, because tuples are immutable.
|
||||
unsafe {
|
||||
// non-negative Py_ssize_t should always fit into Rust uint
|
||||
ffi::PyTuple_GET_SIZE(self.0.as_ptr()) as usize
|
||||
|
@ -63,7 +63,9 @@ impl PyTuple {
|
|||
/// Gets the item at the specified index.
|
||||
///
|
||||
/// Panics if the index is out of range.
|
||||
pub fn get_item(&self, index: usize, py: Python) -> PyObject {
|
||||
pub fn get_item(&self, py: Python, 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 {
|
||||
PyObject::from_borrowed_ptr(py, ffi::PyTuple_GET_ITEM(self.0.as_ptr(), index as Py_ssize_t))
|
||||
|
@ -84,8 +86,10 @@ impl PyTuple {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO impl Index for PyTuple
|
||||
|
||||
/*
|
||||
impl IntoIterator for PyTuple {
|
||||
impl IntoIterator for PyTuple { TODO
|
||||
type Item = PyObject;
|
||||
type IntoIter = PyTupleIterator;
|
||||
|
||||
|
@ -140,7 +144,7 @@ impl <'p> ExactSizeIterator for PyTupleIterator<'p> {
|
|||
}
|
||||
*/
|
||||
|
||||
fn wrong_tuple_length(t: &PyTuple, expected_length: usize, py: Python) -> PyErr {
|
||||
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());
|
||||
PyErr::new_lazy_init(py.get_type::<exc::ValueError>(), Some(msg.to_py_object(py).into_object()))
|
||||
}
|
||||
|
@ -203,7 +207,7 @@ tuple_conversion!(9, (ref0, 0, A), (ref1, 1, B), (ref2, 2, C), (ref3, 3, D),
|
|||
/// let gil_guard = cpython::Python::acquire_gil();
|
||||
/// let py = gil_guard.python();
|
||||
/// let os = py.import("os").unwrap();
|
||||
/// let pid = os.call("get_pid", cpython::NoArgs, None, py);
|
||||
/// let pid = os.call(py, "get_pid", cpython::NoArgs, None);
|
||||
/// ```
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct NoArgs;
|
||||
|
@ -224,7 +228,7 @@ extract!(obj to NoArgs; py => {
|
|||
if t.len() == 0 {
|
||||
Ok(NoArgs)
|
||||
} else {
|
||||
Err(wrong_tuple_length(t, 0, py))
|
||||
Err(wrong_tuple_length(py, t, 0))
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -35,28 +35,29 @@ impl PyType {
|
|||
}
|
||||
|
||||
/// Retrieves the PyType instance for the given FFI pointer.
|
||||
/// 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) -> PyType {
|
||||
PyObject::from_borrowed_ptr(py, p as *mut ffi::PyObject).unchecked_cast_into::<PyType>()
|
||||
}
|
||||
|
||||
/// Return true if self is a subtype of b.
|
||||
/// Return true if `self` is a subtype of `b`.
|
||||
#[inline]
|
||||
pub fn is_subtype_of(&self, b : &PyType, _: Python) -> bool {
|
||||
pub fn is_subtype_of(&self, _: Python, b : &PyType) -> bool {
|
||||
unsafe { ffi::PyType_IsSubtype(self.as_type_ptr(), b.as_type_ptr()) != 0 }
|
||||
}
|
||||
|
||||
/// Return true if obj is an instance of self.
|
||||
/// Return true if `obj` is an instance of `self`.
|
||||
#[inline]
|
||||
pub fn is_instance(&self, obj : &PyObject, _: Python) -> bool {
|
||||
pub fn is_instance(&self, _: Python, obj : &PyObject) -> bool {
|
||||
unsafe { ffi::PyObject_TypeCheck(obj.as_ptr(), self.as_type_ptr()) != 0 }
|
||||
}
|
||||
|
||||
/// Calls the type object, thus creating a new instance.
|
||||
/// This is equivalent to the Python expression: `self(*args, **kwargs)`
|
||||
#[inline]
|
||||
pub fn call<A>(&self, args: A, kwargs: Option<&PyDict>, py: Python) -> PyResult<PyObject>
|
||||
pub fn call<A>(&self, py: Python, args: A, kwargs: Option<&PyDict>) -> PyResult<PyObject>
|
||||
where A: ToPyObject<ObjectType=PyTuple>
|
||||
{
|
||||
args.with_borrowed_ptr(py, |args| unsafe {
|
||||
|
|
|
@ -61,10 +61,10 @@ pub struct PythonObjectDowncastError<'p>(pub Python<'p>);
|
|||
/// Trait implemented by Python object types that allow a checked downcast.
|
||||
pub trait PythonObjectWithCheckedDowncast : PythonObject {
|
||||
/// Cast from PyObject to a concrete Python object type.
|
||||
fn downcast_from<'p>(PyObject, Python<'p>) -> Result<Self, PythonObjectDowncastError<'p>>;
|
||||
fn downcast_from<'p>(Python<'p>, PyObject) -> Result<Self, PythonObjectDowncastError<'p>>;
|
||||
|
||||
/// Cast from PyObject to a concrete Python object type.
|
||||
fn downcast_borrow_from<'a, 'p>(&'a PyObject, Python<'p>) -> Result<&'a Self, PythonObjectDowncastError<'p>>;
|
||||
fn downcast_borrow_from<'a, 'p>(Python<'p>, &'a PyObject) -> Result<&'a Self, PythonObjectDowncastError<'p>>;
|
||||
}
|
||||
|
||||
/// Trait implemented by Python object types that have a corresponding type object.
|
||||
|
@ -318,7 +318,7 @@ mod test {
|
|||
|
||||
let d = PyDict::new(py);
|
||||
|
||||
d.set_item("foo", 13, py).unwrap();
|
||||
d.set_item(py, "foo", 13).unwrap();
|
||||
|
||||
// Inject our own local namespace
|
||||
let v: i32 = py.eval("foo + 29", None, Some(&d)).unwrap().extract(py).unwrap();
|
||||
|
|
|
@ -54,8 +54,8 @@ use err;
|
|||
/// let multiplier_type = PyRustTypeBuilder::<i32>::new(py, "Multiplier")
|
||||
/// .add("mul", py_method!(mul(arg: i32)))
|
||||
/// .finish().unwrap();
|
||||
/// let obj = multiplier_type.create_instance(3, (), py).into_object();
|
||||
/// let result = obj.call_method("mul", &(4,), None, py).unwrap().extract::<i32>(py).unwrap();
|
||||
/// let obj = multiplier_type.create_instance(py, 3, ()).into_object();
|
||||
/// let result = obj.call_method(py, "mul", &(4,), None).unwrap().extract::<i32>(py).unwrap();
|
||||
/// assert_eq!(result, 12);
|
||||
/// }
|
||||
/// ```
|
||||
|
@ -127,7 +127,7 @@ macro_rules! py_method {
|
|||
None => None
|
||||
};
|
||||
let ret: $crate::PyResult<_> =
|
||||
py_argparse!(Some(stringify!($f)), &args, kwargs.as_ref(), py,
|
||||
py_argparse!(py, Some(stringify!($f)), &args, kwargs.as_ref(),
|
||||
( $($pname : $ptype),* ) { $f( py, &slf, $($pname),* ) });
|
||||
$crate::PyDrop::release_ref(kwargs, py);
|
||||
$crate::PyDrop::release_ref(args, py);
|
||||
|
@ -233,7 +233,7 @@ pub mod py_method_impl {
|
|||
|
||||
impl <T> TypeMember<T> for MethodDescriptor<T> where T: PythonObject {
|
||||
#[inline]
|
||||
fn to_descriptor(&self, ty: &PyType, _name: &str, py: Python) -> PyObject {
|
||||
fn to_descriptor(&self, py: Python, ty: &PyType, _name: &str) -> PyObject {
|
||||
unsafe {
|
||||
err::from_owned_ptr_or_panic(py,
|
||||
ffi::PyDescr_NewMethod(ty.as_type_ptr(), self.0))
|
||||
|
@ -250,7 +250,7 @@ impl <T> TypeMember<T> for MethodDescriptor<T> where T: PythonObject {
|
|||
/// Creates a Python class method descriptor that invokes a Rust function.
|
||||
///
|
||||
/// As arguments, takes the name of a rust function with the signature
|
||||
/// `fn(&PyType, &PyTuple, Python) -> PyResult<T>`
|
||||
/// `fn(Python, &PyType, &PyTuple, Option<&PyDict>) -> PyResult<T>`
|
||||
/// for some `T` that implements `ToPyObject`.
|
||||
///
|
||||
/// Returns a type that implements `typebuilder::TypeMember<PyRustObject<_>>`
|
||||
|
@ -261,9 +261,8 @@ impl <T> TypeMember<T> for MethodDescriptor<T> where T: PythonObject {
|
|||
/// #![feature(plugin)]
|
||||
/// #![plugin(interpolate_idents)]
|
||||
/// #[macro_use] extern crate cpython;
|
||||
/// use cpython::{Python, PythonObject, PyResult, PyErr, ObjectProtocol,
|
||||
/// PyTuple, PyType, PyRustTypeBuilder, NoArgs};
|
||||
/// use cpython::{exc};
|
||||
/// use cpython::{Python, PythonObject, PyResult, ObjectProtocol,
|
||||
/// PyRustTypeBuilder, NoArgs};
|
||||
///
|
||||
/// fn method(py: Python) -> PyResult<i32> {
|
||||
/// Ok(42)
|
||||
|
@ -275,7 +274,7 @@ impl <T> TypeMember<T> for MethodDescriptor<T> where T: PythonObject {
|
|||
/// let my_type = PyRustTypeBuilder::<i32>::new(py, "MyType")
|
||||
/// .add("method", py_class_method!(method()))
|
||||
/// .finish().unwrap();
|
||||
/// let result = my_type.as_object().call_method("method", NoArgs, None, py).unwrap();
|
||||
/// let result = my_type.as_object().call_method(py, "method", NoArgs, None).unwrap();
|
||||
/// assert_eq!(42, result.extract::<i32>(py).unwrap());
|
||||
/// }
|
||||
/// ```
|
||||
|
@ -298,7 +297,7 @@ macro_rules! py_class_method {
|
|||
Some(kwargs) => Some(<$crate::PyDict as $crate::PythonObject>::unchecked_downcast_from(kwargs)),
|
||||
None => None
|
||||
};
|
||||
let ret: $crate::PyResult<_> = $f(&slf, &args, kwargs.as_ref(), py);
|
||||
let ret: $crate::PyResult<_> = $f(py, &slf, &args, kwargs.as_ref());
|
||||
$crate::PyDrop::release_ref(kwargs, py);
|
||||
$crate::PyDrop::release_ref(args, py);
|
||||
$crate::PyDrop::release_ref(slf, py);
|
||||
|
@ -349,7 +348,7 @@ macro_rules! py_class_method {
|
|||
None => None
|
||||
};
|
||||
let ret: $crate::PyResult<_> =
|
||||
py_argparse!(Some(stringify!($f)), &args, kwargs.as_ref(), py,
|
||||
py_argparse!(py, Some(stringify!($f)), &args, kwargs.as_ref(),
|
||||
( $($pname : $ptype),* ) { $f( py, $($pname),* ) });
|
||||
$crate::PyDrop::release_ref(kwargs, py);
|
||||
$crate::PyDrop::release_ref(args, py);
|
||||
|
@ -394,7 +393,7 @@ pub unsafe fn py_class_method_impl(def: *mut ffi::PyMethodDef) -> ClassMethodDes
|
|||
|
||||
impl <T> TypeMember<T> for ClassMethodDescriptor where T: PythonObject {
|
||||
#[inline]
|
||||
fn to_descriptor(&self, ty: &PyType, _name: &str, py: Python) -> PyObject {
|
||||
fn to_descriptor(&self, py: Python, ty: &PyType, _name: &str) -> PyObject {
|
||||
unsafe {
|
||||
err::from_owned_ptr_or_panic(py,
|
||||
ffi::PyDescr_NewClassMethod(ty.as_type_ptr(), self.0))
|
||||
|
|
|
@ -40,12 +40,12 @@ pub trait PythonBaseObject : PythonObject {
|
|||
/// 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(ty: &PyType, init_val: Self::InitType, py: Python) -> PyResult<Self>;
|
||||
unsafe fn alloc(py: Python, ty: &PyType, init_val: Self::InitType) -> PyResult<Self>;
|
||||
|
||||
/// 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(ptr: *mut ffi::PyObject, py: Python);
|
||||
unsafe fn dealloc(py: Python, ptr: *mut ffi::PyObject);
|
||||
}
|
||||
|
||||
impl PythonBaseObject for PyObject {
|
||||
|
@ -56,12 +56,12 @@ impl PythonBaseObject for PyObject {
|
|||
|
||||
type InitType = ();
|
||||
|
||||
unsafe fn alloc(ty: &PyType, _init_val: (), py: Python) -> PyResult<PyObject> {
|
||||
unsafe fn alloc(py: Python, ty: &PyType, _init_val: ()) -> PyResult<PyObject> {
|
||||
let ptr = ffi::PyType_GenericAlloc(ty.as_type_ptr(), 0);
|
||||
err::result_from_owned_ptr(py, ptr)
|
||||
}
|
||||
|
||||
unsafe fn dealloc(ptr: *mut ffi::PyObject, _py: Python) {
|
||||
unsafe fn dealloc(_py: Python, ptr: *mut ffi::PyObject) {
|
||||
// Unfortunately, there is no PyType_GenericFree, so
|
||||
// we have to manually un-do the work of PyType_GenericAlloc:
|
||||
let ty = ffi::Py_TYPE(ptr);
|
||||
|
@ -130,17 +130,17 @@ impl <T, B> PythonBaseObject for PyRustObject<T, B> where T: 'static + Send, B:
|
|||
|
||||
type InitType = (T, B::InitType);
|
||||
|
||||
unsafe fn alloc(ty: &PyType, (val, base_val): Self::InitType, py: Python) -> PyResult<Self> {
|
||||
let obj = try!(B::alloc(ty, base_val, py));
|
||||
unsafe fn alloc(py: Python, ty: &PyType, (val, base_val): Self::InitType) -> PyResult<Self> {
|
||||
let obj = try!(B::alloc(py, ty, base_val));
|
||||
let offset = PyRustObject::<T, B>::offset() as isize;
|
||||
ptr::write((obj.as_object().as_ptr() as *mut u8).offset(offset) as *mut T, val);
|
||||
Ok(Self::unchecked_downcast_from(obj.into_object()))
|
||||
}
|
||||
|
||||
unsafe fn dealloc(obj: *mut ffi::PyObject, py: Python) {
|
||||
unsafe fn dealloc(py: Python, obj: *mut ffi::PyObject) {
|
||||
let offset = PyRustObject::<T, B>::offset() as isize;
|
||||
ptr::read_and_drop((obj as *mut u8).offset(offset) as *mut T);
|
||||
B::dealloc(obj, py)
|
||||
B::dealloc(py, obj)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -204,9 +204,9 @@ pub struct PyRustType<T, B = PyObject> where T: 'static + Send, B: PythonBaseObj
|
|||
|
||||
impl <T, B> PyRustType<T, B> where T: 'static + Send, B: PythonBaseObject {
|
||||
/// Creates a PyRustObject instance from a value.
|
||||
pub fn create_instance(&self, val: T, base_val: B::InitType, py: Python) -> PyRustObject<T, B> {
|
||||
pub fn create_instance(&self, py: Python, val: T, base_val: B::InitType) -> PyRustObject<T, B> {
|
||||
unsafe {
|
||||
PythonBaseObject::alloc(&self.type_obj, (val, base_val), py).unwrap()
|
||||
PythonBaseObject::alloc(py, &self.type_obj, (val, base_val)).unwrap()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ fn rustobject_calls_drop() {
|
|||
let t = PyRustTypeBuilder::<MyObj>::new(py, "TypeWithDrop").finish().unwrap();
|
||||
|
||||
let drop_called = Arc::new(AtomicBool::new(false));
|
||||
let inst = t.create_instance(MyObj { drop_called: drop_called.clone() }, (), py);
|
||||
let inst = t.create_instance(py, MyObj { drop_called: drop_called.clone() }, ());
|
||||
assert!(drop_called.load(Ordering::Relaxed) == false);
|
||||
drop(inst);
|
||||
assert!(drop_called.load(Ordering::Relaxed) == true);
|
||||
|
@ -49,7 +49,7 @@ fn no_init_from_python() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let t = PyRustTypeBuilder::<i32>::new(py, "MyType").finish().unwrap();
|
||||
assert!(t.call(&NoArgs, None, py).is_err());
|
||||
assert!(t.call(py, &NoArgs, None).is_err());
|
||||
}
|
||||
|
||||
|
||||
|
@ -61,7 +61,7 @@ fn heaptype_refcount() {
|
|||
// TODO: investigate why the refcnt isn't 1.
|
||||
//assert_eq!(1, t.as_object().get_refcnt());
|
||||
let old_refcnt = t.as_object().get_refcnt(py);
|
||||
let inst = t.create_instance(1, (), py);
|
||||
let inst = t.create_instance(py, 1, ());
|
||||
assert_eq!(old_refcnt + 1, t.as_object().get_refcnt(py));
|
||||
drop(inst);
|
||||
assert_eq!(old_refcnt, t.as_object().get_refcnt(py));
|
||||
|
|
|
@ -68,7 +68,7 @@ pub struct PyRustTypeBuilder<'p, T, B = PyObject> where T: 'static + Send, B: Py
|
|||
phantom: marker::PhantomData<&'p (B, T)>
|
||||
}
|
||||
|
||||
pub fn new_typebuilder_for_module<'p, T>(m: &PyModule, name: &str, py: Python<'p>) -> PyRustTypeBuilder<'p, T>
|
||||
pub fn new_typebuilder_for_module<'p, T>(py: Python<'p>, m: &PyModule, name: &str) -> PyRustTypeBuilder<'p, T>
|
||||
where T: 'static + Send {
|
||||
let b = PyRustTypeBuilder::new(py, name);
|
||||
PyRustTypeBuilder { target_module: Some(m.clone_ref(py)), .. b }
|
||||
|
@ -86,7 +86,7 @@ unsafe extern "C" fn tp_dealloc_callback<T, B>(obj: *mut ffi::PyObject)
|
|||
where T: 'static + Send, B: PythonBaseObject {
|
||||
abort_on_panic!({
|
||||
let py = Python::assume_gil_acquired();
|
||||
PyRustObject::<T, B>::dealloc(obj, py)
|
||||
PyRustObject::<T, B>::dealloc(py, obj)
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -213,7 +213,7 @@ impl <'p, T, B> PyRustTypeBuilder<'p, T, B> where T: 'static + Send, B: PythonBa
|
|||
pub fn add<M>(mut self, name: &str, val: M) -> Self
|
||||
where M: TypeMember<PyRustObject<T, B>> {
|
||||
self.can_change_base = false;
|
||||
self.dict().set_item(name, val.to_descriptor(&self.type_obj, name, self.py), self.py).unwrap();
|
||||
self.dict().set_item(self.py, name, val.to_descriptor(self.py, &self.type_obj, name)).unwrap();
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -241,11 +241,11 @@ impl <'p, T, B> PyRustTypeBuilder<'p, T, B> where T: 'static + Send, B: PythonBa
|
|||
if let Some(m) = self.target_module {
|
||||
// Set module name for new type
|
||||
if let Ok(mod_name) = m.name(py) {
|
||||
try!(self.type_obj.as_object().setattr("__module__", mod_name, py));
|
||||
try!(self.type_obj.as_object().setattr(py, "__module__", mod_name));
|
||||
}
|
||||
// Register the new type in the target module
|
||||
let name = unsafe { PyObject::from_borrowed_ptr(py, (*self.ht).ht_name) };
|
||||
try!(m.dict(py).set_item(name, self.type_obj.as_object(), py));
|
||||
try!(m.dict(py).set_item(py, name, self.type_obj.as_object()));
|
||||
}
|
||||
Ok(PyRustType {
|
||||
type_obj: self.type_obj,
|
||||
|
@ -278,13 +278,13 @@ impl <'p, T, B> PyRustTypeBuilder<'p, T, B> where T: 'static + Send, B: PythonBa
|
|||
self.py, &self.name, PyRustObject::<T, B>::size(),
|
||||
self.flags, &mut self.slots) });
|
||||
for (name, member) in self.members {
|
||||
let descr = member.to_descriptor(&type_obj, &name, self.py);
|
||||
try!(type_obj.as_object().setattr(name, descr, self.py));
|
||||
let descr = member.to_descriptor(self.py, &type_obj, &name);
|
||||
try!(type_obj.as_object().setattr(self.py, name, descr));
|
||||
}
|
||||
if let Some(m) = self.target_module {
|
||||
// Set module name for new type
|
||||
if let Ok(mod_name) = m.name(self.py) {
|
||||
try!(type_obj.as_object().setattr("__module__", mod_name, self.py));
|
||||
try!(type_obj.as_object().setattr(self.py, "__module__", mod_name));
|
||||
}
|
||||
// Register the new type in the target module
|
||||
unsafe {
|
||||
|
@ -353,7 +353,7 @@ unsafe fn create_type_from_slots<'p>(
|
|||
pub trait TypeMember<T> where T: PythonObject {
|
||||
/// Convert the type member into a python object
|
||||
/// that can be stored in the type dict.
|
||||
fn to_descriptor(&self, ty: &PyType, name: &str, py: Python) -> PyObject;
|
||||
fn to_descriptor(&self, py: Python, ty: &PyType, name: &str) -> PyObject;
|
||||
|
||||
/// Put the type member into a box with lifetime `'p` so that
|
||||
/// it can be used at a later point in time.
|
||||
|
@ -367,7 +367,7 @@ pub trait TypeMember<T> where T: PythonObject {
|
|||
|
||||
impl <T, S> TypeMember<T> for S where T: PythonObject, S: ToPyObject {
|
||||
#[inline]
|
||||
fn to_descriptor(&self, _ty: &PyType, _name: &str, py: Python) -> PyObject {
|
||||
fn to_descriptor(&self, py: Python, _ty: &PyType, _name: &str) -> PyObject {
|
||||
self.to_py_object(py).into_object()
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue