Example #1
0
        static void SetupImportHook()
        {
            // Create the import hook module
            var import_hook_module = Runtime.PyModule_New("clr.loader");

            // Run the python code to create the module's classes.
            var builtins = Runtime.PyEval_GetBuiltins();
            var exec     = Runtime.PyDict_GetItemString(builtins, "exec");

            using var args = NewReference.DangerousFromPointer(Runtime.PyTuple_New(2));

            var codeStr = NewReference.DangerousFromPointer(Runtime.PyString_FromString(LoaderCode));

            Runtime.PyTuple_SetItem(args, 0, codeStr);
            var mod_dict = Runtime.PyModule_GetDict(import_hook_module);

            // reference not stolen due to overload incref'ing for us.
            Runtime.PyTuple_SetItem(args, 1, mod_dict);
            Runtime.PyObject_Call(exec, args, default).Dispose();
            // Set as a sub-module of clr.
            if (Runtime.PyModule_AddObject(ClrModuleReference, "loader", import_hook_module.DangerousGetAddress()) != 0)
            {
                Runtime.XDecref(import_hook_module.DangerousGetAddress());
                throw PythonException.ThrowLastAsClrException();
            }

            // Finally, add the hook to the meta path
            var findercls      = Runtime.PyDict_GetItemString(mod_dict, "DotNetFinder");
            var finderCtorArgs = NewReference.DangerousFromPointer(Runtime.PyTuple_New(0));
            var finder_inst    = Runtime.PyObject_CallObject(findercls, finderCtorArgs);
            var metapath       = Runtime.PySys_GetObject("meta_path");

            Runtime.PyList_Append(metapath, finder_inst);
        }
Example #2
0
        /// <summary>
        /// Set the 'args' slot on a python exception object that wraps
        /// a CLR exception. This is needed for pickling CLR exceptions as
        /// BaseException_reduce will only check the slots, bypassing the
        /// __getattr__ implementation, and thus dereferencing a NULL
        /// pointer.
        /// </summary>
        internal static void SetArgsAndCause(BorrowedReference ob, Exception e)
        {
            IntPtr args;

            if (!string.IsNullOrEmpty(e.Message))
            {
                args = Runtime.PyTuple_New(1);
                IntPtr msg = Runtime.PyString_FromString(e.Message);
                Runtime.PyTuple_SetItem(args, 0, msg);
            }
            else
            {
                args = Runtime.PyTuple_New(0);
            }

            using var argsTuple = NewReference.DangerousFromPointer(args);

            if (Runtime.PyObject_SetAttrString(ob, "args", argsTuple) != 0)
            {
                throw PythonException.ThrowLastAsClrException();
            }

            if (e.InnerException != null)
            {
                // Note: For an AggregateException, InnerException is only the first of the InnerExceptions.
                using var cause = CLRObject.GetReference(e.InnerException);
                Runtime.PyException_SetCause(ob, cause.Steal());
            }
        }
Example #3
0
        /// <summary>
        /// Creates <see cref="CLRObject"/> proxy for the given object,
        /// and returns a <see cref="NewReference"/> to it.
        /// </summary>
        internal static NewReference MakeNewReference(object obj)
        {
            if (obj is null)
            {
                throw new ArgumentNullException(nameof(obj));
            }

            // TODO: CLRObject currently does not have Dispose or finalizer which might change in the future
            return(NewReference.DangerousFromPointer(GetInstHandle(obj)));
        }
Example #4
0
        /// <summary>
        /// Return the clr python module (new reference)
        /// </summary>
        public static unsafe NewReference GetCLRModule(BorrowedReference fromList = default)
        {
            root.InitializePreload();

            // update the module dictionary with the contents of the root dictionary
            root.LoadNames();
            BorrowedReference py_mod_dict = Runtime.PyModule_GetDict(ClrModuleReference);

            using (var clr_dict = Runtime.PyObject_GenericGetDict(root.ObjectReference))
            {
                Runtime.PyDict_Update(py_mod_dict, clr_dict);
            }

            // find any items from the from list and get them from the root if they're not
            // already in the module dictionary
            if (fromList != null)
            {
                if (Runtime.PyTuple_Check(fromList))
                {
                    using var mod_dict = new PyDict(py_mod_dict);
                    using var from     = new PyTuple(fromList);
                    foreach (PyObject item in from)
                    {
                        if (mod_dict.HasKey(item))
                        {
                            continue;
                        }

                        var s = item.AsManagedObject(typeof(string)) as string;
                        if (s == null)
                        {
                            continue;
                        }

                        ManagedType attr = root.GetAttribute(s, true);
                        if (attr == null)
                        {
                            continue;
                        }

                        Runtime.XIncref(attr.pyHandle);
                        using (var obj = new PyObject(attr.pyHandle))
                        {
                            mod_dict.SetItem(s, obj);
                        }
                    }
                }
            }
            Runtime.XIncref(py_clr_module);
            return(NewReference.DangerousFromPointer(py_clr_module));
        }
