@@ -83,6 +83,11 @@ impl VirtualMachine {
8383self . new_exception ( value_error, msg)
8484}
8585
86+ pub fn new_not_implemented_error ( & mut self , msg : String ) ->PyObjectRef {
87+ let value_error =self . ctx . exceptions . not_implemented_error . clone ( ) ;
88+ self . new_exception ( value_error, msg)
89+ }
90+
8691pub fn new_scope ( & mut self , parent_scope : Option < PyObjectRef > ) ->PyObjectRef {
8792// let parent_scope = self.current_frame_mut().locals.clone();
8893self . ctx . new_scope ( parent_scope)
@@ -447,23 +452,50 @@ impl VirtualMachine {
447452}
448453
449454pub fn _sub ( & mut self , a : PyObjectRef , b : PyObjectRef ) ->PyResult {
450- // Try __sub__, next __rsub__, next, give up
451- self . call_method ( & a, "__sub__" , vec ! [ b] )
452- /*
453- if a.has_attr("__sub__") {
454- self.call_method(&a, "__sub__", vec![b])
455- } else if b.has_attr("__rsub__") {
456- self.call_method(&b, "__rsub__", vec![a])
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- )))
455+ // 1. Try __sub__, next __rsub__, next, give up
456+ if let Ok ( method) =self . get_method ( a. clone ( ) , "__sub__" ) {
457+ match self . invoke (
458+ method,
459+ PyFuncArgs {
460+ args : vec ! [ b. clone( ) ] ,
461+ kwargs : vec ! [ ] ,
462+ } ,
463+ ) {
464+ Ok ( value) =>return Ok ( value) ,
465+ Err ( err) =>{
466+ if !objtype:: isinstance ( & err, & self . ctx . exceptions . not_implemented_error ) {
467+ return Err ( err) ;
468+ }
469+ }
470+ }
465471}
466- */
472+
473+ // 2. try __rsub__
474+ if let Ok ( method) =self . get_method ( b. clone ( ) , "__rsub__" ) {
475+ match self . invoke (
476+ method,
477+ PyFuncArgs {
478+ args : vec ! [ a. clone( ) ] ,
479+ kwargs : vec ! [ ] ,
480+ } ,
481+ ) {
482+ Ok ( value) =>return Ok ( value) ,
483+ Err ( err) =>{
484+ if !objtype:: isinstance ( & err, & self . ctx . exceptions . not_implemented_error ) {
485+ return Err ( err) ;
486+ }
487+ }
488+ }
489+ }
490+
491+ // 3. It all failed :(
492+ // Cannot sub a and b
493+ let a_type_name = objtype:: get_type_name ( & a. typ ( ) ) ;
494+ let b_type_name = objtype:: get_type_name ( & b. typ ( ) ) ;
495+ Err ( self . new_type_error ( format ! (
496+ "Unsupported operand types for '-': '{}' and '{}'" ,
497+ a_type_name, b_type_name
498+ ) ) )
467499}
468500
469501pub fn _add ( & mut self , a : PyObjectRef , b : PyObjectRef ) ->PyResult {