1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
use super::objtype::PyClassRef;
use crate::pyobject::{
IntoPyObject, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
};
use crate::vm::VirtualMachine;
#[pyclass(name = "NoneType")]
#[derive(Debug)]
pub struct PyNone;
pub type PyNoneRef = PyRef<PyNone>;
impl PyValue for PyNone {
fn class(vm: &VirtualMachine) -> PyClassRef {
vm.ctx.none().class()
}
}
impl IntoPyObject for () {
fn into_pyobject(self, vm: &VirtualMachine) -> PyResult {
Ok(vm.ctx.none())
}
}
impl<T: IntoPyObject> IntoPyObject for Option<T> {
fn into_pyobject(self, vm: &VirtualMachine) -> PyResult {
match self {
Some(x) => x.into_pyobject(vm),
None => Ok(vm.ctx.none()),
}
}
}
#[pyimpl]
impl PyNone {
#[pyslot]
fn tp_new(_: PyClassRef, vm: &VirtualMachine) -> PyNoneRef {
vm.ctx.none.clone()
}
#[pymethod(name = "__repr__")]
fn repr(&self) -> PyResult<String> {
Ok("None".to_owned())
}
#[pymethod(name = "__bool__")]
fn bool(&self) -> PyResult<bool> {
Ok(false)
}
#[pymethod(name = "__eq__")]
fn eq(&self, rhs: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef {
if vm.is_none(&rhs) {
vm.ctx.new_bool(true)
} else {
vm.ctx.not_implemented()
}
}
#[pymethod(name = "__ne__")]
fn ne(&self, rhs: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef {
if vm.is_none(&rhs) {
vm.ctx.new_bool(false)
} else {
vm.ctx.not_implemented()
}
}
}
pub fn init(context: &PyContext) {
PyNone::extend_class(context, &context.none.class());
}