@@ -2570,6 +2570,8 @@ write_module_class(ostream &out, Object *obj) {
2570
2570
out << " return nullptr;\n " ;
2571
2571
out << " }\n\n " ;
2572
2572
2573
+ bool have_eq = false ;
2574
+ bool have_ne = false ;
2573
2575
for (Function *func : obj->_methods ) {
2574
2576
std::set<FunctionRemap*> remaps;
2575
2577
if (!func) {
@@ -2590,8 +2592,10 @@ write_module_class(ostream &out, Object *obj) {
2590
2592
op_type = " Py_LE" ;
2591
2593
} else if (fname == " operator ==" ) {
2592
2594
op_type = " Py_EQ" ;
2595
+ have_eq = true ;
2593
2596
} else if (fname == " operator !=" ) {
2594
2597
op_type = " Py_NE" ;
2598
+ have_ne = true ;
2595
2599
} else if (fname == " operator >" ) {
2596
2600
op_type = " Py_GT" ;
2597
2601
} else if (fname == " operator >=" ) {
@@ -2616,6 +2620,43 @@ write_module_class(ostream &out, Object *obj) {
2616
2620
}
2617
2621
2618
2622
if (has_local_richcompare) {
2623
+ if (have_eq && !have_ne) {
2624
+ // Generate a not-equal function from the equal function.
2625
+ for (Function *func : obj->_methods ) {
2626
+ std::set<FunctionRemap*> remaps;
2627
+ if (!func) {
2628
+ continue ;
2629
+ }
2630
+ const string &fname = func->_ifunc .get_name ();
2631
+ if (fname != " operator ==" ) {
2632
+ continue ;
2633
+ }
2634
+ for (FunctionRemap *remap : func->_remaps ) {
2635
+ if (is_remap_legal (remap) && remap->_has_this && (remap->_args_type == AT_single_arg)) {
2636
+ remaps.insert (remap);
2637
+ }
2638
+ }
2639
+ out << " case Py_NE: // from Py_EQ\n " ;
2640
+ out << " {\n " ;
2641
+
2642
+ string expected_params;
2643
+ write_function_forset (out, remaps, 1 , 1 , expected_params, 6 , true , false ,
2644
+ AT_single_arg, RF_pyobject | RF_invert_bool | RF_err_null, false );
2645
+
2646
+ out << " break;\n " ;
2647
+ out << " }\n " ;
2648
+ }
2649
+ }
2650
+ else if (!have_eq && !slots.count (" tp_compare" )) {
2651
+ // Generate an equals function.
2652
+ out << " case Py_EQ:\n " ;
2653
+ out << " return PyBool_FromLong(DtoolInstance_Check(arg) && DtoolInstance_VOID_PTR(self) == DtoolInstance_VOID_PTR(arg));\n " ;
2654
+ if (!have_ne) {
2655
+ out << " case Py_NE:\n " ;
2656
+ out << " return PyBool_FromLong(!DtoolInstance_Check(arg) || DtoolInstance_VOID_PTR(self) != DtoolInstance_VOID_PTR(arg));\n " ;
2657
+ }
2658
+ }
2659
+
2619
2660
// End of switch block
2620
2661
out << " }\n\n " ;
2621
2662
out << " if (_PyErr_OCCURRED()) {\n " ;
@@ -6048,8 +6089,13 @@ write_function_instance(ostream &out, FunctionRemap *remap,
6048
6089
return_flags &= ~RF_pyobject;
6049
6090
6050
6091
} else if (return_null && TypeManager::is_bool (remap->_return_type ->get_new_type ())) {
6051
- indent (out, indent_level)
6052
- << " return Dtool_Return_Bool(" << return_expr << " );\n " ;
6092
+ if (return_flags & RF_invert_bool) {
6093
+ indent (out, indent_level)
6094
+ << " return Dtool_Return_Bool(!(" << return_expr << " ));\n " ;
6095
+ } else {
6096
+ indent (out, indent_level)
6097
+ << " return Dtool_Return_Bool(" << return_expr << " );\n " ;
6098
+ }
6053
6099
return_flags &= ~RF_pyobject;
6054
6100
6055
6101
} else if (return_null && TypeManager::is_pointer_to_PyObject (remap->_return_type ->get_new_type ())) {
@@ -6415,7 +6461,12 @@ pack_return_value(ostream &out, int indent_level, FunctionRemap *remap,
6415
6461
indent (out, indent_level)
6416
6462
<< " return PyString_FromStringAndSize((char *)return_value.data(), (Py_ssize_t)return_value.size());\n " ;
6417
6463
out << " #endif\n " ;
6418
- } else {
6464
+ }
6465
+ else if (return_flags & RF_invert_bool) {
6466
+ indent (out, indent_level)
6467
+ << " return Dtool_WrapValue(!(" << return_expr << " ));\n " ;
6468
+ }
6469
+ else {
6419
6470
indent (out, indent_level)
6420
6471
<< " return Dtool_WrapValue(" << return_expr << " );\n " ;
6421
6472
}
0 commit comments