@@ -78,6 +78,11 @@ impl VirtualMachine {
78
78
self . new_exception ( value_error, msg)
79
79
}
80
80
81
+ pub fn new_not_implemented_error ( & mut self , msg : String ) -> PyObjectRef {
82
+ let value_error = self . ctx . exceptions . not_implemented_error . clone ( ) ;
83
+ self . new_exception ( value_error, msg)
84
+ }
85
+
81
86
pub fn new_scope ( & mut self , parent_scope : Option < PyObjectRef > ) -> PyObjectRef {
82
87
// let parent_scope = self.current_frame_mut().locals.clone();
83
88
self . ctx . new_scope ( parent_scope)
@@ -437,32 +442,50 @@ impl VirtualMachine {
437
442
}
438
443
439
444
pub fn _sub ( & mut self , a : PyObjectRef , b : PyObjectRef ) -> PyResult {
440
- // Try __sub__, next __rsub__, next, give up
445
+ // 1. Try __sub__, next __rsub__, next, give up
441
446
if let Ok ( method) = self . get_method ( a. clone ( ) , "__sub__" ) {
442
- self . invoke (
447
+ match self . invoke (
443
448
method,
444
449
PyFuncArgs {
445
- args : vec ! [ b] ,
450
+ args : vec ! [ b. clone ( ) ] ,
446
451
kwargs : vec ! [ ] ,
447
452
} ,
448
- )
449
- } else if let Ok ( method) = self . get_method ( b. clone ( ) , "__rsub__" ) {
450
- self . invoke (
453
+ ) {
454
+ Ok ( value) => return Ok ( value) ,
455
+ Err ( err) => {
456
+ if !objtype:: isinstance ( & err, & self . ctx . exceptions . not_implemented_error ) {
457
+ return Err ( err) ;
458
+ }
459
+ }
460
+ }
461
+ }
462
+
463
+ // 2. try __rsub__
464
+ if let Ok ( method) = self . get_method ( b. clone ( ) , "__rsub__" ) {
465
+ match self . invoke (
451
466
method,
452
467
PyFuncArgs {
453
- args : vec ! [ a] ,
468
+ args : vec ! [ a. clone ( ) ] ,
454
469
kwargs : vec ! [ ] ,
455
470
} ,
456
- )
457
- } else {
458
- // Cannot sub a and b
459
- let a_type_name = objtype:: get_type_name ( & a. typ ( ) ) ;
460
- let b_type_name = objtype:: get_type_name ( & b. typ ( ) ) ;
461
- Err ( self . new_type_error ( format ! (
462
- "Unsupported operand types for '-': '{}' and '{}'" ,
463
- a_type_name, b_type_name
464
- ) ) )
471
+ ) {
472
+ Ok ( value) => return Ok ( value) ,
473
+ Err ( err) => {
474
+ if !objtype:: isinstance ( & err, & self . ctx . exceptions . not_implemented_error ) {
475
+ return Err ( err) ;
476
+ }
477
+ }
478
+ }
465
479
}
480
+
481
+ // 3. It all failed :(
482
+ // Cannot sub a and b
483
+ let a_type_name = objtype:: get_type_name ( & a. typ ( ) ) ;
484
+ let b_type_name = objtype:: get_type_name ( & b. typ ( ) ) ;
485
+ Err ( self . new_type_error ( format ! (
486
+ "Unsupported operand types for '-': '{}' and '{}'" ,
487
+ a_type_name, b_type_name
488
+ ) ) )
466
489
}
467
490
468
491
pub fn _add ( & mut self , a : PyObjectRef , b : PyObjectRef ) -> PyResult {
0 commit comments