fix ptr borrowing PyTuple::get_item
This commit is contained in:
parent
4232caf3a3
commit
61b8bd0695
|
@ -449,7 +449,7 @@ pub fn with_extracted_or_default<'p, P: ?Sized, R, F>(
|
|||
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
mod test {
|
||||
use python::{Python};
|
||||
use objects::PyTuple;
|
||||
use conversion::{ToPyTuple};
|
||||
|
|
18
src/err.rs
18
src/err.rs
|
@ -47,7 +47,7 @@ macro_rules! py_exception {
|
|||
($module: ident, $name: ident, $base: ty) => {
|
||||
pub struct $name;
|
||||
|
||||
pyobject_nativetype!($name);
|
||||
// pyobject_nativetype!($name);
|
||||
|
||||
impl $name {
|
||||
pub fn new<'p, T: $crate::ToPyObject>(py: $crate::Python<'p>, args: T) -> $crate::PyErr {
|
||||
|
@ -59,13 +59,14 @@ macro_rules! py_exception {
|
|||
#[inline]
|
||||
fn type_object<'p>(py: $crate::Python<'p>) -> $crate::PyType<'p> {
|
||||
unsafe {
|
||||
#[allow(non_upper_case_globals)]
|
||||
static mut type_object: *mut $crate::ffi::PyTypeObject = 0 as *mut $crate::ffi::PyTypeObject;
|
||||
|
||||
if type_object.is_null() {
|
||||
type_object = $crate::PyErr::new_type(
|
||||
py,
|
||||
concat!(stringify!($module), ".", stringify!($name)),
|
||||
Some(py.get_type::<$base>()), None);
|
||||
Some(py.get_type::<$base>()), None).as_type_ptr();
|
||||
}
|
||||
|
||||
$crate::PyType::from_type_ptr(py, type_object)
|
||||
|
@ -133,7 +134,7 @@ impl PyErr {
|
|||
/// `base` can be an existing exception type to subclass, or a tuple of classes
|
||||
/// `dict` specifies an optional dictionary of class variables and methods
|
||||
pub fn new_type<'p>(py: Python<'p>, name: &str,
|
||||
base: Option<PyObject<'p>>, dict: Option<PyObject<'p>>) -> PyType<'p> {
|
||||
base: Option<PyType<'p>>, dict: Option<PyObject<'p>>) -> PyType<'p> {
|
||||
let base: *mut ffi::PyObject = match base {
|
||||
None => std::ptr::null_mut(),
|
||||
Some(obj) => obj.into_ptr()
|
||||
|
@ -334,17 +335,6 @@ impl PyErr {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/*impl PyClone for PyErr {
|
||||
fn clone_ref(&self, py: Python) -> PyErr {
|
||||
PyErr {
|
||||
ptype: self.ptype.clone_ref(py),
|
||||
pvalue: self.pvalue.clone_ref(py),
|
||||
ptraceback: self.ptraceback.clone_ref(py)
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
/// Converts `PyDowncastError` to Python `TypeError`.
|
||||
impl <'p> std::convert::From<PyDowncastError<'p>> for PyErr {
|
||||
fn from(err: PyDowncastError<'p>) -> PyErr {
|
||||
|
|
|
@ -90,7 +90,7 @@ macro_rules! py_method_def {
|
|||
/// let gil = Python::acquire_gil();
|
||||
/// let py = gil.python();
|
||||
/// let dict = PyDict::new(py);
|
||||
/// dict.set_item(py, "multiply", py_fn!(py, multiply(lhs: i32, rhs: i32))).unwrap();
|
||||
/// dict.set_item("multiply", py_fn!(py, multiply(lhs: i32, rhs: i32))).unwrap();
|
||||
/// py.run("print(multiply(6, 7))", None, Some(&dict)).unwrap();
|
||||
/// }
|
||||
/// ```
|
||||
|
|
10
src/lib.rs
10
src/lib.rs
|
@ -42,11 +42,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()?;
|
||||
//!
|
||||
//! let locals = PyDict::new(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)?;
|
||||
//! let user: String = py.eval("os.getenv('USER') or os.getenv('USERNAME')", None, Some(&locals))?.extract()?;
|
||||
//!
|
||||
//! println!("Hello {}, I'm Python {}", user, version);
|
||||
//! Ok(())
|
||||
|
@ -145,14 +145,14 @@ pub use std::os::raw::*;
|
|||
/// use pyo3::{Python, PyResult, PyObject};
|
||||
///
|
||||
/// py_module_init!(hello, PyInit_hello, |py, m| {
|
||||
/// m.add(py, "__doc__", "Module documentation string")?;
|
||||
/// m.add(py, "run", py_fn!(py, run()))?;
|
||||
/// m.add("__doc__", "Module documentation string")?;
|
||||
/// m.add("run", py_fn!(py, run()))?;
|
||||
/// Ok(())
|
||||
/// });
|
||||
///
|
||||
/// fn run(py: Python) -> PyResult<PyObject> {
|
||||
/// println!("Rust says: Hello Python!");
|
||||
/// Ok(py.None())
|
||||
/// Ok(py.None().into_object(py))
|
||||
/// }
|
||||
/// # fn main() {}
|
||||
/// ```
|
||||
|
|
|
@ -119,6 +119,8 @@ pub trait ObjectProtocol<'p> {
|
|||
// /// This is typically a new iterator but if the argument
|
||||
// /// is an iterator, this returns itself.
|
||||
// fn iter<'a>(&'a self) -> PyResult<Py<'p, ::objects::PyIterator<'a>>>;
|
||||
|
||||
fn get_refcnt(&self) -> isize;
|
||||
}
|
||||
|
||||
|
||||
|
@ -371,6 +373,10 @@ impl<'p, T> ObjectProtocol<'p> for T where T: PythonObjectWithGilToken<'p> + ToP
|
|||
//pub fn iter<'a>(&'a self) -> PyResult<Py<'p, ::objects::PyIterator<'a>>> {
|
||||
// Py::from_owned_ptr_or_err(self.py(), ffi::PyObject_GetIter(self.as_ptr()))
|
||||
//}
|
||||
|
||||
fn get_refcnt(&self) -> isize {
|
||||
unsafe { ffi::Py_REFCNT(self.as_ptr()) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ impl<'p> PyByteArray<'p> {
|
|||
/// Creates a new Python bytearray object
|
||||
/// from other PyObject, that implements the buffer protocol.
|
||||
pub fn from(src: &'p PyObject<'p>) -> PyResult<PyByteArray<'p>> {
|
||||
println!("FROM: {:?} {}", src.as_ptr(), src.get_refcnt());
|
||||
let res = unsafe {ffi::PyByteArray_FromObject(src.as_ptr())};
|
||||
if res != ptr::null_mut() {
|
||||
Ok(unsafe{ PyByteArray(
|
||||
|
@ -77,7 +78,7 @@ impl<'p> PyByteArray<'p> {
|
|||
mod test {
|
||||
use ::ToPyObject;
|
||||
use exc;
|
||||
use python::Python;
|
||||
use python::{Python, ToPythonPointer};
|
||||
use typeob::PyTypeObject;
|
||||
use objects::PyByteArray;
|
||||
|
||||
|
@ -100,6 +101,7 @@ mod test {
|
|||
assert_eq!(20, bytearray.len());
|
||||
|
||||
let none = py.None();
|
||||
println!("NONE: {:?} {}", none.as_ptr(), none.get_refcnt());
|
||||
if let Err(mut err) = PyByteArray::from(none.as_object(py)) {
|
||||
assert!(exc::TypeError::type_object(py).is_instance(&err.instance(py)))
|
||||
} else {
|
||||
|
|
|
@ -8,7 +8,7 @@ use std::os::raw::c_char;
|
|||
use std::ffi::{CStr, CString};
|
||||
|
||||
use ::pptr;
|
||||
use conversion::ToPyTuple;
|
||||
use conversion::{ToPyObject, ToPyTuple};
|
||||
use pyptr::PyPtr;
|
||||
use python::{ToPythonPointer, Python};
|
||||
use token::PythonObjectWithGilToken;
|
||||
|
@ -89,6 +89,19 @@ impl<'p> PyModule<'p> {
|
|||
self.getattr(name)?.call(args, kwargs)
|
||||
}
|
||||
|
||||
/// Gets a member from the module.
|
||||
/// This is equivalent to the Python expression: `getattr(module, name)`
|
||||
pub fn get(&self, name: &str) -> PyResult<PyObject> {
|
||||
self.getattr(name)
|
||||
}
|
||||
|
||||
/// 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) -> PyResult<()> where V: ToPyObject {
|
||||
self.setattr(name, value)
|
||||
}
|
||||
|
||||
/// Adds a new extension type to the module.
|
||||
///
|
||||
/// This is a convenience function that initializes the `class`,
|
||||
|
|
|
@ -88,6 +88,11 @@ impl<'p> PyObject<'p> {
|
|||
{
|
||||
::conversion::FromPyObject::extract(&self)
|
||||
}
|
||||
|
||||
pub fn get_refcnt(&self) -> isize {
|
||||
unsafe { ffi::Py_REFCNT(self.0.as_ptr()) }
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
impl<'p> PartialEq for PyObject<'p> {
|
||||
|
|
|
@ -62,7 +62,7 @@ impl<'p> PyTuple<'p> {
|
|||
// It's quite inconsistent that this method takes `Python` when `len()` does not.
|
||||
assert!(index < self.len());
|
||||
unsafe {
|
||||
PyObject::from_owned_ptr(
|
||||
PyObject::from_borrowed_ptr(
|
||||
self.gil(), ffi::PyTuple_GET_ITEM(self.as_ptr(), index as Py_ssize_t))
|
||||
}
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ impl<'p> PyTuple<'p> {
|
|||
|
||||
impl<'a> ToPyTuple for PyTuple<'a> {
|
||||
fn to_py_tuple<'p>(&self, py: Python<'p>) -> PyTuple<'p> {
|
||||
unsafe { PyTuple(pptr::from_owned_ptr_or_panic(py, self.0.as_ptr())) }
|
||||
unsafe { PyTuple(pptr::from_borrowed_ptr(py, self.0.as_ptr())) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
22
src/ppptr.rs
22
src/ppptr.rs
|
@ -1,8 +1,10 @@
|
|||
// Copyright (c) 2017-present PyO3 Project and Contributors
|
||||
|
||||
use std;
|
||||
|
||||
use ffi;
|
||||
use err::{PyErr, PyResult};
|
||||
use python::{Python, ToPythonPointer};
|
||||
use python::{Python, PyDowncastInto, ToPythonPointer};
|
||||
use typeob::{PyTypeInfo, PyObjectAlloc};
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
|
@ -176,3 +178,21 @@ impl<'p> Drop for pptr<'p> {
|
|||
unsafe { ffi::Py_DECREF(self.1); }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'p> std::fmt::Debug for pptr<'p> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
|
||||
let repr = unsafe { ::PyString::downcast_from_owned_ptr(
|
||||
self.0, ffi::PyObject_Repr(self.1)) };
|
||||
let repr = repr.map_err(|_| std::fmt::Error)?;
|
||||
f.write_str(&repr.to_string_lossy())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'p> std::fmt::Display for pptr<'p> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
|
||||
let ob = unsafe { ::PyString::downcast_from_owned_ptr(
|
||||
self.0, ffi::PyObject_Str(self.1)) };
|
||||
let ob = ob.map_err(|_| std::fmt::Error)?;
|
||||
f.write_str(&ob.to_string_lossy())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -113,6 +113,7 @@ impl<T> PyPtr<T> {
|
|||
/// Converts PyPtr<T> -> &PyObject<'p>.
|
||||
#[inline]
|
||||
pub fn as_object<'p>(&self, _py: Python<'p>) -> &PyObject<'p> {
|
||||
unsafe {ffi::Py_INCREF(self.inner)};
|
||||
unsafe { std::mem::transmute(self) }
|
||||
}
|
||||
|
||||
|
|
|
@ -443,6 +443,7 @@ fn string_methods() {
|
|||
#[py::class]
|
||||
struct Comparisons {
|
||||
val: i32,
|
||||
#[token]
|
||||
token: PythonToken<Comparisons>,
|
||||
}
|
||||
|
||||
|
@ -451,7 +452,6 @@ impl PyObjectProtocol for Comparisons {
|
|||
fn __hash__(&self, py: Python) -> PyResult<usize> {
|
||||
Ok(self.val as usize)
|
||||
}
|
||||
|
||||
fn __bool__(&self, py: Python) -> PyResult<bool> {
|
||||
Ok(self.val != 0)
|
||||
}
|
||||
|
@ -994,16 +994,12 @@ fn context_manager() {
|
|||
assert!(c.exit_called);
|
||||
|
||||
c.exit_called = false;
|
||||
|
||||
//TODO: re-enable
|
||||
|
||||
//py_expect_exception!(
|
||||
// py, c, "with c as x:\n raise NotImplementedError",
|
||||
// NotImplementedError);
|
||||
//assert!(c.exit_called);
|
||||
py_expect_exception!(
|
||||
py, c, "with c as x:\n raise NotImplementedError",
|
||||
NotImplementedError);
|
||||
assert!(c.exit_called);
|
||||
}
|
||||
|
||||
|
||||
#[py::class]
|
||||
struct ClassWithProperties {
|
||||
num: i32,
|
||||
|
|
Loading…
Reference in a new issue