modify PyDict

This commit is contained in:
Nikolay Kim 2017-06-21 14:08:16 -07:00
parent 96788bf192
commit 7cf8e1ab80
13 changed files with 145 additions and 125 deletions

View File

@ -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)

View File

@ -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();

View File

@ -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))
}
}

View File

@ -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();
}
```
*/

View File

@ -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(())

View File

@ -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);
}
}

View File

@ -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)

View File

@ -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()))
}
}

View File

@ -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;

View File

@ -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();

View File

@ -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();
}

View File

@ -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]

View File

@ -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();
}