| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -45,6 +45,8 @@ details about the cause of the failure | |||
| 45 | 45 | able to access members that are part of the implementation class, but not the | |
| 46 | 46 | interface. Use the new `__implementation__` or `__raw_implementation__` properties to | |
| 47 | 47 | if you need to "downcast" to the implementation class. | |
| 48 | + - BREAKING: `==` and `!=` operators on `PyObject` instances now use Python comparison | ||
| 49 | + (previously was equivalent to `object.ReferenceEquals(,)`) | ||
| 48 | 50 | - BREAKING: Parameters marked with `ParameterAttributes.Out` are no longer returned in addition | |
| 49 | 51 | to the regular method return value (unless they are passed with `ref` or `out` keyword). | |
| 50 | 52 | - BREAKING: Drop support for the long-deprecated CLR.* prefix. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -128,6 +128,28 @@ public void PassPyObjectInNet() | |||
| 128 | 128 | Assert.IsTrue(sys.testattr1.Equals(sys.testattr2)); | |
| 129 | 129 | } | |
| 130 | 130 | ||
| 131 | + // regression test for https://github.com/pythonnet/pythonnet/issues/1848 | ||
| 132 | + [Test] | ||
| 133 | + public void EnumEquality() | ||
| 134 | + { | ||
| 135 | + using var scope = Py.CreateScope(); | ||
| 136 | + scope.Exec(@" | ||
| 137 | + import enum | ||
| 138 | + | ||
| 139 | + class MyEnum(enum.IntEnum): | ||
| 140 | + OK = 1 | ||
| 141 | + ERROR = 2 | ||
| 142 | + | ||
| 143 | + def get_status(): | ||
| 144 | + return MyEnum.OK | ||
| 145 | + " | ||
| 146 | + ); | ||
| 147 | + | ||
| 148 | + dynamic MyEnum = scope.Get("MyEnum"); | ||
| 149 | + dynamic status = scope.Get("get_status").Invoke(); | ||
| 150 | + Assert.IsTrue(status == MyEnum.OK); | ||
| 151 | + } | ||
| 152 | + | ||
| 131 | 153 | // regression test for https://github.com/pythonnet/pythonnet/issues/1680 | |
| 132 | 154 | [Test] | |
| 133 | 155 | public void ForEach() | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -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: | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -962,31 +962,6 @@ internal static IntPtr PyObject_CallObject(IntPtr pointer, IntPtr args) | |||
| 962 | 962 | ||
| 963 | 963 | internal static int PyObject_RichCompareBool(BorrowedReference value1, BorrowedReference value2, int opid) => Delegates.PyObject_RichCompareBool(value1, value2, opid); | |
| 964 | 964 | ||
| 965 | - internal static int PyObject_Compare(BorrowedReference value1, BorrowedReference value2) | ||
| 966 | - { | ||
| 967 | - int res; | ||
| 968 | - res = PyObject_RichCompareBool(value1, value2, Py_LT); | ||
| 969 | - if (-1 == res) | ||
| 970 | - return -1; | ||
| 971 | - else if (1 == res) | ||
| 972 | - return -1; | ||
| 973 | - | ||
| 974 | - res = PyObject_RichCompareBool(value1, value2, Py_EQ); | ||
| 975 | - if (-1 == res) | ||
| 976 | - return -1; | ||
| 977 | - else if (1 == res) | ||
| 978 | - return 0; | ||
| 979 | - | ||
| 980 | - res = PyObject_RichCompareBool(value1, value2, Py_GT); | ||
| 981 | - if (-1 == res) | ||
| 982 | - return -1; | ||
| 983 | - else if (1 == res) | ||
| 984 | - return 1; | ||
| 985 | - | ||
| 986 | - Exceptions.SetError(Exceptions.SystemError, "Error comparing objects"); | ||
| 987 | - return -1; | ||
| 988 | - } | ||
| 989 | - | ||
| 990 | 965 | ||
| 991 | 966 | internal static int PyObject_IsInstance(BorrowedReference ob, BorrowedReference type) => Delegates.PyObject_IsInstance(ob, type); | |
| 992 | 967 | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments