1
1
using System ;
2
2
using System . IO ;
3
+ using System . Reflection ;
3
4
using System . Reactive . Concurrency ;
4
5
using System . Reactive . Linq ;
5
6
using Python . Runtime ;
7
+ using SystemPath = System . IO . Path ;
6
8
7
9
namespace Bonsai . Scripting . Python
8
10
{
@@ -13,6 +15,7 @@ namespace Bonsai.Scripting.Python
13
15
/// </summary>
14
16
public class RuntimeManager : IDisposable
15
17
{
18
+ const char AssemblySeparator = ':' ;
16
19
readonly EventLoopScheduler runtimeScheduler ;
17
20
readonly IObserver < RuntimeManager > runtimeObserver ;
18
21
IntPtr threadState ;
@@ -40,6 +43,36 @@ internal RuntimeManager(string pythonHome, string scriptPath, IObserver<RuntimeM
40
43
disposable => disposable . Subject )
41
44
. Take ( 1 ) ;
42
45
46
+ internal static bool IsEmbeddedResourcePath ( string path )
47
+ {
48
+ var separatorIndex = path . IndexOf ( AssemblySeparator ) ;
49
+ return separatorIndex >= 0 && ! SystemPath . IsPathRooted ( path ) ;
50
+ }
51
+
52
+ internal static string GetEmbeddedPythonCode ( string path )
53
+ {
54
+ var nameElements = path . Split ( new [ ] { AssemblySeparator } , 2 ) ;
55
+ if ( string . IsNullOrEmpty ( nameElements [ 0 ] ) )
56
+ {
57
+ throw new InvalidOperationException (
58
+ "The embedded resource path \" " + path +
59
+ "\" must be qualified with a valid assembly name." ) ;
60
+ }
61
+
62
+ var assembly = Assembly . Load ( nameElements [ 0 ] ) ;
63
+ var resourceName = string . Join ( ExpressionHelper . MemberSeparator , nameElements ) ;
64
+ using var resourceStream = assembly . GetManifestResourceStream ( resourceName ) ;
65
+ if ( resourceStream == null )
66
+ {
67
+ throw new InvalidOperationException (
68
+ "The specified embedded resource \" " + nameElements [ 1 ] +
69
+ "\" was not found in assembly \" " + nameElements [ 0 ] + "\" " ) ;
70
+ }
71
+ using var reader = new StreamReader ( resourceStream ) ;
72
+ var code = reader . ReadToEnd ( ) ;
73
+ return code ;
74
+ }
75
+
43
76
internal static DynamicModule CreateModule ( string name = "" , string scriptPath = "" )
44
77
{
45
78
using ( Py . GIL ( ) )
@@ -49,7 +82,7 @@ internal static DynamicModule CreateModule(string name = "", string scriptPath =
49
82
{
50
83
try
51
84
{
52
- var code = File . ReadAllText ( scriptPath ) ;
85
+ var code = IsEmbeddedResourcePath ( scriptPath ) ? GetEmbeddedPythonCode ( scriptPath ) : File . ReadAllText ( scriptPath ) ;
53
86
module . Exec ( code ) ;
54
87
}
55
88
catch ( Exception )
0 commit comments