Example #5
0
        /// <summary>
        /// Helper to get docstring from reflected constructor info.
        /// </summary>
        internal NewReference GetDocString()
        {
            MethodBase[] methods = binder.GetMethods();
            var          str     = "";

            foreach (MethodBase t in methods)
            {
                if (str.Length > 0)
                {
                    str += Environment.NewLine;
                }
                str += t.ToString();
            }
            return(NewReference.DangerousFromPointer(Runtime.PyString_FromString(str)));
        }
Example #6
0
        /// <summary>
        /// The following CreateType implementations do the necessary work to
        /// create Python types to represent managed extension types, reflected
        /// types, subclasses of reflected types and the managed metatype. The
        /// dance is slightly different for each kind of type due to different
        /// behavior needed and the desire to have the existing Python runtime
        /// do as much of the allocation and initialization work as possible.
        /// </summary>
        internal static unsafe IntPtr CreateType(Type impl)
        {
            IntPtr type  = AllocateTypeObject(impl.Name, metatype: Runtime.PyCLRMetaType);
            IntPtr base_ = impl == typeof(CLRModule)
                ? Runtime.PyModuleType
                : Runtime.PyBaseObjectType;

            int newFieldOffset = InheritOrAllocateStandardFields(type, base_);

            int tp_clr_inst_offset = newFieldOffset;

            newFieldOffset += IntPtr.Size;

            int ob_size = newFieldOffset;

            // Set tp_basicsize to the size of our managed instance objects.
            Marshal.WriteIntPtr(type, TypeOffset.tp_basicsize, (IntPtr)ob_size);
            Marshal.WriteInt32(type, ManagedType.Offsets.tp_clr_inst_offset, tp_clr_inst_offset);
            Marshal.WriteIntPtr(type, TypeOffset.tp_new, (IntPtr)Runtime.Delegates.PyType_GenericNew);

            SlotsHolder slotsHolder = CreateSolotsHolder(type);

            InitializeSlots(type, impl, slotsHolder);

            var flags = TypeFlags.Default | TypeFlags.HasClrInstance |
                        TypeFlags.HeapType | TypeFlags.HaveGC;

            Util.WriteCLong(type, TypeOffset.tp_flags, (int)flags);

            if (Runtime.PyType_Ready(type) != 0)
            {
                throw new PythonException();
            }

            var dict = new BorrowedReference(Marshal.ReadIntPtr(type, TypeOffset.tp_dict));
            var mod  = NewReference.DangerousFromPointer(Runtime.PyString_FromString("CLR"));

            Runtime.PyDict_SetItem(dict, PyIdentifier.__module__, mod);
            mod.Dispose();

            InitMethods(type, impl);

            // The type has been modified after PyType_Ready has been called
            // Refresh the type
            Runtime.PyType_Modified(type);
            return(type);
        }
