Skip to content

Commit 3438982

Browse files
committed
Add operator overload and rename pynargs, clrnargs
1 parent 2055cbd commit 3438982

File tree

2 files changed

+43
-14
lines changed

2 files changed

+43
-14
lines changed

src/embed_tests/TestOperator.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ public OperableObject(int num)
3737
Num = num;
3838
}
3939

40+
public static OperableObject operator +(int a, OperableObject b)
41+
{
42+
return new OperableObject(a + b.Num);
43+
}
4044
public static OperableObject operator +(OperableObject a, OperableObject b)
4145
{
4246
return new OperableObject(a.Num + b.Num);
@@ -46,6 +50,10 @@ public OperableObject(int num)
4650
return new OperableObject(a.Num + b);
4751
}
4852

53+
public static OperableObject operator -(int a, OperableObject b)
54+
{
55+
return new OperableObject(a - b.Num);
56+
}
4957
public static OperableObject operator -(OperableObject a, OperableObject b)
5058
{
5159
return new OperableObject(a.Num - b.Num);
@@ -55,6 +63,11 @@ public OperableObject(int num)
5563
return new OperableObject(a.Num - b);
5664
}
5765

66+
67+
public static OperableObject operator *(int a, OperableObject b)
68+
{
69+
return new OperableObject(a * b.Num);
70+
}
5871
public static OperableObject operator *(OperableObject a, OperableObject b)
5972
{
6073
return new OperableObject(a.Num * b.Num);
@@ -64,6 +77,10 @@ public OperableObject(int num)
6477
return new OperableObject(a.Num * b);
6578
}
6679

80+
public static OperableObject operator /(int a, OperableObject b)
81+
{
82+
return new OperableObject(a / b.Num);
83+
}
6784
public static OperableObject operator /(OperableObject a, OperableObject b)
6885
{
6986
return new OperableObject(a.Num / b.Num);
@@ -74,6 +91,10 @@ public OperableObject(int num)
7491
}
7592

7693

94+
public static OperableObject operator &(int a, OperableObject b)
95+
{
96+
return new OperableObject(a & b.Num);
97+
}
7798
public static OperableObject operator &(OperableObject a, OperableObject b)
7899
{
79100
return new OperableObject(a.Num & b.Num);
@@ -84,6 +105,10 @@ public OperableObject(int num)
84105
}
85106

86107

108+
public static OperableObject operator |(int a, OperableObject b)
109+
{
110+
return new OperableObject(a | b.Num);
111+
}
87112
public static OperableObject operator |(OperableObject a, OperableObject b)
88113
{
89114
return new OperableObject(a.Num | b.Num);
@@ -94,6 +119,10 @@ public OperableObject(int num)
94119
}
95120

96121

