| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 1b6d6e6 commit d0988c2
5 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,13 @@ | |||
| 1 | + 1. On MacOS X, create the following directory structure: | ||
| 2 | + | ||
| 3 | + /PythonNET/src/monoclr | ||
| 4 | + | ||
| 5 | + 2. Copy the Makefile and setup.py to /PythonNET | ||
| 6 | + | ||
| 7 | + 3. Copy the C/C++ code and header files to /PythonNET/src/monoclr | ||
| 8 | + | ||
| 9 | + 4. In a terminal window, run: | ||
| 10 | + | ||
| 11 | + $ python setup.py build | ||
| 12 | + | ||
| 13 | + 5. This creates the clr.so | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -87,7 +87,55 @@ internal static MethodInfo MatchParameters(MethodInfo[] mi,Type[] tp) { | |||
| 87 | 87 | } | |
| 88 | 88 | return null; | |
| 89 | 89 | } | |
| 90 | - | ||
| 90 | + | ||
| 91 | + | ||
| 92 | + //==================================================================== | ||
| 93 | + // Given a sequence of MethodInfo and two sequences of type parameters, | ||
| 94 | + // return the MethodInfo that matches the signature and the closed generic. | ||
| 95 | + //==================================================================== | ||
| 96 | + | ||
| 97 | + internal static MethodInfo MatchSignatureAndParameters(MethodInfo[] mi, Type[] genericTp, Type[] sigTp) | ||
| 98 | + { | ||
| 99 | + int genericCount = genericTp.Length; | ||
| 100 | + int signatureCount = sigTp.Length; | ||
| 101 | + for (int i = 0; i < mi.Length; i++) | ||
| 102 | + { | ||
| 103 | + if (!mi[i].IsGenericMethodDefinition) | ||
| 104 | + { | ||
| 105 | + continue; | ||
| 106 | + } | ||
| 107 | + Type[] genericArgs = mi[i].GetGenericArguments(); | ||
| 108 | + if (genericArgs.Length != genericCount) | ||
| 109 | + { | ||
| 110 | + continue; | ||
| 111 | + } | ||
| 112 | + ParameterInfo[] pi = mi[i].GetParameters(); | ||
| 113 | + if (pi.Length != signatureCount) | ||
| 114 | + { | ||
| 115 | + continue; | ||
| 116 | + } | ||
| 117 | + for (int n = 0; n < pi.Length; n++) | ||
| 118 | + { | ||
| 119 | + if (sigTp[n] != pi[n].ParameterType) | ||
| 120 | + { | ||
| 121 | + break; | ||
| 122 | + } | ||
| 123 | + if (n == (pi.Length - 1)) | ||
| 124 | + { | ||
| 125 | + MethodInfo match = mi[i]; | ||
| 126 | + if (match.IsGenericMethodDefinition) | ||
| 127 | + { | ||
| 128 | + Type[] typeArgs = match.GetGenericArguments(); | ||
| 129 | + return match.MakeGenericMethod(genericTp); | ||
| 130 | + } | ||
| 131 | + return match; | ||
| 132 | + } | ||
| 133 | + } | ||
| 134 | + } | ||
| 135 | + return null; | ||
| 136 | + } | ||
| 137 | + | ||
| 138 | + | ||
| 91 | 139 | //==================================================================== | |
| 92 | 140 | // Return the array of MethodInfo for this method. The result array | |
| 93 | 141 | // is arranged in order of precendence (done lazily to avoid doing it | |
@@ -264,7 +312,7 @@ internal Binding Bind(IntPtr inst, IntPtr args, IntPtr kw, | |||
| 264 | 312 | MethodInfo mi = MethodBinder.MatchParameters(methodinfo, types); | |
| 265 | 313 | return Bind(inst, args, kw, mi, null); | |
| 266 | 314 | } | |
| 267 | - return null; | ||
| 315 | + return null; | ||
| 268 | 316 | } | |
| 269 | 317 | ||
| 270 | 318 | internal virtual IntPtr Invoke(IntPtr inst, IntPtr args, IntPtr kw) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -90,31 +90,48 @@ public static IntPtr tp_getattro(IntPtr ob, IntPtr key) { | |||
| 90 | 90 | //==================================================================== | |
| 91 | 91 | ||
| 92 | 92 | public static IntPtr tp_call(IntPtr ob, IntPtr args, IntPtr kw) { | |
| 93 | - MethodBinding self = (MethodBinding)GetManagedObject(ob); | ||
| 94 | - | ||
| 95 | - // This supports calling a method 'unbound', passing the instance | ||
| 96 | - // as the first argument. Note that this is not supported if any | ||
| 97 | - // of the overloads are static since we can't know if the intent | ||
| 98 | - // was to call the static method or the unbound instance method. | ||
| 99 | - | ||
| 100 | - if ((self.target == IntPtr.Zero) && (!self.m.IsStatic())) { | ||
| 101 | - if (Runtime.PyTuple_Size(args) < 1) { | ||
| 102 | - Exceptions.SetError(Exceptions.TypeError, | ||
| 103 | - "not enough arguments" | ||
| 104 | - ); | ||
| 105 | - return IntPtr.Zero; | ||
| 106 | - } | ||
| 107 | - int len = Runtime.PyTuple_Size(args); | ||
| 108 | - IntPtr uargs = Runtime.PyTuple_GetSlice(args, 1, len); | ||
| 109 | - IntPtr inst = Runtime.PyTuple_GetItem(args, 0); | ||
| 110 | - Runtime.Incref(inst); | ||
| 111 | - IntPtr r = self.m.Invoke(inst, uargs, kw, self.info); | ||
| 112 | - Runtime.Decref(inst); | ||
| 113 | - Runtime.Decref(uargs); | ||
| 114 | - return r; | ||
| 115 | - } | ||
| 116 | - | ||
| 117 | - return self.m.Invoke(self.target, args, kw, self.info); | ||
| 93 | + MethodBinding self = (MethodBinding)GetManagedObject(ob); | ||
| 94 | + | ||
| 95 | + // This works around a situation where the wrong generic method is picked, | ||
| 96 | + // for example this method in the tests: string Overloaded<T>(int arg1, int arg2, string arg3) | ||
| 97 | + if (self.info != null) | ||
| 98 | + { | ||
| 99 | + if (self.info.IsGenericMethod) | ||
| 100 | + { | ||
| 101 | + int len = Runtime.PyTuple_Size(args); | ||
| 102 | + Type[] sigTp = Runtime.PythonArgsToTypeArray(args, true); | ||
| 103 | + if (sigTp != null) | ||
| 104 | + { | ||
| 105 | + Type[] genericTp = self.info.GetGenericArguments(); | ||
| 106 | + MethodInfo betterMatch = MethodBinder.MatchSignatureAndParameters(self.m.info, genericTp, sigTp); | ||
| 107 | + if (betterMatch != null) self.info = betterMatch; | ||
| 108 | + } | ||
| 109 | + } | ||
| 110 | + } | ||
| 111 | + | ||
| 112 | + // This supports calling a method 'unbound', passing the instance | ||
| 113 | + // as the first argument. Note that this is not supported if any | ||
| 114 | + // of the overloads are static since we can't know if the intent | ||
| 115 | + // was to call the static method or the unbound instance method. | ||
| 116 | + | ||
| 117 | + if ((self.target == IntPtr.Zero) && (!self.m.IsStatic())) | ||
| 118 | + { | ||
| 119 | + int len = Runtime.PyTuple_Size(args); | ||
| 120 | + if (len < 1) | ||
| 121 | + { | ||
| 122 | + Exceptions.SetError(Exceptions.TypeError, "not enough arguments"); | ||
| 123 | + return IntPtr.Zero; | ||
| 124 | + } | ||
| 125 | + IntPtr uargs = Runtime.PyTuple_GetSlice(args, 1, len); | ||
| 126 | + IntPtr inst = Runtime.PyTuple_GetItem(args, 0); | ||
| 127 | + Runtime.Incref(inst); | ||
| 128 | + IntPtr r = self.m.Invoke(inst, uargs, kw, self.info); | ||
| 129 | + Runtime.Decref(inst); | ||
| 130 | + Runtime.Decref(uargs); | ||
| 131 | + return r; | ||
| 132 | + } | ||
| 133 | + | ||
| 134 | + return self.m.Invoke(self.target, args, kw, self.info); | ||
| 118 | 135 | } | |
| 119 | 136 | ||
| 120 | 137 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -88,6 +88,10 @@ public U Overloaded<Q, U>(Q arg1, U arg2) { | |||
| 88 | 88 | return arg2; | |
| 89 | 89 | } | |
| 90 | 90 | ||
| 91 | + public string Overloaded<T>(int arg1, int arg2, string arg3) { | ||
| 92 | + return arg3; | ||
| 93 | + } | ||
| 94 | + | ||
| 91 | 95 | } | |
| 92 | 96 | ||
| 93 | 97 | public class GenericStaticMethodTest<T> { | |
@@ -110,6 +114,10 @@ public static U Overloaded<Q, U>(Q arg1, U arg2) { | |||
| 110 | 114 | return arg2; | |
| 111 | 115 | } | |
| 112 | 116 | ||
| 117 | + public static string Overloaded<T>(int arg1, int arg2, string arg3) { | ||
| 118 | + return arg3; | ||
| 119 | + } | ||
| 120 | + | ||
| 113 | 121 | } | |
| 114 | 122 | ||
| 115 | 123 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -378,8 +378,8 @@ def testGenericMethodOverloadSelection(self): | |||
| 378 | 378 | self.failUnless(value == True) | |
| 379 | 379 | ||
| 380 | 380 | # public static U Overloaded<Q, U>(Q arg1, U arg2) | |
| 381 | - #value = type.Overloaded[bool, str](True, "true") | ||
| 382 | - #self.failUnless(value == "true") | ||
| 381 | + value = type.Overloaded[bool, str](True, "true") | ||
| 382 | + self.failUnless(value == "true") | ||
| 383 | 383 | ||
| 384 | 384 | # public U Overloaded<Q, U>(Q arg1, U arg2) | |
| 385 | 385 | value = inst.Overloaded[bool, str](True, "true") | |
@@ -393,6 +393,14 @@ def testGenericMethodOverloadSelection(self): | |||
| 393 | 393 | value = inst.Overloaded[str, bool]("true", True) | |
| 394 | 394 | self.failUnless(value == True) | |
| 395 | 395 | ||
| 396 | + # public static string Overloaded<T>(int arg1, int arg2, string arg3) | ||
| 397 | + value = type.Overloaded[str](123, 456, "success") | ||
| 398 | + self.failUnless(value == "success") | ||
| 399 | + | ||
| 400 | + # public string Overloaded<T>(int arg1, int arg2, string arg3) | ||
| 401 | + value = inst.Overloaded[str](123, 456, "success") | ||
| 402 | + self.failUnless(value == "success") | ||
| 403 | + | ||
| 396 | 404 | def test(): | |
| 397 | 405 | value = type.Overloaded[str, bool, int]("true", True, 1) | |
| 398 | 406 | self.failUnlessRaises(TypeError, test) | |
@@ -735,3 +743,4 @@ def main(): | |||
| 735 | 743 | if __name__ == '__main__': | |
| 736 | 744 | main() | |
| 737 | 745 | ||
| 746 | + | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments