Small improvements around function calling
This commit is contained in:
parent
625a3f6738
commit
dbaa2de061
|
@ -43,10 +43,7 @@ extern "C" {
|
|||
value: *const c_char,
|
||||
) -> c_int;
|
||||
|
||||
#[cfg(all(
|
||||
target_pointer_width = "64",
|
||||
not(py_sys_config = "Py_TRACE_REFS")
|
||||
))]
|
||||
#[cfg(all(target_pointer_width = "64", not(py_sys_config = "Py_TRACE_REFS")))]
|
||||
fn Py_InitModule4_64(
|
||||
name: *const c_char,
|
||||
methods: *mut PyMethodDef,
|
||||
|
@ -64,10 +61,7 @@ extern "C" {
|
|||
apiver: c_int,
|
||||
) -> *mut PyObject;
|
||||
|
||||
#[cfg(all(
|
||||
not(target_pointer_width = "64"),
|
||||
not(py_sys_config = "Py_TRACE_REFS")
|
||||
))]
|
||||
#[cfg(all(not(target_pointer_width = "64"), not(py_sys_config = "Py_TRACE_REFS")))]
|
||||
pub fn Py_InitModule4(
|
||||
name: *const c_char,
|
||||
methods: *mut PyMethodDef,
|
||||
|
@ -76,10 +70,7 @@ extern "C" {
|
|||
apiver: c_int,
|
||||
) -> *mut PyObject;
|
||||
|
||||
#[cfg(all(
|
||||
not(target_pointer_width = "64"),
|
||||
py_sys_config = "Py_TRACE_REFS"
|
||||
))]
|
||||
#[cfg(all(not(target_pointer_width = "64"), py_sys_config = "Py_TRACE_REFS"))]
|
||||
fn Py_InitModule4TraceRefs(
|
||||
name: *const c_char,
|
||||
methods: *mut PyMethodDef,
|
||||
|
@ -91,10 +82,7 @@ extern "C" {
|
|||
|
||||
pub const PYTHON_API_VERSION: c_int = 1013;
|
||||
|
||||
#[cfg(all(
|
||||
target_pointer_width = "64",
|
||||
not(py_sys_config = "Py_TRACE_REFS")
|
||||
))]
|
||||
#[cfg(all(target_pointer_width = "64", not(py_sys_config = "Py_TRACE_REFS")))]
|
||||
#[inline]
|
||||
pub unsafe fn Py_InitModule4(
|
||||
name: *const c_char,
|
||||
|
@ -118,10 +106,7 @@ pub unsafe fn Py_InitModule4(
|
|||
Py_InitModule4TraceRefs_64(name, methods, doc, _self, apiver)
|
||||
}
|
||||
|
||||
#[cfg(all(
|
||||
not(target_pointer_width = "64"),
|
||||
py_sys_config = "Py_TRACE_REFS"
|
||||
))]
|
||||
#[cfg(all(not(target_pointer_width = "64"), py_sys_config = "Py_TRACE_REFS"))]
|
||||
#[inline]
|
||||
pub unsafe fn Py_InitModule4(
|
||||
name: *const c_char,
|
||||
|
|
|
@ -216,10 +216,11 @@ pub unsafe fn PyObject_CheckBuffer(obj: *mut PyObject) -> c_int {
|
|||
#[inline]
|
||||
pub unsafe fn PyIter_Check(obj: *mut PyObject) -> c_int {
|
||||
let t = (*obj).ob_type;
|
||||
(PyType_HasFeature(t, Py_TPFLAGS_HAVE_ITER) != 0 && match (*t).tp_iternext {
|
||||
None => false,
|
||||
Some(f) => f as *const c_void != _PyObject_NextNotImplemented as *const c_void,
|
||||
}) as c_int
|
||||
(PyType_HasFeature(t, Py_TPFLAGS_HAVE_ITER) != 0
|
||||
&& match (*t).tp_iternext {
|
||||
None => false,
|
||||
Some(f) => f as *const c_void != _PyObject_NextNotImplemented as *const c_void,
|
||||
}) as c_int
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
@ -39,10 +39,11 @@ pub unsafe fn PyType_IS_GC(t: *mut PyTypeObject) -> c_int {
|
|||
/// Test if an object has a GC head
|
||||
#[inline]
|
||||
pub unsafe fn PyObject_IS_GC(o: *mut PyObject) -> c_int {
|
||||
(PyType_IS_GC(Py_TYPE(o)) != 0 && match (*Py_TYPE(o)).tp_is_gc {
|
||||
Some(tp_is_gc) => tp_is_gc(o) != 0,
|
||||
None => true,
|
||||
}) as c_int
|
||||
(PyType_IS_GC(Py_TYPE(o)) != 0
|
||||
&& match (*Py_TYPE(o)).tp_is_gc {
|
||||
Some(tp_is_gc) => tp_is_gc(o) != 0,
|
||||
None => true,
|
||||
}) as c_int
|
||||
}
|
||||
|
||||
/* Test if a type supports weak references */
|
||||
|
|
|
@ -58,10 +58,11 @@ pub unsafe fn PyType_IS_GC(t: *mut PyTypeObject) -> c_int {
|
|||
#[inline]
|
||||
#[cfg(not(Py_LIMITED_API))]
|
||||
pub unsafe fn PyObject_IS_GC(o: *mut PyObject) -> c_int {
|
||||
(PyType_IS_GC(Py_TYPE(o)) != 0 && match (*Py_TYPE(o)).tp_is_gc {
|
||||
Some(tp_is_gc) => tp_is_gc(o) != 0,
|
||||
None => true,
|
||||
}) as c_int
|
||||
(PyType_IS_GC(Py_TYPE(o)) != 0
|
||||
&& match (*Py_TYPE(o)).tp_is_gc {
|
||||
Some(tp_is_gc) => tp_is_gc(o) != 0,
|
||||
None => true,
|
||||
}) as c_int
|
||||
}
|
||||
|
||||
#[cfg_attr(windows, link(name = "pythonXY"))]
|
||||
|
|
|
@ -12,9 +12,9 @@ use object::PyObject;
|
|||
use objectprotocol::ObjectProtocol;
|
||||
use python::{IntoPyPointer, Python, ToPyPointer};
|
||||
use pythonrun;
|
||||
use typeob::PyTypeCreate;
|
||||
use typeob::{PyTypeInfo, PyTypeObject};
|
||||
use types::PyObjectRef;
|
||||
use typeob::PyTypeCreate;
|
||||
|
||||
pub struct PyToken(PhantomData<Rc<()>>);
|
||||
|
||||
|
|
|
@ -199,16 +199,13 @@ impl PyObject {
|
|||
|
||||
/// Calls a method on the object.
|
||||
/// This is equivalent to the Python expression: 'self.name(*args, **kwargs)'
|
||||
pub fn call_method<A>(
|
||||
pub fn call_method(
|
||||
&self,
|
||||
py: Python,
|
||||
name: &str,
|
||||
args: A,
|
||||
kwargs: Option<PyDict>,
|
||||
) -> PyResult<PyObject>
|
||||
where
|
||||
A: IntoPyTuple,
|
||||
{
|
||||
args: impl IntoPyTuple,
|
||||
kwargs: Option<&PyDict>,
|
||||
) -> PyResult<PyObject> {
|
||||
name.with_borrowed_ptr(py, |name| unsafe {
|
||||
let args = args.into_tuple(py).into_ptr();
|
||||
let kwargs = kwargs.into_ptr();
|
||||
|
@ -232,10 +229,12 @@ impl PyObject {
|
|||
|
||||
/// Calls a method on the object.
|
||||
/// This is equivalent to the Python expression: 'self.name(*args)'
|
||||
pub fn call_method1<A>(&self, py: Python, name: &str, args: A) -> PyResult<PyObject>
|
||||
where
|
||||
A: IntoPyTuple,
|
||||
{
|
||||
pub fn call_method1(
|
||||
&self,
|
||||
py: Python,
|
||||
name: &str,
|
||||
args: impl IntoPyTuple,
|
||||
) -> PyResult<PyObject> {
|
||||
self.call_method(py, name, args, None)
|
||||
}
|
||||
}
|
||||
|
@ -328,10 +327,9 @@ mod test {
|
|||
let py = gil.python();
|
||||
let obj: PyObject = PyDict::new(py).into();
|
||||
assert!(obj.call_method0(py, "asdf").is_err());
|
||||
assert!(
|
||||
obj.call_method(py, "nonexistent_method", (1,), None)
|
||||
.is_err()
|
||||
);
|
||||
assert!(obj
|
||||
.call_method(py, "nonexistent_method", (1,), None)
|
||||
.is_err());
|
||||
assert!(obj.call_method0(py, "nonexistent_method").is_err());
|
||||
assert!(obj.call_method1(py, "nonexistent_method", (1,)).is_err());
|
||||
}
|
||||
|
|
|
@ -102,20 +102,23 @@ pub trait ObjectProtocol {
|
|||
/// This is equivalent to the Python expression: `self.name(*args, **kwargs)`
|
||||
///
|
||||
/// # Example
|
||||
/// ```rust,ignore
|
||||
/// let obj = SomePyObject::new();
|
||||
/// let args = (arg1, arg2, arg3);
|
||||
/// let kwargs = ((key1, value1), (key2, value2));
|
||||
/// let pid = obj.call_method("do_something", args, kwargs.into_py_dict());
|
||||
/// ```rust
|
||||
/// # use pyo3::prelude::*;
|
||||
/// use pyo3::types::IntoPyDict;
|
||||
///
|
||||
/// let gil = Python::acquire_gil();
|
||||
/// let py = gil.python();
|
||||
/// let list = vec![3, 6, 5, 4, 7].to_object(py);
|
||||
/// let dict = vec![("reverse", true)].into_py_dict(py);
|
||||
/// list.call_method(py, "sort", (), Some(dict)).unwrap();
|
||||
/// assert_eq!(list.extract::<Vec<i32>>(py).unwrap(), vec![7, 6, 5, 4, 3]);
|
||||
/// ```
|
||||
fn call_method<A>(
|
||||
fn call_method(
|
||||
&self,
|
||||
name: &str,
|
||||
args: A,
|
||||
args: impl IntoPyTuple,
|
||||
kwargs: Option<&PyDict>,
|
||||
) -> PyResult<&PyObjectRef>
|
||||
where
|
||||
A: IntoPyTuple;
|
||||
) -> PyResult<&PyObjectRef>;
|
||||
|
||||
/// Calls a method on the object.
|
||||
/// This is equivalent to the Python expression: `self.name()`
|
||||
|
@ -123,7 +126,7 @@ pub trait ObjectProtocol {
|
|||
|
||||
/// Calls a method on the object with positional arguments only .
|
||||
/// This is equivalent to the Python expression: `self.name(*args)`
|
||||
fn call_method1<A: IntoPyTuple>(&self, name: &str, args: A) -> PyResult<&PyObjectRef>;
|
||||
fn call_method1(&self, name: &str, args: impl IntoPyTuple) -> PyResult<&PyObjectRef>;
|
||||
|
||||
/// Retrieves the hash code of the object.
|
||||
/// This is equivalent to the Python expression: `hash(self)`
|
||||
|
@ -346,10 +349,12 @@ where
|
|||
self.call(args, None)
|
||||
}
|
||||
|
||||
fn call_method<A>(&self, name: &str, args: A, kwargs: Option<&PyDict>) -> PyResult<&PyObjectRef>
|
||||
where
|
||||
A: IntoPyTuple,
|
||||
{
|
||||
fn call_method(
|
||||
&self,
|
||||
name: &str,
|
||||
args: impl IntoPyTuple,
|
||||
kwargs: Option<&PyDict>,
|
||||
) -> PyResult<&PyObjectRef> {
|
||||
name.with_borrowed_ptr(self.py(), |name| unsafe {
|
||||
let py = self.py();
|
||||
let ptr = ffi::PyObject_GetAttr(self.as_ptr(), name);
|
||||
|
@ -371,7 +376,7 @@ where
|
|||
self.call_method(name, PyTuple::empty(self.py()), None)
|
||||
}
|
||||
|
||||
fn call_method1<A: IntoPyTuple>(&self, name: &str, args: A) -> PyResult<&PyObjectRef> {
|
||||
fn call_method1(&self, name: &str, args: impl IntoPyTuple) -> PyResult<&PyObjectRef> {
|
||||
self.call_method(name, args, None)
|
||||
}
|
||||
|
||||
|
@ -531,10 +536,10 @@ mod test {
|
|||
fn test_call_with_kwargs() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let list = py.eval("list([3, 6, 5, 4, 7])", None, None).unwrap();
|
||||
let list = vec![3, 6, 5, 4, 7].to_object(py);
|
||||
let dict = vec![("reverse", true)].into_py_dict(py);
|
||||
list.call_method("sort", (), Some(dict)).unwrap();
|
||||
assert_eq!(list.extract::<Vec<i32>>().unwrap(), vec![7, 6, 5, 4, 3]);
|
||||
list.call_method(py, "sort", (), Some(dict)).unwrap();
|
||||
assert_eq!(list.extract::<Vec<i32>>(py).unwrap(), vec![7, 6, 5, 4, 3]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -532,10 +532,9 @@ mod test {
|
|||
fn test_is_instance() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
assert!(
|
||||
py.is_instance::<PyBool, PyObjectRef>(PyBool::new(py, true).into())
|
||||
.unwrap()
|
||||
);
|
||||
assert!(py
|
||||
.is_instance::<PyBool, PyObjectRef>(PyBool::new(py, true).into())
|
||||
.unwrap());
|
||||
let list = PyList::new(py, &[1, 2, 3, 4]);
|
||||
assert!(!py.is_instance::<PyBool, _>(list.as_ref()).unwrap());
|
||||
assert!(py.is_instance::<PyList, _>(list.as_ref()).unwrap());
|
||||
|
|
|
@ -21,13 +21,11 @@ fn empty_class_with_new() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let typeobj = py.get_type::<EmptyClassWithNew>();
|
||||
assert!(
|
||||
typeobj
|
||||
.call(NoArgs, None)
|
||||
.unwrap()
|
||||
.cast_as::<EmptyClassWithNew>()
|
||||
.is_ok()
|
||||
);
|
||||
assert!(typeobj
|
||||
.call(NoArgs, None)
|
||||
.unwrap()
|
||||
.cast_as::<EmptyClassWithNew>()
|
||||
.is_ok());
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
|
Loading…
Reference in New Issue