PyDict_SetItem() private method

private PyDict_SetItem ( IntPtr pointer, IntPtr key, IntPtr value ) : int
pointer IntPtr
key IntPtr
value IntPtr
return int
示例#1
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);
            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);

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

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

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

            IntPtr dict = Marshal.ReadIntPtr(type, TypeOffset.tp_dict);
            IntPtr mod  = Runtime.PyString_FromString("CLR");

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

            InitMethods(type, impl);
            return(type);
        }
示例#2
0
            public override ValueType Execute(ValueType arg)
            {
                const string code = @"
from Python.EmbeddingTest.Domain import MyClass

def test_obj_call():
    obj = MyClass()
    obj.Method()
    obj.StaticMethod()
    obj.Property = 1
    obj.Field = 10

test_obj_call()
";
                const string name = "test_domain_reload_mod";

                using (Py.GIL())
                {
                    // Create a new module
                    IntPtr module = PyRuntime.PyModule_New(name);
                    Assert.That(module != IntPtr.Zero);
                    IntPtr globals = PyRuntime.PyObject_GetAttr(module, PyIdentifier.__dict__);
                    Assert.That(globals != IntPtr.Zero);
                    try
                    {
                        // import builtins
                        // module.__dict__[__builtins__] = builtins
                        int res = PyRuntime.PyDict_SetItem(globals, PyIdentifier.__builtins__,
                                                           PyRuntime.PyEval_GetBuiltins());
                        PythonException.ThrowIfIsNotZero(res);

                        // Execute the code in the module's scope
                        PythonEngine.Exec(code, globals);
                        // import sys
                        // modules = sys.modules
                        IntPtr modules = PyRuntime.PyImport_GetModuleDict();
                        // modules[name] = module
                        res = PyRuntime.PyDict_SetItemString(modules, name, module);
                        PythonException.ThrowIfIsNotZero(res);
                    }
                    catch
                    {
                        PyRuntime.XDecref(module);
                        throw;
                    }
                    finally
                    {
                        PyRuntime.XDecref(globals);
                    }
                    return(module);
                }
            }
示例#3
0
        public new static int tp_setattro(IntPtr ob, IntPtr key, IntPtr val)
        {
            var managedKey = Runtime.GetManagedString(key);

            if ((settableAttributes.Contains(managedKey)) ||
                (ManagedType.GetManagedObject(val)?.GetType() == typeof(ModuleObject)))
            {
                var self = (ModuleObject)ManagedType.GetManagedObject(ob);
                return(Runtime.PyDict_SetItem(self.dict, key, val));
            }

            return(ExtensionType.tp_setattro(ob, key, val));
        }
示例#4
0
        internal static IntPtr BasicSubType(string name, IntPtr base_, Type impl)
        {
            // Utility to create a subtype of a std Python type, but with
            // a managed type able to override implementation

            IntPtr type = AllocateTypeObject(name, metatype: Runtime.PyTypeType);

            //Marshal.WriteIntPtr(type, TypeOffset.tp_basicsize, (IntPtr)obSize);
            //Marshal.WriteIntPtr(type, TypeOffset.tp_itemsize, IntPtr.Zero);

            //IntPtr offset = (IntPtr)ObjectOffset.ob_dict;
            //Marshal.WriteIntPtr(type, TypeOffset.tp_dictoffset, offset);

            //IntPtr dc = Runtime.PyDict_Copy(dict);
            //Marshal.WriteIntPtr(type, TypeOffset.tp_dict, dc);

            Marshal.WriteIntPtr(type, TypeOffset.tp_base, base_);
            Runtime.XIncref(base_);

            var flags = TypeFlags.Default;

            flags |= TypeFlags.Managed;
            flags |= TypeFlags.HeapType;
            flags |= TypeFlags.HaveGC;
            Util.WriteCLong(type, TypeOffset.tp_flags, (int)flags);

            CopySlot(base_, type, TypeOffset.tp_traverse);
            CopySlot(base_, type, TypeOffset.tp_clear);
            CopySlot(base_, type, TypeOffset.tp_is_gc);

            SlotsHolder slotsHolder = CreateSolotsHolder(type);

            InitializeSlots(type, impl, slotsHolder);

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

            IntPtr tp_dict = Marshal.ReadIntPtr(type, TypeOffset.tp_dict);
            IntPtr mod     = Runtime.PyString_FromString("CLR");

            Runtime.PyDict_SetItem(tp_dict, PyIdentifier.__module__, mod);

            // The type has been modified after PyType_Ready has been called
            // Refresh the type
            Runtime.PyType_Modified(type);

            return(type);
        }
