rustpython_vm/builtins/
singletons.rs1use super::{PyStrRef, PyType, PyTypeRef};
2use crate::{
3 class::PyClassImpl,
4 convert::ToPyObject,
5 protocol::PyNumberMethods,
6 types::{AsNumber, Constructor, Representable},
7 Context, Py, PyObjectRef, PyPayload, PyResult, VirtualMachine,
8};
9
10#[pyclass(module = false, name = "NoneType")]
11#[derive(Debug)]
12pub struct PyNone;
13
14impl PyPayload for PyNone {
15 fn class(ctx: &Context) -> &'static Py<PyType> {
16 ctx.types.none_type
17 }
18}
19
20impl ToPyObject for () {
23 fn to_pyobject(self, vm: &VirtualMachine) -> PyObjectRef {
24 vm.ctx.none()
25 }
26}
27
28impl<T: ToPyObject> ToPyObject for Option<T> {
29 fn to_pyobject(self, vm: &VirtualMachine) -> PyObjectRef {
30 match self {
31 Some(x) => x.to_pyobject(vm),
32 None => vm.ctx.none(),
33 }
34 }
35}
36
37impl Constructor for PyNone {
38 type Args = ();
39
40 fn py_new(_: PyTypeRef, _args: Self::Args, vm: &VirtualMachine) -> PyResult {
41 Ok(vm.ctx.none.clone().into())
42 }
43}
44
45#[pyclass(with(Constructor, AsNumber, Representable))]
46impl PyNone {
47 #[pymethod(magic)]
48 fn bool(&self) -> bool {
49 false
50 }
51}
52
53impl Representable for PyNone {
54 #[inline]
55 fn repr(_zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<PyStrRef> {
56 Ok(vm.ctx.names.None.to_owned())
57 }
58
59 #[cold]
60 fn repr_str(_zelf: &Py<Self>, _vm: &VirtualMachine) -> PyResult<String> {
61 unreachable!("use repr instead")
62 }
63}
64
65impl AsNumber for PyNone {
66 fn as_number() -> &'static PyNumberMethods {
67 static AS_NUMBER: PyNumberMethods = PyNumberMethods {
68 boolean: Some(|_number, _vm| Ok(false)),
69 ..PyNumberMethods::NOT_IMPLEMENTED
70 };
71 &AS_NUMBER
72 }
73}
74
75#[pyclass(module = false, name = "NotImplementedType")]
76#[derive(Debug)]
77pub struct PyNotImplemented;
78
79impl PyPayload for PyNotImplemented {
80 fn class(ctx: &Context) -> &'static Py<PyType> {
81 ctx.types.not_implemented_type
82 }
83}
84
85impl Constructor for PyNotImplemented {
86 type Args = ();
87
88 fn py_new(_: PyTypeRef, _args: Self::Args, vm: &VirtualMachine) -> PyResult {
89 Ok(vm.ctx.not_implemented.clone().into())
90 }
91}
92
93#[pyclass(with(Constructor))]
94impl PyNotImplemented {
95 #[pymethod(magic)]
99 fn bool(&self) -> bool {
100 true
101 }
102
103 #[pymethod(magic)]
104 fn reduce(&self, vm: &VirtualMachine) -> PyStrRef {
105 vm.ctx.names.NotImplemented.to_owned()
106 }
107}
108
109impl Representable for PyNotImplemented {
110 #[inline]
111 fn repr(_zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<PyStrRef> {
112 Ok(vm.ctx.names.NotImplemented.to_owned())
113 }
114
115 #[cold]
116 fn repr_str(_zelf: &Py<Self>, _vm: &VirtualMachine) -> PyResult<String> {
117 unreachable!("use repr instead")
118 }
119}
120
121pub fn init(context: &Context) {
122 PyNone::extend_class(context, context.types.none_type);
123 PyNotImplemented::extend_class(context, context.types.not_implemented_type);
124}