Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Implemented dynamic equality and inequality forPyObject instances#1849

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
lostmsu merged 1 commit intopythonnet:masterfromlosttech:bugs/1848
Jun 30, 2022
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletionsCHANGELOG.md
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -44,6 +44,8 @@ details about the cause of the failure
able to access members that are part of the implementation class, but not the
interface. Use the new `__implementation__` or `__raw_implementation__` properties to
if you need to "downcast" to the implementation class.
- BREAKING: `==` and `!=` operators on `PyObject` instances now use Python comparison
(previously was equivalent to `object.ReferenceEquals(,)`)
- BREAKING: Parameters marked with `ParameterAttributes.Out` are no longer returned in addition
to the regular method return value (unless they are passed with `ref` or `out` keyword).
- BREAKING: Drop support for the long-deprecated CLR.* prefix.
Expand Down
22 changes: 22 additions & 0 deletionssrc/embed_tests/dynamic.cs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -128,6 +128,28 @@ public void PassPyObjectInNet()
Assert.IsTrue(sys.testattr1.Equals(sys.testattr2));
}

// regression test for https://github.com/pythonnet/pythonnet/issues/1848
[Test]
public void EnumEquality()
{
using var scope = Py.CreateScope();
scope.Exec(@"
import enum

class MyEnum(enum.IntEnum):
OK = 1
ERROR = 2

def get_status():
return MyEnum.OK
"
);

dynamic MyEnum = scope.Get("MyEnum");
dynamic status = scope.Get("get_status").Invoke();
Assert.IsTrue(status == MyEnum.OK);
}

// regression test for https://github.com/pythonnet/pythonnet/issues/1680
[Test]
public void ForEach()
Expand Down
75 changes: 59 additions & 16 deletionssrc/runtime/PythonTypes/PyObject.cs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -1075,12 +1075,9 @@ public virtual bool Equals(PyObject? other)
{
return true;
}
int r = Runtime.PyObject_Compare(this, other);
if (Exceptions.ErrorOccurred())
{
throw PythonException.ThrowLastAsClrException();
}
return r == 0;
int result = Runtime.PyObject_RichCompareBool(obj, other.obj, Runtime.Py_EQ);
if (result < 0) throw PythonException.ThrowLastAsClrException();
return result != 0;
}


Expand DownExpand Up@@ -1304,6 +1301,18 @@ public override bool TryConvert(ConvertBinder binder, out object? result)
return false;
}

private bool TryCompare(PyObject arg, int op, out object @out)
{
int result = Runtime.PyObject_RichCompareBool(this.obj, arg.obj, op);
@out = result != 0;
if (result < 0)
{
Exceptions.Clear();
return false;
}
return true;
}