示例#5
0
        private static void RestoreDotNetModules(Dictionary <PyString, PyObject> modules)
        {
            var pyMoudles = Runtime.PyImport_GetModuleDict();

            foreach (var item in modules)
            {
                var moduleName = item.Key;
                var module     = item.Value;
                int res        = Runtime.PyDict_SetItem(pyMoudles, moduleName, module);
                PythonException.ThrowIfIsNotZero(res);
                item.Key.Dispose();
                item.Value.Dispose();
            }
            modules.Clear();
        }
示例#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);
        }
示例#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";
            }

            dict = Runtime.PyDict_New();
            IntPtr pyname      = Runtime.PyString_FromString(moduleName);
            IntPtr pyfilename  = Runtime.PyString_FromString(filename);
            IntPtr pydocstring = Runtime.PyString_FromString(docstring);
            IntPtr pycls       = TypeManager.GetTypeHandle(GetType());

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

            Runtime.XIncref(dict);
            SetObjectDict(pyHandle, dict);

            InitializeModuleMembers();
        }
示例#8
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <remarks>
        /// Create a scope based on a Python Module.
        /// </remarks>
        internal PyScope(ref NewReference ptr, PyScopeManager manager)
        {
            if (!Runtime.PyType_IsSubtype(Runtime.PyObject_TYPE(ptr), Runtime.PyModuleType))
            {
                throw new PyScopeException("object is not a module");
            }
            Manager = manager ?? PyScopeManager.Global;
            obj     = ptr.MoveToPyObject();
            //Refcount of the variables not increase
            variables = Runtime.PyModule_GetDict(Reference).DangerousGetAddress();
            PythonException.ThrowIfIsNull(variables);

            int res = Runtime.PyDict_SetItem(
                VarsRef, PyIdentifier.__builtins__,
                Runtime.PyEval_GetBuiltins()
                );

            PythonException.ThrowIfIsNotZero(res);
            this.Name = this.Get <string>("__name__");
        }
示例#9
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();
        }
示例#10
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);
        }
示例#11
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);
        }
示例#12
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);
        }
示例#13
0
        /// <summary>
        /// Initialize Method
        /// </summary>
        /// <remarks>
        /// Initialize the Python runtime. It is safe to call this method
        /// more than once, though initialization will only happen on the
        /// first call. It is *not* necessary to hold the Python global
        /// interpreter lock (GIL) to call this method.
        /// initSigs can be set to 1 to do default python signal configuration. This will override the way signals are handled by the application.
        /// </remarks>
        public static void Initialize(IEnumerable <string> args, bool setSysArgv = true, bool initSigs = false)
        {
            if (!initialized)
            {
                // Creating the delegateManager MUST happen before Runtime.Initialize
                // is called. If it happens afterwards, DelegateManager's CodeGenerator
                // throws an exception in its ctor.  This exception is eaten somehow
                // during an initial "import clr", and the world ends shortly thereafter.
                // This is probably masking some bad mojo happening somewhere in Runtime.Initialize().
                delegateManager = new DelegateManager();
                Runtime.Initialize(initSigs);
                initialized = true;
                Exceptions.Clear();

                // Make sure we clean up properly on app domain unload.
                AppDomain.CurrentDomain.DomainUnload += OnDomainUnload;

                // Remember to shut down the runtime.
                AddShutdownHandler(Runtime.Shutdown);

                // The global scope gets used implicitly quite early on, remember
                // to clear it out when we shut down.
                AddShutdownHandler(PyScopeManager.Global.Clear);

                if (setSysArgv)
                {
                    Py.SetArgv(args);
                }

                // register the atexit callback (this doesn't use Py_AtExit as the C atexit
                // callbacks are called after python is fully finalized but the python ones
                // are called while the python engine is still running).
                string code =
                    "import atexit, clr\n" +
                    "atexit.register(clr._AtExit)\n";
                PythonEngine.Exec(code);

                // Load the clr.py resource into the clr module
                IntPtr clr      = Python.Runtime.ImportHook.GetCLRModule();
                IntPtr clr_dict = Runtime.PyModule_GetDict(clr);

                var locals = new PyDict();
                try
                {
                    IntPtr module         = Runtime.PyImport_AddModule("clr._extras");
                    IntPtr module_globals = Runtime.PyModule_GetDict(module);
                    IntPtr builtins       = Runtime.PyEval_GetBuiltins();
                    Runtime.PyDict_SetItemString(module_globals, "__builtins__", builtins);

                    Assembly assembly = Assembly.GetExecutingAssembly();
                    using (Stream stream = assembly.GetManifestResourceStream("clr.py"))
                        using (var reader = new StreamReader(stream))
                        {
                            // add the contents of clr.py to the module
                            string clr_py = reader.ReadToEnd();
                            Exec(clr_py, module_globals, locals.Handle);
                        }

                    // add the imported module to the clr module, and copy the API functions
                    // and decorators into the main clr module.
                    Runtime.PyDict_SetItemString(clr_dict, "_extras", module);
                    foreach (PyObject key in locals.Keys())
                    {
                        if (!key.ToString().StartsWith("_") || key.ToString().Equals("__version__"))
                        {
                            PyObject value = locals[key];
                            Runtime.PyDict_SetItem(clr_dict, key.Handle, value.Handle);
                            value.Dispose();
                        }
                        key.Dispose();
                    }
                }
                finally
                {
                    locals.Dispose();
                }
            }
        }
