/// <summary> /// Migrates Python 2 code to Python 3 using Pythons 2to3 library. /// </summary> /// <param name="code">Python 2 code that needs to be migrated</param> /// <returns></returns> internal static string MigrateCode(string code) { Installer.SetupPython().Wait(); if (!PythonEngine.IsInitialized) { PythonEngine.Initialize(); PythonEngine.BeginAllowThreads(); } IntPtr gs = PythonEngine.AcquireLock(); try { using (Py.GIL()) { using (PyScope scope = Py.CreateScope()) { scope.Set(INPUT_NAME, code.ToPython()); scope.Exec(GetPythonMigrationScript()); var result = scope.Contains(RETURN_NAME) ? scope.Get(RETURN_NAME) : null; return(result.ToString()); } } } finally { PythonEngine.ReleaseLock(gs); } }
/// <summary> /// Executes a Python script with custom variable names. Script may be a string /// read from a file, for example. Pass a list of names (matching the variable /// names in the script) to bindingNames and pass a corresponding list of values /// to bindingValues. /// </summary> /// <param name="code">Python script as a string.</param> /// <param name="bindingNames">Names of values referenced in Python script.</param> /// <param name="bindingValues">Values referenced in Python script.</param> public static object EvaluatePythonScript( string code, IList bindingNames, [ArbitraryDimensionArrayImport] IList bindingValues) { if (code != prev_code) { Python.Included.Installer.SetupPython().Wait(); if (!PythonEngine.IsInitialized) { PythonEngine.Initialize(); PythonEngine.BeginAllowThreads(); } IntPtr gs = PythonEngine.AcquireLock(); try { using (Py.GIL()) { using (PyScope scope = Py.CreateScope()) { int amt = Math.Min(bindingNames.Count, bindingValues.Count); for (int i = 0; i < amt; i++) { scope.Set((string)bindingNames[i], InputMarshaler.Marshal(bindingValues[i]).ToPython()); } try { OnEvaluationBegin(scope, code, bindingValues); scope.Exec(code); OnEvaluationEnd(false, scope, code, bindingValues); var result = scope.Contains("OUT") ? scope.Get("OUT") : null; return(OutputMarshaler.Marshal(result)); } catch (Exception e) { OnEvaluationEnd(false, scope, code, bindingValues); throw e; } } } } catch (PythonException pe) { throw pe; } finally { PythonEngine.ReleaseLock(gs); } } return(null); }
public void TestImportModule() { using (Py.GIL()) { dynamic sys = ps.Import("sys"); Assert.IsTrue(ps.Contains("sys")); ps.Exec("sys.attr1 = 2"); var value1 = ps.Eval <int>("sys.attr1"); var value2 = sys.attr1.As <int>(); Assert.AreEqual(2, value1); Assert.AreEqual(2, value2); //import as ps.Import("sys", "sys1"); Assert.IsTrue(ps.Contains("sys1")); } }
/// <summary> /// Migrates Python 2 code to Python 3 using Pythons 2to3 library. /// </summary> /// <param name="code">Python 2 code that needs to be migrated</param> /// <returns></returns> internal static string MigrateCode(string code) { InstallPython(); if (!PythonEngine.IsInitialized) { PythonEngine.Initialize(); PythonEngine.BeginAllowThreads(); } IntPtr gs = PythonEngine.AcquireLock(); try { using (Py.GIL()) { string output; var asm = Assembly.GetExecutingAssembly(); using (PyScope scope = Py.CreateScope()) { scope.Set(INPUT_NAME, code.ToPython()); var path = Path.GetDirectoryName(asm.Location); scope.Set(PATH_NAME, path.ToPython()); scope.Exec(Get2To3MigrationScript(asm)); output = scope.Contains(RETURN_NAME) ? scope.Get(RETURN_NAME).ToString() : string.Empty; } // If the code contains tabs, normalize the whitespaces. This is a Python 3 requirement // that's not addressed by 2to3. if (output.Contains("\t")) { using (PyScope scope = Py.CreateScope()) { scope.Set(INPUT_NAME, output.ToPython()); scope.Exec(GetReindentationScript(asm)); output = scope.Contains(RETURN_NAME) ? scope.Get(RETURN_NAME).ToString() : string.Empty; } } return(output); } } finally { PythonEngine.ReleaseLock(gs); } }
/// <summary> /// Executes a Python script with custom variable names. Script may be a string /// read from a file, for example. Pass a list of names (matching the variable /// names in the script) to bindingNames and pass a corresponding list of values /// to bindingValues. /// </summary> /// <param name="code">Python script as a string.</param> /// <param name="bindingNames">Names of values referenced in Python script.</param> /// <param name="bindingValues">Values referenced in Python script.</param> public static object EvaluatePythonScript( string code, IList bindingNames, [ArbitraryDimensionArrayImport] IList bindingValues) { var evaluationSuccess = true; if (code == null) { return(null); } InstallPython(); if (!PythonEngine.IsInitialized) { PythonEngine.Initialize(); PythonEngine.BeginAllowThreads(); } IntPtr gs = PythonEngine.AcquireLock(); try { using (Py.GIL()) { if (globalScope == null) { globalScope = CreateGlobalScope(); } using (PyScope scope = Py.CreateScope()) { // Reset the 'sys.path' value to the default python paths on node evaluation. var pythonNodeSetupCode = "import sys" + Environment.NewLine + "sys.path = sys.path[0:3]"; scope.Exec(pythonNodeSetupCode); ProcessAdditionalBindings(scope, bindingNames, bindingValues); int amt = Math.Min(bindingNames.Count, bindingValues.Count); for (int i = 0; i < amt; i++) { scope.Set((string)bindingNames[i], InputMarshaler.Marshal(bindingValues[i]).ToPython()); } try { OnEvaluationBegin(scope, code, bindingValues); scope.Exec(code); var result = scope.Contains("OUT") ? scope.Get("OUT") : null; return(OutputMarshaler.Marshal(result)); } catch (Exception e) { evaluationSuccess = false; var traceBack = GetTraceBack(e); if (!string.IsNullOrEmpty(traceBack)) { // Throw a new error including trace back info added to the message throw new InvalidOperationException($"{e.Message} {traceBack}", e); } else { throw e; } } finally { OnEvaluationEnd(evaluationSuccess, scope, code, bindingValues); } } } } finally { PythonEngine.ReleaseLock(gs); } }