Example #1
0
        public void TestIsPythonLibraryLoaded()
        {
            PythonRunner.EnsureInitialized();
            var result = PythonRunner.IsPythonLibraryLoaded();

            Assert.That(result, Is.True);
        }
Example #2
0
        public void TestScriptAssembliesInSysPath()
        {
            PythonRunner.EnsureInitialized();

            using (Py.GIL())
            {
                dynamic sysmod  = Py.Import("sys");
                dynamic syspath = sysmod.path;
                bool    found   = false;
                foreach (string path in syspath)
                {
                    if (path == Path.GetFullPath("Library/ScriptAssemblies").Replace("\\", "/"))
                    {
                        found = true;
                        break;
                    }
                }
                Assert.True(found);

                // Next, try to load PythonRunner from python
                dynamic clrmod = Py.Import("clr");
                clrmod.AddReference("Unity.Scripting.Python.Editor");
                dynamic pythonRunnerMod = Py.Import("UnityEditor.Scripting.Python");
                string  version         = pythonRunnerMod.PythonRunner.PythonVersion;
                Assert.That(version, Is.EqualTo(PythonRunner.PythonVersion));
            }
        }
 public void Setup()
 {
     PythonRunner.EnsureInitialized();
     using (Py.GIL())
     {
         dynamic module = PythonEngine.ImportModule("unity_python.common.spawn_process");
         spawn = module.spawn_process_in_environment;
     }
 }
Example #4
0
        static void CreateOrReinitialize()
        {
            // You can manually add the sample directory to your sys.path in
            // the Python Settings under site-packages. Or you can do it
            // programmatically like so.
            string dir = __DIR__();

            PythonRunner.EnsureInitialized();
            using (Py.GIL())
            {
                dynamic sys = PythonEngine.ImportModule("sys");
                if ((int)sys.path.count(dir) == 0)
                {
                    sys.path.append(dir);
                }
            }

            // Now that we've set up the path correctly, we can import the
            // Python side of this example as a module:
            PythonRunner.RunString(@"
                    import PySideExample

                    PySideExample.create_or_reinitialize()
                    ");

            // We can't register events in Python directly, so register them
            // here in C#:
            EditorApplication.hierarchyChanged += OnHierarchyChanged;
            EditorApplication.update           += OnUpdate;

            //
            // A domain reload happens when you change C# code or when you
            // launch into play mode (unless you selected the option not to
            // reload then).
            //
            // When it happens, your C# state is entirely reinitialized. The
            // Python state, however, remains as it was.
            //
            // To store information about what happened in the previous domain,
            // Unity provides the SessionState. Alternately we could have
            // stored the data in a variable in Python.
            //
            SessionState.SetBool(kStateName, true);
        }
        /// <summary>
        /// Execute the Python script `update_packages.py`: using a package requirements.txt file, it will install
        /// needed packages and uninstall unused ones
        /// </summary>
        /// <param="requirementsFile">Path to the requirements.txt file</param>
        /// <param="pythonInterpreter">Path to the Python interpreter on wich we run the update packages script</param>
        /// <returns>Standard output of the script</returns>
        internal static string UpdatePackages(string requirementsFile,
                                              string pythonInterpreter = PythonSettings.kDefaultPython)
        {
            PythonRunner.EnsureInitialized();
            using (Py.GIL())
            {
                dynamic spawn_process = PythonEngine.ImportModule("unity_python.common.spawn_process");

                dynamic args = new PyList();
                args.append(updatePackagesScript);
                args.append(requirementsFile);

                dynamic subprocess       = PythonEngine.ImportModule("subprocess");
                var     subprocessKwargs = new PyDict();
                subprocessKwargs["stdout"]             = subprocess.PIPE;
                subprocessKwargs["stderr"]             = subprocess.PIPE;
                subprocessKwargs["universal_newlines"] = true.ToPython();

                dynamic process = spawn_process.spawn_process_in_environment(pythonInterpreter, args,
                                                                             kwargs: subprocessKwargs,
                                                                             wantLogging: false);
                dynamic res = process.communicate();
                (string output, string errors) = (res[0], res[1]);
                if (!string.IsNullOrEmpty(errors))
                {
                    var pipWarningStringBuilder = new StringBuilder();
                    // Split errors lines to filter them individually
                    foreach (var line in Regex.Split(errors, "\r\n|\n|\r"))
                    {
                        if (IsInterestingWarning(line))
                        {
                            pipWarningStringBuilder.AppendLine(line);
                        }
                    }

                    if (pipWarningStringBuilder.Length > 0)
                    {
                        UnityEngine.Debug.LogError(pipWarningStringBuilder.ToString());
                    }
                }

                return(output);
            }
        }
        /// <summary>
        /// Spawns a `python -m pip freeze` subprocess and returns its output
        /// </summary>
        /// <param="pythonInterpreter">Path to the Python interpreter on which we call pip freeze</param>
        /// <param="pythonPath">Override PYTHONPATH with the passed argument; no override if empty string</param>
        /// <returns>Standard output of the pip freeze subprocess</returns>
        internal static string CallPipFreeze(string pythonInterpreter = PythonSettings.kDefaultPython,
                                             string pythonPath        = "")
        {
            PythonRunner.EnsureInitialized();
            using (Py.GIL())
            {
                dynamic subprocess = PythonEngine.ImportModule("subprocess");
                dynamic module     = PythonEngine.ImportModule("unity_python.common.spawn_process");
                dynamic spawn      = module.spawn_process_in_environment;

                dynamic args = new PyList();
                args.append(new PyString("-m"));
                args.append(new PyString("pip"));
                args.append(new PyString("freeze"));
                var subprocessKwargs = new PyDict();
                subprocessKwargs["stdout"]             = subprocess.PIPE;
                subprocessKwargs["stderr"]             = subprocess.PIPE;
                subprocessKwargs["universal_newlines"] = true.ToPython(); // text streams instead of bytes

                dynamic envOverride = new PyDict();
                if (string.IsNullOrEmpty(pythonPath))
                {
                    envOverride["PYTHONPATH"] = new PyString("");
                }

                dynamic process = spawn(pythonInterpreter, args,
                                        kwargs: subprocessKwargs,
                                        env_override: envOverride,
                                        wantLogging: false);
                dynamic res = process.communicate();
                (string output, string errors) = (res[0], res[1]);
                if (errors != null && errors.Length > 0)
                {
                    UnityEngine.Debug.LogError(errors);
                }

                return(output);
            }
        }