modify PyDict
This commit is contained in:
parent
96788bf192
commit
7cf8e1ab80
|
@ -55,15 +55,14 @@ pub fn py3_init(fnname: &syn::Ident, name: &String, doc: syn::Lit) -> Tokens {
|
|||
let guard = _pyo3::callback::AbortOnDrop("py_module_init");
|
||||
let py = _pyo3::Python::assume_gil_acquired();
|
||||
_pyo3::ffi::PyEval_InitThreads();
|
||||
|
||||
let module = _pyo3::ffi::PyModule_Create(&mut MODULE_DEF);
|
||||
if module.is_null() {
|
||||
std::mem::forget(guard);
|
||||
return module;
|
||||
}
|
||||
|
||||
let module = match _pyo3::PyObject::from_owned_ptr(
|
||||
py, module).cast_into::<PyModule>(py)
|
||||
{
|
||||
let module = match py.unchecked_cast_from_ptr_or_err::<PyModule>(module) {
|
||||
Ok(m) => m,
|
||||
Err(e) => {
|
||||
_pyo3::PyErr::from(e).restore(py);
|
||||
|
@ -71,8 +70,8 @@ pub fn py3_init(fnname: &syn::Ident, name: &String, doc: syn::Lit) -> Tokens {
|
|||
return std::ptr::null_mut();
|
||||
}
|
||||
};
|
||||
module.add(py, "__doc__", #doc).expect("Failed to add doc for module");
|
||||
let ret = match #fnname(py, &module) {
|
||||
module.add("__doc__", #doc).expect("Failed to add doc for module");
|
||||
let result = match #fnname(py, module) {
|
||||
Ok(_) => module.into_ptr(),
|
||||
Err(e) => {
|
||||
e.restore(py);
|
||||
|
@ -80,7 +79,7 @@ pub fn py3_init(fnname: &syn::Ident, name: &String, doc: syn::Lit) -> Tokens {
|
|||
}
|
||||
};
|
||||
std::mem::forget(guard);
|
||||
ret
|
||||
result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -133,9 +132,7 @@ pub fn py2_init(fnname: &syn::Ident, name: &String, doc: syn::Lit) -> Tokens {
|
|||
return
|
||||
}
|
||||
|
||||
let module = match pyo3::PyObject::from_borrowed_ptr(
|
||||
py, module).cast_into::<pyo3::PyModule>(py)
|
||||
{
|
||||
let module = match py.unchecked_cast_from_ptr_or_err::<_pyo3::PyModule>(module) {
|
||||
Ok(m) => m,
|
||||
Err(e) => {
|
||||
_pyo3::PyErr::from(e).restore(py);
|
||||
|
@ -143,8 +140,8 @@ pub fn py2_init(fnname: &syn::Ident, name: &String, doc: syn::Lit) -> Tokens {
|
|||
return
|
||||
}
|
||||
};
|
||||
module.add(py, "__doc__", #doc).expect("Failed to add doc for module");
|
||||
let ret = match #fnname(py, &module) {
|
||||
module.add("__doc__", #doc).expect("Failed to add doc for module");
|
||||
let ret = match #fnname(py, module) {
|
||||
Ok(()) => (),
|
||||
Err(e) => e.restore(py)
|
||||
};
|
||||
|
@ -286,7 +283,7 @@ fn wrap_fn(item: &mut syn::Item) -> Option<Box<syn::Block>> {
|
|||
Box::into_raw(Box::new(def.as_method_def())),
|
||||
std::ptr::null_mut()));
|
||||
|
||||
#m.add(py, stringify!(#fnname), func)?
|
||||
#m.add(stringify!(#fnname), func)?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -332,7 +329,6 @@ pub fn impl_wrap(name: &syn::Ident, spec: &method::FnSpec) -> Tokens {
|
|||
let result: #output = {
|
||||
#body
|
||||
};
|
||||
py.release(kwargs);
|
||||
py.release(args);
|
||||
_pyo3::callback::cb_convert(
|
||||
_pyo3::callback::PyObjectCallbackConverter, py, result)
|
||||
|
|
|
@ -90,7 +90,6 @@ pub fn impl_wrap(cls: &Box<syn::Ty>, name: &syn::Ident, spec: &FnSpec, noargs: b
|
|||
_pyo3::callback::cb_convert(
|
||||
_pyo3::callback::PyObjectCallbackConverter, py, result)
|
||||
};
|
||||
py.release(kwargs);
|
||||
py.release(args);
|
||||
py.release(slf);
|
||||
result
|
||||
|
@ -343,7 +342,7 @@ pub fn impl_arg_params(spec: &FnSpec, body: Tokens) -> Tokens {
|
|||
let mut output = [#(#placeholders),*];
|
||||
let result = match _pyo3::argparse::parse_args(
|
||||
py, Some(LOCATION), PARAMS, &args,
|
||||
kwargs.as_ref(), #accept_args, #accept_kwargs, &mut output)
|
||||
kwargs, #accept_args, #accept_kwargs, &mut output)
|
||||
{
|
||||
Ok(_) => {
|
||||
let mut _iter = output.iter();
|
||||
|
|
|
@ -36,7 +36,7 @@ pub fn parse_args<'p>(py: Python<'p>,
|
|||
assert!(params.len() == output.len());
|
||||
|
||||
let nargs = args.len(py);
|
||||
let nkeywords = kwargs.map_or(0, |d| d.len(py));
|
||||
let nkeywords = kwargs.map_or(0, |d| d.len());
|
||||
if !accept_args && (nargs + nkeywords > params.len()) {
|
||||
return Err(err::PyErr::new::<exc::TypeError, _>(
|
||||
py,
|
||||
|
@ -51,7 +51,7 @@ pub fn parse_args<'p>(py: Python<'p>,
|
|||
let mut used_keywords = 0;
|
||||
// Iterate through the parameters and assign values to output:
|
||||
for (i, (p, out)) in params.iter().zip(output).enumerate() {
|
||||
match kwargs.and_then(|d| d.get_item(py, p.name)) {
|
||||
match kwargs.and_then(|d| d.get_item(p.name)) {
|
||||
Some(kwarg) => {
|
||||
*out = Some(kwarg);
|
||||
used_keywords += 1;
|
||||
|
@ -81,7 +81,7 @@ pub fn parse_args<'p>(py: Python<'p>,
|
|||
}
|
||||
if !accept_kwargs && used_keywords != nkeywords {
|
||||
// check for extraneous keyword arguments
|
||||
for (key, _value) in kwargs.unwrap().items(py) {
|
||||
for (key, _value) in kwargs.unwrap().items() {
|
||||
let key = try!(try!(key.cast_as::<PyString>(py)).to_string());
|
||||
if !params.iter().any(|p| p.name == key) {
|
||||
return Err(err::PyErr::new::<exc::TypeError, _>(
|
||||
|
@ -96,11 +96,11 @@ pub fn parse_args<'p>(py: Python<'p>,
|
|||
|
||||
#[inline]
|
||||
#[doc(hidden)]
|
||||
pub unsafe fn get_kwargs(py: Python, ptr: *mut ffi::PyObject) -> Option<PyDict> {
|
||||
pub unsafe fn get_kwargs<'p>(py: Python<'p>, ptr: *mut ffi::PyObject) -> Option<&PyDict> {
|
||||
if ptr.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(PyDict::from_borrowed_ptr(py, ptr))
|
||||
Some(py.unchecked_cast_from_ptr::<PyDict>(ptr))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,10 +34,10 @@ let gil = Python::acquire_gil();
|
|||
let py = gil.python();
|
||||
let ctx = PyDict::new(py);
|
||||
|
||||
ctx.set_item(py, "CustomError", py.get_type::<CustomError>()).unwrap();
|
||||
ctx.set_item("CustomError", py.get_type::<CustomError>()).unwrap();
|
||||
|
||||
py.run("assert str(CustomError) == \"<class 'mymodule.CustomError'>\"", None, Some(&ctx)).unwrap();
|
||||
py.run("assert CustomError('oops').args == ('oops',)", None, Some(&ctx)).unwrap();
|
||||
py.run("assert CustomError('oops').args == ('oops',)", None, Some(ctx)).unwrap();
|
||||
}
|
||||
```
|
||||
*/
|
||||
|
|
10
src/lib.rs
10
src/lib.rs
|
@ -43,11 +43,11 @@
|
|||
//!
|
||||
//! fn hello(py: Python) -> PyResult<()> {
|
||||
//! let sys = py.import("sys")?;
|
||||
//! let version: String = sys.get(py, "version")?.extract(py)?;
|
||||
//! let version: String = sys.get("version")?.extract(py)?;
|
||||
//!
|
||||
//! let locals = PyDict::new(py);
|
||||
//! locals.set_item(py, "os", py.import("os")?)?;
|
||||
//! let user: String = py.eval("os.getenv('USER') or os.getenv('USERNAME')", None, Some(&locals))?.extract(py)?;
|
||||
//! locals.set_item("os", py.import("os")?)?;
|
||||
//! let user: String = py.eval("os.getenv('USER') or os.getenv('USERNAME')", None, Some(locals))?.extract(py)?;
|
||||
//!
|
||||
//! println!("Hello {}, I'm Python {}", user, version);
|
||||
//! Ok(())
|
||||
|
@ -95,9 +95,9 @@
|
|||
//! // Note that the `#[pyfn()]` annotation automatically converts the arguments from
|
||||
//! // Python objects to Rust values; and the Rust return value back into a Python object.
|
||||
//! #[pyfn(m, "run_rust_func")]
|
||||
//! fn run(py: Python, name: &PyString) -> PyResult<PyObject> {
|
||||
//! fn run(py: Python, name: &PyString) -> PyResult<()> {
|
||||
//! println!("Rust says: Hello {} of Python!", name);
|
||||
//! Ok(py.None())
|
||||
//! Ok(())
|
||||
//! }
|
||||
//!
|
||||
//! Ok(())
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
use std::{mem, collections, hash, cmp};
|
||||
|
||||
use ffi;
|
||||
use token::Py;
|
||||
use pointers::PyPtr;
|
||||
use token::PyObjectWithToken;
|
||||
use python::{Python, ToPyPointer};
|
||||
use conversion::{ToPyObject};
|
||||
use objects::{PyObject, PyList};
|
||||
|
@ -15,111 +15,107 @@ use err::{self, PyResult, PyErr};
|
|||
/// Represents a Python `dict`.
|
||||
pub struct PyDict(PyPtr);
|
||||
|
||||
pyobject_convert!(PyDict);
|
||||
pyobject_nativetype!(PyDict, PyDict_Type, PyDict_Check);
|
||||
pyobject_nativetype2!(PyDict, PyDict_Type, PyDict_Check);
|
||||
|
||||
|
||||
impl PyDict {
|
||||
/// Creates a new empty dictionary.
|
||||
///
|
||||
/// May panic when running out of memory.
|
||||
pub fn new(_py: Python) -> PyDict {
|
||||
unsafe { PyDict(PyPtr::from_owned_ptr_or_panic(ffi::PyDict_New())) }
|
||||
}
|
||||
|
||||
/// Construct a new dict with the given raw pointer
|
||||
/// Undefined behavior if the pointer is NULL or invalid.
|
||||
pub unsafe fn from_borrowed_ptr(_py: Python, ptr: *mut ffi::PyObject) -> PyDict {
|
||||
PyDict(PyPtr::from_borrowed_ptr(ptr))
|
||||
pub fn new<'p>(py: Python<'p>) -> &'p PyDict {
|
||||
unsafe {
|
||||
py.unchecked_cast_from_ptr::<PyDict>(ffi::PyDict_New())
|
||||
}
|
||||
}
|
||||
|
||||
/// Return a new dictionary that contains the same key-value pairs as self.
|
||||
/// Corresponds to `dict(self)` in Python.
|
||||
pub fn copy(&self, py: Python) -> PyResult<PyDict> {
|
||||
pub fn copy(&self) -> PyResult<&PyDict> {
|
||||
unsafe {
|
||||
Ok(PyDict(
|
||||
PyPtr::from_owned_ptr_or_err(py, ffi::PyDict_Copy(self.0.as_ptr()))?
|
||||
))
|
||||
self.token().unchecked_cast_from_ptr_or_err::<PyDict>(
|
||||
ffi::PyDict_Copy(self.as_ptr()))
|
||||
}
|
||||
}
|
||||
|
||||
/// Empty an existing dictionary of all key-value pairs.
|
||||
#[inline]
|
||||
pub fn clear(&self, _py: Python) {
|
||||
pub fn clear(&self) {
|
||||
unsafe { ffi::PyDict_Clear(self.as_ptr()) }
|
||||
}
|
||||
|
||||
/// Return the number of items in the dictionary.
|
||||
/// This is equivalent to len(p) on a dictionary.
|
||||
#[inline]
|
||||
pub fn len(&self, _py: Python) -> usize {
|
||||
pub fn len(&self) -> usize {
|
||||
unsafe { ffi::PyDict_Size(self.as_ptr()) as usize }
|
||||
}
|
||||
|
||||
/// Determine if the dictionary contains the specified key.
|
||||
/// This is equivalent to the Python expression `key in self`.
|
||||
pub fn contains<K>(&self, py: Python, key: K) -> PyResult<bool> where K: ToPyObject {
|
||||
key.with_borrowed_ptr(py, |key| unsafe {
|
||||
pub fn contains<K>(&self, key: K) -> PyResult<bool> where K: ToPyObject {
|
||||
key.with_borrowed_ptr(self.token(), |key| unsafe {
|
||||
match ffi::PyDict_Contains(self.as_ptr(), key) {
|
||||
1 => Ok(true),
|
||||
0 => Ok(false),
|
||||
_ => Err(PyErr::fetch(py))
|
||||
_ => Err(PyErr::fetch(self.token()))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Gets an item from the dictionary.
|
||||
/// Returns None if the item is not present, or if an error occurs.
|
||||
pub fn get_item<K>(&self, py: Python, key: K) -> Option<PyObject> where K: ToPyObject {
|
||||
key.with_borrowed_ptr(py, |key| unsafe {
|
||||
pub fn get_item<K>(&self, key: K) -> Option<PyObject> where K: ToPyObject {
|
||||
key.with_borrowed_ptr(self.token(), |key| unsafe {
|
||||
PyObject::from_borrowed_ptr_or_opt(
|
||||
py, ffi::PyDict_GetItem(self.as_ptr(), key))
|
||||
self.token(), ffi::PyDict_GetItem(self.as_ptr(), key))
|
||||
})
|
||||
}
|
||||
|
||||
/// Sets an item value.
|
||||
/// This is equivalent to the Python expression `self[key] = value`.
|
||||
pub fn set_item<K, V>(&self, py: Python, key: K, value: V)
|
||||
-> PyResult<()> where K: ToPyObject, V: ToPyObject {
|
||||
pub fn set_item<K, V>(&self, key: K, value: V) -> PyResult<()>
|
||||
where K: ToPyObject, V: ToPyObject
|
||||
{
|
||||
key.with_borrowed_ptr(
|
||||
py, move |key|
|
||||
value.with_borrowed_ptr(py, |value| unsafe {
|
||||
self.token(), move |key|
|
||||
value.with_borrowed_ptr(self.token(), |value| unsafe {
|
||||
err::error_on_minusone(
|
||||
py, ffi::PyDict_SetItem(self.as_ptr(), key, value))
|
||||
self.token(), ffi::PyDict_SetItem(self.as_ptr(), key, value))
|
||||
}))
|
||||
}
|
||||
|
||||
/// Deletes an item.
|
||||
/// This is equivalent to the Python expression `del self[key]`.
|
||||
pub fn del_item<K>(&self, py: Python, key: K) -> PyResult<()> where K: ToPyObject {
|
||||
key.with_borrowed_ptr(py, |key| unsafe {
|
||||
pub fn del_item<K>(&self, key: K) -> PyResult<()> where K: ToPyObject
|
||||
{
|
||||
key.with_borrowed_ptr(self.token(), |key| unsafe {
|
||||
err::error_on_minusone(
|
||||
py, ffi::PyDict_DelItem(self.as_ptr(), key))
|
||||
self.token(), ffi::PyDict_DelItem(self.as_ptr(), key))
|
||||
})
|
||||
}
|
||||
|
||||
/// List of dict items.
|
||||
/// This is equivalent to the python expression `list(dict.items())`.
|
||||
pub fn items_list(&self, py: Python) -> Py<PyList> {
|
||||
pub fn items_list(&self) -> &PyList {
|
||||
unsafe {
|
||||
PyObject::from_owned_ptr(
|
||||
py, ffi::PyDict_Items(self.as_ptr())).unchecked_cast_into::<Py<PyList>>()
|
||||
self.token().unchecked_cast_from_ptr::<PyList>(
|
||||
ffi::PyDict_Items(self.as_ptr()))
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the list of (key, value) pairs in this dictionary.
|
||||
pub fn items(&self, py: Python) -> Vec<(PyObject, PyObject)> {
|
||||
pub fn items(&self) -> Vec<(PyObject, PyObject)> {
|
||||
// Note that we don't provide an iterator because
|
||||
// PyDict_Next() is unsafe to use when the dictionary might be changed
|
||||
// by other python code.
|
||||
let mut vec = Vec::with_capacity(self.len(py));
|
||||
let mut vec = Vec::with_capacity(self.len());
|
||||
unsafe {
|
||||
let mut pos = 0;
|
||||
let mut key: *mut ffi::PyObject = mem::uninitialized();
|
||||
let mut value: *mut ffi::PyObject = mem::uninitialized();
|
||||
while ffi::PyDict_Next(self.as_ptr(), &mut pos, &mut key, &mut value) != 0 {
|
||||
vec.push((PyObject::from_borrowed_ptr(py, key),
|
||||
PyObject::from_borrowed_ptr(py, value)));
|
||||
vec.push((PyObject::from_borrowed_ptr(self.token(), key),
|
||||
PyObject::from_borrowed_ptr(self.token(), value)));
|
||||
}
|
||||
}
|
||||
vec
|
||||
|
@ -133,7 +129,7 @@ impl <K, V> ToPyObject for collections::HashMap<K, V>
|
|||
fn to_object(&self, py: Python) -> PyObject {
|
||||
let dict = PyDict::new(py);
|
||||
for (key, value) in self {
|
||||
dict.set_item(py, key, value).expect("Failed to set_item on dict");
|
||||
dict.set_item(key, value).expect("Failed to set_item on dict");
|
||||
};
|
||||
dict.into()
|
||||
}
|
||||
|
@ -146,7 +142,7 @@ impl <K, V> ToPyObject for collections::BTreeMap<K, V>
|
|||
fn to_object(&self, py: Python) -> PyObject {
|
||||
let dict = PyDict::new(py);
|
||||
for (key, value) in self {
|
||||
dict.set_item(py, key, value).expect("Failed to set_item on dict");
|
||||
dict.set_item(key, value).expect("Failed to set_item on dict");
|
||||
};
|
||||
dict.into()
|
||||
}
|
||||
|
@ -160,6 +156,27 @@ mod test {
|
|||
use objects::{PyDict, PyTuple};
|
||||
use ::PyDowncastFrom;
|
||||
|
||||
#[test]
|
||||
fn test_new() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let dict = PyDict::new(py);
|
||||
dict.set_item(7, 32).unwrap();
|
||||
assert_eq!(32, dict.get_item(7i32).unwrap().extract::<i32>(py).unwrap());
|
||||
assert_eq!(None, dict.get_item(8i32));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_copy() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let dict = PyDict::new(py);
|
||||
dict.set_item(7, 32).unwrap();
|
||||
|
||||
let ndict = dict.copy().unwrap();
|
||||
assert_eq!(32, ndict.get_item(7i32).unwrap().extract::<i32>(py).unwrap());
|
||||
assert_eq!(None, ndict.get_item(8i32));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_len() {
|
||||
|
@ -168,11 +185,11 @@ mod test {
|
|||
let mut v = HashMap::new();
|
||||
let ob = v.to_object(py);
|
||||
let dict = PyDict::downcast_from(py, &ob).unwrap();
|
||||
assert_eq!(0, dict.len(py));
|
||||
assert_eq!(0, dict.len());
|
||||
v.insert(7, 32);
|
||||
let ob = v.to_object(py);
|
||||
let dict2 = PyDict::downcast_from(py, &ob).unwrap();
|
||||
assert_eq!(1, dict2.len(py));
|
||||
assert_eq!(1, dict2.len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -183,8 +200,8 @@ mod test {
|
|||
v.insert(7, 32);
|
||||
let ob = v.to_object(py);
|
||||
let dict = PyDict::downcast_from(py, &ob).unwrap();
|
||||
assert_eq!(true, dict.contains(py, 7i32).unwrap());
|
||||
assert_eq!(false, dict.contains(py, 8i32).unwrap());
|
||||
assert_eq!(true, dict.contains(7i32).unwrap());
|
||||
assert_eq!(false, dict.contains(8i32).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -195,8 +212,8 @@ mod test {
|
|||
v.insert(7, 32);
|
||||
let ob = v.to_object(py);
|
||||
let dict = PyDict::downcast_from(py, &ob).unwrap();
|
||||
assert_eq!(32, dict.get_item(py, 7i32).unwrap().extract::<i32>(py).unwrap());
|
||||
assert_eq!(None, dict.get_item(py, 8i32));
|
||||
assert_eq!(32, dict.get_item(7i32).unwrap().extract::<i32>(py).unwrap());
|
||||
assert_eq!(None, dict.get_item(8i32));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -207,10 +224,10 @@ mod test {
|
|||
v.insert(7, 32);
|
||||
let ob = v.to_object(py);
|
||||
let dict = PyDict::downcast_from(py, &ob).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());
|
||||
assert!(dict.set_item(7i32, 42i32).is_ok()); // change
|
||||
assert!(dict.set_item(8i32, 123i32).is_ok()); // insert
|
||||
assert_eq!(42i32, dict.get_item(7i32).unwrap().extract::<i32>(py).unwrap());
|
||||
assert_eq!(123i32, dict.get_item(8i32).unwrap().extract::<i32>(py).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -221,13 +238,12 @@ mod test {
|
|||
v.insert(7, 32);
|
||||
let ob = v.to_object(py);
|
||||
let dict = PyDict::downcast_from(py, &ob).unwrap();
|
||||
assert!(dict.set_item(py, 7i32, 42i32).is_ok()); // change
|
||||
assert!(dict.set_item(py, 8i32, 123i32).is_ok()); // insert
|
||||
assert!(dict.set_item(7i32, 42i32).is_ok()); // change
|
||||
assert!(dict.set_item(8i32, 123i32).is_ok()); // insert
|
||||
assert_eq!(32i32, *v.get(&7i32).unwrap()); // not updated!
|
||||
assert_eq!(None, v.get(&8i32));
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_del_item() {
|
||||
let gil = Python::acquire_gil();
|
||||
|
@ -236,9 +252,9 @@ mod test {
|
|||
v.insert(7, 32);
|
||||
let ob = v.to_object(py);
|
||||
let dict = PyDict::downcast_from(py, &ob).unwrap();
|
||||
assert!(dict.del_item(py, 7i32).is_ok());
|
||||
assert_eq!(0, dict.len(py));
|
||||
assert_eq!(None, dict.get_item(py, 7i32));
|
||||
assert!(dict.del_item(7i32).is_ok());
|
||||
assert_eq!(0, dict.len());
|
||||
assert_eq!(None, dict.get_item(7i32));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -249,11 +265,11 @@ mod test {
|
|||
v.insert(7, 32);
|
||||
let ob = v.to_object(py);
|
||||
let dict = PyDict::downcast_from(py, &ob).unwrap();
|
||||
assert!(dict.del_item(py, 7i32).is_ok()); // change
|
||||
assert!(dict.del_item(7i32).is_ok()); // change
|
||||
assert_eq!(32i32, *v.get(&7i32).unwrap()); // not updated!
|
||||
}
|
||||
|
||||
/*#[test]
|
||||
#[test]
|
||||
fn test_items_list() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
@ -266,14 +282,14 @@ mod test {
|
|||
// Can't just compare against a vector of tuples since we don't have a guaranteed ordering.
|
||||
let mut key_sum = 0;
|
||||
let mut value_sum = 0;
|
||||
for el in dict.items_list().iter(py) {
|
||||
let tuple = el.cast_into::<PyTuple>(py).unwrap();
|
||||
for el in dict.items_list().iter() {
|
||||
let tuple = el.cast_as::<PyTuple>(py).unwrap();
|
||||
key_sum += tuple.get_item(py, 0).extract::<i32>(py).unwrap();
|
||||
value_sum += tuple.get_item(py, 1).extract::<i32>(py).unwrap();
|
||||
}
|
||||
assert_eq!(7 + 8 + 9, key_sum);
|
||||
assert_eq!(32 + 42 + 123, value_sum);
|
||||
}*/
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_items() {
|
||||
|
@ -288,7 +304,7 @@ mod test {
|
|||
// Can't just compare against a vector of tuples since we don't have a guaranteed ordering.
|
||||
let mut key_sum = 0;
|
||||
let mut value_sum = 0;
|
||||
for (key, value) in dict.items(py) {
|
||||
for (key, value) in dict.items() {
|
||||
key_sum += key.extract::<i32>(py).unwrap();
|
||||
value_sum += value.extract::<i32>(py).unwrap();
|
||||
}
|
||||
|
@ -307,8 +323,8 @@ mod test {
|
|||
let m = map.to_object(py);
|
||||
let py_map = PyDict::downcast_from(py, &m).unwrap();
|
||||
|
||||
assert!(py_map.len(py) == 1);
|
||||
assert!( py_map.get_item(py, 1).unwrap().extract::<i32>(py).unwrap() == 1);
|
||||
assert!(py_map.len() == 1);
|
||||
assert!( py_map.get_item(1).unwrap().extract::<i32>(py).unwrap() == 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -322,7 +338,7 @@ mod test {
|
|||
let m = map.to_object(py);
|
||||
let py_map = PyDict::downcast_from(py, &m).unwrap();
|
||||
|
||||
assert!(py_map.len(py) == 1);
|
||||
assert!( py_map.get_item(py, 1).unwrap().extract::<i32>(py).unwrap() == 1);
|
||||
assert!(py_map.len() == 1);
|
||||
assert!( py_map.get_item(1).unwrap().extract::<i32>(py).unwrap() == 1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -311,14 +311,22 @@ macro_rules! pyobject_nativetype2(
|
|||
self.0.as_ptr()
|
||||
}
|
||||
}
|
||||
impl<'a> $crate::python::ToPyPointer for &'a $name {
|
||||
/*impl<'a> $crate::python::ToPyPointer for &'a $name {
|
||||
/// Gets the underlying FFI pointer, returns a borrowed pointer.
|
||||
#[inline]
|
||||
fn as_ptr(&self) -> *mut $crate::ffi::PyObject {
|
||||
self.0.as_ptr()
|
||||
}
|
||||
}*/
|
||||
impl<'a> $crate::python::IntoPyPointer for &'a $name {
|
||||
/// Gets the underlying FFI pointer, returns a borrowed pointer.
|
||||
#[inline]
|
||||
fn into_ptr(self) -> *mut $crate::ffi::PyObject {
|
||||
let ptr = self.0.as_ptr();
|
||||
unsafe { $crate::ffi::Py_INCREF(ptr); }
|
||||
ptr
|
||||
}
|
||||
}
|
||||
|
||||
impl $crate::python::PyDowncastFrom for $name
|
||||
{
|
||||
fn downcast_from<'a, 'p>(py: $crate::Python<'p>, ob: &'a $crate::PyObject)
|
||||
|
|
|
@ -43,9 +43,10 @@ impl PyModule {
|
|||
|
||||
/// Return the dictionary object that implements module's namespace;
|
||||
/// this object is the same as the `__dict__` attribute of the module object.
|
||||
pub fn dict(&self) -> PyDict {
|
||||
pub fn dict(&self) -> &PyDict {
|
||||
unsafe {
|
||||
PyDict::from_borrowed_ptr(self.token(), ffi::PyModule_GetDict(self.as_ptr()))
|
||||
self.token().unchecked_cast_from_ptr::<PyDict>(
|
||||
ffi::PyModule_GetDict(self.as_ptr()))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -198,7 +198,7 @@ tuple_conversion!(9, (ref0, 0, A), (ref1, 1, B), (ref2, 2, C), (ref3, 3, D),
|
|||
/// let gil = pyo3::Python::acquire_gil();
|
||||
/// let py = gil.python();
|
||||
/// let os = py.import("os").unwrap();
|
||||
/// let pid = os.call(py, "get_pid", pyo3::NoArgs, None);
|
||||
/// let pid = os.call("get_pid", pyo3::NoArgs, None);
|
||||
/// ```
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct NoArgs;
|
||||
|
|
|
@ -328,7 +328,7 @@ mod test {
|
|||
assert_eq!(v, 1);
|
||||
|
||||
let d = PyDict::new(py);
|
||||
d.set_item(py, "foo", 13).unwrap();
|
||||
d.set_item("foo", 13).unwrap();
|
||||
|
||||
// Inject our own global namespace
|
||||
let v: i32 = py.eval("foo + 29", Some(&d), None).unwrap().extract(py).unwrap();
|
||||
|
|
|
@ -74,8 +74,8 @@ fn test_buffer() {
|
|||
let t = py.init(|t| TestClass{vec: vec![b' ', b'2', b'3'], token: t}).unwrap();
|
||||
|
||||
let d = PyDict::new(py);
|
||||
let _ = d.set_item(py, "ob", t);
|
||||
py.run("assert bytes(ob) == b' 23'", None, Some(&d)).unwrap();
|
||||
d.set_item("ob", t).unwrap();
|
||||
py.run("assert bytes(ob) == b' 23'", None, Some(d)).unwrap();
|
||||
}
|
||||
|
||||
#[cfg(not(Py_3))]
|
||||
|
@ -87,6 +87,6 @@ fn test_buffer() {
|
|||
let t = py.init(|t| TestClass{vec: vec![b' ', b'2', b'3'], token: t}).unwrap();
|
||||
|
||||
let d = PyDict::new(py);
|
||||
let _ = d.set_item(py, "ob", t);
|
||||
py.run("assert memoryview(ob).tobytes() == ' 23'", None, Some(&d)).unwrap();
|
||||
d.set_item("ob", t);
|
||||
py.run("assert memoryview(ob).tobytes() == ' 23'", None, Some(d)).unwrap();
|
||||
}
|
||||
|
|
|
@ -14,8 +14,8 @@ use pyo3::ffi;
|
|||
macro_rules! py_run {
|
||||
($py:expr, $val:ident, $code:expr) => {{
|
||||
let d = PyDict::new($py);
|
||||
d.set_item($py, stringify!($val), &$val).unwrap();
|
||||
$py.run($code, None, Some(&d)).expect($code);
|
||||
d.set_item(stringify!($val), &$val).unwrap();
|
||||
$py.run($code, None, Some(d)).expect($code);
|
||||
}}
|
||||
}
|
||||
|
||||
|
@ -26,8 +26,8 @@ macro_rules! py_assert {
|
|||
macro_rules! py_expect_exception {
|
||||
($py:expr, $val:ident, $code:expr, $err:ident) => {{
|
||||
let d = PyDict::new($py);
|
||||
d.set_item($py, stringify!($val), &$val).unwrap();
|
||||
let res = $py.run($code, None, Some(&d));
|
||||
d.set_item(stringify!($val), &$val).unwrap();
|
||||
let res = $py.run($code, None, Some(d));
|
||||
let err = res.unwrap_err();
|
||||
if !err.matches($py, $py.get_type::<exc::$err>()) {
|
||||
panic!(format!("Expected {} but got {:?}", stringify!($err), err))
|
||||
|
@ -239,8 +239,8 @@ fn instance_method() {
|
|||
let obj = Py::new(py, |t| InstanceMethod{member: 42, token: t}).unwrap();
|
||||
assert!(obj.as_ref(py).method(py).unwrap() == 42);
|
||||
let d = PyDict::new(py);
|
||||
d.set_item(py, "obj", obj).unwrap();
|
||||
py.run("assert obj.method() == 42", None, Some(&d)).unwrap();
|
||||
d.set_item("obj", obj).unwrap();
|
||||
py.run("assert obj.method() == 42", None, Some(d)).unwrap();
|
||||
py.run("assert obj.method.__doc__ == 'Test method'", None, Some(&d)).unwrap();
|
||||
}
|
||||
|
||||
|
@ -265,9 +265,9 @@ fn instance_method_with_args() {
|
|||
let obj = Py::new(py, |t| InstanceMethodWithArgs{member: 7, token: t}).unwrap();
|
||||
assert!(obj.as_ref(py).method(py, 6).unwrap() == 42);
|
||||
let d = PyDict::new(py);
|
||||
d.set_item(py, "obj", obj).unwrap();
|
||||
py.run("assert obj.method(3) == 21", None, Some(&d)).unwrap();
|
||||
py.run("assert obj.method(multiplier=6) == 42", None, Some(&d)).unwrap();
|
||||
d.set_item("obj", obj).unwrap();
|
||||
py.run("assert obj.method(3) == 21", None, Some(d)).unwrap();
|
||||
py.run("assert obj.method(multiplier=6) == 42", None, Some(d)).unwrap();
|
||||
}
|
||||
|
||||
|
||||
|
@ -293,9 +293,9 @@ fn class_method() {
|
|||
let py = gil.python();
|
||||
|
||||
let d = PyDict::new(py);
|
||||
d.set_item(py, "C", py.get_type::<ClassMethod>()).unwrap();
|
||||
py.run("assert C.method() == 'ClassMethod.method()!'", None, Some(&d)).unwrap();
|
||||
py.run("assert C().method() == 'ClassMethod.method()!'", None, Some(&d)).unwrap();
|
||||
d.set_item("C", py.get_type::<ClassMethod>()).unwrap();
|
||||
py.run("assert C.method() == 'ClassMethod.method()!'", None, Some(d)).unwrap();
|
||||
py.run("assert C().method() == 'ClassMethod.method()!'", None, Some(d)).unwrap();
|
||||
}
|
||||
|
||||
|
||||
|
@ -316,8 +316,8 @@ fn class_method_with_args() {
|
|||
let py = gil.python();
|
||||
|
||||
let d = PyDict::new(py);
|
||||
d.set_item(py, "C", py.get_type::<ClassMethodWithArgs>()).unwrap();
|
||||
py.run("assert C.method('abc') == 'ClassMethodWithArgs.method(abc)'", None, Some(&d)).unwrap();
|
||||
d.set_item("C", py.get_type::<ClassMethodWithArgs>()).unwrap();
|
||||
py.run("assert C.method('abc') == 'ClassMethodWithArgs.method(abc)'", None, Some(d)).unwrap();
|
||||
}
|
||||
|
||||
#[py::class]
|
||||
|
@ -345,9 +345,9 @@ fn static_method() {
|
|||
|
||||
assert_eq!(StaticMethod::method(py).unwrap(), "StaticMethod.method()!");
|
||||
let d = PyDict::new(py);
|
||||
d.set_item(py, "C", py.get_type::<StaticMethod>()).unwrap();
|
||||
py.run("assert C.method() == 'StaticMethod.method()!'", None, Some(&d)).unwrap();
|
||||
py.run("assert C().method() == 'StaticMethod.method()!'", None, Some(&d)).unwrap();
|
||||
d.set_item("C", py.get_type::<StaticMethod>()).unwrap();
|
||||
py.run("assert C.method() == 'StaticMethod.method()!'", None, Some(d)).unwrap();
|
||||
py.run("assert C().method() == 'StaticMethod.method()!'", None, Some(d)).unwrap();
|
||||
}
|
||||
|
||||
#[py::class]
|
||||
|
@ -370,8 +370,8 @@ fn static_method_with_args() {
|
|||
assert_eq!(StaticMethodWithArgs::method(py, 1234).unwrap(), "0x4d2");
|
||||
|
||||
let d = PyDict::new(py);
|
||||
d.set_item(py, "C", py.get_type::<StaticMethodWithArgs>()).unwrap();
|
||||
py.run("assert C.method(1337) == '0x539'", None, Some(&d)).unwrap();
|
||||
d.set_item("C", py.get_type::<StaticMethodWithArgs>()).unwrap();
|
||||
py.run("assert C.method(1337) == '0x539'", None, Some(d)).unwrap();
|
||||
}
|
||||
|
||||
#[py::class]
|
||||
|
|
|
@ -51,8 +51,8 @@ fn test_cls_impl() {
|
|||
|
||||
let ob = py.init(|t| Test{token: t}).unwrap();
|
||||
let d = PyDict::new(py);
|
||||
d.set_item(py, "ob", ob).unwrap();
|
||||
d.set_item("ob", ob).unwrap();
|
||||
|
||||
py.run("assert ob[1] == 'int'", None, Some(&d)).unwrap();
|
||||
py.run("assert ob[100:200:1] == 'slice'", None, Some(&d)).unwrap();
|
||||
py.run("assert ob[1] == 'int'", None, Some(d)).unwrap();
|
||||
py.run("assert ob[100:200:1] == 'slice'", None, Some(d)).unwrap();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue