@@ -94,7 +94,7 @@ public virtual NewReference type_subscript(BorrowedReference idx)
9494 public static NewReference tp_richcompare ( BorrowedReference ob , BorrowedReference other , int op )
9595 {
9696 CLRObject co1 ;
97- CLRObject ? co2 ;
97+ object co2Inst ;
9898 BorrowedReference tp = Runtime . PyObject_TYPE ( ob ) ;
9999 var cls = ( ClassBase ) GetManagedObject ( tp ) ! ;
100100 // C# operator methods take precedence over IComparable.
@@ -127,17 +127,12 @@ public static NewReference tp_richcompare(BorrowedReference ob, BorrowedReferenc
127127 return new NewReference ( pytrue ) ;
128128 }
129129
130- co1 = ( CLRObject ) GetManagedObject ( ob ) ! ;
131- co2 = GetManagedObject ( other ) as CLRObject ;
132- if ( null == co2 )
130+ if ( ! TryGetSecondCompareOperandInstance ( ob , other , out co1 , out co2Inst ) )
133131 {
134132 return new NewReference ( pyfalse ) ;
135133 }
136134
137- object o1 = co1 . inst ;
138- object o2 = co2 . inst ;
139-
140- if ( Equals ( o1 , o2 ) )
135+ if ( Equals ( co1 . inst , co2Inst ) )
141136 {
142137 return new NewReference ( pytrue ) ;
143138 }
@@ -147,12 +142,11 @@ public static NewReference tp_richcompare(BorrowedReference ob, BorrowedReferenc
147142 case Runtime . Py_LE :
148143 case Runtime . Py_GT :
149144 case Runtime . Py_GE :
150- co1 = ( CLRObject ) GetManagedObject ( ob ) ! ;
151- co2 = GetManagedObject ( other ) as CLRObject ;
152- if ( co1 == null || co2 == null )
145+ if ( ! TryGetSecondCompareOperandInstance ( ob , other , out co1 , out co2Inst ) )
153146 {
154147 return Exceptions . RaiseTypeError ( "Cannot get managed object" ) ;
155148 }
149+
156150 var co1Comp = co1 . inst as IComparable ;
157151 if ( co1Comp == null )
158152 {
@@ -161,7 +155,7 @@ public static NewReference tp_richcompare(BorrowedReference ob, BorrowedReferenc
161155 }
162156 try
163157 {
164- int cmp = co1Comp . CompareTo ( co2 . inst ) ;
158+ int cmp = co1Comp . CompareTo ( co2Inst ) ;
165159
166160 BorrowedReference pyCmp ;
167161 if ( cmp < 0 )
@@ -208,6 +202,38 @@ public static NewReference tp_richcompare(BorrowedReference ob, BorrowedReferenc
208202 }
209203 }
210204
205+ private static bool TryGetSecondCompareOperandInstance ( BorrowedReference left , BorrowedReference right , out CLRObject co1 , out object co2Inst )
206+ {
207+ co2Inst = null ;
208+
209+ co1 = ( CLRObject ) GetManagedObject ( left ) ! ;
210+ if ( co1 == null )
211+ {
212+ return false ;
213+ }
214+
215+ var co2 = GetManagedObject ( right ) as CLRObject ;
216+
217+ // The object comparing against is not a managed object. It could still be a Python object
218+ // that can be compared against (e.g. comparing against a Python string)
219+ if ( co2 == null )
220+ {
221+ if ( right != null )
222+ {
223+ using var pyCo2 = new PyObject ( right ) ;
224+ if ( Converter . ToManagedValue ( pyCo2 , typeof ( object ) , out var result , false ) )
225+ {
226+ co2Inst = result ;
227+ return true ;
228+ }
229+ }
230+ return false ;
231+ }
232+
233+ co2Inst = co2 . inst ;
234+ return true ;
235+ }
236+
211237 /// <summary>
212238 /// Standard iteration support for instances of reflected types. This
213239 /// allows natural iteration over objects that either are IEnumerable
0 commit comments