Example #7
0
        public ModuleObject(string name)
        {
            if (name == string.Empty)
            {
                throw new ArgumentException("Name must not be empty!");
            }
            moduleName = name;
            cache      = new Dictionary <string, ManagedType>();
            _namespace = name;

            // Use the filename from any of the assemblies just so there's something for
            // anything that expects __file__ to be set.
            var filename  = "unknown";
            var docstring = "Namespace containing types from the following assemblies:\n\n";

            foreach (Assembly a in AssemblyManager.GetAssemblies(name))
            {
                if (!a.IsDynamic && a.Location != null)
                {
                    filename = a.Location;
                }
                docstring += "- " + a.FullName + "\n";
            }

            var dictRef = Runtime.PyObject_GenericGetDict(ObjectReference);

            PythonException.ThrowIfIsNull(dictRef);
            dict = dictRef.DangerousMoveToPointer();

            using var pyname      = NewReference.DangerousFromPointer(Runtime.PyString_FromString(moduleName));
            using var pyfilename  = NewReference.DangerousFromPointer(Runtime.PyString_FromString(filename));
            using var pydocstring = NewReference.DangerousFromPointer(Runtime.PyString_FromString(docstring));
            BorrowedReference pycls = TypeManager.GetTypeReference(GetType());

            Runtime.PyDict_SetItem(DictRef, PyIdentifier.__name__, pyname);
            Runtime.PyDict_SetItem(DictRef, PyIdentifier.__file__, pyfilename);
            Runtime.PyDict_SetItem(DictRef, PyIdentifier.__doc__, pydocstring);
            Runtime.PyDict_SetItem(DictRef, PyIdentifier.__class__, pycls);

            InitializeModuleMembers();
        }
Example #8
0
        public static IntPtr CreateObjectType()
        {
            using var globals = NewReference.DangerousFromPointer(Runtime.PyDict_New());
            if (Runtime.PyDict_SetItemString(globals, "__builtins__", Runtime.PyEval_GetBuiltins()) != 0)
            {
                globals.Dispose();
                throw new PythonException();
            }
            const string code = "class A(object): pass";

            using var resRef = Runtime.PyRun_String(code, RunFlagType.File, globals, globals);
            if (resRef.IsNull())
            {
                globals.Dispose();
                throw new PythonException();
            }
            resRef.Dispose();
            BorrowedReference A = Runtime.PyDict_GetItemString(globals, "A");

            Debug.Assert(!A.IsNull);
            return(new NewReference(A).DangerousMoveToPointer());
        }
Example #9
0
        /// <summary>
        /// The following CreateType implementations do the necessary work to
        /// create Python types to represent managed extension types, reflected
        /// types, subclasses of reflected types and the managed metatype. The
        /// dance is slightly different for each kind of type due to different
        /// behavior needed and the desire to have the existing Python runtime
        /// do as much of the allocation and initialization work as possible.
        /// </summary>
        internal static IntPtr CreateType(Type impl)
        {
            IntPtr type    = AllocateTypeObject(impl.Name, metatype: Runtime.PyTypeType);
            int    ob_size = ObjectOffset.Size(type);

            // Set tp_basicsize to the size of our managed instance objects.
            Marshal.WriteIntPtr(type, TypeOffset.tp_basicsize, (IntPtr)ob_size);

            var offset = (IntPtr)ObjectOffset.TypeDictOffset(type);

            Marshal.WriteIntPtr(type, TypeOffset.tp_dictoffset, offset);

            SlotsHolder slotsHolder = CreateSolotsHolder(type);

            InitializeSlots(type, impl, slotsHolder);

            var flags = TypeFlags.Default | TypeFlags.Managed |
                        TypeFlags.HeapType | TypeFlags.HaveGC;

            Util.WriteCLong(type, TypeOffset.tp_flags, (int)flags);

            if (Runtime.PyType_Ready(type) != 0)
            {
                throw new PythonException();
            }

            var dict = new BorrowedReference(Marshal.ReadIntPtr(type, TypeOffset.tp_dict));
            var mod  = NewReference.DangerousFromPointer(Runtime.PyString_FromString("CLR"));

            Runtime.PyDict_SetItem(dict, PyIdentifier.__module__, mod);
            mod.Dispose();

            InitMethods(type, impl);

            // The type has been modified after PyType_Ready has been called
            // Refresh the type
            Runtime.PyType_Modified(type);
            return(type);
        }
