From 8ee0c657dca15e0d200feb51606c4ca12a58d026 Mon Sep 17 00:00:00 2001 From: dse Date: Wed, 23 Aug 2017 16:24:26 +0400 Subject: [PATCH 1/2] Implicit assembly loading optimization. --- CHANGELOG.md | 1 + src/runtime/assemblymanager.cs | 15 +++++++++++++-- src/runtime/pythonengine.cs | 30 +++++++++++++++++++++++++++++- 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d408a8d1..657da9ccb 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 06a4449a2..2ee04ee94 100644 --- a/src/runtime/assemblymanager.cs +++ b/src/runtime/assemblymanager.cs @@ -196,6 +196,14 @@ public static Assembly LoadAssembly(string name) Assembly assembly = null; try { + var importEvent = new ImplicitAssemblyLoadingEventArgs(name); + if (importEvent.SkipAssemblyLoad) + { + return null; + } + + PythonEngine.RaiseAssemblyAsModuleImportingEvent(importEvent); + assembly = Assembly.Load(name); } catch (Exception) @@ -419,12 +427,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 From d09fc92c45a06911668e655bb9a77b002cace5ad Mon Sep 17 00:00:00 2001 From: dse Date: Thu, 7 Sep 2017 16:49:41 +0400 Subject: [PATCH 2/2] Assembly loading experience improved + fixes. --- src/runtime/assemblymanager.cs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/runtime/assemblymanager.cs b/src/runtime/assemblymanager.cs index 2ee04ee94..379d01572 100644 --- a/src/runtime/assemblymanager.cs +++ b/src/runtime/assemblymanager.cs @@ -203,8 +203,10 @@ public static Assembly LoadAssembly(string name) } PythonEngine.RaiseAssemblyAsModuleImportingEvent(importEvent); - - assembly = Assembly.Load(name); + if (!importEvent.SkipAssemblyLoad) + { + assembly = Assembly.Load(name); + } } catch (Exception) { @@ -351,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 ?? ""; 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