Inheritance: ExtensionType
Example #1
0
        //====================================================================
        // Implement explicit overload selection using subscript syntax ([]).
        //====================================================================

        public static IntPtr mp_subscript(IntPtr tp, IntPtr idx)
        {
            OverloadMapper self = (OverloadMapper)GetManagedObject(tp);

            // Note: if the type provides a non-generic method with N args
            // and a generic method that takes N params, then we always
            // prefer the non-generic version in doing overload selection.

            Type[] types = Runtime.PythonArgsToTypeArray(idx);
            if (types == null)
            {
                return Exceptions.RaiseTypeError("type(s) expected");
            }

            MethodInfo mi = MethodBinder.MatchSignature(self.m.info, types);
            if (mi == null)
            {
                string e = "No match found for signature";
                return Exceptions.RaiseTypeError(e);
            }

            MethodBinding mb = new MethodBinding(self.m, self.target);
            mb.info = mi;
            Runtime.Incref(mb.pyHandle);
            return mb.pyHandle;
        }
Example #2
0
 	public static IntPtr mp_subscript(IntPtr tp, IntPtr idx) {
 	    MethodBinding self = (MethodBinding)GetManagedObject(tp);
 	    MethodInfo sig = MethodBinder.MatchByTypeSig(self.m.info, idx);
 	    if (sig == null) {
 		return Exceptions.RaiseTypeError(
 				  "No match found for signature"
 				  );
 	    }
 	    MethodBinding mb = new MethodBinding(self.m, self.target);
 	    mb.info = sig;
 	    Runtime.Incref(mb.pyHandle);
 	    return mb.pyHandle;	    
 	}
Example #3
0
         //====================================================================
         // Implement binding of generic methods using the subscript syntax [].
         //====================================================================
 
         public static IntPtr mp_subscript(IntPtr tp, IntPtr idx) {
             MethodBinding self = (MethodBinding)GetManagedObject(tp);

            Type[] types = Runtime.PythonArgsToTypeArray(idx);
            if (types == null) {
                 return Exceptions.RaiseTypeError("type(s) expected");
            }

             MethodInfo mi = MethodBinder.MatchParameters(self.m.info, types);
            if (mi == null) {
                string e = "No match found for given type params";
                return Exceptions.RaiseTypeError(e);
            }

             MethodBinding mb = new MethodBinding(self.m, self.target);
             mb.info = mi;
             Runtime.Incref(mb.pyHandle);
             return mb.pyHandle;            
         }
Example #4
0
        /// <summary>
        /// Implement binding of generic methods using the subscript syntax [].
        /// </summary>
        public static IntPtr mp_subscript(IntPtr tp, IntPtr idx)
        {
            var self = (MethodBinding)GetManagedObject(tp);

            Type[] types = Runtime.PythonArgsToTypeArray(idx);
            if (types == null)
            {
                return(Exceptions.RaiseTypeError("type(s) expected"));
            }

            MethodInfo mi = MethodBinder.MatchParameters(self.m.info, types);

            if (mi == null)
            {
                return(Exceptions.RaiseTypeError("No match found for given type params"));
            }

            var mb = new MethodBinding(self.m, self.target)
            {
                info = mi
            };

            return(mb.pyHandle);
        }
Example #5
0
        //====================================================================
        // Descriptor __get__ implementation. Accessing a CLR method returns
        // a "bound" method similar to a Python bound method. 
        //====================================================================

        public static IntPtr tp_descr_get(IntPtr ds, IntPtr ob, IntPtr tp) {
            MethodObject self = (MethodObject)GetManagedObject(ds);
            MethodBinding binding;

            // If the method is accessed through its type (rather than via
            // an instance) we return an 'unbound' MethodBinding that will
            // cached for future accesses through the type.

            if (ob == IntPtr.Zero) {
                if (self.unbound == null) {
                    self.unbound = new MethodBinding(self, IntPtr.Zero);
                }
                binding = self.unbound;
                Runtime.Incref(binding.pyHandle);;
                return binding.pyHandle;
            }

            if (Runtime.PyObject_IsInstance(ob, tp) < 1) {
                return Exceptions.RaiseTypeError("invalid argument");
            }

            binding = new MethodBinding(self, ob);
            return binding.pyHandle;
        }