示例#14
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;

            // 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.
            IntPtr dict = Marshal.ReadIntPtr(tp, TypeOffset.tp_dict);


            IDictionaryEnumerator iter = info.members.GetEnumerator();

            while (iter.MoveNext())
            {
                var item = (ManagedType)iter.Value;
                var name = (string)iter.Key;
                Runtime.PyDict_SetItemString(dict, name, item.pyHandle);
                // Decref the item now that it's been used.
                item.DecrRefCount();
            }

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

            if (attrs.Length == 0)
            {
                doc = IntPtr.Zero;
            }
            else
            {
                var    attr   = (DocStringAttribute)attrs[0];
                string docStr = attr.DocString;
                doc = Runtime.PyString_FromString(docStr);
                Runtime.PyDict_SetItem(dict, PyIdentifier.__doc__, doc);
                Runtime.XDecref(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.ctors.Length > 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.pyHandle);
                        Runtime.PyDict_SetItem(dict, PyIdentifier.Overloads, ctors.pyHandle);
                        ctors.DecrRefCount();
                    }

                    // don't generate the docstring if one was already set from a DocStringAttribute.
                    if (!CLRModule._SuppressDocs && doc == IntPtr.Zero)
                    {
                        doc = co.GetDocString();
                        Runtime.PyDict_SetItem(dict, PyIdentifier.__doc__, doc);
                        Runtime.XDecref(doc);
                    }
                }
            }
        }
示例#15
0
        /// <summary>
        /// Initialize Method
        /// </summary>
        ///
        /// <remarks>
        /// Initialize the Python runtime. It is safe to call this method
        /// more than once, though initialization will only happen on the
        /// first call. It is *not* necessary to hold the Python global
        /// interpreter lock (GIL) to call this method.
        /// </remarks>
        public static void Initialize()
        {
            if (!initialized)
            {
                // Creating the delegateManager MUST happen before Runtime.Initialize
                // is called. If it happens afterwards, DelegateManager's CodeGenerator
                // throws an exception in its ctor.  This exception is eaten somehow
                // during an initial "import clr", and the world ends shortly thereafter.
                // This is probably masking some bad mojo happening somewhere in Runtime.Initialize().
                delegateManager = new DelegateManager();
                Runtime.Initialize();
                initialized = true;
                Exceptions.Clear();

                // register the atexit callback (this doesn't use Py_AtExit as the C atexit
                // callbacks are called after python is fully finalized but the python ones
                // are called while the python engine is still running).
                string code =
                    "import atexit, clr\n" +
                    "atexit.register(clr._AtExit)\n";
                PyObject r = PythonEngine.RunString(code);
                if (r != null)
                {
                    r.Dispose();
                }

                // Load the clr.py resource into the clr module
                IntPtr clr      = Python.Runtime.ImportHook.GetCLRModule();
                IntPtr clr_dict = Runtime.PyModule_GetDict(clr);

                PyDict locals = new PyDict();
                try
                {
                    IntPtr module         = Runtime.PyImport_AddModule("clr._extras");
                    IntPtr module_globals = Runtime.PyModule_GetDict(module);
                    IntPtr builtins       = Runtime.PyEval_GetBuiltins();
                    Runtime.PyDict_SetItemString(module_globals, "__builtins__", builtins);

                    var assembly = Assembly.GetExecutingAssembly();
                    using (Stream stream = assembly.GetManifestResourceStream("clr.py"))
                        using (StreamReader reader = new StreamReader(stream))
                        {
                            // add the contents of clr.py to the module
                            string   clr_py = reader.ReadToEnd();
                            PyObject result = RunString(clr_py, module_globals, locals.Handle);
                            if (null == result)
                            {
                                throw new PythonException();
                            }
                            result.Dispose();
                        }

                    // add the imported module to the clr module, and copy the API functions
                    // and decorators into the main clr module.
                    Runtime.PyDict_SetItemString(clr_dict, "_extras", module);
                    foreach (PyObject key in locals.Keys())
                    {
                        if (!key.ToString().StartsWith("_"))
                        {
                            PyObject value = locals[key];
                            Runtime.PyDict_SetItem(clr_dict, key.Handle, value.Handle);
                            value.Dispose();
                        }
                        key.Dispose();
                    }
                }
                finally
                {
                    locals.Dispose();
                }
            }
        }