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 /.
This commit is contained in:
rdb 2021-02-22 19:14:18 +01:00
parent fb9b334d58
commit 7ed9f573e7
3 changed files with 13 additions and 11 deletions

View File

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

View File

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

View File

@ -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 // 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++. // nb_floor_divide, but they have different semantics than in C++.
// Ugh. Make special slots to store the nb_divide members that take a // Ugh. Make special slots to store the nb_divide members that don't
// float. We'll use this to build up nb_true_divide, so that we can // take an int. We'll use this to build up nb_true_divide, in the
// still properly divide float vector types. // absence of a custom __truediv__, so that we can still properly divide
if (remap->_flags & FunctionRemap::F_divide_float) { // float vector types.
if ((key == "nb_divide" || key == "nb_inplace_divide") &&
(remap->_flags & FunctionRemap::F_divide_integer) == 0) {
string true_key; string true_key;
if (key == "nb_inplace_divide") { if (key == "nb_inplace_divide") {
true_key = "nb_inplace_true_divide"; true_key = "nb_inplace_true_divide";