Example #6
0
        //====================================================================
        // Descriptor __get__ implementation. Accessing a CLR method returns
        // a "bound" method similar to a Python bound method.
        //====================================================================
        public static IntPtr tp_descr_get(IntPtr ds, IntPtr ob, IntPtr tp)
        {
            MethodObject self = (MethodObject)GetManagedObject(ds);
            MethodBinding binding;

            // If the method is accessed through its type (rather than via
            // an instance) we return an 'unbound' MethodBinding that will
            // cached for future accesses through the type.

            if (ob == IntPtr.Zero)
            {
                if (self.unbound == null)
                {
                    self.unbound = new MethodBinding(self, IntPtr.Zero, tp);
                }
                binding = self.unbound;
                Runtime.XIncref(binding.pyHandle);
                ;
                return binding.pyHandle;
            }

            if (Runtime.PyObject_IsInstance(ob, tp) < 1)
            {
                return Exceptions.RaiseTypeError("invalid argument");
            }

            // If the object this descriptor is being called with is a subclass of the type
            // this descriptor was defined on then it will be because the base class method
            // is being called via super(Derived, self).method(...).
            // In which case create a MethodBinding bound to the base class.
            CLRObject obj = GetManagedObject(ob) as CLRObject;
            if (obj != null
                && obj.inst.GetType() != self.type
                && obj.inst is IPythonDerivedType
                && self.type.IsAssignableFrom(obj.inst.GetType()))
            {
                ClassBase basecls = ClassManager.GetClass(self.type);
                binding = new MethodBinding(self, ob, basecls.pyHandle);
                return binding.pyHandle;
            }

            binding = new MethodBinding(self, ob, tp);
            return binding.pyHandle;
        }
Example #7
0
        //====================================================================
        // MethodBinding  __call__ implementation.
        //====================================================================

        public static IntPtr tp_call(IntPtr ob, IntPtr args, IntPtr kw)
        {
            MethodBinding self = (MethodBinding)GetManagedObject(ob);

            // This works around a situation where the wrong generic method is picked,
            // for example this method in the tests: string Overloaded<T>(int arg1, int arg2, string arg3)
            if (self.info != null)
            {
                if (self.info.IsGenericMethod)
                {
                    int    len   = Runtime.PyTuple_Size(args);
                    Type[] sigTp = Runtime.PythonArgsToTypeArray(args, true);
                    if (sigTp != null)
                    {
                        Type[]     genericTp   = self.info.GetGenericArguments();
                        MethodInfo betterMatch = MethodBinder.MatchSignatureAndParameters(self.m.info, genericTp, sigTp);
                        if (betterMatch != null)
                        {
                            self.info = betterMatch;
                        }
                    }
                }
            }

            // This supports calling a method 'unbound', passing the instance
            // as the first argument. Note that this is not supported if any
            // of the overloads are static since we can't know if the intent
            // was to call the static method or the unbound instance method.
            List <IntPtr> disposeList = new List <IntPtr>();

            try
            {
                IntPtr target = self.target;

                if ((target == IntPtr.Zero) && (!self.m.IsStatic()))
                {
                    int len = Runtime.PyTuple_Size(args);
                    if (len < 1)
                    {
                        Exceptions.SetError(Exceptions.TypeError, "not enough arguments");
                        return(IntPtr.Zero);
                    }
                    target = Runtime.PyTuple_GetItem(args, 0);
                    Runtime.Incref(target);
                    disposeList.Add(target);

                    args = Runtime.PyTuple_GetSlice(args, 1, len);
                    disposeList.Add(args);
                }

                // if the class is a IPythonDerivedClass and target is not the same as self.targetType
                // (eg if calling the base class method) then call the original base class method instead
                // of the target method.
                IntPtr superType = IntPtr.Zero;
                if (Runtime.PyObject_TYPE(target) != self.targetType)
                {
                    CLRObject inst = CLRObject.GetManagedObject(target) as CLRObject;
                    if (inst != null && (inst.inst as IPythonDerivedType) != null)
                    {
                        ClassBase baseType = GetManagedObject(self.targetType) as ClassBase;
                        if (baseType != null)
                        {
                            string baseMethodName = "_" + baseType.type.Name + "__" + self.m.name;
                            IntPtr baseMethod     = Runtime.PyObject_GetAttrString(target, baseMethodName);
                            if (baseMethod != IntPtr.Zero)
                            {
                                MethodBinding baseSelf = GetManagedObject(baseMethod) as MethodBinding;
                                if (baseSelf != null)
                                {
                                    self = baseSelf;
                                }
                                Runtime.Decref(baseMethod);
                            }
                            else
                            {
                                Runtime.PyErr_Clear();
                            }
                        }
                    }
                }

                return(self.m.Invoke(target, args, kw, self.info));
            }
            finally
            {
                foreach (IntPtr ptr in disposeList)
                {
                    Runtime.Decref(ptr);
                }
            }
        }