diff --git a/extra_tests/snippets/builtin_none.py b/extra_tests/snippets/builtin_none.py index c75f04ea73..c8a07f518d 100644 --- a/extra_tests/snippets/builtin_none.py +++ b/extra_tests/snippets/builtin_none.py @@ -22,4 +22,4 @@ def none2(): assert None.__eq__(3) is NotImplemented assert None.__ne__(3) is NotImplemented assert None.__eq__(None) is True -# assert None.__ne__(None) is False # changed in 3.12 +assert None.__ne__(None) is NotImplemented diff --git a/vm/src/builtins/singletons.rs b/vm/src/builtins/singletons.rs index 65b171a262..d4487b586d 100644 --- a/vm/src/builtins/singletons.rs +++ b/vm/src/builtins/singletons.rs @@ -2,9 +2,10 @@ use super::{PyStrRef, PyType, PyTypeRef}; use crate::{ class::PyClassImpl, convert::ToPyObject, + function::{PyArithmeticValue, PyComparisonValue}, protocol::PyNumberMethods, - types::{AsNumber, Constructor, Representable}, - Context, Py, PyObjectRef, PyPayload, PyResult, VirtualMachine, + types::{AsNumber, Comparable, Constructor, PyComparisonOp, Representable}, + Context, Py, PyObject, PyObjectRef, PyPayload, PyResult, VirtualMachine, }; #[pyclass(module = false, name = "NoneType")] @@ -42,7 +43,7 @@ impl Constructor for PyNone { } } -#[pyclass(with(Constructor, AsNumber, Representable))] +#[pyclass(with(Constructor, Comparable, AsNumber, Representable))] impl PyNone { #[pymethod(magic)] fn bool(&self) -> bool { @@ -72,6 +73,28 @@ impl AsNumber for PyNone { } } +impl Comparable for PyNone { + fn cmp( + _zelf: &Py, + other: &PyObject, + op: PyComparisonOp, + vm: &VirtualMachine, + ) -> PyResult { + let value = match op { + PyComparisonOp::Eq => { + if vm.is_none(other) { + PyArithmeticValue::Implemented(true) + } else { + PyArithmeticValue::NotImplemented + } + } + _ => PyComparisonValue::NotImplemented, + }; + + Ok(value) + } +} + #[pyclass(module = false, name = "NotImplementedType")] #[derive(Debug)] pub struct PyNotImplemented;