Skip to content

Commit 6d863fb

Browse files
committed
Implement missing slots for NoneType
1 parent b31b812 commit 6d863fb

2 files changed

Lines changed: 38 additions & 3 deletions

File tree

crates/vm/src/builtins/singletons.rs

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,15 @@ use super::{PyStrRef, PyType, PyTypeRef};
22
use crate::{
33
Context, Py, PyObjectRef, PyPayload, PyResult, VirtualMachine,
44
class::PyClassImpl,
5+
common::hash::PyHash,
56
convert::ToPyObject,
6-
function::FuncArgs,
7+
function::{FuncArgs, PyComparisonValue},
78
protocol::PyNumberMethods,
8-
types::{AsNumber, Constructor, Representable},
9+
types::{AsNumber, Comparable, Constructor, Hashable, PyComparisonOp, Representable},
910
};
1011

12+
const NONE_HASH: PyHash = 0xFCA8_6420;
13+
1114
#[pyclass(module = false, name = "NoneType")]
1215
#[derive(Debug)]
1316
pub struct PyNone;
@@ -49,7 +52,7 @@ impl Constructor for PyNone {
4952
}
5053
}
5154

52-
#[pyclass(with(Constructor, AsNumber, Representable))]
55+
#[pyclass(with(Constructor, AsNumber, Comparable, Hashable, Representable))]
5356
impl PyNone {}
5457

5558
impl Representable for PyNone {
@@ -74,6 +77,26 @@ impl AsNumber for PyNone {
7477
}
7578
}
7679

80+
impl Comparable for PyNone {
81+
fn cmp(
82+
zelf: &Py<Self>,
83+
other: &crate::PyObject,
84+
op: PyComparisonOp,
85+
_vm: &VirtualMachine,
86+
) -> PyResult<PyComparisonValue> {
87+
Ok(op
88+
.identical_optimization(zelf, other)
89+
.map(PyComparisonValue::Implemented)
90+
.unwrap_or(PyComparisonValue::NotImplemented))
91+
}
92+
}
93+
94+
impl Hashable for PyNone {
95+
fn hash(_zelf: &Py<Self>, _vm: &VirtualMachine) -> PyResult<PyHash> {
96+
Ok(NONE_HASH)
97+
}
98+
}
99+
77100
#[pyclass(module = false, name = "NotImplementedType")]
78101
#[derive(Debug)]
79102
pub struct PyNotImplemented;

extra_tests/snippets/builtin_none.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,15 @@ def none2():
2626
assert None.__ne__(3) is NotImplemented
2727
assert None.__eq__(None) is True
2828
assert None.__ne__(None) is False
29+
assert None.__lt__(3) is NotImplemented
30+
assert None.__le__(3) is NotImplemented
31+
assert None.__gt__(3) is NotImplemented
32+
assert None.__ge__(3) is NotImplemented
33+
34+
none_type_dict = type(None).__dict__
35+
for name in ("__eq__", "__ne__", "__lt__", "__le__", "__gt__", "__ge__", "__hash__"):
36+
assert name in none_type_dict
37+
assert none_type_dict[name] is not object.__dict__[name]
38+
assert type(none_type_dict[name]).__name__ == "wrapper_descriptor"
39+
40+
assert hash(None) & 0xFFFFFFFF == 0xFCA86420

0 commit comments

Comments
 (0)