| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 3fccfd5 commit fa8629e
11 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -39,8 +39,6 @@ public static IntPtr tp_new(IntPtr tp, IntPtr args, IntPtr kw) { | |||
| 39 | 39 | return IntPtr.Zero; | |
| 40 | 40 | } | |
| 41 | 41 | return CLRObject.GetInstHandle(result, tp); | |
| 42 | - string message = "cannot instantiate array wrapper"; | ||
| 43 | - return Exceptions.RaiseTypeError(message); | ||
| 44 | 42 | } | |
| 45 | 43 | ||
| 46 | 44 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -327,6 +327,8 @@ public static bool IsValidNamespace(string name) { | |||
| 327 | 327 | ||
| 328 | 328 | public static List<string> GetNames(string nsname) { | |
| 329 | 329 | List<string> names = new List<string>(32); | |
| 330 | + Dictionary<string, int> seen = new Dictionary<string, int>(); | ||
| 331 | + | ||
| 330 | 332 | if (namespaces.ContainsKey(nsname)) { | |
| 331 | 333 | foreach (Assembly a in namespaces[nsname].Keys) { | |
| 332 | 334 | Type[] types = a.GetTypes(); | |
@@ -347,6 +349,7 @@ public static List<string> GetNames(string nsname) { | |||
| 347 | 349 | } | |
| 348 | 350 | } | |
| 349 | 351 | } | |
| 352 | + names.Sort(); // ensure that non-generics come first! | ||
| 350 | 353 | return names; | |
| 351 | 354 | } | |
| 352 | 355 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -28,6 +28,7 @@ internal class ClassBase : ManagedType { | |||
| 28 | 28 | ||
| 29 | 29 | internal bool is_exception; | |
| 30 | 30 | internal Indexer indexer; | |
| 31 | + internal Type[] generics; | ||
| 31 | 32 | internal Type type; | |
| 32 | 33 | ||
| 33 | 34 | internal ClassBase(Type tp) : base() { | |
@@ -40,8 +41,6 @@ internal virtual bool CanSubclass() { | |||
| 40 | 41 | return (!this.type.IsEnum); | |
| 41 | 42 | } | |
| 42 | 43 | ||
| 43 | - | ||
| 44 | - | ||
| 45 | 44 | //==================================================================== | |
| 46 | 45 | // Implements __init__ for reflected classes and value types. | |
| 47 | 46 | //==================================================================== | |
@@ -50,15 +49,13 @@ public static int tp_init(IntPtr ob, IntPtr args, IntPtr kw) { | |||
| 50 | 49 | return 0; | |
| 51 | 50 | } | |
| 52 | 51 | ||
| 53 | - | ||
| 54 | 52 | //==================================================================== | |
| 55 | 53 | // Default implementation of [] semantics for reflected types. | |
| 56 | 54 | //==================================================================== | |
| 57 | 55 | ||
| 58 | - public virtual IntPtr type_subscript(IntPtr ob, IntPtr idx) { | ||
| 59 | - return Exceptions.RaiseTypeError("unsubscriptable object"); | ||
| 60 | - } | ||
| 61 | - | ||
| 56 | + public virtual IntPtr type_subscript(IntPtr idx) { | ||
| 57 | + return Exceptions.RaiseTypeError("unsubscriptable object"); | ||
| 58 | + } | ||
| 62 | 59 | ||
| 63 | 60 | //==================================================================== | |
| 64 | 61 | // Standard comparison implementation for instances of reflected types. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -80,16 +80,12 @@ private static ClassBase CreateClass(Type type) { | |||
| 80 | 80 | // lets us check once (vs. on every lookup) in case we need to | |
| 81 | 81 | // wrap Exception-derived types in old-style classes | |
| 82 | 82 | ||
| 83 | - if (type.IsSubclassOf(dtype)) { | ||
| 84 | - impl = new DelegateObject(type); | ||
| 85 | - } | ||
| 86 | - | ||
| 87 | - else if (type.ContainsGenericParameters) { | ||
| 83 | + if (type.ContainsGenericParameters) { | ||
| 88 | 84 | impl = new GenericType(type); | |
| 89 | 85 | } | |
| 90 | 86 | ||
| 91 | - else if (type.IsGenericType) { | ||
| 92 | - impl = new GenericType(type); | ||
| 87 | + else if (type.IsSubclassOf(dtype)) { | ||
| 88 | + impl = new DelegateObject(type); | ||
| 93 | 89 | } | |
| 94 | 90 | ||
| 95 | 91 | else if (type.IsArray) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -22,9 +22,10 @@ namespace Python.Runtime { | |||
| 22 | 22 | internal class ClassObject : ClassBase { | |
| 23 | 23 | ||
| 24 | 24 | ConstructorBinder binder; | |
| 25 | + ConstructorInfo[] ctors; | ||
| 25 | 26 | ||
| 26 | 27 | internal ClassObject(Type tp) : base(tp) { | |
| 27 | - ConstructorInfo[] ctors = type.GetConstructors(); | ||
| 28 | + ctors = type.GetConstructors(); | ||
| 28 | 29 | binder = new ConstructorBinder(); | |
| 29 | 30 | ||
| 30 | 31 | for (int i = 0; i < ctors.Length; i++) { | |
@@ -125,28 +126,49 @@ public static IntPtr tp_new(IntPtr tp, IntPtr args, IntPtr kw) { | |||
| 125 | 126 | ||
| 126 | 127 | ||
| 127 | 128 | //==================================================================== | |
| 128 | - // Implementation of [] semantics for reflected types. This mainly | ||
| 129 | - // exists to implement the Array[int] syntax for creating arrays. | ||
| 129 | + // Implementation of [] semantics for reflected types. This exists | ||
| 130 | + // both to implement the Array[int] syntax for creating arrays and | ||
| 131 | + // to support generic name overload resolution using []. | ||
| 130 | 132 | //==================================================================== | |
| 131 | 133 | ||
| 132 | - public override IntPtr type_subscript(IntPtr ob, IntPtr idx) { | ||
| 133 | - if ((this.type) != typeof(Array)) { | ||
| 134 | - return Exceptions.RaiseTypeError("unsubscriptable object"); | ||
| 135 | - } | ||
| 136 | - | ||
| 137 | - if (Runtime.PyTuple_Check(idx)) { | ||
| 138 | - return Exceptions.RaiseTypeError("expected single type"); | ||
| 139 | - } | ||
| 140 | - | ||
| 141 | - ClassBase c = GetManagedObject(idx) as ClassBase; | ||
| 142 | - Type t = (c != null) ? c.type : Converter.GetTypeByAlias(idx); | ||
| 143 | - if (t == null) { | ||
| 144 | - return Exceptions.RaiseTypeError("type expected"); | ||
| 145 | - } | ||
| 146 | - Array a = Array.CreateInstance(t, 0); | ||
| 147 | - c = ClassManager.GetClass(a.GetType()); | ||
| 148 | - Runtime.Incref(c.pyHandle); | ||
| 149 | - return c.pyHandle; | ||
| 134 | + public override IntPtr type_subscript(IntPtr idx) { | ||
| 135 | + | ||
| 136 | + // If this type is the Array type, the [<type>] means we need to | ||
| 137 | + // construct and return an array type of the given element type. | ||
| 138 | + | ||
| 139 | + if ((this.type) == typeof(Array)) { | ||
| 140 | + if (Runtime.PyTuple_Check(idx)) { | ||
| 141 | + return Exceptions.RaiseTypeError("type expected"); | ||
| 142 | + } | ||
| 143 | + ClassBase c = GetManagedObject(idx) as ClassBase; | ||
| 144 | + Type t = (c != null) ? c.type : Converter.GetTypeByAlias(idx); | ||
| 145 | + if (t == null) { | ||
| 146 | + return Exceptions.RaiseTypeError("type expected"); | ||
| 147 | + } | ||
| 148 | + Array a = Array.CreateInstance(t, 0); | ||
| 149 | + ClassBase o = ClassManager.GetClass(a.GetType()); | ||
| 150 | + Runtime.Incref(o.pyHandle); | ||
| 151 | + return o.pyHandle; | ||
| 152 | + } | ||
| 153 | + | ||
| 154 | + // If there are generics in our namespace with the same base name | ||
| 155 | + // as the current type, then [<type>] means the caller wants to | ||
| 156 | + // bind the generic type matching the given type parameters. | ||
| 157 | + | ||
| 158 | + Type[] types = Runtime.PythonArgsToTypeArray(idx); | ||
| 159 | + if (types == null) { | ||
| 160 | + return Exceptions.RaiseTypeError("type(s) expected"); | ||
| 161 | + } | ||
| 162 | + | ||
| 163 | + string gname = this.type.FullName + "`" + types.Length.ToString(); | ||
| 164 | + Type gtype = AssemblyManager.LookupType(gname); | ||
| 165 | + if (gtype != null) { | ||
| 166 | + GenericType g = ClassManager.GetClass(gtype) as GenericType; | ||
| 167 | + return g.type_subscript(idx); | ||
| 168 | + Runtime.Incref(g.pyHandle); | ||
| 169 | + return g.pyHandle; | ||
| 170 | + } | ||
| 171 | + return Exceptions.RaiseTypeError("unsubscriptable object"); | ||
| 150 | 172 | } | |
| 151 | 173 | ||
| 152 | 174 | ||
@@ -205,7 +227,7 @@ public static int mp_ass_subscript(IntPtr ob, IntPtr idx, IntPtr v) { | |||
| 205 | 227 | ||
| 206 | 228 | if (cls.indexer == null || !cls.indexer.CanSet) { | |
| 207 | 229 | Exceptions.SetError(Exceptions.TypeError, | |
| 208 | - "object doesn't support item assignment x" | ||
| 230 | + "object doesn't support item assignment" | ||
| 209 | 231 | ); | |
| 210 | 232 | return -1; | |
| 211 | 233 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -46,58 +46,29 @@ public static IntPtr tp_call(IntPtr ob, IntPtr args, IntPtr kw) { | |||
| 46 | 46 | } | |
| 47 | 47 | ||
| 48 | 48 | //==================================================================== | |
| 49 | - // Implements __getitem__ for reflected open generic types. A closed | ||
| 49 | + // Implements subscript syntax for reflected generic types. A closed | ||
| 50 | 50 | // type is created by binding the generic type via subscript syntax: | |
| 51 | 51 | // inst = List[str]() | |
| 52 | 52 | //==================================================================== | |
| 53 | 53 | ||
| 54 | - public static IntPtr bind(IntPtr ob, IntPtr idx) { | ||
| 55 | - ClassBase cls = (ClassBase)GetManagedObject(ob) as ClassBase; | ||
| 56 | - | ||
| 57 | - // Ensure that the reflected class is a generic type definition, | ||
| 58 | - // or that | ||
| 59 | - if (!cls.type.IsGenericTypeDefinition) { | ||
| 60 | - return Exceptions.RaiseTypeError( | ||
| 61 | - "type is not a generic type definition" | ||
| 62 | - ); | ||
| 63 | - } | ||
| 64 | - | ||
| 65 | - // The index argument will often be a tuple, for generic types | ||
| 66 | - // that have more than one generic binding parameter. | ||
| 67 | - | ||
| 68 | - IntPtr args = idx; | ||
| 69 | - bool free = false; | ||
| 70 | - | ||
| 71 | - if (!Runtime.PyTuple_Check(idx)) { | ||
| 72 | - args = Runtime.PyTuple_New(1); | ||
| 73 | - Runtime.Incref(idx); | ||
| 74 | - Runtime.PyTuple_SetItem(args, 0, idx); | ||
| 75 | - free = true; | ||
| 54 | + public override IntPtr type_subscript(IntPtr idx) { | ||
| 55 | + Type[] types = Runtime.PythonArgsToTypeArray(idx); | ||
| 56 | + if (types == null) { | ||
| 57 | + return Exceptions.RaiseTypeError("type(s) expected"); | ||
| 76 | 58 | } | |
| 77 | - | ||
| 78 | - int n = Runtime.PyTuple_Size(args); | ||
| 79 | - Type[] types = new Type[n]; | ||
| 80 | - Type t = null; | ||
| 81 | - | ||
| 82 | - for (int i = 0; i < n; i++) { | ||
| 83 | - IntPtr op = Runtime.PyTuple_GetItem(args, i); | ||
| 84 | - ClassBase cb = GetManagedObject(op) as ClassBase; | ||
| 85 | - t = (cb != null) ? cb.type : Converter.GetTypeByAlias(op); | ||
| 86 | - if (t == null) { | ||
| 87 | - if (free) Runtime.Decref(args); | ||
| 88 | - return Exceptions.RaiseTypeError("type expected"); | ||
| 89 | - } | ||
| 90 | - types[i] = t; | ||
| 59 | + if (!this.type.IsGenericTypeDefinition) { | ||
| 60 | + return Exceptions.RaiseTypeError( | ||
| 61 | + "type is not a generic type definition" | ||
| 62 | + ); | ||
| 91 | 63 | } | |
| 92 | - | ||
| 93 | - if (free) { | ||
| 94 | - Runtime.Decref(args); | ||
| 64 | + if (this.type.ContainsGenericParameters) { | ||
| 65 | + Type t = this.type.MakeGenericType(types); | ||
| 66 | + ManagedType c = (ManagedType)ClassManager.GetClass(t); | ||
| 67 | + Runtime.Incref(c.pyHandle); | ||
| 68 | + return c.pyHandle; | ||
| 95 | 69 | } | |
| 96 | 70 | ||
| 97 | - t =cls.type.MakeGenericType(types); | ||
| 98 | - ManagedType c = (ManagedType)ClassManager.GetClass(t); | ||
| 99 | - Runtime.Incref(c.pyHandle); | ||
| 100 | - return c.pyHandle; | ||
| 71 | + return Exceptions.RaiseTypeError("unsubscriptable object"); | ||
| 101 | 72 | } | |
| 102 | 73 | ||
| 103 | 74 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -223,7 +223,7 @@ public static int tp_setattro(IntPtr tp, IntPtr name, IntPtr value) { | |||
| 223 | 223 | public static IntPtr mp_subscript(IntPtr tp, IntPtr idx) { | |
| 224 | 224 | ClassBase cb = GetManagedObject(tp) as ClassBase; | |
| 225 | 225 | if (cb != null) { | |
| 226 | - return cb.type_subscript(tp, idx); | ||
| 226 | + return cb.type_subscript(idx); | ||
| 227 | 227 | } | |
| 228 | 228 | return Exceptions.RaiseTypeError("unsubscriptable object"); | |
| 229 | 229 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -206,6 +206,39 @@ internal static IntPtr ExtendTuple(IntPtr t, params IntPtr[] args) { | |||
| 206 | 206 | return items; | |
| 207 | 207 | } | |
| 208 | 208 | ||
| 209 | + internal static Type[] PythonArgsToTypeArray(IntPtr arg) { | ||
| 210 | + // Given a PyObject * that is either a single type object or a | ||
| 211 | + // tuple of (managed or unmanaged) type objects, return a Type[] | ||
| 212 | + // containing the CLR Type objects that map to those types. | ||
| 213 | + IntPtr args = arg; | ||
| 214 | + bool free = false; | ||
| 215 | + | ||
| 216 | + if (!Runtime.PyTuple_Check(arg)) { | ||
| 217 | + args = Runtime.PyTuple_New(1); | ||
| 218 | + Runtime.Incref(arg); | ||
| 219 | + Runtime.PyTuple_SetItem(args, 0, arg); | ||
| 220 | + free = true; | ||
| 221 | + } | ||
| 222 | + | ||
| 223 | + int n = Runtime.PyTuple_Size(args); | ||
| 224 | + Type[] types = new Type[n]; | ||
| 225 | + Type t = null; | ||
| 226 | + | ||
| 227 | + for (int i = 0; i < n; i++) { | ||
| 228 | + IntPtr op = Runtime.PyTuple_GetItem(args, i); | ||
| 229 | + ClassBase cb = ManagedType.GetManagedObject(op) as ClassBase; | ||
| 230 | + t = (cb != null) ? cb.type : Converter.GetTypeByAlias(op); | ||
| 231 | + if (t == null) { | ||
| 232 | + types = null; | ||
| 233 | + break; | ||
| 234 | + } | ||
| 235 | + types[i] = t; | ||
| 236 | + } | ||
| 237 | + if (free) { | ||
| 238 | + Runtime.Decref(args); | ||
| 239 | + } | ||
| 240 | + return types; | ||
| 241 | + } | ||
| 209 | 242 | ||
| 210 | 243 | //=================================================================== | |
| 211 | 244 | // Managed exports of the Python C API. Where appropriate, we do | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -33,9 +33,6 @@ public GenericTypeDefinition(T arg1, U arg2) { | |||
| 33 | 33 | this.value1 = arg1; | |
| 34 | 34 | this.value2 = arg2; | |
| 35 | 35 | } | |
| 36 | - | ||
| 37 | - | ||
| 38 | - | ||
| 39 | 36 | } | |
| 40 | 37 | ||
| 41 | 38 | public class DerivedFromOpenGeneric<V, W> : | |
@@ -50,9 +47,78 @@ public DerivedFromOpenGeneric(int arg1, V arg2, W arg3) : | |||
| 50 | 47 | } | |
| 51 | 48 | ||
| 52 | 49 | ||
| 53 | - public class NameTest {} | ||
| 54 | - public class NameTest<T,U> {} | ||
| 55 | - public class NameTest<T> {} | ||
| 50 | + public class GenericNameTest1 { | ||
| 51 | + public static int value = 0; | ||
| 52 | + } | ||
| 53 | + | ||
| 54 | + public class GenericNameTest1<T> { | ||
| 55 | + public static int value = 1; | ||
| 56 | + } | ||
| 57 | + | ||
| 58 | + public class GenericNameTest1<T,U> { | ||
| 59 | + public static int value = 2; | ||
| 60 | + } | ||
| 61 | + | ||
| 62 | + public class GenericNameTest2<T> { | ||
| 63 | + public static int value = 1; | ||
| 64 | + } | ||
| 65 | + | ||
| 66 | + public class GenericNameTest2<T,U> { | ||
| 67 | + public static int value = 2; | ||
| 68 | + } | ||
| 69 | + | ||
| 70 | + | ||
| 71 | + public class GenericMethodTest<T> { | ||
| 72 | + | ||
| 73 | + public GenericMethodTest() {} | ||
| 74 | + | ||
| 75 | + public int OverloadedMethod() { | ||
| 76 | + return 1; | ||
| 77 | + } | ||
| 78 | + | ||
| 79 | + public int OverloadedMethod(int arg) { | ||
| 80 | + return arg; | ||
| 81 | + } | ||
| 82 | + | ||
| 83 | + public T OverloadedMethod(T arg) { | ||
| 84 | + return arg; | ||
| 85 | + } | ||
| 86 | + | ||
| 87 | + public Q OverloadedMethod<Q>(Q arg) { | ||
| 88 | + return arg; | ||
| 89 | + } | ||
| 90 | + | ||
| 91 | + public U OverloadedMethod<Q, U>(Q arg1, U arg2) { | ||
| 92 | + return arg2; | ||
| 93 | + } | ||
| 94 | + | ||
| 95 | + } | ||
| 96 | + | ||
| 97 | + public class GenericStaticMethodTest<T> { | ||
| 98 | + | ||
| 99 | + public GenericStaticMethodTest() {} | ||
| 100 | + | ||
| 101 | + public static int OverloadedMethod() { | ||
| 102 | + return 1; | ||
| 103 | + } | ||
| 104 | + | ||
| 105 | + public static int OverloadedMethod(int arg) { | ||
| 106 | + return arg; | ||
| 107 | + } | ||
| 108 | + | ||
| 109 | + public static T OverloadedMethod(T arg) { | ||
| 110 | + return arg; | ||
| 111 | + } | ||
| 112 | + | ||
| 113 | + public static Q OverloadedMethod<Q>(Q arg) { | ||
| 114 | + return arg; | ||
| 115 | + } | ||
| 116 | + | ||
| 117 | + public static U OverloadedMethod<Q, U>(Q arg1, U arg2) { | ||
| 118 | + return arg2; | ||
| 119 | + } | ||
| 120 | + | ||
| 121 | + } | ||
| 56 | 122 | ||
| 57 | 123 | ||
| 58 | 124 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -15,7 +15,7 @@ | |||
| 15 | 15 | 'test_exceptions', | |
| 16 | 16 | 'test_module', | |
| 17 | 17 | 'test_compat', | |
| 18 | - #'test_generic', | ||
| 18 | + 'test_generic', | ||
| 19 | 19 | 'test_conversion', | |
| 20 | 20 | 'test_class', | |
| 21 | 21 | 'test_interface', | |
| Back | FazBrowse Home | New Git URL |
0 commit comments