Browse Source

interrogate: Map operator / to true divide unless it takes an int

This is a little less conservative than the previous behaviour of only mapping if it takes a float, but this behaviour is more intuitive for non-scalar operands such as for Filename's operator /.
rdb 4 years ago
parent
commit
7ed9f573e7

+ 6 - 6
dtool/src/interrogate/functionRemap.cxx

@@ -900,9 +900,9 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak
 
     } else if (fname == "operator /") {
       if (_has_this && _parameters.size() == 2 &&
-          TypeManager::is_float(_parameters[1]._remap->get_new_type())) {
-        // This division operator takes a single float argument.
-        _flags |= F_divide_float;
+          TypeManager::is_integer(_parameters[1]._remap->get_new_type())) {
+        // This division operator takes a single integer argument.
+        _flags |= F_divide_integer;
       }
 
     } else if (fname == "get_key" || fname == "get_hash") {
@@ -947,9 +947,9 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak
   case T_assignment_method:
     if (fname == "operator /=") {
       if (_has_this && _parameters.size() == 2 &&
-          TypeManager::is_float(_parameters[1]._remap->get_new_type())) {
-        // This division operator takes a single float argument.
-        _flags |= F_divide_float;
+          TypeManager::is_integer(_parameters[1]._remap->get_new_type())) {
+        // This division operator takes a single integer argument.
+        _flags |= F_divide_integer;
       }
     }
     break;

+ 1 - 1
dtool/src/interrogate/functionRemap.h

@@ -98,7 +98,7 @@ public:
     F_iter               = 0x0400,
     F_compare_to         = 0x0800,
     F_coerce_constructor = 0x1000,
-    F_divide_float       = 0x2000,
+    F_divide_integer     = 0x2000,
     F_hash               = 0x4000,
     F_explicit_args      = 0x8000,
   };

+ 6 - 4
dtool/src/interrogate/interfaceMakerPythonNative.cxx

@@ -1693,10 +1693,12 @@ write_module_class(ostream &out, Object *obj) {
 
         // Python 3 doesn't support nb_divide.  It has nb_true_divide and also
         // nb_floor_divide, but they have different semantics than in C++.
-        // Ugh.  Make special slots to store the nb_divide members that take a
-        // float.  We'll use this to build up nb_true_divide, so that we can
-        // still properly divide float vector types.
-        if (remap->_flags & FunctionRemap::F_divide_float) {
+        // Ugh.  Make special slots to store the nb_divide members that don't
+        // take an int.  We'll use this to build up nb_true_divide, in the
+        // absence of a custom __truediv__, so that we can still properly divide
+        // float vector types.
+        if ((key == "nb_divide" || key == "nb_inplace_divide") &&
+            (remap->_flags & FunctionRemap::F_divide_integer) == 0) {
           string true_key;
           if (key == "nb_inplace_divide") {
             true_key = "nb_inplace_true_divide";