@@ -350,9 +350,20 @@ internal Binding Bind(IntPtr inst, IntPtr args, IntPtr kw, MethodBase info, Meth
350
350
var outs = 0 ;
351
351
int clrnargs = pi . Length ;
352
352
isOperator = isOperator && pynargs == clrnargs - 1 ; // Handle mismatched arg numbers due to Python operator being bound.
353
+ // Preprocessing pi to remove either the first or second argument.
354
+ bool isForward = isOperator && OperatorMethod . IsForward ( ( MethodInfo ) mi ) ; // Only cast if isOperator.
355
+ if ( isOperator && isForward ) {
356
+ // The first Python arg is the right operand, while the bound instance is the left.
357
+ // We need to skip the first (left operand) CLR argument.
358
+ pi = pi . Skip ( 1 ) . Take ( 1 ) . ToArray ( ) ;
359
+ }
360
+ else if ( isOperator && ! isForward ) {
361
+ // The first Python arg is the left operand.
362
+ // We need to take the first CLR argument.
363
+ pi = pi . Take ( 1 ) . ToArray ( ) ;
364
+ }
353
365
var margs = TryConvertArguments ( pi , paramsArray , args , pynargs , kwargDict , defaultArgList ,
354
366
needsResolution : _methods . Length > 1 , // If there's more than one possible match.
355
- isOperator : isOperator ,
356
367
outs : out outs ) ;
357
368
if ( margs == null )
358
369
{
@@ -364,7 +375,15 @@ internal Binding Bind(IntPtr inst, IntPtr args, IntPtr kw, MethodBase info, Meth
364
375
{
365
376
if ( ManagedType . GetManagedObject ( inst ) is CLRObject co )
366
377
{
367
- margs [ 0 ] = co . inst ;
378
+ // Postprocessing to extend margs.
379
+ var margsTemp = new object [ 2 ] ;
380
+ // If forward, the bound instance is the left operand.
381
+ int boundOperandIndex = isForward ? 0 : 1 ;
382
+ // If forward, the passed instance is the right operand.
383
+ int passedOperandIndex = isForward ? 1 : 0 ;
384
+ margsTemp [ boundOperandIndex ] = co . inst ;
385
+ margsTemp [ passedOperandIndex ] = margs [ 0 ] ;
386
+ margs = margsTemp ;
368
387
}
369
388
else { break ; }
370
389
}
@@ -488,15 +507,13 @@ static IntPtr HandleParamsArray(IntPtr args, int arrayStart, int pyArgCount, out
488
507
/// <param name="kwargDict">Dictionary of keyword argument name to python object pointer</param>
489
508
/// <param name="defaultArgList">A list of default values for omitted parameters</param>
490
509
/// <param name="needsResolution"><c>true</c>, if overloading resolution is required</param>
491
- /// <param name="isOperator"><c>true</c>, if is operator method</param>
492
510
/// <param name="outs">Returns number of output parameters</param>
493
511
/// <returns>An array of .NET arguments, that can be passed to a method.</returns>
494
512
static object [ ] TryConvertArguments ( ParameterInfo [ ] pi , bool paramsArray ,
495
513
IntPtr args , int pyArgCount ,
496
514
Dictionary < string , IntPtr > kwargDict ,
497
515
ArrayList defaultArgList ,
498
516
bool needsResolution ,
499
- bool isOperator ,
500
517
out int outs )
501
518
{
502
519
outs = 0 ;
@@ -535,13 +552,6 @@ static object[] TryConvertArguments(ParameterInfo[] pi, bool paramsArray,
535
552
op = Runtime . PyTuple_GetItem ( args , paramIndex ) ;
536
553
}
537
554
}
538
- if ( isOperator && paramIndex == 0 )
539
- {
540
- // After we've obtained the first argument from Python, we need to skip the first argument of the CLR
541
- // because operator method is a bound method in Python
542
- paramIndex ++ ; // Leave the first .NET param as null (margs).
543
- parameter = pi [ paramIndex ] ;
544
- }
545
555
546
556
bool isOut ;
547
557
if ( ! TryConvertArgument ( op , parameter . ParameterType , needsResolution , out margs [ paramIndex ] , out isOut ) )
0 commit comments