@@ -1075,12 +1075,9 @@ public virtual bool Equals(PyObject? other)
1075
1075
{
1076
1076
return true ;
1077
1077
}
1078
- int r = Runtime . PyObject_Compare ( this , other ) ;
1079
- if ( Exceptions . ErrorOccurred ( ) )
1080
- {
1081
- throw PythonException . ThrowLastAsClrException ( ) ;
1082
- }
1083
- return r == 0 ;
1078
+ int result = Runtime . PyObject_RichCompareBool ( obj , other . obj , Runtime . Py_EQ ) ;
1079
+ if ( result < 0 ) throw PythonException . ThrowLastAsClrException ( ) ;
1080
+ return result != 0 ;
1084
1081
}
1085
1082
1086
1083
@@ -1304,6 +1301,18 @@ public override bool TryConvert(ConvertBinder binder, out object? result)
1304
1301
return false ;
1305
1302
}
1306
1303
1304
+ private bool TryCompare ( PyObject arg , int op , out object @out )
1305
+ {
1306
+ int result = Runtime . PyObject_RichCompareBool ( this . obj , arg . obj , op ) ;
1307
+ @out = result != 0 ;
1308
+ if ( result < 0 )
1309
+ {
1310
+ Exceptions . Clear ( ) ;
1311
+ return false ;
1312
+ }
1313
+ return true ;
1314
+ }
1315
+
1307
1316
public override bool TryBinaryOperation ( BinaryOperationBinder binder , object arg , out object ? result )
1308
1317
{
1309
1318
using var _ = Py . GIL ( ) ;
@@ -1352,32 +1361,29 @@ public override bool TryBinaryOperation(BinaryOperationBinder binder, object arg
1352
1361
res = Runtime . PyNumber_InPlaceXor ( this . obj , ( ( PyObject ) arg ) . obj ) ;
1353
1362
break ;
1354
1363
case ExpressionType . GreaterThan :
1355
- result = Runtime . PyObject_Compare ( this . obj , ( ( PyObject ) arg ) . obj ) > 0 ;
1356
- return true ;
1364
+ return this . TryCompare ( ( PyObject ) arg , Runtime . Py_GT , out result ) ;
1357
1365
case ExpressionType . GreaterThanOrEqual :
1358
- result = Runtime . PyObject_Compare ( this . obj , ( ( PyObject ) arg ) . obj ) >= 0 ;
1359
- return true ;
1366
+ return this . TryCompare ( ( PyObject ) arg , Runtime . Py_GE , out result ) ;
1360
1367
case ExpressionType . LeftShift :
1361
1368
res = Runtime . PyNumber_Lshift ( this . obj , ( ( PyObject ) arg ) . obj ) ;
1362
1369
break ;
1363
1370
case ExpressionType . LeftShiftAssign :
1364
1371
res = Runtime . PyNumber_InPlaceLshift ( this . obj , ( ( PyObject ) arg ) . obj ) ;
1365
1372
break ;
1366
1373
case ExpressionType . LessThan :
1367
- result = Runtime . PyObject_Compare ( this . obj , ( ( PyObject ) arg ) . obj ) < 0 ;
1368
- return true ;
1374
+ return this . TryCompare ( ( PyObject ) arg , Runtime . Py_LT , out result ) ;
1369
1375
case ExpressionType . LessThanOrEqual :
1370
- result = Runtime . PyObject_Compare ( this . obj , ( ( PyObject ) arg ) . obj ) <= 0 ;
1371
- return true ;
1376
+ return this . TryCompare ( ( PyObject ) arg , Runtime . Py_LE , out result ) ;
1372
1377
case ExpressionType . Modulo :
1373
1378
res = Runtime . PyNumber_Remainder ( this . obj , ( ( PyObject ) arg ) . obj ) ;
1374
1379
break ;
1375
1380
case ExpressionType . ModuloAssign :
1376
1381
res = Runtime . PyNumber_InPlaceRemainder ( this . obj , ( ( PyObject ) arg ) . obj ) ;
1377
1382
break ;
1378
1383
case ExpressionType . NotEqual :
1379
- result = Runtime . PyObject_Compare ( this . obj , ( ( PyObject ) arg ) . obj ) != 0 ;
1380
- return true ;
1384
+ return this . TryCompare ( ( PyObject ) arg , Runtime . Py_NE , out result ) ;
1385
+ case ExpressionType . Equal :
1386
+ return this . TryCompare ( ( PyObject ) arg , Runtime . Py_EQ , out result ) ;
1381
1387
case ExpressionType . Or :
1382
1388
res = Runtime . PyNumber_Or ( this . obj , ( ( PyObject ) arg ) . obj ) ;
1383
1389
break ;
@@ -1402,6 +1408,40 @@ public override bool TryBinaryOperation(BinaryOperationBinder binder, object arg
1402
1408
return true ;
1403
1409
}
1404
1410
1411
+ public static bool operator == ( PyObject ? a , PyObject ? b )
1412
+ {
1413
+ if ( a is null && b is null )
1414
+ {
1415
+ return true ;
1416
+ }
1417
+ if ( a is null || b is null )
1418
+ {
1419
+ return false ;
1420
+ }
1421
+
1422
+ using var _ = Py . GIL ( ) ;
1423
+ int result = Runtime . PyObject_RichCompareBool ( a . obj , b . obj , Runtime . Py_EQ ) ;
1424
+ if ( result < 0 ) throw PythonException . ThrowLastAsClrException ( ) ;
1425
+ return result != 0 ;
1426
+ }
1427
+
1428
+ public static bool operator != ( PyObject ? a , PyObject ? b )
1429
+ {
1430
+ if ( a is null && b is null )
1431
+ {
1432
+ return false ;
1433
+ }
1434
+ if ( a is null || b is null )
1435
+ {
1436
+ return true ;
1437
+ }
1438
+
1439
+ using var _ = Py . GIL ( ) ;
1440
+ int result = Runtime . PyObject_RichCompareBool ( a . obj , b . obj , Runtime . Py_NE ) ;
1441
+ if ( result < 0 ) throw PythonException . ThrowLastAsClrException ( ) ;
1442
+ return result != 0 ;
1443
+ }
1444
+
1405
1445
// Workaround for https://bugzilla.xamarin.com/show_bug.cgi?id=41509
1406
1446
// See https://github.com/pythonnet/pythonnet/pull/219
1407
1447
internal static object ? CheckNone ( PyObject pyObj )
@@ -1436,14 +1476,17 @@ public override bool TryUnaryOperation(UnaryOperationBinder binder, out object?
1436
1476
case ExpressionType . Not :
1437
1477
r = Runtime . PyObject_Not ( this . obj ) ;
1438
1478
result = r == 1 ;
1479
+ if ( r == - 1 ) Exceptions . Clear ( ) ;
1439
1480
return r != - 1 ;
1440
1481
case ExpressionType . IsFalse :
1441
1482
r = Runtime . PyObject_IsTrue ( this . obj ) ;
1442
1483
result = r == 0 ;
1484
+ if ( r == - 1 ) Exceptions . Clear ( ) ;
1443
1485
return r != - 1 ;
1444
1486
case ExpressionType . IsTrue :
1445
1487
r = Runtime . PyObject_IsTrue ( this . obj ) ;
1446
1488
result = r == 1 ;
1489
+ if ( r == - 1 ) Exceptions . Clear ( ) ;
1447
1490
return r != - 1 ;
1448
1491
case ExpressionType . Decrement :
1449
1492
case ExpressionType . Increment :
0 commit comments