Example #10
0
        private static void InitClassBase(Type type, ClassBase impl)
        {
            // First, we introspect the managed type and build some class
            // information, including generating the member descriptors
            // that we'll be putting in the Python class __dict__.

            ClassInfo info = GetClassInfo(type);

            impl.indexer     = info.indexer;
            impl.richcompare = new Dictionary <int, MethodObject>();

            // Now we allocate the Python type object to reflect the given
            // managed type, filling the Python type slots with thunks that
            // point to the managed methods providing the implementation.


            IntPtr tp = TypeManager.GetTypeHandle(impl, type);

            // Finally, initialize the class __dict__ and return the object.
            var dict = new BorrowedReference(Marshal.ReadIntPtr(tp, TypeOffset.tp_dict));


            if (impl.dotNetMembers == null)
            {
                impl.dotNetMembers = new List <string>();
            }
            IDictionaryEnumerator iter = info.members.GetEnumerator();

            while (iter.MoveNext())
            {
                var item = (ManagedType)iter.Value;
                var name = (string)iter.Key;
                impl.dotNetMembers.Add(name);
                Runtime.PyDict_SetItemString(dict, name, item.ObjectReference);
                // Decref the item now that it's been used.
                item.DecrRefCount();
                if (ClassBase.CilToPyOpMap.TryGetValue(name, out var pyOp))
                {
                    impl.richcompare.Add(pyOp, (MethodObject)item);
                }
            }

            // If class has constructors, generate an __doc__ attribute.
            NewReference doc    = default;
            Type         marker = typeof(DocStringAttribute);
            var          attrs  = (Attribute[])type.GetCustomAttributes(marker, false);

            if (attrs.Length != 0)
            {
                var    attr   = (DocStringAttribute)attrs[0];
                string docStr = attr.DocString;
                doc = NewReference.DangerousFromPointer(Runtime.PyString_FromString(docStr));
                Runtime.PyDict_SetItem(dict, PyIdentifier.__doc__, doc);
            }

            var co = impl as ClassObject;

            // If this is a ClassObject AND it has constructors, generate a __doc__ attribute.
            // required that the ClassObject.ctors be changed to internal
            if (co != null)
            {
                if (co.NumCtors > 0)
                {
                    // Implement Overloads on the class object
                    if (!CLRModule._SuppressOverloads)
                    {
                        var ctors = new ConstructorBinding(type, tp, co.binder);
                        // ExtensionType types are untracked, so don't Incref() them.
                        // TODO: deprecate __overloads__ soon...
                        Runtime.PyDict_SetItem(dict, PyIdentifier.__overloads__, ctors.ObjectReference);
                        Runtime.PyDict_SetItem(dict, PyIdentifier.Overloads, ctors.ObjectReference);
                        ctors.DecrRefCount();
                    }

                    // don't generate the docstring if one was already set from a DocStringAttribute.
                    if (!CLRModule._SuppressDocs && doc.IsNull())
                    {
                        doc = co.GetDocString();
                        Runtime.PyDict_SetItem(dict, PyIdentifier.__doc__, doc);
                    }
                }
            }
            doc.Dispose();

            // The type has been modified after PyType_Ready has been called
            // Refresh the type
            Runtime.PyType_Modified(tp);
        }
