Skip to content

Commit 27fbe41

Browse files
twastvedtGitHub Enterprise
authored andcommitted
Always set PythonDLL path (#11)
* Always set PythonDLL path * Move path reset to initialization * Add environment variable to disable PythonDLL reset.
1 parent 0256894 commit 27fbe41

File tree

2 files changed

+71
-66
lines changed

2 files changed

+71
-66
lines changed

DSPythonNet3/DSPythonNet3CodeCompletionProviderCore.cs

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,7 @@ import clr
7171

7272
private object ExecutePythonScriptCode(string code)
7373
{
74-
Task.Run(DSPythonNet3Evaluator.InstallPythonAsync).Wait();
75-
76-
if (!PythonEngine.IsInitialized)
77-
{
78-
PythonEngine.Initialize();
79-
PythonEngine.BeginAllowThreads();
80-
}
74+
DSPythonNet3Evaluator.InitializePython();
8175

8276
using (Py.GIL())
8377
{
@@ -375,13 +369,7 @@ public DSPythonNet3CodeCompletionProviderCore()
375369
BasicVariableTypes.Add(Tuple.Create(LIST_VARIABLE, typeof(PyList)));
376370
BasicVariableTypes.Add(Tuple.Create(DICT_VARIABLE, typeof(PyDict)));
377371

378-
Task.Run(DSPythonNet3Evaluator.InstallPythonAsync).Wait();
379-
380-
if (!PythonEngine.IsInitialized)
381-
{
382-
PythonEngine.Initialize();
383-
PythonEngine.BeginAllowThreads();
384-
}
372+
DSPythonNet3Evaluator.InitializePython();
385373

386374
try
387375
{

DSPythonNet3/DSPythonNet3Evaluator.cs

Lines changed: 69 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)