Merge pull request #2493 from pypeclub/bugfix/OP-2333_PYTHONPATH-may-break-OpenPype

General: PYTHONPATH may break OpenPype dependencies
This commit is contained in:
Jakub Trllo 2022-01-10 18:02:29 +01:00 committed by GitHub
commit 1b3cfad689
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 83 additions and 24 deletions

View file

@ -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)

View file

@ -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
)

View file

@ -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",

View file

@ -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", "<path to .py script>")
```
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

View file

@ -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:

View file

@ -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"]
]

View file

@ -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,

View file

@ -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"]

View file

@ -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)

View file

@ -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 = {}

View file

@ -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)