Example #11
0
        internal static IntPtr CreateType(ManagedType impl, Type clrType)
        {
            // Cleanup the type name to get rid of funny nested type names.
            string name = $"clr.{clrType.FullName}";
            int    i    = name.LastIndexOf('+');

            if (i > -1)
            {
                name = name.Substring(i + 1);
            }
            i = name.LastIndexOf('.');
            if (i > -1)
            {
                name = name.Substring(i + 1);
            }

            IntPtr base_   = IntPtr.Zero;
            int    ob_size = ObjectOffset.Size(Runtime.PyTypeType);

            // XXX Hack, use a different base class for System.Exception
            // Python 2.5+ allows new style class exceptions but they *must*
            // subclass BaseException (or better Exception).
            if (typeof(Exception).IsAssignableFrom(clrType))
            {
                ob_size = ObjectOffset.Size(Exceptions.Exception);
            }

            int tp_dictoffset = ob_size + ManagedDataOffsets.ob_dict;

            if (clrType == typeof(Exception))
            {
                base_ = Exceptions.Exception;
            }
            else if (clrType.BaseType != null)
            {
                ClassBase bc = ClassManager.GetClass(clrType.BaseType);
                base_ = bc.pyHandle;
            }

            IntPtr type = AllocateTypeObject(name, Runtime.PyCLRMetaType);

            Marshal.WriteIntPtr(type, TypeOffset.ob_type, Runtime.PyCLRMetaType);
            Runtime.XIncref(Runtime.PyCLRMetaType);

            Marshal.WriteIntPtr(type, TypeOffset.tp_basicsize, (IntPtr)ob_size);
            Marshal.WriteIntPtr(type, TypeOffset.tp_itemsize, IntPtr.Zero);
            Marshal.WriteIntPtr(type, TypeOffset.tp_dictoffset, (IntPtr)tp_dictoffset);

            // we want to do this after the slot stuff above in case the class itself implements a slot method
            SlotsHolder slotsHolder = CreateSolotsHolder(type);

            InitializeSlots(type, impl.GetType(), slotsHolder);

            if (Marshal.ReadIntPtr(type, TypeOffset.mp_length) == IntPtr.Zero &&
                mp_length_slot.CanAssign(clrType))
            {
                InitializeSlot(type, TypeOffset.mp_length, mp_length_slot.Method, slotsHolder);
            }

            if (!typeof(IEnumerable).IsAssignableFrom(clrType) &&
                !typeof(IEnumerator).IsAssignableFrom(clrType))
            {
                // The tp_iter slot should only be set for enumerable types.
                Marshal.WriteIntPtr(type, TypeOffset.tp_iter, IntPtr.Zero);
            }


            // Only set mp_subscript and mp_ass_subscript for types with indexers
            if (impl is ClassBase cb)
            {
                if (!(impl is ArrayObject))
                {
                    if (cb.indexer == null || !cb.indexer.CanGet)
                    {
                        Marshal.WriteIntPtr(type, TypeOffset.mp_subscript, IntPtr.Zero);
                    }
                    if (cb.indexer == null || !cb.indexer.CanSet)
                    {
                        Marshal.WriteIntPtr(type, TypeOffset.mp_ass_subscript, IntPtr.Zero);
                    }
                }
            }
            else
            {
                Marshal.WriteIntPtr(type, TypeOffset.mp_subscript, IntPtr.Zero);
                Marshal.WriteIntPtr(type, TypeOffset.mp_ass_subscript, IntPtr.Zero);
            }

            if (base_ != IntPtr.Zero)
            {
                Marshal.WriteIntPtr(type, TypeOffset.tp_base, base_);
                Runtime.XIncref(base_);
            }

            const TypeFlags flags = TypeFlags.Default
                                    | TypeFlags.Managed
                                    | TypeFlags.HeapType
                                    | TypeFlags.BaseType
                                    | TypeFlags.HaveGC;

            Util.WriteCLong(type, TypeOffset.tp_flags, (int)flags);

            OperatorMethod.FixupSlots(type, clrType);
            // Leverage followup initialization from the Python runtime. Note
            // that the type of the new type must PyType_Type at the time we
            // call this, else PyType_Ready will skip some slot initialization.

            if (Runtime.PyType_Ready(type) != 0)
            {
                throw new PythonException();
            }

            var    dict = new BorrowedReference(Marshal.ReadIntPtr(type, TypeOffset.tp_dict));
            string mn   = clrType.Namespace ?? "";
            var    mod  = NewReference.DangerousFromPointer(Runtime.PyString_FromString(mn));

            Runtime.PyDict_SetItem(dict, PyIdentifier.__module__, mod);
            mod.Dispose();

            // Hide the gchandle of the implementation in a magic type slot.
            GCHandle gc = impl.AllocGCHandle();

            Marshal.WriteIntPtr(type, TypeOffset.magic(), (IntPtr)gc);

            // Set the handle attributes on the implementing instance.
            impl.tpHandle = type;
            impl.pyHandle = type;

            //DebugUtil.DumpType(type);

            return(type);
        }
Example #12
0
 internal static NewReference GetReference(object ob)
 => NewReference.DangerousFromPointer(GetInstHandle(ob));
Example #13
0
        internal static NewReference GetInstHandle(object ob, BorrowedReference pyType)
        {
            CLRObject co = GetInstance(ob, pyType.DangerousGetAddress());

            return(NewReference.DangerousFromPointer(co.pyHandle));
        }
Example #14
0
 internal static NewReference ToPythonReference <T>(T value)
 => NewReference.DangerousFromPointer(ToPython(value, typeof(T)));
Example #15
0
 internal static NewReference ToPythonReference(object value, Type type)
 => NewReference.DangerousFromPointer(ToPython(value, type));
