Skip to content

Commit c11c50a

Browse files
committed
commit method overload selection
1 parent 9f06a5e commit c11c50a

8 files changed

Lines changed: 73 additions & 15 deletions

File tree

pythonnet/src/runtime/constructorbinder.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,12 @@ internal ConstructorBinder () : base() {}
3333
// Python type to use when wrapping the result (may be a subclass).
3434
//====================================================================
3535

36-
internal object InvokeRaw(IntPtr inst, IntPtr args, IntPtr kw) {
36+
internal object InvokeRaw(IntPtr inst, IntPtr args, IntPtr kw) {
37+
return this.InvokeRaw(inst, args, kw, null);
38+
}
39+
40+
internal object InvokeRaw(IntPtr inst, IntPtr args, IntPtr kw,
41+
MethodBase info) {
3742
Binding binding = this.Bind(inst, args, kw);
3843
Object result;
3944

pythonnet/src/runtime/converter.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,6 @@ internal static bool ToManaged(IntPtr value, Type type,
204204

205205
internal static bool ToManagedValue(IntPtr value, Type obType,
206206
out Object result, bool setError) {
207-
208207
// Common case: if the Python value is a wrapped managed object
209208
// instance, just return the wrapped object.
210209
ManagedType mt = ManagedType.GetManagedObject(value);
@@ -628,6 +627,8 @@ static bool ToArray(IntPtr value, Type obType, out Object result,
628627

629628
Array items = Array.CreateInstance(elementType, size);
630629

630+
// XXX - is there a better way to unwrap this if it is a real
631+
// array?
631632
for (int i = 0; i < size; i++) {
632633
Object obj = null;
633634
IntPtr item = Runtime.PySequence_GetItem(value, i);

pythonnet/src/runtime/managedtype.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,19 @@ internal static ManagedType GetManagedObject(IntPtr ob) {
4646
GCHandle gc = (GCHandle)op;
4747
return (ManagedType)gc.Target;
4848
}
49+
50+
51+
// // Hmm - check to see if its a wrapped exception?
52+
// if (Runtime.wrap_exceptions) {
53+
// IntPtr p = Runtime.PyObject_GetAttrString(ob, "_inner");
54+
// if (p != IntPtr.Zero) {
55+
// ManagedType m = GetManagedObject(p);
56+
// Runtime.Decref(p);
57+
// if (m != null)
58+
// return m;
59+
// }
60+
// }
61+
4962
}
5063
return null;
5164
}

pythonnet/src/runtime/methodbinder.cs

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ internal static MethodInfo MatchByTypeSig(MethodInfo[] msig,
136136
if (pi.Length != plen) {
137137
continue;
138138
}
139+
bool matched = true;
139140
for (int n = 0; n < pi.Length; n++) {
140141
IntPtr p = Runtime.PyTuple_GetItem(args, n);
141142
if (p == IntPtr.Zero) {
@@ -145,15 +146,19 @@ internal static MethodInfo MatchByTypeSig(MethodInfo[] msig,
145146
ClassBase c = ManagedType.GetManagedObject(p) as ClassBase;
146147
Type t = (c != null) ? c.type :
147148
Converter.GetTypeByAlias(p);
149+
148150
if (t == null) {
149151
break;
150152
}
151153
if (t != pi[n].ParameterType) {
154+
matched = false;
152155
break;
153156
}
154157
}
155-
match = msig[i];
156-
break;
158+
if (matched) {
159+
match = msig[i];
160+
break;
161+
}
157162
}
158163

159164
if (free) {
@@ -171,12 +176,26 @@ internal static MethodInfo MatchByTypeSig(MethodInfo[] msig,
171176
//====================================================================
172177

173178
internal Binding Bind(IntPtr inst, IntPtr args, IntPtr kw) {
179+
return this.Bind(inst, args, kw, null);
180+
}
181+
182+
internal Binding Bind(IntPtr inst, IntPtr args, IntPtr kw,
183+
MethodBase info) {
174184
// loop to find match, return invoker w/ or /wo error
185+
MethodBase[] _methods = null;
175186
int nargs = Runtime.PyTuple_Size(args);
176187
object arg;
177188

178-
MethodBase[] _methods = GetMethods();
179-
189+
if (info != null) {
190+
_methods = (MethodBase[])Array.CreateInstance(
191+
typeof(MethodBase), 1
192+
);
193+
_methods.SetValue(info, 0);
194+
}
195+
else {
196+
_methods = GetMethods();
197+
}
198+
180199
for (int i = 0; i < _methods.Length; i++) {
181200
MethodBase mi = _methods[i];
182201
ParameterInfo[] pi = mi.GetParameters();
@@ -220,9 +239,14 @@ internal Binding Bind(IntPtr inst, IntPtr args, IntPtr kw) {
220239
return null;
221240
}
222241

223-
224242
internal virtual IntPtr Invoke(IntPtr inst, IntPtr args, IntPtr kw) {
225-
Binding binding = this.Bind(inst, args, kw);
243+
return this.Invoke(inst, args, kw, null);
244+
245+
}
246+
247+
internal virtual IntPtr Invoke(IntPtr inst, IntPtr args, IntPtr kw,
248+
MethodBase info) {
249+
Binding binding = this.Bind(inst, args, kw, info);
226250
Object result;
227251

228252
if (binding == null) {

pythonnet/src/runtime/methodbinding.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,12 +97,13 @@ public static IntPtr tp_call(IntPtr ob, IntPtr args, IntPtr kw) {
9797
IntPtr uargs = Runtime.PyTuple_GetSlice(args, 1, len);
9898
IntPtr inst = Runtime.PyTuple_GetItem(args, 0);
9999
Runtime.Incref(inst);
100-
IntPtr r = self.m.Invoke(inst, uargs, kw);
100+
IntPtr r = self.m.Invoke(inst, uargs, kw, self.info);
101101
Runtime.Decref(inst);
102+
Runtime.Decref(uargs);
102103
return r;
103104
}
104105

105-
return self.m.Invoke(self.target, args, kw);
106+
return self.m.Invoke(self.target, args, kw, self.info);
106107
}
107108

108109

pythonnet/src/runtime/methodobject.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,13 @@ public MethodObject(string name, MethodInfo[] info) : base() {
4141
}
4242

4343

44-
public virtual IntPtr Invoke(IntPtr target, IntPtr args, IntPtr kw) {
45-
return binder.Invoke(target, args, kw);
44+
public virtual IntPtr Invoke(IntPtr inst, IntPtr args, IntPtr kw) {
45+
return this.Invoke(inst, args, kw, null);
46+
}
47+
48+
public virtual IntPtr Invoke(IntPtr target, IntPtr args, IntPtr kw,
49+
MethodBase info) {
50+
return binder.Invoke(target, args, kw, info);
4651
}
4752

4853

pythonnet/src/testing/methodtest.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,10 @@ public static string TestOverloadSelection(string v) {
185185
return v;
186186
}
187187

188+
public static ShortEnum TestOverloadSelection(ShortEnum v) {
189+
return v;
190+
}
191+
188192
public static object TestOverloadSelection(object v) {
189193
return v;
190194
}
@@ -253,6 +257,10 @@ public static string[] TestOverloadSelection(string[] v) {
253257
return v;
254258
}
255259

260+
public static ShortEnum[] TestOverloadSelection(ShortEnum[] v) {
261+
return v;
262+
}
263+
256264
public static object[] TestOverloadSelection(object[] v) {
257265
return v;
258266
}

pythonnet/src/tests/test_method.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,7 @@ def test():
391391
def testExplicitOverloadSelection(self):
392392
"""Check explicit overload selection using [] syntax."""
393393
from Python.Test import ISayHello1, InterfaceTest, ShortEnum
394+
from System import Array
394395
inst = InterfaceTest()
395396

396397
value = MethodTest.TestOverloadSelection[System.Boolean](True)
@@ -479,7 +480,7 @@ def testExplicitOverloadSelection(self):
479480

480481
atype = Array[System.Object]
481482
value = MethodTest.TestOverloadSelection[str, int, atype](
482-
"one", 1, atype(1, 2, 3)
483+
"one", 1, atype([1, 2, 3])
483484
)
484485
self.failUnless(value == 3)
485486

@@ -512,7 +513,7 @@ def testOverloadSelectionWithArrayTypes(self):
512513
input = vtype([0, 255])
513514
value = MethodTest.TestOverloadSelection[vtype](input)
514515
self.failUnless(value[0] == 0)
515-
self.failUnless(value[0] == 255)
516+
self.failUnless(value[1] == 255)
516517

517518
vtype = Array[System.SByte]
518519
input = vtype([0, 127])
@@ -887,7 +888,7 @@ def test():
887888
self.failUnlessRaises(TypeError, test)
888889

889890
def test():
890-
value = MethodTest.TestOverloadSelection[int](1)
891+
value = MethodTest.TestOverloadSelection[int, long](1)
891892

892893
self.failUnlessRaises(TypeError, test)
893894

0 commit comments

Comments
 (0)