public override bool TryBinaryOperation(BinaryOperationBinder binder, object arg, out object? result)
{
using var _ = Py.GIL();
Expand DownExpand Up@@ -1352,32 +1361,29 @@ public override bool TryBinaryOperation(BinaryOperationBinder binder, object arg
res = Runtime.PyNumber_InPlaceXor(this.obj, ((PyObject)arg).obj);
break;
case ExpressionType.GreaterThan:
result = Runtime.PyObject_Compare(this.obj, ((PyObject)arg).obj) > 0;
return true;
return this.TryCompare((PyObject)arg, Runtime.Py_GT, out result);
case ExpressionType.GreaterThanOrEqual:
result = Runtime.PyObject_Compare(this.obj, ((PyObject)arg).obj) >= 0;
return true;
return this.TryCompare((PyObject)arg, Runtime.Py_GE, out result);
case ExpressionType.LeftShift:
res = Runtime.PyNumber_Lshift(this.obj, ((PyObject)arg).obj);
break;
case ExpressionType.LeftShiftAssign:
res = Runtime.PyNumber_InPlaceLshift(this.obj, ((PyObject)arg).obj);
break;
case ExpressionType.LessThan:
result = Runtime.PyObject_Compare(this.obj, ((PyObject)arg).obj) < 0;
return true;
return this.TryCompare((PyObject)arg, Runtime.Py_LT, out result);
case ExpressionType.LessThanOrEqual:
result = Runtime.PyObject_Compare(this.obj, ((PyObject)arg).obj) <= 0;
return true;
return this.TryCompare((PyObject)arg, Runtime.Py_LE, out result);
case ExpressionType.Modulo:
res = Runtime.PyNumber_Remainder(this.obj, ((PyObject)arg).obj);
break;
case ExpressionType.ModuloAssign:
res = Runtime.PyNumber_InPlaceRemainder(this.obj, ((PyObject)arg).obj);
break;
case ExpressionType.NotEqual:
result = Runtime.PyObject_Compare(this.obj, ((PyObject)arg).obj) != 0;
return true;
return this.TryCompare((PyObject)arg, Runtime.Py_NE, out result);
case ExpressionType.Equal:
return this.TryCompare((PyObject)arg, Runtime.Py_EQ, out result);
case ExpressionType.Or:
res = Runtime.PyNumber_Or(this.obj, ((PyObject)arg).obj);
break;
Expand All@@ -1402,6 +1408,40 @@ public override bool TryBinaryOperation(BinaryOperationBinder binder, object arg
return true;
}

public static bool operator ==(PyObject? a, PyObject? b)
{
if (a is null && b is null)
{
return true;
}
if (a is null || b is null)
{
return false;
}

using var _ = Py.GIL();
int result = Runtime.PyObject_RichCompareBool(a.obj, b.obj, Runtime.Py_EQ);
if (result < 0) throw PythonException.ThrowLastAsClrException();
return result != 0;
}

public static bool operator !=(PyObject? a, PyObject? b)
{
if (a is null && b is null)
{
return false;
}
if (a is null || b is null)
{
return true;
}

using var _ = Py.GIL();
int result = Runtime.PyObject_RichCompareBool(a.obj, b.obj, Runtime.Py_NE);
if (result < 0) throw PythonException.ThrowLastAsClrException();
return result != 0;
}

// Workaround for https://bugzilla.xamarin.com/show_bug.cgi?id=41509
// See https://github.com/pythonnet/pythonnet/pull/219
internal static object? CheckNone(PyObject pyObj)
Expand DownExpand Up@@ -1436,14 +1476,17 @@ public override bool TryUnaryOperation(UnaryOperationBinder binder, out object?
case ExpressionType.Not:
r = Runtime.PyObject_Not(this.obj);
result = r == 1;
if (r == -1) Exceptions.Clear();
return r != -1;
case ExpressionType.IsFalse:
r = Runtime.PyObject_IsTrue(this.obj);
result = r == 0;
if (r == -1) Exceptions.Clear();
return r != -1;
case ExpressionType.IsTrue:
r = Runtime.PyObject_IsTrue(this.obj);
result = r == 1;
if (r == -1) Exceptions.Clear();
return r != -1;
case ExpressionType.Decrement:
case ExpressionType.Increment:
Expand Down
25 changes: 0 additions & 25 deletionssrc/runtime/Runtime.cs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -962,31 +962,6 @@ internal static IntPtr PyObject_CallObject(IntPtr pointer, IntPtr args)

internal static int PyObject_RichCompareBool(BorrowedReference value1, BorrowedReference value2, int opid) => Delegates.PyObject_RichCompareBool(value1, value2, opid);

internal static int PyObject_Compare(BorrowedReference value1, BorrowedReference value2)
{
int res;
res = PyObject_RichCompareBool(value1, value2, Py_LT);
if (-1 == res)
return -1;
else if (1 == res)
return -1;

res = PyObject_RichCompareBool(value1, value2, Py_EQ);
if (-1 == res)
return -1;
else if (1 == res)
return 0;

res = PyObject_RichCompareBool(value1, value2, Py_GT);
if (-1 == res)
return -1;
else if (1 == res)
return 1;

Exceptions.SetError(Exceptions.SystemError, "Error comparing objects");
return -1;
}


internal static int PyObject_IsInstance(BorrowedReference ob, BorrowedReference type) => Delegates.PyObject_IsInstance(ob, type);

Expand Down

[8]ページ先頭

©2009-2025 Movatter.jp