@@ -1075,12 +1075,9 @@ public virtual bool Equals(PyObject? other)
10751075 {
10761076 return true ;
10771077 }
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 ;
10841081 }
10851082
10861083
@@ -1304,6 +1301,18 @@ public override bool TryConvert(ConvertBinder binder, out object? result)
13041301 return false ;
13051302 }
13061303
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+
13071316 public override bool TryBinaryOperation ( BinaryOperationBinder binder , object arg , out object ? result )
13081317 {
13091318 using var _ = Py . GIL ( ) ;
@@ -1352,32 +1361,29 @@ public override bool TryBinaryOperation(BinaryOperationBinder binder, object arg
13521361 res = Runtime . PyNumber_InPlaceXor ( this . obj , ( ( PyObject ) arg ) . obj ) ;
13531362 break ;
13541363 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 ) ;
13571365 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 ) ;
13601367 case ExpressionType . LeftShift :
13611368 res = Runtime . PyNumber_Lshift ( this . obj , ( ( PyObject ) arg ) . obj ) ;
13621369 break ;
13631370 case ExpressionType . LeftShiftAssign :
13641371 res = Runtime . PyNumber_InPlaceLshift ( this . obj , ( ( PyObject ) arg ) . obj ) ;
13651372 break ;
13661373 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 ) ;
13691375 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 ) ;
13721377 case ExpressionType . Modulo :
13731378 res = Runtime . PyNumber_Remainder ( this . obj , ( ( PyObject ) arg ) . obj ) ;
13741379 break ;
13751380 case ExpressionType . ModuloAssign :
13761381 res = Runtime . PyNumber_InPlaceRemainder ( this . obj , ( ( PyObject ) arg ) . obj ) ;
13771382 break ;
13781383 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 ) ;
13811387 case ExpressionType . Or :
13821388 res = Runtime . PyNumber_Or ( this . obj , ( ( PyObject ) arg ) . obj ) ;
13831389 break ;
@@ -1402,6 +1408,40 @@ public override bool TryBinaryOperation(BinaryOperationBinder binder, object arg
14021408 return true ;
14031409 }
14041410
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+
14051445 // Workaround for https://bugzilla.xamarin.com/show_bug.cgi?id=41509
14061446 // See https://github.com/pythonnet/pythonnet/pull/219
14071447 internal static object ? CheckNone ( PyObject pyObj )
@@ -1436,14 +1476,17 @@ public override bool TryUnaryOperation(UnaryOperationBinder binder, out object?
14361476 case ExpressionType . Not :
14371477 r = Runtime . PyObject_Not ( this . obj ) ;
14381478 result = r == 1 ;
1479+ if ( r == - 1 ) Exceptions . Clear ( ) ;
14391480 return r != - 1 ;
14401481 case ExpressionType . IsFalse :
14411482 r = Runtime . PyObject_IsTrue ( this . obj ) ;
14421483 result = r == 0 ;
1484+ if ( r == - 1 ) Exceptions . Clear ( ) ;
14431485 return r != - 1 ;
14441486 case ExpressionType . IsTrue :
14451487 r = Runtime . PyObject_IsTrue ( this . obj ) ;
14461488 result = r == 1 ;
1489+ if ( r == - 1 ) Exceptions . Clear ( ) ;
14471490 return r != - 1 ;
14481491 case ExpressionType . Decrement :
14491492 case ExpressionType . Increment :
0 commit comments