Merge #2911
2911: add `Ellipsis()` and `is_ellipsis()` methods r=mejrs,davidhewitt a=samuelcolvin fix #2906 Please consider adding the following to your pull request: - [x] an entry for this PR in newsfragments - see [https://pyo3.rs/main/contributing.html#documenting-changes] - [x] docs to all new functions and / or detail in the guide - [x] tests for all new or changed functions Co-authored-by: Samuel Colvin <s@muelcolvin.com>
This commit is contained in:
commit
794e19d796
|
@ -0,0 +1 @@
|
|||
Add `py.Ellipsis()` and `py_any.is_ellipsis()` methods.
|
|
@ -2,6 +2,7 @@ use crate::object::*;
|
|||
use crate::pyport::Py_ssize_t;
|
||||
use std::os::raw::c_int;
|
||||
|
||||
#[cfg_attr(windows, link(name = "pythonXY"))]
|
||||
extern "C" {
|
||||
#[cfg_attr(PyPy, link_name = "_PyPy_EllipsisObject")]
|
||||
static mut _Py_EllipsisObject: PyObject;
|
||||
|
|
|
@ -519,6 +519,13 @@ impl<T> Py<T> {
|
|||
unsafe { ffi::Py_None() == self.as_ptr() }
|
||||
}
|
||||
|
||||
/// Returns whether the object is Ellipsis, e.g. `...`.
|
||||
///
|
||||
/// This is equivalent to the Python expression `self is ...`.
|
||||
pub fn is_ellipsis(&self) -> bool {
|
||||
unsafe { ffi::Py_Ellipsis() == self.as_ptr() }
|
||||
}
|
||||
|
||||
/// Returns whether the object is considered to be true.
|
||||
///
|
||||
/// This is equivalent to the Python expression `bool(self)`.
|
||||
|
@ -1147,6 +1154,22 @@ a = A()
|
|||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_ellipsis() {
|
||||
Python::with_gil(|py| {
|
||||
let v = py
|
||||
.eval("...", None, None)
|
||||
.map_err(|e| e.print(py))
|
||||
.unwrap()
|
||||
.to_object(py);
|
||||
|
||||
assert!(v.is_ellipsis());
|
||||
|
||||
let not_ellipsis = 5.to_object(py);
|
||||
assert!(!not_ellipsis.is_ellipsis());
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(feature = "macros")]
|
||||
mod using_macros {
|
||||
use super::*;
|
||||
|
|
|
@ -619,6 +619,13 @@ impl<'py> Python<'py> {
|
|||
unsafe { PyObject::from_borrowed_ptr(self, ffi::Py_None()) }
|
||||
}
|
||||
|
||||
/// Gets the Python builtin value `Ellipsis`, or `...`.
|
||||
#[allow(non_snake_case)] // the Python keyword starts with uppercase
|
||||
#[inline]
|
||||
pub fn Ellipsis(self) -> PyObject {
|
||||
unsafe { PyObject::from_borrowed_ptr(self, ffi::Py_Ellipsis()) }
|
||||
}
|
||||
|
||||
/// Gets the Python builtin value `NotImplemented`.
|
||||
#[allow(non_snake_case)] // the Python keyword starts with uppercase
|
||||
#[inline]
|
||||
|
@ -1032,4 +1039,15 @@ mod tests {
|
|||
let state = unsafe { crate::ffi::PyGILState_Check() };
|
||||
assert_eq!(state, GIL_NOT_HELD);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ellipsis() {
|
||||
Python::with_gil(|py| {
|
||||
assert_eq!(py.Ellipsis().to_string(), "Ellipsis");
|
||||
|
||||
let v = py.eval("...", None, None).map_err(|e| e.print(py)).unwrap();
|
||||
|
||||
assert!(v.eq(py.Ellipsis()).unwrap());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -669,6 +669,13 @@ impl PyAny {
|
|||
unsafe { ffi::Py_None() == self.as_ptr() }
|
||||
}
|
||||
|
||||
/// Returns whether the object is Ellipsis, e.g. `...`.
|
||||
///
|
||||
/// This is equivalent to the Python expression `self is ...`.
|
||||
pub fn is_ellipsis(&self) -> bool {
|
||||
unsafe { ffi::Py_Ellipsis() == self.as_ptr() }
|
||||
}
|
||||
|
||||
/// Returns true if the sequence or mapping has a length of 0.
|
||||
///
|
||||
/// This is equivalent to the Python expression `len(self) == 0`.
|
||||
|
@ -1135,4 +1142,16 @@ class SimpleClass:
|
|||
let bools = [true, false];
|
||||
test_eq_methods_generic(&bools);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_ellipsis() {
|
||||
Python::with_gil(|py| {
|
||||
let v = py.eval("...", None, None).map_err(|e| e.print(py)).unwrap();
|
||||
|
||||
assert!(v.is_ellipsis());
|
||||
|
||||
let not_ellipsis = 5.to_object(py).into_ref(py);
|
||||
assert!(!not_ellipsis.is_ellipsis());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue