/// <summary> /// Implementation of [] semantics for reflected types. This exists /// both to implement the Array[int] syntax for creating arrays and /// to support generic name overload resolution using []. /// </summary> public override IntPtr type_subscript(IntPtr idx) { if (!type.Valid) { return(Exceptions.RaiseTypeError(type.DeletedMessage)); } // If this type is the Array type, the [<type>] means we need to // construct and return an array type of the given element type. if (type.Value == typeof(Array)) { if (Runtime.PyTuple_Check(idx)) { return(Exceptions.RaiseTypeError("type expected")); } var c = GetManagedObject(idx) as ClassBase; Type t = c != null ? c.type.Value : Converter.GetTypeByAlias(idx); if (t == null) { return(Exceptions.RaiseTypeError("type expected")); } Type a = t.MakeArrayType(); ClassBase o = ClassManager.GetClass(a); Runtime.XIncref(o.pyHandle); return(o.pyHandle); } // If there are generics in our namespace with the same base name // as the current type, then [<type>] means the caller wants to // bind the generic type matching the given type parameters. Type[] types = Runtime.PythonArgsToTypeArray(idx); if (types == null) { return(Exceptions.RaiseTypeError("type(s) expected")); } Type gtype = AssemblyManager.LookupTypes($"{type.Value.FullName}`{types.Length}").FirstOrDefault(); if (gtype != null) { var g = ClassManager.GetClass(gtype) as GenericType; return(g.type_subscript(idx)); //Runtime.XIncref(g.pyHandle); //return g.pyHandle; } return(Exceptions.RaiseTypeError("unsubscriptable object")); }
//==================================================================== // Implementation of [] semantics for reflected types. This exists // both to implement the Array[int] syntax for creating arrays and // to support generic name overload resolution using []. //==================================================================== public override IntPtr type_subscript(IntPtr idx) { // If this type is the Array type, the [<type>] means we need to // construct and return an array type of the given element type. if ((this.type) == typeof(Array)) { if (Runtime.PyTuple_Check(idx)) { return(Exceptions.RaiseTypeError("type expected")); } ClassBase c = GetManagedObject(idx) as ClassBase; Type t = (c != null) ? c.type : Converter.GetTypeByAlias(idx); if (t == null) { return(Exceptions.RaiseTypeError("type expected")); } Type a = t.MakeArrayType(); ClassBase o = ClassManager.GetClass(a); Runtime.Incref(o.pyHandle); return(o.pyHandle); } // If there are generics in our namespace with the same base name // as the current type, then [<type>] means the caller wants to // bind the generic type matching the given type parameters. Type[] types = Runtime.PythonArgsToTypeArray(idx); if (types == null) { return(Exceptions.RaiseTypeError("type(s) expected")); } string gname = this.type.FullName + "`" + types.Length.ToString(); Type gtype = AssemblyManager.LookupType(gname); if (gtype != null) { GenericType g = ClassManager.GetClass(gtype) as GenericType; return(g.type_subscript(idx)); /*Runtime.Incref(g.pyHandle); * return g.pyHandle;*/ } return(Exceptions.RaiseTypeError("unsubscriptable object")); }
public static Assembly AddReference(string name) { AssemblyManager.UpdatePath(); Assembly assembly = null; assembly = AssemblyManager.LoadAssemblyPath(name); if (assembly == null) { assembly = AssemblyManager.LoadAssembly(name); } if (assembly == null) { string msg = String.Format("Unable to find assembly '{0}'.", name); throw new System.IO.FileNotFoundException(msg); } return(assembly); }
public static String[] ListAssemblies(bool verbose) { AssemblyName[] assnames = AssemblyManager.ListAssemblies(); String[] names = new String[assnames.Length]; for (int i = 0; i < assnames.Length; i++) { if (verbose) { names[i] = assnames[i].FullName; } else { names[i] = assnames[i].Name; } } return(names); }
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(); }
/// <summary> /// Preloads all currently-known names for the module namespace. This /// can be called multiple times, to add names from assemblies that /// may have been loaded since the last call to the method. /// </summary> public void LoadNames() { ManagedType m = null; foreach (string name in AssemblyManager.GetNames(_namespace)) { cache.TryGetValue(name, out m); if (m != null) { continue; } BorrowedReference attr = Runtime.PyDict_GetItemString(DictRef, name); // If __dict__ has already set a custom property, skip it. if (!attr.IsNull) { continue; } GetAttribute(name, true); } }
/// <summary> /// Preloads all currently-known names for the module namespace. This /// can be called multiple times, to add names from assemblies that /// may have been loaded since the last call to the method. /// </summary> public void LoadNames() { ManagedType m = null; foreach (string name in AssemblyManager.GetNames(_namespace)) { cache.TryGetValue(name, out m); if (m != null) { continue; } IntPtr attr = Runtime.PyDict_GetItemString(dict, name); // If __dict__ has already set a custom property, skip it. if (attr != IntPtr.Zero) { continue; } GetAttribute(name, true); } }
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(); }
//==================================================================== // xxx //==================================================================== public static List <Type> GenericsForType(Type t) { Dictionary <string, List <string> > nsmap = null; mapping.TryGetValue(t.Namespace, out nsmap); if (nsmap == null) { return(null); } string basename = t.Name; int tick = basename.IndexOf("`"); if (tick > -1) { basename = basename.Substring(0, tick); } List <string> names = null; nsmap.TryGetValue(basename, out names); if (names == null) { return(null); } List <Type> result = new List <Type>(); foreach (string name in names) { string qname = t.Namespace + "." + name; Type o = AssemblyManager.LookupType(qname); if (o != null) { result.Add(o); } } return(result); }
public ModuleObject(string name) : base() { 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. string filename = "unknown"; string docstring = "Namespace containing types from the following assemblies:\n\n"; foreach (Assembly a in AssemblyManager.GetAssemblies(name)) { 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(this.GetType()); Runtime.PyDict_SetItemString(dict, "__name__", pyname); Runtime.PyDict_SetItemString(dict, "__file__", pyfilename); Runtime.PyDict_SetItemString(dict, "__doc__", pydocstring); Runtime.PyDict_SetItemString(dict, "__class__", pycls); Runtime.Decref(pyname); Runtime.Decref(pyfilename); Runtime.Decref(pydocstring); Marshal.WriteIntPtr(this.pyHandle, ObjectOffset.DictOffset(this.pyHandle), dict); InitializeModuleMembers(); }
public static List <Type> GenericsByName(string ns, string basename) { Dictionary <string, List <string> > nsmap = null; mapping.TryGetValue(ns, out nsmap); if (nsmap == null) { return(null); } int tick = basename.IndexOf("`"); if (tick > -1) { basename = basename.Substring(0, tick); } List <string> names = null; nsmap.TryGetValue(basename, out names); if (names == null) { return(null); } var result = new List <Type>(); foreach (string name in names) { string qname = ns + "." + name; Type o = AssemblyManager.LookupTypes(qname).FirstOrDefault(); if (o != null) { result.Add(o); } } return(result); }
public static Assembly AddReference(string name) { AssemblyManager.UpdatePath(); var origNs = AssemblyManager.GetNamespaces(); Assembly assembly = null; assembly = AssemblyManager.FindLoadedAssembly(name); if (assembly == null) { assembly = AssemblyManager.LoadAssemblyPath(name); } if (assembly == null && AssemblyManager.TryParseAssemblyName(name) is { } parsedName) { assembly = AssemblyManager.LoadAssembly(parsedName); } if (assembly == null) { assembly = AssemblyManager.LoadAssemblyFullPath(name); } if (assembly == null) { throw new FileNotFoundException($"Unable to find assembly '{name}'."); } // Classes that are not in a namespace needs an extra nudge to be found. ImportHook.UpdateCLRModuleDict(); // A bit heavyhanded, but we can't use the AssemblyManager's AssemblyLoadHandler // method because it may be called from other threads, leading to deadlocks // if it is called while Python code is executing. var currNs = AssemblyManager.GetNamespaces().Except(origNs); foreach (var ns in currNs) { ImportHook.AddNamespaceWithGIL(ns); } return(assembly); }
//=================================================================== // Preloads all currently-known names for the module namespace. This // can be called multiple times, to add names from assemblies that // may have been loaded since the last call to the method. //=================================================================== public void LoadNames() { foreach (string name in AssemblyManager.GetNames(_namespace)) { if (!this.cache.ContainsKey(name)) { ManagedType attr = this.GetAttribute(name); if (Runtime.wrap_exceptions) { if (attr is ClassBase) { ClassBase c = attr as ClassBase; if (c.is_exception) { IntPtr p = attr.pyHandle; IntPtr r = Exceptions.GetExceptionClassWrapper(p); Runtime.PyDict_SetItemString(dict, name, r); Runtime.Incref(r); } } } } } }
/// <summary> /// Preloads all currently-known names for the module namespace. This /// can be called multiple times, to add names from assemblies that /// may have been loaded since the last call to the method. /// </summary> public void LoadNames() { ManagedType m = null; foreach (string name in AssemblyManager.GetNames(_namespace)) { cache.TryGetValue(name, out m); if (m != null) { continue; } BorrowedReference attr = Runtime.PyDict_GetItemString(DictRef, name); // If __dict__ has already set a custom property, skip it. if (!attr.IsNull) { continue; } if (GetAttribute(name, true) != null) { // if it's a valid attribute, add it to __all__ var pyname = Runtime.PyString_FromString(name); try { if (Runtime.PyList_Append(new BorrowedReference(__all__), new BorrowedReference(pyname)) != 0) { throw PythonException.ThrowLastAsClrException(); } } finally { Runtime.XDecref(pyname); } } } }
//=================================================================== // The actual import hook that ties Python to the managed world. //=================================================================== public static IntPtr __import__(IntPtr self, IntPtr args, IntPtr kw) { // Replacement for the builtin __import__. The original import // hook is saved as this.py_import. This version handles CLR // import and defers to the normal builtin for everything else. int num_args = Runtime.PyTuple_Size(args); if (num_args < 1) { return(Exceptions.RaiseTypeError( "__import__() takes at least 1 argument (0 given)" )); } // borrowed reference IntPtr py_mod_name = Runtime.PyTuple_GetItem(args, 0); if ((py_mod_name == IntPtr.Zero) || (!Runtime.IsStringType(py_mod_name))) { return(Exceptions.RaiseTypeError("string expected")); } // Check whether the import is of the form 'from x import y'. // This determines whether we return the head or tail module. IntPtr fromList = IntPtr.Zero; bool fromlist = false; if (num_args >= 4) { fromList = Runtime.PyTuple_GetItem(args, 3); if ((fromList != IntPtr.Zero) && (Runtime.PyObject_IsTrue(fromList) == 1)) { fromlist = true; } } string mod_name = Runtime.GetManagedString(py_mod_name); // Check these BEFORE the built-in import runs; may as well // do the Incref()ed return here, since we've already found // the module. if (mod_name == "clr") { root.InitializePreload(); Runtime.Incref(root.pyHandle); return(root.pyHandle); } if (mod_name == "CLR") { Exceptions.deprecation("The CLR module is deprecated. " + "Please use 'clr'."); root.InitializePreload(); Runtime.Incref(root.pyHandle); return(root.pyHandle); } string realname = mod_name; if (mod_name.StartsWith("CLR.")) { realname = mod_name.Substring(4); string msg = String.Format("Importing from the CLR.* namespace " + "is deprecated. Please import '{0}' directly.", realname); Exceptions.deprecation(msg); } else { // 2010-08-15: Always seemed smart to let python try first... // This shaves off a few tenths of a second on test_module.py // and works around a quirk where 'sys' is found by the // LoadImplicit() deprecation logic. // Turns out that the AssemblyManager.ResolveHandler() checks to see if any // Assembly's FullName.ToLower().StartsWith(name.ToLower()), which makes very // little sense to me. IntPtr res = Runtime.PyObject_Call(py_import, args, kw); if (res != IntPtr.Zero) { // There was no error. return(res); } // There was an error if (!Exceptions.ExceptionMatches(Exceptions.ImportError)) { // and it was NOT an ImportError; bail out here. return(IntPtr.Zero); } // Otherwise, just clear the it. Exceptions.Clear(); } string[] names = realname.Split('.'); // Now we need to decide if the name refers to a CLR module, // and may have to do an implicit load (for b/w compatibility) // using the AssemblyManager. The assembly manager tries // really hard not to use Python objects or APIs, because // parts of it can run recursively and on strange threads. // // It does need an opportunity from time to time to check to // see if sys.path has changed, in a context that is safe. Here // we know we have the GIL, so we'll let it update if needed. AssemblyManager.UpdatePath(); if (!AssemblyManager.IsValidNamespace(realname)) { bool fromFile = false; if (AssemblyManager.LoadImplicit(realname, out fromFile)) { if (true == fromFile) { string deprWarning = String.Format("\nThe module was found, but not in a referenced namespace.\n" + "Implicit loading is deprecated. Please use clr.AddReference(\"{0}\").", realname); Exceptions.deprecation(deprWarning); } } else { // May be called when a module being imported imports a module. // In particular, I've seen decimal import copy import org.python.core return(Runtime.PyObject_Call(py_import, args, kw)); } } // See if sys.modules for this interpreter already has the // requested module. If so, just return the exising module. IntPtr modules = Runtime.PyImport_GetModuleDict(); IntPtr module = Runtime.PyDict_GetItem(modules, py_mod_name); if (module != IntPtr.Zero) { if (fromlist) { Runtime.Incref(module); return(module); } module = Runtime.PyDict_GetItemString(modules, names[0]); Runtime.Incref(module); return(module); } Exceptions.Clear(); // Traverse the qualified module name to get the named module // and place references in sys.modules as we go. Note that if // we are running in interactive mode we pre-load the names in // each module, which is often useful for introspection. If we // are not interactive, we stick to just-in-time creation of // objects at lookup time, which is much more efficient. // NEW: The clr got a new module variable preload. You can // enable preloading in a non-interactive python processing by // setting clr.preload = True ModuleObject head = (mod_name == realname) ? null : root; ModuleObject tail = root; root.InitializePreload(); for (int i = 0; i < names.Length; i++) { string name = names[i]; ManagedType mt = tail.GetAttribute(name, true); if (!(mt is ModuleObject)) { string error = String.Format("No module named {0}", name); Exceptions.SetError(Exceptions.ImportError, error); return(IntPtr.Zero); } if (head == null) { head = (ModuleObject)mt; } tail = (ModuleObject)mt; if (CLRModule.preload) { tail.LoadNames(); } Runtime.PyDict_SetItemString(modules, tail.moduleName, tail.pyHandle ); } ModuleObject mod = fromlist ? tail : head; if (fromlist && Runtime.PySequence_Size(fromList) == 1) { IntPtr fp = Runtime.PySequence_GetItem(fromList, 0); if ((!CLRModule.preload) && Runtime.GetManagedString(fp) == "*") { mod.LoadNames(); } Runtime.Decref(fp); } Runtime.Incref(mod.pyHandle); return(mod.pyHandle); }
public static string FindAssembly(string name) { AssemblyManager.UpdatePath(); return(AssemblyManager.FindAssembly(name)); }
/// <summary> /// Returns a ClassBase object representing a type that appears in /// this module's namespace or a ModuleObject representing a child /// namespace (or null if the name is not found). This method does /// not increment the Python refcount of the returned object. /// </summary> public ManagedType GetAttribute(string name, bool guess) { ManagedType cached = null; cache.TryGetValue(name, out cached); if (cached != null) { return(cached); } ModuleObject m; ClassBase c; Type type; //if (AssemblyManager.IsValidNamespace(name)) //{ // IntPtr py_mod_name = Runtime.PyString_FromString(name); // IntPtr modules = Runtime.PyImport_GetModuleDict(); // IntPtr module = Runtime.PyDict_GetItem(modules, py_mod_name); // if (module != IntPtr.Zero) // return (ManagedType)this; // return null; //} string qname = _namespace == string.Empty ? name : _namespace + "." + name; // If the fully-qualified name of the requested attribute is // a namespace exported by a currently loaded assembly, return // a new ModuleObject representing that namespace. if (AssemblyManager.IsValidNamespace(qname)) { m = new ModuleObject(qname); StoreAttribute(name, m); return(m); } // Look for a type in the current namespace. Note that this // includes types, delegates, enums, interfaces and structs. // Only public namespace members are exposed to Python. type = AssemblyManager.LookupType(qname); if (type != null) { if (!type.IsPublic) { return(null); } c = ClassManager.GetClass(type); StoreAttribute(name, c); return(c); } // This is a little repetitive, but it ensures that the right // thing happens with implicit assembly loading at a reasonable // cost. Ask the AssemblyManager to do implicit loading for each // of the steps in the qualified name, then try it again. bool ignore = name.StartsWith("__"); if (AssemblyManager.LoadImplicit(qname, !ignore)) { if (AssemblyManager.IsValidNamespace(qname)) { m = new ModuleObject(qname); StoreAttribute(name, m); return(m); } type = AssemblyManager.LookupType(qname); if (type != null) { if (!type.IsPublic) { return(null); } c = ClassManager.GetClass(type); StoreAttribute(name, c); return(c); } } // We didn't find the name, so we may need to see if there is a // generic type with this base name. If so, we'll go ahead and // return it. Note that we store the mapping of the unmangled // name to generic type - it is technically possible that some // future assembly load could contribute a non-generic type to // the current namespace with the given basename, but unlikely // enough to complicate the implementation for now. if (guess) { string gname = GenericUtil.GenericNameForBaseName(_namespace, name); if (gname != null) { ManagedType o = GetAttribute(gname, false); if (o != null) { StoreAttribute(name, o); return(o); } } } return(null); }
//=================================================================== // Returns a ClassBase object representing a type that appears in // this module's namespace or a ModuleObject representing a child // namespace (or null if the name is not found). This method does // not increment the Python refcount of the returned object. //=================================================================== public ManagedType GetAttribute(string name) { Object ob = this.cache[name]; if (ob != null) { return((ManagedType)ob); } string qname = (_namespace == String.Empty) ? name : _namespace + "." + name; ModuleObject m; ClassBase c; // If the fully-qualified name of the requested attribute is // a namespace exported by a currently loaded assembly, return // a new ModuleObject representing that namespace. if (AssemblyManager.IsValidNamespace(qname)) { m = new ModuleObject(qname); StoreAttribute(name, m); return((ManagedType)m); } // Look for a type in the current namespace. Note that this // includes types, delegates, enums, interfaces and structs. // Only public namespace members are exposed to Python. Type type = AssemblyManager.LookupType(qname); if (type != null) { if (!type.IsPublic) { return(null); } c = ClassManager.GetClass(type); StoreAttribute(name, c); return((ManagedType)c); } // This is a little repetitive, but it ensures that the right // thing happens with implicit assembly loading at a reasonable // cost. Ask the AssemblyManager to do implicit loading for each // of the steps in the qualified name, then try it again. if (AssemblyManager.LoadImplicit(qname)) { if (AssemblyManager.IsValidNamespace(qname)) { m = new ModuleObject(qname); StoreAttribute(name, m); return((ManagedType)m); } type = AssemblyManager.LookupType(qname); if (type != null) { if (!type.IsPublic) { return(null); } c = ClassManager.GetClass(type); StoreAttribute(name, c); return((ManagedType)c); } } return(null); }
/// <summary> /// Creates a new managed type derived from a base type with any virtual /// methods overridden to call out to python if the associated python /// object has overridden the method. /// </summary> internal static Type CreateDerivedType(string name, Type baseType, BorrowedReference dictRef, string namespaceStr, string assemblyName, string moduleName = "Python.Runtime.Dynamic.dll") { // TODO: clean up IntPtr py_dict = dictRef.DangerousGetAddress(); if (null != namespaceStr) { name = namespaceStr + "." + name; } if (null == assemblyName) { assemblyName = "Python.Runtime.Dynamic"; } ModuleBuilder moduleBuilder = GetModuleBuilder(assemblyName, moduleName); Type baseClass = baseType; var interfaces = new List <Type> { typeof(IPythonDerivedType) }; // if the base type is an interface then use System.Object as the base class // and add the base type to the list of interfaces this new class will implement. if (baseType.IsInterface) { interfaces.Add(baseType); baseClass = typeof(object); } TypeBuilder typeBuilder = moduleBuilder.DefineType(name, TypeAttributes.Public | TypeAttributes.Class, baseClass, interfaces.ToArray()); // add a field for storing the python object pointer // FIXME: fb not used FieldBuilder fb = typeBuilder.DefineField("__pyobj__", typeof(CLRObject), FieldAttributes.Public); // override any constructors ConstructorInfo[] constructors = baseClass.GetConstructors(); foreach (ConstructorInfo ctor in constructors) { AddConstructor(ctor, baseType, typeBuilder); } // Override any properties explicitly overridden in python var pyProperties = new HashSet <string>(); if (py_dict != IntPtr.Zero && Runtime.PyDict_Check(py_dict)) { Runtime.XIncref(py_dict); using (var dict = new PyDict(py_dict)) using (PyObject keys = dict.Keys()) { foreach (PyObject pyKey in keys) { using (PyObject value = dict[pyKey]) { if (value.HasAttr("_clr_property_type_")) { string propertyName = pyKey.ToString(); pyProperties.Add(propertyName); // Add the property to the type AddPythonProperty(propertyName, value, typeBuilder); } } } } } // override any virtual methods not already overridden by the properties above MethodInfo[] methods = baseType.GetMethods(); var virtualMethods = new HashSet <string>(); foreach (MethodInfo method in methods) { if (!method.Attributes.HasFlag(MethodAttributes.Virtual) | method.Attributes.HasFlag(MethodAttributes.Final)) { continue; } // skip if this property has already been overridden if ((method.Name.StartsWith("get_") || method.Name.StartsWith("set_")) && pyProperties.Contains(method.Name.Substring(4))) { continue; } // keep track of the virtual methods redirected to the python instance virtualMethods.Add(method.Name); // override the virtual method to call out to the python method, if there is one. AddVirtualMethod(method, baseType, typeBuilder); } // Add any additional methods and properties explicitly exposed from Python. if (py_dict != IntPtr.Zero && Runtime.PyDict_Check(py_dict)) { Runtime.XIncref(py_dict); using (var dict = new PyDict(py_dict)) using (PyObject keys = dict.Keys()) { foreach (PyObject pyKey in keys) { using (PyObject value = dict[pyKey]) { if (value.HasAttr("_clr_return_type_") && value.HasAttr("_clr_arg_types_")) { string methodName = pyKey.ToString(); // if this method has already been redirected to the python method skip it if (virtualMethods.Contains(methodName)) { continue; } // Add the method to the type AddPythonMethod(methodName, value, typeBuilder); } } } } } // add the destructor so the python object created in the constructor gets destroyed MethodBuilder methodBuilder = typeBuilder.DefineMethod("Finalize", MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.HideBySig, CallingConventions.Standard, typeof(void), Type.EmptyTypes); ILGenerator il = methodBuilder.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Call, typeof(PythonDerivedType).GetMethod("Finalize")); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Call, baseClass.GetMethod("Finalize", BindingFlags.NonPublic | BindingFlags.Instance)); il.Emit(OpCodes.Ret); Type type = typeBuilder.CreateType(); // scan the assembly so the newly added class can be imported Assembly assembly = Assembly.GetAssembly(type); AssemblyManager.ScanAssembly(assembly); // FIXME: assemblyBuilder not used AssemblyBuilder assemblyBuilder = assemblyBuilders[assemblyName]; return(type); }
/// <summary> /// The actual import hook that ties Python to the managed world. /// </summary> public static IntPtr __import__(IntPtr self, IntPtr args, IntPtr kw) { // Replacement for the builtin __import__. The original import // hook is saved as this.py_import. This version handles CLR // import and defers to the normal builtin for everything else. var num_args = Runtime.PyTuple_Size(args); if (num_args < 1) { return(Exceptions.RaiseTypeError("__import__() takes at least 1 argument (0 given)")); } // borrowed reference IntPtr py_mod_name = Runtime.PyTuple_GetItem(args, 0); if (py_mod_name == IntPtr.Zero || !Runtime.IsStringType(py_mod_name)) { return(Exceptions.RaiseTypeError("string expected")); } // Check whether the import is of the form 'from x import y'. // This determines whether we return the head or tail module. IntPtr fromList = IntPtr.Zero; var fromlist = false; if (num_args >= 4) { fromList = Runtime.PyTuple_GetItem(args, 3); if (fromList != IntPtr.Zero && Runtime.PyObject_IsTrue(fromList) == 1) { fromlist = true; } } string mod_name = Runtime.GetManagedString(py_mod_name); // Check these BEFORE the built-in import runs; may as well // do the Incref()ed return here, since we've already found // the module. if (mod_name == "clr" || mod_name == "CLR") { if (mod_name == "CLR") { Exceptions.deprecation("The CLR module is deprecated. Please use 'clr'."); } IntPtr clr_module = GetCLRModule(fromList); if (clr_module != IntPtr.Zero) { IntPtr sys_modules = Runtime.PyImport_GetModuleDict(); if (sys_modules != IntPtr.Zero) { Runtime.PyDict_SetItemString(sys_modules, "clr", clr_module); } } return(clr_module); } string realname = mod_name; string clr_prefix = null; if (mod_name.StartsWith("CLR.")) { clr_prefix = "CLR."; // prepend when adding the module to sys.modules realname = mod_name.Substring(4); string msg = $"Importing from the CLR.* namespace is deprecated. Please import '{realname}' directly."; Exceptions.deprecation(msg); } else { // 2010-08-15: Always seemed smart to let python try first... // This shaves off a few tenths of a second on test_module.py // and works around a quirk where 'sys' is found by the // LoadImplicit() deprecation logic. // Turns out that the AssemblyManager.ResolveHandler() checks to see if any // Assembly's FullName.ToLower().StartsWith(name.ToLower()), which makes very // little sense to me. IntPtr res = Runtime.PyObject_Call(py_import, args, kw); if (res != IntPtr.Zero) { // There was no error. if (fromlist && IsLoadAll(fromList)) { var mod = ManagedType.GetManagedObject(res) as ModuleObject; mod?.LoadNames(); } return(res); } // There was an error if (!Exceptions.ExceptionMatches(Exceptions.ImportError)) { // and it was NOT an ImportError; bail out here. return(IntPtr.Zero); } if (mod_name == string.Empty) { // Most likely a missing relative import. // For example site-packages\bs4\builder\__init__.py uses it to check if a package exists: // from . import _html5lib // We don't support them anyway return(IntPtr.Zero); } // Otherwise, just clear the it. Exceptions.Clear(); } string[] names = realname.Split('.'); // Now we need to decide if the name refers to a CLR module, // and may have to do an implicit load (for b/w compatibility) // using the AssemblyManager. The assembly manager tries // really hard not to use Python objects or APIs, because // parts of it can run recursively and on strange threads. // // It does need an opportunity from time to time to check to // see if sys.path has changed, in a context that is safe. Here // we know we have the GIL, so we'll let it update if needed. AssemblyManager.UpdatePath(); if (!AssemblyManager.IsValidNamespace(realname)) { var loadExceptions = new List <Exception>(); if (!AssemblyManager.LoadImplicit(realname, assemblyLoadErrorHandler: loadExceptions.Add)) { // May be called when a module being imported imports a module. // In particular, I've seen decimal import copy import org.python.core IntPtr importResult = Runtime.PyObject_Call(py_import, args, kw); // TODO: use ModuleNotFoundError in Python 3.6+ if (importResult == IntPtr.Zero && loadExceptions.Count > 0 && Exceptions.ExceptionMatches(Exceptions.ImportError)) { loadExceptions.Add(new PythonException()); var importError = new PyObject(new BorrowedReference(Exceptions.ImportError)); importError.SetAttr("__cause__", new AggregateException(loadExceptions).ToPython()); Runtime.PyErr_SetObject(new BorrowedReference(Exceptions.ImportError), importError.Reference); } return(importResult); } } // See if sys.modules for this interpreter already has the // requested module. If so, just return the existing module. IntPtr modules = Runtime.PyImport_GetModuleDict(); IntPtr module = Runtime.PyDict_GetItem(modules, py_mod_name); if (module != IntPtr.Zero) { if (fromlist) { if (IsLoadAll(fromList)) { var mod = ManagedType.GetManagedObject(module) as ModuleObject; mod?.LoadNames(); } Runtime.XIncref(module); return(module); } if (clr_prefix != null) { return(GetCLRModule(fromList)); } module = Runtime.PyDict_GetItemString(modules, names[0]); Runtime.XIncref(module); return(module); } Exceptions.Clear(); // Traverse the qualified module name to get the named module // and place references in sys.modules as we go. Note that if // we are running in interactive mode we pre-load the names in // each module, which is often useful for introspection. If we // are not interactive, we stick to just-in-time creation of // objects at lookup time, which is much more efficient. // NEW: The clr got a new module variable preload. You can // enable preloading in a non-interactive python processing by // setting clr.preload = True ModuleObject head = mod_name == realname ? null : root; ModuleObject tail = root; root.InitializePreload(); foreach (string name in names) { ManagedType mt = tail.GetAttribute(name, true); if (!(mt is ModuleObject)) { Exceptions.SetError(Exceptions.ImportError, $"No module named {name}"); return(IntPtr.Zero); } if (head == null) { head = (ModuleObject)mt; } tail = (ModuleObject)mt; if (CLRModule.preload) { tail.LoadNames(); } // Add the module to sys.modules Runtime.PyDict_SetItemString(modules, tail.moduleName, tail.pyHandle); // If imported from CLR add CLR.<modulename> to sys.modules as well if (clr_prefix != null) { Runtime.PyDict_SetItemString(modules, clr_prefix + tail.moduleName, tail.pyHandle); } } { var mod = fromlist ? tail : head; if (fromlist && IsLoadAll(fromList)) { mod.LoadNames(); } Runtime.XIncref(mod.pyHandle); return(mod.pyHandle); } }
public static Type GetCOMObjectType(ITypeInfo info) { Guid guid = GetTypeInfoGuid(info); Type result = null; //If we've found it previously, no need to look again #region Check Type Cache s_Cache.TryGetValue(guid, out result); if (result != null) { return(result); } #endregion //Works for most of the cases #region Check AssemblyManager Assemblies AssemblyName[] names = AssemblyManager.ListAssemblies(); foreach (AssemblyName an in names) { try { Assembly a = Assembly.Load(an); Type[] aTypes = a.GetTypes(); foreach (Type t in aTypes) { if (t.IsInterface && t.IsImport && t.GUID == guid && !t.Name.StartsWith("_")) { result = t; List <Type> possible = aTypes.Where(x => x.Name.Equals(t.Name + "Class", StringComparison.Ordinal)).ToList <Type>(); if (possible.Count > 0) { s_Cache.Add(guid, result); return(result); } } } } catch (Exception ex) { } } if (result != null) { s_Cache.Add(guid, result); return(result); } #endregion //Extended check of assemblies #region Check CurrentDomain Assemblies Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly a in assemblies) { Type[] aTypes = a.GetTypes(); foreach (Type t in aTypes) { if (t.IsInterface && t.IsImport && t.GUID == guid && !t.Name.StartsWith("_")) { result = t; List <Type> possible = aTypes.Where(x => x.Name.Equals(t.Name + "Class", StringComparison.Ordinal)).ToList <Type>(); if (possible.Count > 0) { s_Cache.Add(guid, result); return(result); } } } } if (result != null) { s_Cache.Add(guid, result); return(result); } #endregion //Almost never works for my cases but worth a shot i guess #region Check Type CLSID result = Type.GetTypeFromCLSID(guid); if (result != null) { s_Cache.Add(guid, result); return(result); } #endregion //Reliable but incredibly slow, like really really really slow #region Get Type for ITypeInfo IntPtr pInfo = Marshal.GetIUnknownForObject(info); result = Marshal.GetTypeForITypeInfo(pInfo); s_Cache.Add(guid, result); return(result); #endregion }
//=================================================================== // The actual import hook that ties Python to the managed world. //=================================================================== public static IntPtr __import__(IntPtr self, IntPtr args, IntPtr kw) { // Replacement for the builtin __import__. The original import // hook is saved as this.py_import. This version handles CLR // import and defers to the normal builtin for everything else. int num_args = Runtime.PyTuple_Size(args); if (num_args < 1) { return(Exceptions.RaiseTypeError( "__import__() takes at least 1 argument (0 given)" )); } // borrowed reference IntPtr py_mod_name = Runtime.PyTuple_GetItem(args, 0); if ((py_mod_name == IntPtr.Zero) || (!Runtime.IsStringType(py_mod_name))) { return(Exceptions.RaiseTypeError("string expected")); } // Check whether the import is of the form 'from x import y'. // This determines whether we return the head or tail module. IntPtr fromList = IntPtr.Zero; bool fromlist = false; if (num_args >= 4) { fromList = Runtime.PyTuple_GetItem(args, 3); if ((fromList != IntPtr.Zero) && (Runtime.PyObject_IsTrue(fromList) == 1)) { fromlist = true; } } string mod_name = Runtime.GetManagedString(py_mod_name); if (mod_name == "CLR") { Exceptions.deprecation("The CLR module is deprecated. " + "Please use 'clr'."); root.InitializePreload(); Runtime.Incref(root.pyHandle); return(root.pyHandle); } if (mod_name == "clr") { root.InitializePreload(); Runtime.Incref(root.pyHandle); return(root.pyHandle); } string realname = mod_name; if (mod_name.StartsWith("CLR.")) { realname = mod_name.Substring(4); string msg = String.Format("Importing from the CLR.* namespace " + "is deprecated. Please import '{0}' directly.", realname); Exceptions.deprecation(msg); } string[] names = realname.Split('.'); // Now we need to decide if the name refers to a CLR module, // and may have to do an implicit load (for b/w compatibility) // using the AssemblyManager. The assembly manager tries // really hard not to use Python objects or APIs, because // parts of it can run recursively and on strange threads. // // It does need an opportunity from time to time to check to // see if sys.path has changed, in a context that is safe. Here // we know we have the GIL, so we'll let it update if needed. AssemblyManager.UpdatePath(); AssemblyManager.LoadImplicit(realname); if (!AssemblyManager.IsValidNamespace(realname)) { return(Runtime.PyObject_Call(py_import, args, kw)); } // See if sys.modules for this interpreter already has the // requested module. If so, just return the exising module. IntPtr modules = Runtime.PyImport_GetModuleDict(); IntPtr module = Runtime.PyDict_GetItem(modules, py_mod_name); if (module != IntPtr.Zero) { if (fromlist) { Runtime.Incref(module); return(module); } module = Runtime.PyDict_GetItemString(modules, names[0]); Runtime.Incref(module); return(module); } Exceptions.Clear(); // Traverse the qualified module name to get the named module // and place references in sys.modules as we go. Note that if // we are running in interactive mode we pre-load the names in // each module, which is often useful for introspection. If we // are not interactive, we stick to just-in-time creation of // objects at lookup time, which is much more efficient. // NEW: The clr got a new module variable preload. You can // enable preloading in a non-interactive python processing by // setting clr.preload = True ModuleObject head = (mod_name == realname) ? null : root; ModuleObject tail = root; root.InitializePreload(); for (int i = 0; i < names.Length; i++) { string name = names[i]; ManagedType mt = tail.GetAttribute(name, true); if (!(mt is ModuleObject)) { string error = String.Format("No module named {0}", name); Exceptions.SetError(Exceptions.ImportError, error); return(IntPtr.Zero); } if (head == null) { head = (ModuleObject)mt; } tail = (ModuleObject)mt; if (CLRModule.preload) { tail.LoadNames(); } Runtime.PyDict_SetItemString(modules, tail.moduleName, tail.pyHandle ); } ModuleObject mod = fromlist ? tail : head; if (fromlist && Runtime.PySequence_Size(fromList) == 1) { IntPtr fp = Runtime.PySequence_GetItem(fromList, 0); if ((!CLRModule.preload) && Runtime.GetManagedString(fp) == "*") { mod.LoadNames(); } Runtime.Decref(fp); } Runtime.Incref(mod.pyHandle); return(mod.pyHandle); }
//==================================================================== // Creates a new managed type derived from a base type with any virtual // methods overriden to call out to python if the associated python // object has overriden the method. //==================================================================== internal static Type CreateDerivedType(string name, Type baseType, string namespaceStr, string assemblyName, string moduleName = "Python.Runtime.Dynamic.dll") { if (null != namespaceStr) { name = namespaceStr + "." + name; } if (null == assemblyName) { assemblyName = Assembly.GetExecutingAssembly().FullName; } ModuleBuilder moduleBuilder = GetModuleBuilder(assemblyName, moduleName); TypeBuilder typeBuilder; Type baseClass = baseType; List <Type> interfaces = new List <Type> { typeof(IPythonDerivedType) }; // if the base type is an interface then use System.Object as the base class // and add the base type to the list of interfaces this new class will implement. if (baseType.IsInterface) { interfaces.Add(baseType); baseClass = typeof(System.Object); } typeBuilder = moduleBuilder.DefineType(name, TypeAttributes.Public | TypeAttributes.Class, baseClass, interfaces.ToArray()); ILGenerator il; MethodBuilder mb; // add a field for storing the python object pointer FieldBuilder fb = typeBuilder.DefineField("__pyobj__", typeof(CLRObject), FieldAttributes.Public); // override any constructors ConstructorInfo[] constructors = baseClass.GetConstructors(); foreach (ConstructorInfo ctor in constructors) { ParameterInfo[] parameters = ctor.GetParameters(); Type[] parameterTypes = (from param in parameters select param.ParameterType).ToArray(); // create a method for calling the original constructor string baseCtorName = "_" + baseType.Name + "__cinit__"; mb = typeBuilder.DefineMethod(baseCtorName, MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.HideBySig, typeof(void), parameterTypes); // emit the assembly for calling the original method using call instead of callvirt il = mb.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); for (int i = 0; i < parameters.Length; ++i) { il.Emit(OpCodes.Ldarg, i + 1); } il.Emit(OpCodes.Call, ctor); il.Emit(OpCodes.Ret); // override the original method with a new one that dispatches to python ConstructorBuilder cb = typeBuilder.DefineConstructor(MethodAttributes.Public | MethodAttributes.ReuseSlot | MethodAttributes.HideBySig, ctor.CallingConvention, parameterTypes); il = cb.GetILGenerator(); il.DeclareLocal(typeof(Object[])); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldstr, baseCtorName); il.Emit(OpCodes.Ldc_I4, parameters.Length); il.Emit(OpCodes.Newarr, typeof(System.Object)); il.Emit(OpCodes.Stloc_0); for (int i = 0; i < parameters.Length; ++i) { il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Ldc_I4, i); il.Emit(OpCodes.Ldarg, i + 1); if (parameterTypes[i].IsValueType) { il.Emit(OpCodes.Box, parameterTypes[i]); } il.Emit(OpCodes.Stelem, typeof(Object)); } il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Call, typeof(PythonDerivedType).GetMethod("InvokeCtor")); il.Emit(OpCodes.Ret); } // override any virtual methods MethodInfo[] methods = baseType.GetMethods(); foreach (MethodInfo method in methods) { if (!method.Attributes.HasFlag(MethodAttributes.Virtual) | method.Attributes.HasFlag(MethodAttributes.Final)) { continue; } ParameterInfo[] parameters = method.GetParameters(); Type[] parameterTypes = (from param in parameters select param.ParameterType).ToArray(); // create a method for calling the original method string baseMethodName = "_" + baseType.Name + "__" + method.Name; mb = typeBuilder.DefineMethod(baseMethodName, MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.HideBySig, method.ReturnType, parameterTypes); // emit the assembly for calling the original method using call instead of callvirt il = mb.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); for (int i = 0; i < parameters.Length; ++i) { il.Emit(OpCodes.Ldarg, i + 1); } il.Emit(OpCodes.Call, method); il.Emit(OpCodes.Ret); // override the original method with a new one that dispatches to python mb = typeBuilder.DefineMethod(method.Name, MethodAttributes.Public | MethodAttributes.ReuseSlot | MethodAttributes.Virtual | MethodAttributes.HideBySig, method.CallingConvention, method.ReturnType, parameterTypes); il = mb.GetILGenerator(); il.DeclareLocal(typeof(Object[])); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldstr, method.Name); il.Emit(OpCodes.Ldstr, baseMethodName); il.Emit(OpCodes.Ldc_I4, parameters.Length); il.Emit(OpCodes.Newarr, typeof(System.Object)); il.Emit(OpCodes.Stloc_0); for (int i = 0; i < parameters.Length; ++i) { il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Ldc_I4, i); il.Emit(OpCodes.Ldarg, i + 1); if (parameterTypes[i].IsValueType) { il.Emit(OpCodes.Box, parameterTypes[i]); } il.Emit(OpCodes.Stelem, typeof(Object)); } il.Emit(OpCodes.Ldloc_0); if (method.ReturnType == typeof(void)) { il.Emit(OpCodes.Call, typeof(PythonDerivedType).GetMethod("InvokeMethodVoid")); } else { il.Emit(OpCodes.Call, typeof(PythonDerivedType).GetMethod("InvokeMethod").MakeGenericMethod(method.ReturnType)); } il.Emit(OpCodes.Ret); } // add the destructor so the python object created in the constructor gets destroyed mb = typeBuilder.DefineMethod("Finalize", MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.HideBySig, CallingConventions.Standard, typeof(void), Type.EmptyTypes); il = mb.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Call, typeof(PythonDerivedType).GetMethod("Finalize")); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Call, baseClass.GetMethod("Finalize", BindingFlags.NonPublic | BindingFlags.Instance)); il.Emit(OpCodes.Ret); Type type = typeBuilder.CreateType(); // scan the assembly so the newly added class can be imported Assembly assembly = Assembly.GetAssembly(type); AssemblyManager.ScanAssembly(assembly); return(type); }
/// <summary> /// Initialize the runtime... /// </summary> internal static void Initialize() { if (Interop.Py_IsInitialized() == 0) { Interop.Py_Initialize(); } if (Interop.PyEval_ThreadsInitialized() == 0) { Interop.PyEval_InitThreads(); } IntPtr op; IntPtr dict; if (IsPython3) { op = Interop.PyImport_ImportModule("builtins"); dict = Interop.PyObject_GetAttrString(op, "__dict__"); } else // Python2 { dict = Interop.PyImport_GetModuleDict(); op = Interop.PyDict_GetItemString(dict, "__builtin__"); } PyNotImplemented = Interop.PyObject_GetAttrString(op, "NotImplemented"); PyBaseObjectType = Interop.PyObject_GetAttrString(op, "object"); PyModuleType = PyObject_Type(op); PyNone = Interop.PyObject_GetAttrString(op, "None"); PyTrue = Interop.PyObject_GetAttrString(op, "True"); PyFalse = Interop.PyObject_GetAttrString(op, "False"); PyBoolType = PyObject_Type(PyTrue); PyNoneType = PyObject_Type(PyNone); PyTypeType = PyObject_Type(PyNoneType); op = Interop.PyObject_GetAttrString(dict, "keys"); PyMethodType = PyObject_Type(op); XDecref(op); // For some arcane reason, builtins.__dict__.__setitem__ is *not* // a wrapper_descriptor, even though dict.__setitem__ is. // // object.__init__ seems safe, though. op = Interop.PyObject_GetAttrString(PyBaseObjectType, "__init__"); PyWrapperDescriptorType = PyObject_Type(op); XDecref(op); #if PYTHON3 XDecref(dict); #endif op = PyString_FromString("string"); PyStringType = PyObject_Type(op); XDecref(op); op = PyUnicode_FromString("unicode"); PyUnicodeType = PyObject_Type(op); XDecref(op); #if PYTHON3 op = Interop.PyBytes_FromString("bytes"); PyBytesType = PyObject_Type(op); XDecref(op); #endif op = Interop.PyTuple_New(0); PyTupleType = PyObject_Type(op); XDecref(op); op = Interop.PyList_New(0); PyListType = PyObject_Type(op); XDecref(op); op = Interop.PyDict_New(); PyDictType = PyObject_Type(op); XDecref(op); op = PyInt_FromInt32(0); PyIntType = PyObject_Type(op); XDecref(op); op = Interop.PyLong_FromLong(0); PyLongType = PyObject_Type(op); XDecref(op); op = Interop.PyFloat_FromDouble(0); PyFloatType = PyObject_Type(op); XDecref(op); #if PYTHON3 PyClassType = IntPtr.Zero; PyInstanceType = IntPtr.Zero; #elif PYTHON2 IntPtr s = Interop.PyString_FromString("_temp"); IntPtr d = Interop.PyDict_New(); IntPtr c = Interop.PyClass_New(IntPtr.Zero, d, s); PyClassType = Interop.PyObject_Type(c); IntPtr i = Interop.PyInstance_New(c, IntPtr.Zero, IntPtr.Zero); PyInstanceType = Interop.PyObject_Type(i); XDecref(s); XDecref(i); XDecref(c); XDecref(d); #endif Error = new IntPtr(-1); IntPtr dllLocal = IntPtr.Zero; if (Interop.GetDllName() != "__Internal") { if (OS.IsLinux) { dllLocal = NativeMethods_Linux.LoadLibrary(Interop.GetDllName()); } else if (OS.IsOSX) { dllLocal = NativeMethods_OSX.LoadLibrary(Interop.GetDllName()); } else if (OS.IsWindows) { dllLocal = NativeMethods_Windows.LoadLibrary(Interop.GetDllName()); } } if (OS.IsLinux) { _PyObject_NextNotImplemented = NativeMethods_Linux.GetProcAddress(dllLocal, "_PyObject_NextNotImplemented"); } else if (OS.IsOSX) { _PyObject_NextNotImplemented = NativeMethods_OSX.GetProcAddress(dllLocal, "_PyObject_NextNotImplemented"); } else if (OS.IsWindows) { _PyObject_NextNotImplemented = NativeMethods_Windows.GetProcAddress(dllLocal, "_PyObject_NextNotImplemented"); } if (OS.IsWindows && dllLocal != IntPtr.Zero) { NativeMethods_Windows.FreeLibrary(dllLocal); } // Initialize modules that depend on the runtime class. AssemblyManager.Initialize(); PyCLRMetaType = MetaType.Initialize(); Exceptions.Initialize(); ImportHook.Initialize(); // Need to add the runtime directory to sys.path so that we // can find built-in assemblies like System.Data, et. al. string rtdir = RuntimeEnvironment.GetRuntimeDirectory(); IntPtr path = Interop.PySys_GetObject("path"); IntPtr item = PyString_FromString(rtdir); Interop.PyList_Append(path, item); XDecref(item); AssemblyManager.UpdatePath(); }