Skip to content

Commit ac992c8

Browse files
committed
checkpoint
1 parent fa8629e commit ac992c8

File tree

9 files changed

+510
-196
lines changed

9 files changed

+510
-196
lines changed

pythonnet/src/runtime/classobject.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,8 @@ public override IntPtr type_subscript(IntPtr idx) {
145145
if (t == null) {
146146
return Exceptions.RaiseTypeError("type expected");
147147
}
148-
Array a = Array.CreateInstance(t, 0);
149-
ClassBase o = ClassManager.GetClass(a.GetType());
148+
Type a = t.MakeArrayType();
149+
ClassBase o = ClassManager.GetClass(a);
150150
Runtime.Incref(o.pyHandle);
151151
return o.pyHandle;
152152
}

pythonnet/src/runtime/methodbinder.cs

Lines changed: 0 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -113,62 +113,6 @@ internal static int ArgPrecedence(Type t) {
113113
return 2000;
114114
}
115115

116-
117-
internal static MethodInfo MatchByTypeSig(MethodInfo[] msig,
118-
IntPtr psig) {
119-
IntPtr args = psig;
120-
bool free = false;
121-
122-
if (!Runtime.PyTuple_Check(psig)) {
123-
args = Runtime.PyTuple_New(1);
124-
Runtime.Incref(psig);
125-
Runtime.PyTuple_SetItem(args, 0, psig);
126-
free = true;
127-
}
128-
129-
int plen = Runtime.PyTuple_Size(args);
130-
MethodInfo match = null;
131-
132-
// XXX: what about out args, etc.?
133-
134-
for (int i = 0; i < msig.Length; i++) {
135-
ParameterInfo[] pi = msig[i].GetParameters();
136-
if (pi.Length != plen) {
137-
continue;
138-
}
139-
bool matched = true;
140-
for (int n = 0; n < pi.Length; n++) {
141-
IntPtr p = Runtime.PyTuple_GetItem(args, n);
142-
if (p == IntPtr.Zero) {
143-
Exceptions.Clear();
144-
break;
145-
}
146-
ClassBase c = ManagedType.GetManagedObject(p) as ClassBase;
147-
Type t = (c != null) ? c.type :
148-
Converter.GetTypeByAlias(p);
149-
150-
if (t == null) {
151-
break;
152-
}
153-
if (t != pi[n].ParameterType) {
154-
matched = false;
155-
break;
156-
}
157-
}
158-
if (matched) {
159-
match = msig[i];
160-
break;
161-
}
162-
}
163-
164-
if (free) {
165-
Runtime.Decref(args);
166-
}
167-
168-
return match;
169-
}
170-
171-
172116
//====================================================================
173117
// Bind the given Python instance and arguments to a particular method
174118
// overload and return a structure that contains the converted Python

pythonnet/src/runtime/methodbinding.cs

Lines changed: 61 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,21 +31,76 @@ public MethodBinding(MethodObject m, IntPtr target) : base() {
3131
this.m = m;
3232
}
3333

34+
//====================================================================
35+
// Given a sequence of MethodInfo and a sequence of types, return the
36+
// MethodInfo that matches the signature represented by those types.
37+
//====================================================================
38+
39+
internal static MethodInfo MatchSignature(MethodInfo[] mi, Type[] tp) {
40+
int count = tp.Length;
41+
for (int i = 0; i < mi.Length; i++) {
42+
ParameterInfo[] pi = mi[i].GetParameters();
43+
if (pi.Length != count) {
44+
continue;
45+
}
46+
for (int n = 0; n < pi.Length; n++) {
47+
if (tp[n]!= pi[n].ParameterType) {
48+
break;
49+
}
50+
if (n == (pi.Length - 1)) {
51+
return mi[i];
52+
}
53+
}
54+
}
55+
return null;
56+
}
57+
58+
//====================================================================
59+
// Given a sequence of MethodInfo and a sequence of type parameters,
60+
// return the MethodInfo that represents the matching closed generic.
61+
//====================================================================
3462

63+
internal static MethodInfo MatchParameters(MethodInfo[] mi,Type[] tp) {
64+
int count = tp.Length;
65+
for (int i = 0; i < mi.Length; i++) {
66+
if (!mi[i].IsGenericMethodDefinition) {
67+
continue;
68+
}
69+
Type[] args = mi[0].GetGenericArguments();
70+
if (args.Length != count) {
71+
continue;
72+
}
73+
return mi[i].MakeGenericMethod(tp);
74+
}
75+
return null;
76+
}
77+
3578
//====================================================================
3679
// Implement explicit overload selection using subscript syntax ([]).
3780
//====================================================================
3881

