diff --git a/openpype/hooks/pre_non_python_host_launch.py b/openpype/hooks/pre_non_python_host_launch.py index 848ed675a8..29e40d28c8 100644 --- a/openpype/hooks/pre_non_python_host_launch.py +++ b/openpype/hooks/pre_non_python_host_launch.py @@ -3,7 +3,7 @@ import subprocess from openpype.lib import ( PreLaunchHook, - get_pype_execute_args + get_openpype_execute_args ) from openpype import PACKAGE_DIR as OPENPYPE_DIR @@ -35,7 +35,7 @@ class NonPythonHostHook(PreLaunchHook): "non_python_host_launch.py" ) - new_launch_args = get_pype_execute_args( + new_launch_args = get_openpype_execute_args( "run", script_path, executable_path ) # Add workfile path if exists @@ -48,4 +48,3 @@ class NonPythonHostHook(PreLaunchHook): if remainders: self.launch_context.launch_args.extend(remainders) - diff --git a/openpype/hosts/tvpaint/hooks/pre_launch_args.py b/openpype/hosts/tvpaint/hooks/pre_launch_args.py index 62fd662d79..2a8f49d5b0 100644 --- a/openpype/hosts/tvpaint/hooks/pre_launch_args.py +++ b/openpype/hosts/tvpaint/hooks/pre_launch_args.py @@ -4,7 +4,7 @@ import shutil from openpype.hosts import tvpaint from openpype.lib import ( PreLaunchHook, - get_pype_execute_args + get_openpype_execute_args ) import avalon @@ -30,7 +30,7 @@ class TvpaintPrelaunchHook(PreLaunchHook): while self.launch_context.launch_args: remainders.append(self.launch_context.launch_args.pop(0)) - new_launch_args = get_pype_execute_args( + new_launch_args = get_openpype_execute_args( "run", self.launch_script_path(), executable_path ) diff --git a/openpype/lib/__init__.py b/openpype/lib/__init__.py index 34926453cb..12e47a8961 100644 --- a/openpype/lib/__init__.py +++ b/openpype/lib/__init__.py @@ -24,10 +24,13 @@ from .env_tools import ( from .terminal import Terminal from .execute import ( + get_openpype_execute_args, get_pype_execute_args, get_linux_launcher_args, execute, run_subprocess, + run_openpype_process, + clean_envs_for_openpype_process, path_to_subprocess_arg, CREATE_NO_WINDOW ) @@ -173,10 +176,13 @@ from .pype_info import ( terminal = Terminal __all__ = [ + "get_openpype_execute_args", "get_pype_execute_args", "get_linux_launcher_args", "execute", "run_subprocess", + "run_openpype_process", + "clean_envs_for_openpype_process", "path_to_subprocess_arg", "CREATE_NO_WINDOW", diff --git a/openpype/lib/execute.py b/openpype/lib/execute.py index f97617d906..3cf67a379c 100644 --- a/openpype/lib/execute.py +++ b/openpype/lib/execute.py @@ -138,6 +138,49 @@ def run_subprocess(*args, **kwargs): return full_output +def clean_envs_for_openpype_process(env=None): + """Modify environemnts that may affect OpenPype process. + + Main reason to implement this function is to pop PYTHONPATH which may be + affected by in-host environments. + """ + if env is None: + env = os.environ + return { + key: value + for key, value in env.items() + if key not in ("PYTHONPATH",) + } + + +def run_openpype_process(*args, **kwargs): + """Execute OpenPype process with passed arguments and wait. + + Wrapper for 'run_process' which prepends OpenPype executable arguments + before passed arguments and define environments if are not passed. + + Values from 'os.environ' are used for environments if are not passed. + They are cleaned using 'clean_envs_for_openpype_process' function. + + Example: + ``` + run_openpype_process("run", "") + ``` + + Args: + *args (tuple): OpenPype cli arguments. + **kwargs (dict): Keyword arguments for for subprocess.Popen. + """ + args = get_openpype_execute_args(*args) + env = kwargs.pop("env", None) + # Keep env untouched if are passed and not empty + if not env: + # Skip envs that can affect OpenPype process + # - fill more if you find more + env = clean_envs_for_openpype_process(os.environ) + return run_subprocess(args, env=env, **kwargs) + + def path_to_subprocess_arg(path): """Prepare path for subprocess arguments. @@ -147,6 +190,18 @@ def path_to_subprocess_arg(path): def get_pype_execute_args(*args): + """Backwards compatible function for 'get_openpype_execute_args'.""" + import traceback + + log = Logger.get_logger("get_pype_execute_args") + stack = "\n".join(traceback.format_stack()) + log.warning(( + "Using deprecated function 'get_pype_execute_args'. Called from:\n{}" + ).format(stack)) + return get_openpype_execute_args(*args) + + +def get_openpype_execute_args(*args): """Arguments to run pype command. Arguments for subprocess when need to spawn new pype process. Which may be diff --git a/openpype/lib/pype_info.py b/openpype/lib/pype_info.py index 33715e369d..15856bfb19 100644 --- a/openpype/lib/pype_info.py +++ b/openpype/lib/pype_info.py @@ -7,7 +7,7 @@ import socket import openpype.version from openpype.settings.lib import get_local_settings -from .execute import get_pype_execute_args +from .execute import get_openpype_execute_args from .local_settings import get_local_site_id from .python_module_tools import import_filepath @@ -71,7 +71,7 @@ def is_running_staging(): def get_pype_info(): """Information about currently used Pype process.""" - executable_args = get_pype_execute_args() + executable_args = get_openpype_execute_args() if is_running_from_build(): version_type = "build" else: diff --git a/openpype/modules/default_modules/ftrack/ftrack_server/event_server_cli.py b/openpype/modules/default_modules/ftrack/ftrack_server/event_server_cli.py index 1a76905b38..90ce757242 100644 --- a/openpype/modules/default_modules/ftrack/ftrack_server/event_server_cli.py +++ b/openpype/modules/default_modules/ftrack/ftrack_server/event_server_cli.py @@ -14,7 +14,7 @@ import uuid import ftrack_api import pymongo from openpype.lib import ( - get_pype_execute_args, + get_openpype_execute_args, OpenPypeMongoConnection, get_openpype_version, get_build_version, @@ -136,7 +136,7 @@ def legacy_server(ftrack_url): if subproc is None: if subproc_failed_count < max_fail_count: - args = get_pype_execute_args("run", subproc_path) + args = get_openpype_execute_args("run", subproc_path) subproc = subprocess.Popen( args, stdout=subprocess.PIPE @@ -248,7 +248,7 @@ def main_loop(ftrack_url): ["Username", getpass.getuser()], ["Host Name", host_name], ["Host IP", socket.gethostbyname(host_name)], - ["OpenPype executable", get_pype_execute_args()[-1]], + ["OpenPype executable", get_openpype_execute_args()[-1]], ["OpenPype version", get_openpype_version() or "N/A"], ["OpenPype build version", get_build_version() or "N/A"] ] diff --git a/openpype/modules/default_modules/ftrack/ftrack_server/socket_thread.py b/openpype/modules/default_modules/ftrack/ftrack_server/socket_thread.py index eb8ec4d06c..f49ca5557e 100644 --- a/openpype/modules/default_modules/ftrack/ftrack_server/socket_thread.py +++ b/openpype/modules/default_modules/ftrack/ftrack_server/socket_thread.py @@ -6,7 +6,7 @@ import threading import traceback import subprocess from openpype.api import Logger -from openpype.lib import get_pype_execute_args +from openpype.lib import get_openpype_execute_args class SocketThread(threading.Thread): @@ -59,7 +59,7 @@ class SocketThread(threading.Thread): env = os.environ.copy() env["OPENPYPE_PROCESS_MONGO_ID"] = str(Logger.mongo_process_id) # OpenPype executable (with path to start script if not build) - args = get_pype_execute_args( + args = get_openpype_execute_args( # Add `run` command "run", self.filepath, diff --git a/openpype/modules/standalonepublish_action.py b/openpype/modules/standalonepublish_action.py index 9321a415a9..ba53ce9b9e 100644 --- a/openpype/modules/standalonepublish_action.py +++ b/openpype/modules/standalonepublish_action.py @@ -1,7 +1,7 @@ import os import platform import subprocess -from openpype.lib import get_pype_execute_args +from openpype.lib import get_openpype_execute_args from openpype.modules import OpenPypeModule from openpype_interfaces import ITrayAction @@ -35,7 +35,7 @@ class StandAlonePublishAction(OpenPypeModule, ITrayAction): self.publish_paths.extend(publish_paths) def run_standalone_publisher(self): - args = get_pype_execute_args("standalonepublisher") + args = get_openpype_execute_args("standalonepublisher") kwargs = {} if platform.system().lower() == "darwin": new_args = ["open", "-na", args.pop(0), "--args"] diff --git a/openpype/plugins/publish/extract_burnin.py b/openpype/plugins/publish/extract_burnin.py index df7dc47e17..459c66ee43 100644 --- a/openpype/plugins/publish/extract_burnin.py +++ b/openpype/plugins/publish/extract_burnin.py @@ -13,7 +13,7 @@ import pyblish import openpype import openpype.api from openpype.lib import ( - get_pype_execute_args, + run_openpype_process, get_transcode_temp_directory, convert_for_ffmpeg, @@ -168,9 +168,8 @@ class ExtractBurnin(openpype.api.Extractor): anatomy = instance.context.data["anatomy"] scriptpath = self.burnin_script_path() - # Executable args that will execute the script - # [pype executable, *pype script, "run"] - executable_args = get_pype_execute_args("run", scriptpath) + # Args that will execute the script + executable_args = ["run", scriptpath] burnins_per_repres = self._get_burnins_per_representations( instance, burnin_defs ) @@ -313,7 +312,7 @@ class ExtractBurnin(openpype.api.Extractor): if platform.system().lower() == "windows": process_kwargs["creationflags"] = CREATE_NO_WINDOW - openpype.api.run_subprocess(args, **process_kwargs) + run_openpype_process(*args, **process_kwargs) # Remove the temporary json os.remove(temporary_json_filepath) diff --git a/openpype/tools/standalonepublish/widgets/widget_components.py b/openpype/tools/standalonepublish/widgets/widget_components.py index 2ac54af4e3..4d7f94f825 100644 --- a/openpype/tools/standalonepublish/widgets/widget_components.py +++ b/openpype/tools/standalonepublish/widgets/widget_components.py @@ -10,7 +10,7 @@ from .constants import HOST_NAME from avalon import io from openpype.api import execute, Logger from openpype.lib import ( - get_pype_execute_args, + get_openpype_execute_args, apply_project_environments_value ) @@ -193,7 +193,7 @@ def cli_publish(data, publish_paths, gui=True): project_name = os.environ["AVALON_PROJECT"] env_copy = apply_project_environments_value(project_name, envcopy) - args = get_pype_execute_args("run", PUBLISH_SCRIPT_PATH) + args = get_openpype_execute_args("run", PUBLISH_SCRIPT_PATH) result = execute(args, env=envcopy) result = {} diff --git a/openpype/tools/tray/pype_tray.py b/openpype/tools/tray/pype_tray.py index 8c6a6d3266..df0238c848 100644 --- a/openpype/tools/tray/pype_tray.py +++ b/openpype/tools/tray/pype_tray.py @@ -14,7 +14,7 @@ from openpype.api import ( resources, get_system_settings ) -from openpype.lib import get_pype_execute_args +from openpype.lib import get_openpype_execute_args from openpype.modules import TrayModulesManager from openpype import style from openpype.settings import ( @@ -208,10 +208,10 @@ class TrayManager: First creates new process with same argument and close current tray. """ - args = get_pype_execute_args() + args = get_openpype_execute_args() # Create a copy of sys.argv additional_args = list(sys.argv) - # Check last argument from `get_pype_execute_args` + # Check last argument from `get_openpype_execute_args` # - when running from code it is the same as first from sys.argv if args[-1] == additional_args[0]: additional_args.pop(0)