|
1 | 1 | using System;
|
2 | 2 | using System.Collections;
|
3 | 3 | using System.Collections.Generic;
|
| 4 | +using System.Linq; |
4 | 5 | using System.Reflection;
|
5 | 6 | using System.Text;
|
6 | 7 |
|
@@ -325,6 +326,28 @@ internal Binding Bind(IntPtr inst, IntPtr args, IntPtr kw, MethodBase info, Meth
|
325 | 326 | {
|
326 | 327 | isGeneric = true;
|
327 | 328 | }
|
| 329 | + |
| 330 | + bool isOperator = OperatorMethod.IsOperatorMethod(mi); |
| 331 | + // Binary operator methods will have 2 CLR args but only one Python arg |
| 332 | + // (unary operators will have 1 less each), since Python operator methods are bound. |
| 333 | + isOperator = isOperator && pynargs == pi.Length - 1; |
| 334 | + bool isReverse = isOperator && OperatorMethod.IsReverse((MethodInfo)mi); // Only cast if isOperator. |
| 335 | + if (isReverse && OperatorMethod.IsComparisonOp((MethodInfo)mi)) |
| 336 | + continue; // Comparison operators in Python have no reverse mode. |
| 337 | + // Preprocessing pi to remove either the first or second argument. |
| 338 | + if (isOperator && !isReverse) |
| 339 | + { |
| 340 | + // The first Python arg is the right operand, while the bound instance is the left. |
| 341 | + // We need to skip the first (left operand) CLR argument. |
| 342 | + pi = pi.Skip(1).ToArray(); |
| 343 | + } |
| 344 | + else if (isOperator && isReverse) |
| 345 | + { |
| 346 | + // The first Python arg is the left operand. |
| 347 | + // We need to take the first CLR argument. |
| 348 | + pi = pi.Take(1).ToArray(); |
| 349 | + } |
| 350 | + |
328 | 351 | int clrnargs = pi.Length;
|
329 | 352 | int arrayStart;
|
330 | 353 |
|
@@ -564,6 +587,30 @@ static object[] TryConvertArguments(ParameterInfo[] pi, bool paramsArray,
|
564 | 587 | continue;
|
565 | 588 | }
|
566 | 589 |
|
| 590 | + if (isOperator) |
| 591 | + { |
| 592 | + if (inst != IntPtr.Zero) |
| 593 | + { |
| 594 | + if (ManagedType.GetManagedObject(inst) is CLRObject co) |
| 595 | + { |
| 596 | + bool isUnary = pynargs == 0; |
| 597 | + // Postprocessing to extend margs. |
| 598 | + var margsTemp = isUnary ? new object[1] : new object[2]; |
| 599 | + // If reverse, the bound instance is the right operand. |
| 600 | + int boundOperandIndex = isReverse ? 1 : 0; |
| 601 | + // If reverse, the passed instance is the left operand. |
| 602 | + int passedOperandIndex = isReverse ? 0 : 1; |
| 603 | + margsTemp[boundOperandIndex] = co.inst; |
| 604 | + if (!isUnary) |
| 605 | + { |
| 606 | + margsTemp[passedOperandIndex] = margs[0]; |
| 607 | + } |
| 608 | + margs = margsTemp; |
| 609 | + } |
| 610 | + else continue; |
| 611 | + } |
| 612 | + } |
| 613 | + |
567 | 614 | object target = null;
|
568 | 615 | if (!mi.IsStatic && inst != IntPtr.Zero)
|
569 | 616 | {
|
|
0 commit comments