3982
public static IntPtr mp_subscript(IntPtr tp, IntPtr idx) {
4083
MethodBinding self = (MethodBinding)GetManagedObject(tp);
41-
MethodInfo sig = MethodBinder.MatchByTypeSig(self.m.info, idx);
42-
if (sig == null) {
43-
return Exceptions.RaiseTypeError(
44-
"No match found for signature"
45-
);
84+
85+
// Note: if the type provides a non-generic method with N args
86+
// and a generic method that takes N params, then we always
87+
// prefer the non-generic version in doing overload selection.
88+
89+
Type[] types = Runtime.PythonArgsToTypeArray(idx);
90+
if (types == null) {
91+
return Exceptions.RaiseTypeError("type(s) expected");
92+
}
93+
94+
MethodInfo mi = MatchSignature(self.m.info, types);
95+
if (mi == null) {
96+
mi = MatchParameters(self.m.info, types);
97+
if (mi == null) {
98+
return Exceptions.RaiseTypeError("No match found");
99+
}
46100
}
101+
47102
MethodBinding mb = new MethodBinding(self.m, self.target);
48-
mb.info = sig;
103+
mb.info = mi;
49104
Runtime.Incref(mb.pyHandle);
50105
return mb.pyHandle;
51106
}
@@ -137,7 +192,6 @@ public static IntPtr tp_hash(IntPtr ob) {
137192
return new IntPtr(x);
138193
}
139194

140-
141195
//====================================================================
142196
// MethodBinding __repr__ implementation.
143197
//====================================================================

pythonnet/src/runtime/methodobject.cs

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@ internal bool IsStatic() {
8888
return this.is_static;
8989
}
9090

91-
9291
//====================================================================
9392
// Descriptor __getattribute__ implementation.
9493
//====================================================================
@@ -110,7 +109,6 @@ public static IntPtr tp_getattro(IntPtr ob, IntPtr key) {
110109
return Runtime.PyObject_GenericGetAttr(ob, key);
111110
}
112111

113-
114112
//====================================================================
115113
// Descriptor __get__ implementation. Accessing a CLR method returns
116114
// a "bound" method similar to a Python bound method.
@@ -141,15 +139,6 @@ public static IntPtr tp_descr_get(IntPtr ds, IntPtr ob, IntPtr tp) {
141139
return binding.pyHandle;
142140
}
143141

144-
//====================================================================
145-
// Implement [] semantics to select overload based on type signature.
146-
//====================================================================
147-
148-
public static IntPtr mp_subscript(IntPtr op, IntPtr idx) {
149-
MethodObject self = GetManagedObject(op) as MethodObject;
150-
return Exceptions.RaiseTypeError("not implemented");
151-
}
152-
153142
//====================================================================
154143
// Descriptor __repr__ implementation.
155144
//====================================================================

pythonnet/src/runtime/runtime.cs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -226,8 +226,21 @@ internal static Type[] PythonArgsToTypeArray(IntPtr arg) {
226226

227227
for (int i = 0; i < n; i++) {
228228
IntPtr op = Runtime.PyTuple_GetItem(args, i);
229-
ClassBase cb = ManagedType.GetManagedObject(op) as ClassBase;
230-
t = (cb != null) ? cb.type : Converter.GetTypeByAlias(op);
229+
ManagedType mt = ManagedType.GetManagedObject(op);
230+
231+
if (mt is ClassBase) {
232+
t = ((ClassBase)mt).type;
233+
}
234+
else if (mt is CLRObject) {
235+
object inst = ((CLRObject)mt).inst;
236+
if (inst is Type) {
237+
t = inst as Type;
238+
}
239+
}
240+
else {
241+
t = Converter.GetTypeByAlias(op);
242+
}
243+
231244
if (t == null) {
232245
types = null;
233246
break;

pythonnet/src/testing/generictest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public int OverloadedMethod() {
7777
}
7878

7979
public int OverloadedMethod(int arg) {
80-
return arg;
80+
return arg * 2;
8181
}
8282

8383
public T OverloadedMethod(T arg) {

0 commit comments

Comments
 (0)