1
- using System . Diagnostics ;
1
+ using System ;
2
+ using System . Diagnostics ;
2
3
using System . IO ;
3
4
using System . Text . Json ;
4
5
using System . Threading ;
@@ -25,14 +26,13 @@ public PythonPlugin(string filename)
25
26
26
27
var path = Path . Combine ( Constant . ProgramDirectory , JsonRPC ) ;
27
28
_startInfo . EnvironmentVariables [ "PYTHONPATH" ] = path ;
29
+ // Prevent Python from writing .py[co] files.
30
+ // Because .pyc contains location infos which will prevent python portable.
31
+ _startInfo . EnvironmentVariables [ "PYTHONDONTWRITEBYTECODE" ] = "1" ;
28
32
29
33
_startInfo . EnvironmentVariables [ "FLOW_VERSION" ] = Constant . Version ;
30
34
_startInfo . EnvironmentVariables [ "FLOW_PROGRAM_DIRECTORY" ] = Constant . ProgramDirectory ;
31
35
_startInfo . EnvironmentVariables [ "FLOW_APPLICATION_DIRECTORY" ] = Constant . ApplicationDirectory ;
32
-
33
-
34
- //Add -B flag to tell python don't write .py[co] files. Because .pyc contains location infos which will prevent python portable
35
- _startInfo . ArgumentList . Add ( "-B" ) ;
36
36
}
37
37
38
38
protected override Task < Stream > RequestAsync ( JsonRPCRequestModel request , CancellationToken token = default )
@@ -50,10 +50,53 @@ protected override string Request(JsonRPCRequestModel rpcRequest, CancellationTo
50
50
// TODO: Async Action
51
51
return Execute ( _startInfo ) ;
52
52
}
53
+
53
54
public override async Task InitAsync ( PluginInitContext context )
54
55
{
55
- _startInfo . ArgumentList . Add ( context . CurrentPluginMetadata . ExecuteFilePath ) ;
56
- _startInfo . ArgumentList . Add ( "" ) ;
56
+ // Run .py files via `-c <code>`
57
+ if ( context . CurrentPluginMetadata . ExecuteFilePath . EndsWith ( ".py" , StringComparison . OrdinalIgnoreCase ) )
58
+ {
59
+ var rootDirectory = context . CurrentPluginMetadata . PluginDirectory ;
60
+ var libDirectory = Path . Combine ( rootDirectory , "lib" ) ;
61
+ var libPyWin32Directory = Path . Combine ( libDirectory , "win32" ) ;
62
+ var libPyWin32LibDirectory = Path . Combine ( libPyWin32Directory , "lib" ) ;
63
+ var pluginDirectory = Path . Combine ( rootDirectory , "plugin" ) ;
64
+
65
+ // This makes it easier for plugin authors to import their own modules.
66
+ // They won't have to add `.`, `./lib`, or `./plugin` to their sys.path manually.
67
+ // Instead of running the .py file directly, we pass the code we want to run as a CLI argument.
68
+ // This code sets sys.path for the plugin author and then runs the .py file via runpy.
69
+ _startInfo . ArgumentList . Add ( "-c" ) ;
70
+ _startInfo . ArgumentList . Add (
71
+ $ """
72
+ import sys
73
+ sys.path.append(r'{ rootDirectory } ')
74
+ sys.path.append(r'{ libDirectory } ')
75
+ sys.path.append(r'{ libPyWin32LibDirectory } ')
76
+ sys.path.append(r'{ libPyWin32Directory } ')
77
+ sys.path.append(r'{ pluginDirectory } ')
78
+
79
+ import runpy
80
+ runpy.run_path(r'{ context . CurrentPluginMetadata . ExecuteFilePath } ', None, '__main__')
81
+ """
82
+ ) ;
83
+ // Plugins always expect the JSON data to be in the third argument
84
+ // (we're always setting it as _startInfo.ArgumentList[2] = ...).
85
+ _startInfo . ArgumentList . Add ( "" ) ;
86
+ }
87
+ // Run .pyz files as is
88
+ else
89
+ {
90
+ // No need for -B flag because we're using PYTHONDONTWRITEBYTECODE env variable now,
91
+ // but the plugins still expect data to be sent as the third argument, so we're keeping
92
+ // the flag here, even though it's not necessary anymore.
93
+ _startInfo . ArgumentList . Add ( "-B" ) ;
94
+ _startInfo . ArgumentList . Add ( context . CurrentPluginMetadata . ExecuteFilePath ) ;
95
+ // Plugins always expect the JSON data to be in the third argument
96
+ // (we're always setting it as _startInfo.ArgumentList[2] = ...).
97
+ _startInfo . ArgumentList . Add ( "" ) ;
98
+ }
99
+
57
100
await base . InitAsync ( context ) ;
58
101
_startInfo . WorkingDirectory = context . CurrentPluginMetadata . PluginDirectory ;
59
102
}
0 commit comments