Skip to content

Commit 3f15cd5

Browse files
committed
Add is_none method for efficient None test
Rather than contructing `py.None()` just to compare against (which increments and then decrements the refcount on `None`), add a method on `PyObject` that tests whether the object is the `None` instance. Use this more widely to reduce the number of `unsafe` blocks.
1 parent 7851eda commit 3f15cd5

File tree

5 files changed

+12
-6
lines changed

5 files changed

+12
-6
lines changed

src/argparse.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -463,7 +463,7 @@ macro_rules! py_argparse_extract {
463463
// second unwrap() asserts the parameter was not missing (which fn parse_args already checked for).
464464
let v = $iter.next().unwrap().as_ref().unwrap();
465465
let mut c = |$pname: $ptype| $crate::py_argparse_extract!($py, $iter, $body, [$($tail)*]);
466-
let r = if v.as_ptr() == unsafe { $crate::_detail::ffi::Py_None() } {
466+
let r = if v.is_none($py) {
467467
Ok(c(None))
468468
} else {
469469
<$rtype as $crate::RefFromPyObject>::with_extracted($py, v, |r: &$rtype| c(Some(r)))
@@ -537,7 +537,7 @@ where
537537
{
538538
match obj {
539539
Some(obj) => {
540-
if obj.as_ptr() == unsafe { crate::ffi::Py_None() } {
540+
if obj.is_none(py) {
541541
f(None)
542542
} else {
543543
match P::with_extracted(py, obj, |p| f(Some(p))) {

src/conversion.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ where
224224
T: FromPyObject<'s>,
225225
{
226226
fn extract(py: Python, obj: &'s PyObject) -> PyResult<Self> {
227-
if obj.as_ptr() == unsafe { ffi::Py_None() } {
227+
if obj.is_none(py) {
228228
Ok(None)
229229
} else {
230230
match T::extract(py, obj) {
@@ -242,7 +242,7 @@ where T: ExtractPyObject<'prepared>
242242
type Prepared = Option<T::Prepared>;
243243
244244
fn prepare_extract(py: Python, obj: &PyObject) -> PyResult<Self::Prepared> {
245-
if obj.as_ptr() == unsafe { ffi::Py_None() } {
245+
if obj.is_none(py) {
246246
Ok(None)
247247
} else {
248248
Ok(Some(T::prepare_extract(py, obj)?))

src/objects/object.rs

+6
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,12 @@ impl PyObject {
259259
{
260260
crate::conversion::FromPyObject::extract(py, self)
261261
}
262+
263+
/// True if this is None in Python.
264+
#[inline]
265+
pub fn is_none(&self, _py: Python) -> bool {
266+
self.as_ptr() == unsafe { ffi::Py_None() }
267+
}
262268
}
263269

264270
/// PyObject implements the `==` operator using reference equality:

src/py_class/slots.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ macro_rules! py_class_call_slot_impl_with_ref {
266266
$arg_if_some:expr
267267
$(, $extra_arg:ident)*
268268
) => {{
269-
if $arg.as_ptr() == unsafe { $crate::_detail::ffi::Py_None() } {
269+
if $arg.is_none($py) {
270270
Ok($slf.$f($py, $arg_if_none $(, $extra_arg)*))
271271
} else {
272272
<$arg_type as $crate::RefFromPyObject>::with_extracted(

src/serde/de.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ impl<'gil> Deserializer<'gil> {
8585

8686
/// Test whether `self.obj` is `None` in Python.
8787
fn is_none(&self) -> bool {
88-
self.obj == self.py.None()
88+
self.obj.is_none(self.py)
8989
}
9090
}
9191

0 commit comments

Comments
 (0)