Example #16
0
        private object TrueDispatch(object[] args)
        {
            MethodInfo method = dtype.GetMethod("Invoke");

            ParameterInfo[] pi    = method.GetParameters();
            Type            rtype = method.ReturnType;

            NewReference op;

            using (var pyargs = NewReference.DangerousFromPointer(Runtime.PyTuple_New(pi.Length)))
            {
                for (var i = 0; i < pi.Length; i++)
                {
                    // Here we own the reference to the Python value, and we
                    // give the ownership to the arg tuple.
                    var arg = Converter.ToPythonReference(args[i], pi[i].ParameterType);
                    if (arg.IsNull())
                    {
                        throw PythonException.ThrowLastAsClrException();
                    }
                    int res = Runtime.PyTuple_SetItem(pyargs, i, arg.Steal());
                    if (res != 0)
                    {
                        throw PythonException.ThrowLastAsClrException();
                    }
                }

                op = Runtime.PyObject_Call(target.Reference, pyargs, BorrowedReference.Null);
            }

            if (op.IsNull())
            {
                throw PythonException.ThrowLastAsClrException();
            }

            using (op)
            {
                int byRefCount = pi.Count(parameterInfo => parameterInfo.ParameterType.IsByRef);
                if (byRefCount > 0)
                {
                    // By symmetry with MethodBinder.Invoke, when there are out
                    // parameters we expect to receive a tuple containing
                    // the result, if any, followed by the out parameters. If there is only
                    // one out parameter and the return type of the method is void,
                    // we instead receive the out parameter as the result from Python.

                    bool isVoid    = rtype == typeof(void);
                    int  tupleSize = byRefCount + (isVoid ? 0 : 1);
                    if (isVoid && byRefCount == 1)
                    {
                        // The return type is void and there is a single out parameter.
                        for (int i = 0; i < pi.Length; i++)
                        {
                            Type t = pi[i].ParameterType;
                            if (t.IsByRef)
                            {
                                if (!Converter.ToManaged(op, t, out object newArg, true))
                                {
                                    Exceptions.RaiseTypeError($"The Python function did not return {t.GetElementType()} (the out parameter type)");
                                    throw PythonException.ThrowLastAsClrException();
                                }
                                args[i] = newArg;
                                break;
                            }
                        }
                        return(null);
                    }
                    else if (Runtime.PyTuple_Check(op) && Runtime.PyTuple_Size(op) == tupleSize)
                    {
                        int index = isVoid ? 0 : 1;
                        for (int i = 0; i < pi.Length; i++)
                        {
                            Type t = pi[i].ParameterType;
                            if (t.IsByRef)
                            {
                                BorrowedReference item = Runtime.PyTuple_GetItem(op, index++);
                                if (!Converter.ToManaged(item, t, out object newArg, true))
                                {
                                    Exceptions.RaiseTypeError($"The Python function returned a tuple where element {i} was not {t.GetElementType()} (the out parameter type)");
                                    throw PythonException.ThrowLastAsClrException();
                                }
                                args[i] = newArg;
                            }
                        }
                        if (isVoid)
                        {
                            return(null);
                        }
                        BorrowedReference item0 = Runtime.PyTuple_GetItem(op, 0);
                        if (!Converter.ToManaged(item0, rtype, out object result0, true))
                        {
                            Exceptions.RaiseTypeError($"The Python function returned a tuple where element 0 was not {rtype} (the return type)");
                            throw PythonException.ThrowLastAsClrException();
                        }
                        return(result0);
                    }
                    else
                    {
                        string tpName = Runtime.PyObject_GetTypeName(op);
                        if (Runtime.PyTuple_Check(op))
                        {
                            tpName += $" of size {Runtime.PyTuple_Size(op)}";
                        }
                        StringBuilder sb = new StringBuilder();
                        if (!isVoid)
                        {
                            sb.Append(rtype.FullName);
                        }
                        for (int i = 0; i < pi.Length; i++)
                        {
                            Type t = pi[i].ParameterType;
                            if (t.IsByRef)
                            {
                                if (sb.Length > 0)
                                {
                                    sb.Append(",");
                                }
                                sb.Append(t.GetElementType().FullName);
                            }
                        }
                        string returnValueString = isVoid ? "" : "the return value and ";
                        Exceptions.RaiseTypeError($"Expected a tuple ({sb}) of {returnValueString}the values for out and ref parameters, got {tpName}.");
                        throw PythonException.ThrowLastAsClrException();
                    }
                }

                if (rtype == typeof(void))
                {
                    return(null);
                }

                object result;
                if (!Converter.ToManaged(op, rtype, out result, true))
                {
                    throw PythonException.ThrowLastAsClrException();
                }

                return(result);
            }
        }