From 254e8f55f656355da653af350452fcdf2040523c Mon Sep 17 00:00:00 2001 From: Nicholas Date: Mon, 22 Jan 2024 09:37:33 +0000 Subject: [PATCH 1/2] Updated to load assembly locations --- src/Bonsai.Scripting.Python/RuntimeManager.cs | 35 ++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/src/Bonsai.Scripting.Python/RuntimeManager.cs b/src/Bonsai.Scripting.Python/RuntimeManager.cs index 5b6c385..66d34b3 100644 --- a/src/Bonsai.Scripting.Python/RuntimeManager.cs +++ b/src/Bonsai.Scripting.Python/RuntimeManager.cs @@ -1,8 +1,10 @@ using System; using System.IO; +using System.Reflection; using System.Reactive.Concurrency; using System.Reactive.Linq; using Python.Runtime; +using SystemPath = System.IO.Path; namespace Bonsai.Scripting.Python { @@ -13,6 +15,7 @@ namespace Bonsai.Scripting.Python /// public class RuntimeManager : IDisposable { + const char AssemblySeparator = ':'; readonly EventLoopScheduler runtimeScheduler; readonly IObserver runtimeObserver; IntPtr threadState; @@ -40,6 +43,36 @@ internal RuntimeManager(string pythonHome, string scriptPath, IObserver disposable.Subject) .Take(1); + internal static bool IsEmbeddedResourcePath(string path) + { + var separatorIndex = path.IndexOf(AssemblySeparator); + return separatorIndex >= 0 && !SystemPath.IsPathRooted(path); + } + + internal static string GetEmbeddedPythonCode(string path) + { + var nameElements = path.Split(new[] { AssemblySeparator }, 2); + if (string.IsNullOrEmpty(nameElements[0])) + { + throw new InvalidOperationException( + "The embedded resource path \"" + path + + "\" must be qualified with a valid assembly name."); + } + + var assembly = Assembly.Load(nameElements[0]); + var resourceName = string.Join(ExpressionHelper.MemberSeparator, nameElements); + using var resourceStream = assembly.GetManifestResourceStream(resourceName); + if (resourceStream == null) + { + throw new InvalidOperationException( + "The specified embedded resource \"" + nameElements[1] + + "\" was not found in assembly \"" + nameElements[0] + "\""); + } + using var reader = new StreamReader(resourceStream); + var code = reader.ReadToEnd(); + return code; + } + internal static DynamicModule CreateModule(string name = "", string scriptPath = "") { using (Py.GIL()) @@ -49,7 +82,7 @@ internal static DynamicModule CreateModule(string name = "", string scriptPath = { try { - var code = File.ReadAllText(scriptPath); + var code = IsEmbeddedResourcePath(scriptPath) ? GetEmbeddedPythonCode(scriptPath) : File.ReadAllText(scriptPath); module.Exec(code); } catch (Exception) From c774db3370ac4bdce73b680b8ece0b6c66dd7e5e Mon Sep 17 00:00:00 2001 From: ncguilbeault Date: Fri, 16 Feb 2024 10:26:53 +0000 Subject: [PATCH 2/2] Apply suggestions from code review Co-authored-by: glopesdev --- src/Bonsai.Scripting.Python/RuntimeManager.cs | 44 ++++++++++--------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/src/Bonsai.Scripting.Python/RuntimeManager.cs b/src/Bonsai.Scripting.Python/RuntimeManager.cs index 66d34b3..949b0d5 100644 --- a/src/Bonsai.Scripting.Python/RuntimeManager.cs +++ b/src/Bonsai.Scripting.Python/RuntimeManager.cs @@ -43,34 +43,38 @@ internal RuntimeManager(string pythonHome, string scriptPath, IObserver disposable.Subject) .Take(1); - internal static bool IsEmbeddedResourcePath(string path) + static bool IsEmbeddedResourcePath(string path) { var separatorIndex = path.IndexOf(AssemblySeparator); return separatorIndex >= 0 && !SystemPath.IsPathRooted(path); } - internal static string GetEmbeddedPythonCode(string path) + static string ReadAllText(string path) { - var nameElements = path.Split(new[] { AssemblySeparator }, 2); - if (string.IsNullOrEmpty(nameElements[0])) + if (IsEmbeddedResourcePath(path)) { - throw new InvalidOperationException( - "The embedded resource path \"" + path + - "\" must be qualified with a valid assembly name."); - } + var nameElements = path.Split(new[] { AssemblySeparator }, 2); + if (string.IsNullOrEmpty(nameElements[0])) + { + throw new InvalidOperationException( + "The embedded resource path \"" + path + + "\" must be qualified with a valid assembly name."); + } - var assembly = Assembly.Load(nameElements[0]); - var resourceName = string.Join(ExpressionHelper.MemberSeparator, nameElements); - using var resourceStream = assembly.GetManifestResourceStream(resourceName); - if (resourceStream == null) - { - throw new InvalidOperationException( - "The specified embedded resource \"" + nameElements[1] + - "\" was not found in assembly \"" + nameElements[0] + "\""); + var assembly = Assembly.Load(nameElements[0]); + var resourceName = string.Join(ExpressionHelper.MemberSeparator, nameElements); + using var resourceStream = assembly.GetManifestResourceStream(resourceName); + if (resourceStream == null) + { + throw new InvalidOperationException( + "The specified embedded resource \"" + nameElements[1] + + "\" was not found in assembly \"" + nameElements[0] + "\""); + } + + using var reader = new StreamReader(resourceStream); + return reader.ReadToEnd(); } - using var reader = new StreamReader(resourceStream); - var code = reader.ReadToEnd(); - return code; + else return File.ReadAllText(path); } internal static DynamicModule CreateModule(string name = "", string scriptPath = "") @@ -82,7 +86,7 @@ internal static DynamicModule CreateModule(string name = "", string scriptPath = { try { - var code = IsEmbeddedResourcePath(scriptPath) ? GetEmbeddedPythonCode(scriptPath) : File.ReadAllText(scriptPath); + var code = ReadAllText(scriptPath); module.Exec(code); } catch (Exception)