diff --git a/CHANGELOG.md b/CHANGELOG.md index 3dc668b0c..a95a9aa81 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ This document follows the conventions laid out in [Keep a CHANGELOG][]. ## [unreleased][] ### Added +- Optimized implicit assembly loading on module import, PythonEngine.ImplicitAssemblyLoading event added. - Added support for embedding python into dotnet core 2.0 (NetStandard 2.0) - Added new build system (pythonnet.15.sln) based on dotnetcore-sdk/xplat(crossplatform msbuild). Currently there two side-by-side build systems that produces the same output (net40) from the same sources. diff --git a/src/runtime/assemblymanager.cs b/src/runtime/assemblymanager.cs index d63930a58..59afc0e90 100644 --- a/src/runtime/assemblymanager.cs +++ b/src/runtime/assemblymanager.cs @@ -196,7 +196,17 @@ public static Assembly LoadAssembly(string name) Assembly assembly = null; try { - assembly = Assembly.Load(name); + var importEvent = new ImplicitAssemblyLoadingEventArgs(name); + if (importEvent.SkipAssemblyLoad) + { + return null; + } + + PythonEngine.RaiseAssemblyAsModuleImportingEvent(importEvent); + if (!importEvent.SkipAssemblyLoad) + { + assembly = Assembly.Load(name); + } } catch (Exception) { @@ -343,8 +353,17 @@ internal static void ScanAssembly(Assembly assembly) // A couple of things we want to do here: first, we want to // gather a list of all of the namespaces contributed to by // the assembly. + Type[] types = new Type[0]; + try + { + types = assembly.IsDynamic ? assembly.GetTypes():assembly.GetExportedTypes(); + } + catch(TypeLoadException) + { + // Do nothing. + // This problem usually occurs when transitive dependencies have references to older packages than main application. + } - Type[] types = assembly.GetTypes(); foreach (Type t in types) { string ns = t.Namespace ?? ""; @@ -419,12 +438,15 @@ public static List GetNames(string nsname) { foreach (Assembly a in namespaces[nsname].Keys) { - Type[] types = a.GetTypes(); + Type[] types = a.IsDynamic ? a.GetTypes(): a.GetExportedTypes(); foreach (Type t in types) { if ((t.Namespace ?? "") == nsname) { - names.Add(t.Name); + if (!t.IsNested) + { + names.Add(t.Name); + } } } } diff --git a/src/runtime/pythonengine.cs b/src/runtime/pythonengine.cs index a23c7ac79..0c212de6b 100644 --- a/src/runtime/pythonengine.cs +++ b/src/runtime/pythonengine.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -130,6 +130,11 @@ public static string Compiler get { return Marshal.PtrToStringAnsi(Runtime.Py_GetCompiler()); } } + /// + /// Fires when python engines importing module and probably tries to load an assembly. + /// + public static event EventHandler ImplicitAssemblyLoading; + public static int RunSimpleString(string code) { return Runtime.PyRun_SimpleString(code); @@ -520,6 +525,29 @@ internal static PyObject RunString(string code, IntPtr? globals, IntPtr? locals, } } } + + internal static void RaiseAssemblyAsModuleImportingEvent(ImplicitAssemblyLoadingEventArgs e) + { + ImplicitAssemblyLoading?.Invoke(null, e); + } + } + + public class ImplicitAssemblyLoadingEventArgs: EventArgs + { + public ImplicitAssemblyLoadingEventArgs(string moduleName) + { + ModuleName = moduleName; + } + + /// + /// The name of the module to import that is probably assembly name. + /// + public string ModuleName { get; } + + /// + /// Set it to true, if you know that is not an assembly to import. + /// + public bool SkipAssemblyLoad { get; set; } } public enum RunFlagType pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy