@@ -50,7 +50,7 @@ fn dir_object(vm: &mut VirtualMachine, obj: &PyObjectRef) -> PyObjectRef {
50
50
51
51
fn builtin_abs ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
52
52
arg_check ! ( vm, args, required = [ ( x, None ) ] ) ;
53
- match vm. get_attribute ( x. clone ( ) , & "__abs__" ) {
53
+ match vm. get_method ( x. clone ( ) , "__abs__" ) {
54
54
Ok ( attrib) => vm. invoke ( attrib, PyFuncArgs :: new ( vec ! [ ] , vec ! [ ] ) ) ,
55
55
Err ( ..) => Err ( vm. new_type_error ( "bad operand for abs" . to_string ( ) ) ) ,
56
56
}
@@ -134,7 +134,7 @@ fn builtin_dir(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
134
134
135
135
fn builtin_divmod ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
136
136
arg_check ! ( vm, args, required = [ ( x, None ) , ( y, None ) ] ) ;
137
- match vm. get_attribute ( x. clone ( ) , & "__divmod__" ) {
137
+ match vm. get_method ( x. clone ( ) , "__divmod__" ) {
138
138
Ok ( attrib) => vm. invoke ( attrib, PyFuncArgs :: new ( vec ! [ y. clone( ) ] , vec ! [ ] ) ) ,
139
139
Err ( ..) => Err ( vm. new_type_error ( "unsupported operand type(s) for divmod" . to_string ( ) ) ) ,
140
140
}
@@ -218,11 +218,7 @@ fn builtin_getattr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
218
218
args,
219
219
required = [ ( obj, None ) , ( attr, Some ( vm. ctx. str_type( ) ) ) ]
220
220
) ;
221
- if let PyObjectKind :: String { ref value } = attr. borrow ( ) . kind {
222
- vm. get_attribute ( obj. clone ( ) , value)
223
- } else {
224
- panic ! ( "argument checking failure: attr not string" )
225
- }
221
+ vm. get_attribute ( obj. clone ( ) , attr. clone ( ) )
226
222
}
227
223
228
224
// builtin_globals
@@ -233,15 +229,11 @@ fn builtin_hasattr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
233
229
args,
234
230
required = [ ( obj, None ) , ( attr, Some ( vm. ctx. str_type( ) ) ) ]
235
231
) ;
236
- if let PyObjectKind :: String { ref value } = attr. borrow ( ) . kind {
237
- let has_attr = match vm. get_attribute ( obj. clone ( ) , value) {
238
- Ok ( ..) => true ,
239
- Err ( ..) => false ,
240
- } ;
241
- Ok ( vm. context ( ) . new_bool ( has_attr) )
242
- } else {
243
- panic ! ( "argument checking failure: attr not string" )
244
- }
232
+ let has_attr = match vm. get_attribute ( obj. clone ( ) , attr. clone ( ) ) {
233
+ Ok ( ..) => true ,
234
+ Err ( ..) => false ,
235
+ } ;
236
+ Ok ( vm. context ( ) . new_bool ( has_attr) )
245
237
}
246
238
247
239
fn builtin_hash ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
@@ -308,7 +300,7 @@ fn builtin_len(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
308
300
}
309
301
_ => {
310
302
let len_method_name = "__len__" . to_string ( ) ;
311
- match vm. get_attribute ( obj. clone ( ) , & len_method_name) {
303
+ match vm. get_method ( obj. clone ( ) , & len_method_name) {
312
304
Ok ( value) => vm. invoke ( value, PyFuncArgs :: default ( ) ) ,
313
305
Err ( ..) => Err ( vm. context ( ) . new_str (
314
306
format ! (
@@ -444,7 +436,7 @@ fn builtin_pow(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
444
436
optional = [ ( mod_value, Some ( vm. ctx. int_type( ) ) ) ]
445
437
) ;
446
438
let pow_method_name = "__pow__" . to_string ( ) ;
447
- let result = match vm. get_attribute ( x. clone ( ) , & pow_method_name) {
439
+ let result = match vm. get_method ( x. clone ( ) , & pow_method_name) {
448
440
Ok ( attrib) => vm. invoke ( attrib, PyFuncArgs :: new ( vec ! [ y. clone( ) ] , vec ! [ ] ) ) ,
449
441
Err ( ..) => Err ( vm. new_type_error ( "unsupported operand type(s) for pow" . to_string ( ) ) ) ,
450
442
} ;
@@ -454,7 +446,7 @@ fn builtin_pow(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
454
446
match mod_value {
455
447
Some ( mod_value) => {
456
448
let mod_method_name = "__mod__" . to_string ( ) ;
457
- match vm. get_attribute (
449
+ match vm. get_method (
458
450
result. expect ( "result not defined" ) . clone ( ) ,
459
451
& mod_method_name,
460
452
) {
@@ -644,14 +636,10 @@ pub fn make_module(ctx: &PyContext) -> PyObjectRef {
644
636
pub fn builtin_build_class_ ( vm : & mut VirtualMachine , mut args : PyFuncArgs ) -> PyResult {
645
637
let function = args. shift ( ) ;
646
638
let name_arg = args. shift ( ) ;
647
- let name_arg_ref = name_arg. borrow ( ) ;
648
- let name = match name_arg_ref. kind {
649
- PyObjectKind :: String { ref value } => value,
650
- _ => panic ! ( "Class name must by a string!" ) ,
651
- } ;
652
639
let mut bases = args. args . clone ( ) ;
640
+ let metaclass = args. get_kwarg ( "metaclass" , vm. get_type ( ) ) ;
641
+
653
642
bases. push ( vm. context ( ) . object ( ) ) ;
654
- let metaclass = vm. get_type ( ) ;
655
643
let namespace = vm. new_dict ( ) ;
656
644
& vm. invoke (
657
645
function,
@@ -660,5 +648,18 @@ pub fn builtin_build_class_(vm: &mut VirtualMachine, mut args: PyFuncArgs) -> Py
660
648
kwargs : vec ! [ ] ,
661
649
} ,
662
650
) ;
663
- objtype:: new ( metaclass, name, bases, namespace)
651
+
652
+ let bases = vm. context ( ) . new_tuple ( bases) ;
653
+
654
+ // Special case: __new__ must be looked up on the metaclass, not the meta-metaclass as
655
+ // per vm.call(metaclass, "__new__", ...)
656
+ let new = metaclass. get_attr ( "__new__" ) . unwrap ( ) ;
657
+ let wrapped = vm. call_get_descriptor ( new, metaclass) ?;
658
+ vm. invoke (
659
+ wrapped,
660
+ PyFuncArgs {
661
+ args : vec ! [ name_arg, bases, namespace] ,
662
+ kwargs : vec ! [ ] ,
663
+ } ,
664
+ )
664
665
}
0 commit comments