@@ -5,6 +5,7 @@ use super::super::pyobject::{
5
5
use super :: super :: vm:: VirtualMachine ;
6
6
use super :: objbool;
7
7
use super :: objdict;
8
+ use super :: objstr;
8
9
use super :: objtype;
9
10
10
11
pub fn new_instance ( vm : & mut VirtualMachine , mut args : PyFuncArgs ) -> PyResult {
@@ -15,12 +16,6 @@ pub fn new_instance(vm: &mut VirtualMachine, mut args: PyFuncArgs) -> PyResult {
15
16
Ok ( obj)
16
17
}
17
18
18
- pub fn call ( vm : & mut VirtualMachine , mut args : PyFuncArgs ) -> PyResult {
19
- let instance = args. shift ( ) ;
20
- let function = objtype:: get_attribute ( vm, instance, & String :: from ( "__call__" ) ) ?;
21
- vm. invoke ( function, args)
22
- }
23
-
24
19
pub fn create_object ( type_type : PyObjectRef , object_type : PyObjectRef , dict_type : PyObjectRef ) {
25
20
( * object_type. borrow_mut ( ) ) . kind = PyObjectKind :: Class {
26
21
name : String :: from ( "object" ) ,
@@ -101,6 +96,10 @@ pub fn init(context: &PyContext) {
101
96
object. set_attr ( "__hash__" , context. new_rustfunc ( object_hash) ) ;
102
97
object. set_attr ( "__str__" , context. new_rustfunc ( object_str) ) ;
103
98
object. set_attr ( "__repr__" , context. new_rustfunc ( object_repr) ) ;
99
+ object. set_attr (
100
+ "__getattribute__" ,
101
+ context. new_rustfunc ( object_getattribute) ,
102
+ ) ;
104
103
}
105
104
106
105
fn object_init ( vm : & mut VirtualMachine , _args : PyFuncArgs ) -> PyResult {
@@ -114,3 +113,65 @@ fn object_dict(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
114
113
_ => Err ( vm. new_type_error ( "TypeError: no dictionary." . to_string ( ) ) ) ,
115
114
}
116
115
}
116
+
117
+ fn object_getattribute ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
118
+ arg_check ! (
119
+ vm,
120
+ args,
121
+ required = [
122
+ ( obj, Some ( vm. ctx. object( ) ) ) ,
123
+ ( name_str, Some ( vm. ctx. str_type( ) ) )
124
+ ]
125
+ ) ;
126
+ let name = objstr:: get_value ( & name_str) ;
127
+ trace ! ( "object.__getattribute__({:?}, {:?})" , obj, name) ;
128
+ let cls = obj. typ ( ) ;
129
+
130
+ if let Some ( attr) = cls. get_attr ( & name) {
131
+ let attr_class = attr. typ ( ) ;
132
+ if attr_class. has_attr ( "__set__" ) {
133
+ if let Some ( descriptor) = attr_class. get_attr ( "__get__" ) {
134
+ return vm. invoke (
135
+ descriptor,
136
+ PyFuncArgs {
137
+ args : vec ! [ attr, obj. clone( ) , cls] ,
138
+ kwargs : vec ! [ ] ,
139
+ } ,
140
+ ) ;
141
+ }
142
+ }
143
+ }
144
+
145
+ if let Some ( obj_attr) = obj. get_attr ( & name) {
146
+ Ok ( obj_attr)
147
+ } else if let Some ( attr) = cls. get_attr ( & name) {
148
+ let attr_class = attr. typ ( ) ;
149
+ if let Some ( descriptor) = attr_class. get_attr ( "__get__" ) {
150
+ vm. invoke (
151
+ descriptor,
152
+ PyFuncArgs {
153
+ args : vec ! [ attr, obj. clone( ) , cls] ,
154
+ kwargs : vec ! [ ] ,
155
+ } ,
156
+ )
157
+ } else {
158
+ Ok ( attr)
159
+ }
160
+ } else {
161
+ if let Some ( getter) = cls. get_attr ( "__getattr__" ) {
162
+ vm. invoke (
163
+ getter,
164
+ PyFuncArgs {
165
+ args : vec ! [ cls, name_str. clone( ) ] ,
166
+ kwargs : vec ! [ ] ,
167
+ } ,
168
+ )
169
+ } else {
170
+ let attribute_error = vm. context ( ) . exceptions . attribute_error . clone ( ) ;
171
+ Err ( vm. new_exception (
172
+ attribute_error,
173
+ format ! ( "{:?} object has no attribute {}" , cls, name) ,
174
+ ) )
175
+ }
176
+ }
177
+ }
0 commit comments