@@ -247,71 +247,63 @@ public override object Evaluate(
247247 return null ;
248248 }
249249
250- Task . Run ( InstallPythonAsync ) . Wait ( ) ;
251- if ( ! PythonEngine . IsInitialized )
252- {
253- PythonEngine . Initialize ( ) ;
254- PythonEngine . BeginAllowThreads ( ) ;
250+ InitializePython ( ) ;
255251
256- using ( Py . GIL ( ) )
257- using ( PyModule scope = Py . CreateScope ( ) )
252+ using ( Py . GIL ( ) )
253+ {
254+ if ( globalScope == null )
258255 {
259- scope . Exec ( "import sys" + Environment . NewLine + "path = str(sys.path)" ) ;
260- path = scope . Get < string > ( "path" ) ;
256+ globalScope = CreateGlobalScope ( ) ;
261257 }
262- }
263- using ( Py . GIL ( ) )
264- {
265- if ( globalScope == null )
266- {
267- globalScope = CreateGlobalScope ( ) ;
268- }
269258
270- using ( PyModule scope = Py . CreateScope ( ) )
259+ using ( PyModule scope = Py . CreateScope ( ) )
260+ {
261+ if ( path is not null )
271262 {
272263 // Reset the 'sys.path' value to the default python paths on node evaluation. See https://github.com/DynamoDS/Dynamo/pull/10977.
273264 var pythonNodeSetupCode = "import sys" + Environment . NewLine + $ "sys.path = { path } ";
274265 scope . Exec ( pythonNodeSetupCode ) ;
266+ }
275267
276- ProcessAdditionalBindings ( scope , bindingNames , bindingValues ) ;
268+ ProcessAdditionalBindings ( scope , bindingNames , bindingValues ) ;
277269
278- int amt = Math . Min ( bindingNames . Count , bindingValues . Count ) ;
270+ int amt = Math . Min ( bindingNames . Count , bindingValues . Count ) ;
279271
280- for ( int i = 0 ; i < amt ; i ++ )
281- {
282- scope . Set ( ( string ) bindingNames [ i ] , InputMarshaler . Marshal ( bindingValues [ i ] ) . ToPython ( ) ) ;
283- }
272+ for ( int i = 0 ; i < amt ; i ++ )
273+ {
274+ scope . Set ( ( string ) bindingNames [ i ] , InputMarshaler . Marshal ( bindingValues [ i ] ) . ToPython ( ) ) ;
275+ }
284276
285- try
286- {
287- OnEvaluationBegin ( scope , code , bindingValues ) ;
288- scope . Exec ( code ) ;
289- var result = scope . Contains ( "OUT" ) ? scope . Get ( "OUT" ) : null ;
277+ try
278+ {
279+ OnEvaluationBegin ( scope , code , bindingValues ) ;
280+ scope . Exec ( code ) ;
281+ var result = scope . Contains ( "OUT" ) ? scope . Get ( "OUT" ) : null ;
290282
291- return OutputMarshaler . Marshal ( result ) ;
283+ return OutputMarshaler . Marshal ( result ) ;
284+ }
285+ catch ( Exception e )
286+ {
287+ evaluationSuccess = false ;
288+ var traceBack = GetTraceBack ( e ) ;
289+ if ( ! string . IsNullOrEmpty ( traceBack ) )
290+ {
291+ // Throw a new error including trace back info added to the message
292+ throw new InvalidOperationException ( $ "{ e . Message } \n { traceBack } ", e ) ;
292293 }
293- catch ( Exception e )
294+ else
294295 {
295- evaluationSuccess = false ;
296- var traceBack = GetTraceBack ( e ) ;
297- if ( ! string . IsNullOrEmpty ( traceBack ) )
298- {
299- // Throw a new error including trace back info added to the message
300- throw new InvalidOperationException ( $ "{ e . Message } \n { traceBack } ", e ) ;
301- }
302- else
303- {
304296#pragma warning disable CA2200 // Rethrow to preserve stack details
305- throw e ;
297+ throw e ;
306298#pragma warning restore CA2200 // Rethrow to preserve stack details
307- }
308- }
309- finally
310- {
311- OnEvaluationEnd ( evaluationSuccess , scope , code , bindingValues ) ;
312299 }
313300 }
301+ finally
302+ {
303+ OnEvaluationEnd ( evaluationSuccess , scope , code , bindingValues ) ;
304+ }
314305 }
306+ }
315307 }
316308
317309 public static object EvaluatePythonScript (
@@ -334,12 +326,6 @@ internal static async Task InstallPythonAsync()
334326 {
335327 try
336328 {
337- // First try the custom ways of supplying the python dll name (environment variables, or static API calls)
338- if ( string . IsNullOrEmpty ( Runtime . PythonDLL ) )
339- {
340- Runtime . PythonDLL = Python . Included . Installer . PYTHON_VERSION + ".dll" ;
341- }
342-
343329 var disableEmbedded = ! string . IsNullOrEmpty ( Environment . GetEnvironmentVariable ( "DYN_DISABLE_PYNET_EMBEDDED" ) ) ;
344330 if ( disableEmbedded )
345331 {
@@ -363,6 +349,38 @@ internal static async Task InstallPythonAsync()
363349 }
364350 }
365351
352+ private static string path ;
353+
354+ /// <summary>
355+ /// Install, if necessary, and initialize, if necessary, Python.
356+ /// </summary>
357+ /// <returns>True if Python was not already initialized</returns>
358+ internal static bool InitializePython ( )
359+ {
360+ Task . Run ( InstallPythonAsync ) . Wait ( ) ;
361+
362+ if ( ! PythonEngine . IsInitialized )
363+ {
364+ if ( string . IsNullOrEmpty ( Environment . GetEnvironmentVariable ( "DYN_DISABLE_PYTHONDLL_OVERRIDE" ) ) )
365+ {
366+ Runtime . PythonDLL = Path . Join ( Python . Included . Installer . EmbeddedPythonHome , Python . Included . Installer . PYTHON_VERSION + ".dll" ) ;
367+ }
368+
369+ PythonEngine . Initialize ( ) ;
370+ PythonEngine . BeginAllowThreads ( ) ;
371+
372+ using ( Py . GIL ( ) )
373+ using ( PyModule scope = Py . CreateScope ( ) )
374+ {
375+ scope . Exec ( "import sys" + Environment . NewLine + "path = str(sys.path)" ) ;
376+ path = scope . Get < string > ( "path" ) ;
377+ }
378+
379+ return true ;
380+ }
381+ return false ;
382+ }
383+
366384 /// <summary>
367385 /// Creates and initializes the global Python scope.
368386 /// </summary>
@@ -674,7 +692,6 @@ private static bool IsMarkedToSkipConversion(PyObject pyObj)
674692
675693 private DataMarshaler inputMarshaler ;
676694 private DataMarshaler outputMarshaler ;
677- private string path ;
678695
679696 #endregion
680697
0 commit comments