122+
public static OperableObject operator ^(int a, OperableObject b)
123+
{
124+
return new OperableObject(a ^ b.Num);
125+
}
97126
public static OperableObject operator ^(OperableObject a, OperableObject b)
98127
{
99128
return new OperableObject(a.Num ^ b.Num);

src/runtime/methodbinder.cs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ internal Binding Bind(IntPtr inst, IntPtr args, IntPtr kw, MethodBase info, Meth
316316
Runtime.XDecref(valueList);
317317
}
318318

319-
var pynargs = (int)Runtime.PyTuple_Size(args);
319+
var numPyArgs = (int)Runtime.PyTuple_Size(args);
320320
var isGeneric = false;
321321
if (info != null)
322322
{
@@ -343,14 +343,14 @@ internal Binding Bind(IntPtr inst, IntPtr args, IntPtr kw, MethodBase info, Meth
343343
int kwargsMatched;
344344
int defaultsNeeded;
345345
bool isOperator = OperatorMethod.IsOperatorMethod(mi); // e.g. op_Addition is defined for OperableObject
346-
if (!MatchesArgumentCount(pynargs, pi, kwargDict, isOperator, out paramsArray, out defaultArgList, out kwargsMatched, out defaultsNeeded))
346+
if (!MatchesArgumentCount(numPyArgs, pi, kwargDict, isOperator, out paramsArray, out defaultArgList, out kwargsMatched, out defaultsNeeded))
347347
{
348348
continue;
349349
}
350350
var outs = 0;
351-
int clrnargs = pi.Length;
352-
isOperator = isOperator && pynargs == clrnargs - 1; // Handle mismatched arg numbers due to Python operator being bound.
353-
var margs = TryConvertArguments(pi, paramsArray, args, pynargs, kwargDict, defaultArgList,
351+
int numClrArgs = pi.Length;
352+
isOperator = isOperator && numPyArgs == numClrArgs - 1; // Handle mismatched arg numbers due to Python operator being bound.
353+
var margs = TryConvertArguments(pi, paramsArray, args, numPyArgs, kwargDict, defaultArgList,
354354
needsResolution: _methods.Length > 1, // If there's more than one possible match.
355355
isOperator: isOperator,
356356
outs: out outs);
@@ -669,7 +669,7 @@ static Type TryComputeClrArgumentType(Type parameterType, IntPtr argument, bool
669669
/// <summary>
670670
/// Check whether the number of Python and .NET arguments match, and compute additional arg information.
671671
/// </summary>
672-
/// <param name="pynargs">Number of positional args passed from Python.</param>
672+
/// <param name="numPyArgs">Number of positional args passed from Python.</param>
673673
/// <param name="parameters">Parameters of the specified .NET method.</param>
674674
/// <param name="kwargDict">Keyword args passed from Python.</param>
675675
/// <param name="isOperator">True if the parameters' method is an operator.</param>
@@ -678,7 +678,7 @@ static Type TryComputeClrArgumentType(Type parameterType, IntPtr argument, bool
678678
/// <param name="kwargsMatched">Number of kwargs from Python that are also present in the .NET method.</param>
679679
/// <param name="defaultsNeeded">Number of non-null defaultsArgs.</param>
680680
/// <returns></returns>
681-
static bool MatchesArgumentCount(int pynargs, ParameterInfo[] parameters,
681+
static bool MatchesArgumentCount(int numPyArgs, ParameterInfo[] parameters,
682682
Dictionary<string, IntPtr> kwargDict,
683683
bool isOperator,
684684
out bool paramsArray,
@@ -688,15 +688,15 @@ static bool MatchesArgumentCount(int pynargs, ParameterInfo[] parameters,
688688
{
689689
defaultArgList = null;
690690
var match = false;
691-
int clrnargs = parameters.Length;
692-
paramsArray = clrnargs > 0 ? Attribute.IsDefined(parameters[clrnargs - 1], typeof(ParamArrayAttribute)) : false;
691+
int numClrArgs = parameters.Length;
692+
paramsArray = numClrArgs > 0 ? Attribute.IsDefined(parameters[numClrArgs - 1], typeof(ParamArrayAttribute)) : false;
693693
kwargsMatched = 0;
694694
defaultsNeeded = 0;
695-
if (pynargs == clrnargs && kwargDict.Count == 0)
695+
if (numPyArgs == numClrArgs && kwargDict.Count == 0)
696696
{
697697
match = true;
698698
}
699-
else if (pynargs < clrnargs && (!paramsArray || pynargs == clrnargs - 1))
699+
else if (numPyArgs < numClrArgs && (!paramsArray || numPyArgs == numClrArgs - 1))
700700
{
701701
match = true;
702702
// operator methods will have 2 CLR args but only one Python arg,
@@ -711,7 +711,7 @@ static bool MatchesArgumentCount(int pynargs, ParameterInfo[] parameters,
711711
// a corresponding keyword arg or a default param, unless the method
712712
// method accepts a params array (which cannot have a default value)
713713
defaultArgList = new ArrayList();
714-
for (var v = pynargs; v < clrnargs; v++)
714+
for (var v = numPyArgs; v < numClrArgs; v++)
715715
{
716716
if (kwargDict.ContainsKey(parameters[v].Name))
717717
{
@@ -736,8 +736,8 @@ static bool MatchesArgumentCount(int pynargs, ParameterInfo[] parameters,
736736
}
737737
}
738738
}
739-
else if (pynargs > clrnargs && clrnargs > 0 &&
740-
Attribute.IsDefined(parameters[clrnargs - 1], typeof(ParamArrayAttribute)))
739+
else if (numPyArgs > numClrArgs && numClrArgs > 0 &&
740+
Attribute.IsDefined(parameters[numClrArgs - 1], typeof(ParamArrayAttribute)))
741741
{
742742
// This is a `foo(params object[] bar)` style method
743743
match = true;

0 commit comments

Comments
 (0)