python_ast/datamodel/
mod.rs

1//! Module representing the Python Data Model in Rust form.
2//! See: [here](https://docs.python.org/3/reference/datamodel.html).
3
4/// The Python Object. Anything that implements this trait is a Python Object.
5pub trait Object: Sized {
6    /// Returns the unique identifier of the object, which is the memory address of the object.
7    fn id(&self) -> usize {
8        std::ptr::addr_of!(*self) as usize
9    }
10
11    /// Returns the type name of the object.
12    fn r#type(&self) -> String {
13        std::any::type_name::<Self>().to_string()
14    }
15
16    /// Returns the type name of the object.
17    fn is<T: Object>(&self, other: &Option<T>) -> bool {
18        self.id() == other.id()
19    }
20
21    /// __getattribute__ is called to look up an attribute of the object.
22    fn __getattribute__(&self, _name: impl AsRef<str>) -> Option<impl Object> {
23        std::option::Option::<i32>::None
24    }
25
26    /// __setattribute__ is called to set an attribute of the object.
27    fn __setattribute__<T: Object>(&mut self, _name: impl AsRef<str>, _value: T) {
28        unimplemented!()
29    }
30
31    /// __delattribute__ is called to delete an attribute of the object.
32    fn __delattribute__(&mut self, _name: impl AsRef<str>) {
33        unimplemented!()
34    }
35
36    /// __dir__ is called to list the attributes of the object.
37    fn __dir__(&self) -> Vec<impl AsRef<str>> {
38        unimplemented!();
39        vec![
40            "__class__",
41            "__class_getitem__",
42            "__contains__",
43            "__delattr__",
44            "__delitem__",
45            "__dir__",
46            "__doc__",
47            "__eq__",
48            "__format__",
49            "__ge__",
50            "__getattribute__",
51            "__getitem__",
52            "__getstate__",
53            "__gt__",
54            "__hash__",
55            "__init__",
56            "__init_subclass__",
57            "__ior__",
58            "__iter__",
59            "__le__",
60            "__len__",
61            "__lt__",
62            "__ne__",
63            "__new__",
64            "__or__",
65            "__reduce__",
66            "__reduce_ex__",
67            "__repr__",
68            "__reversed__",
69            "__ror__",
70            "__setattr__",
71            "__setitem__",
72            "__sizeof__",
73            "__str__",
74            "__subclasshook__",
75            "clear",
76            "copy",
77            "fromkeys",
78            "get",
79            "items",
80            "keys",
81            "pop",
82            "popitem",
83            "setdefault",
84            "update",
85            "values",
86        ]
87    }
88}
89
90impl Object for i8 {}
91impl Object for i16 {}
92impl Object for i32 {}
93impl Object for i64 {}
94impl Object for i128 {}
95impl Object for u8 {}
96impl Object for u16 {}
97impl Object for u32 {}
98impl Object for u64 {}
99impl Object for u128 {}
100impl Object for String {}
101impl Object for &str {}
102impl Object for bool {}
103impl Object for f32 {}
104impl Object for f64 {}
105impl Object for char {}
106
107// There is a special implementation for the Option type, which allows Option<T>::None to be None in all cases.
108impl<T: Object> Object for Option<T> {
109    fn is<U: Object>(&self, other: &Option<U>) -> bool {
110        match (self, other) {
111            (Some(_), std::option::Option::None) => false,
112            (std::option::Option::None, Some(_)) => false,
113            (Some(a), Some(_b)) => a.is(other),
114            (std::option::Option::None, std::option::Option::None) => true,
115        }
116    }
117}
118
119/// The Python None object.
120#[allow(non_upper_case_globals)]
121pub static None: Option<String> = std::option::Option::<String>::None;
122
123/// The Python NotImplemented object.
124#[allow(non_upper_case_globals)]
125pub static NotImplemented: Option<&str> = Some("NotImplemented");
126
127/// The Python NotImplemented object.
128#[allow(non_upper_case_globals)]
129pub static Ellipsis: &str = "...";
130
131pub mod number;
132//pub use number::*;
133
134pub mod namespace;
135pub use namespace::*;
136
137pub mod class;
138pub use class::*;
139
140#[cfg(test)]
141mod tests {
142    use super::*;
143
144    #[test]
145    fn test_id() {
146        let x = 5;
147        let y = 6;
148        println!("x: {:p}, type: {}", &x, x.r#type());
149        assert_eq!(Object::id(&x), Object::id(&x));
150        assert_ne!(Object::id(&x), Object::id(&y));
151    }
152
153    #[test]
154    fn test_none() {
155        let x = &None;
156        let y: Option<i32> = std::option::Option::None;
157
158        assert_eq!(x.is(&None), true);
159        assert_ne!(x.is(&NotImplemented), true);
160        assert_eq!(y.is(&None), true);
161        assert_ne!(y.is(&NotImplemented), true);
162    }
163}