Skip to content

Commit

Permalink
Add env directory from trame v1
Browse files Browse the repository at this point in the history
Signed-off-by: Patrick Avery <[email protected]>
  • Loading branch information
psavery committed May 19, 2022
1 parent 4e57496 commit 89d4149
Show file tree
Hide file tree
Showing 4 changed files with 221 additions and 0 deletions.
Empty file added trame/env/__init__.py
Empty file.
55 changes: 55 additions & 0 deletions trame/env/paraview.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
"""Set up sys.path to include ParaView, if available
This checks the TRAME_PARAVIEW environment variable and the --paraview
argument in sys.argv. The specified path will then be automatically
searched for the python library directory and, if found, it will be
added to the sys.path so that the ParaView libraries may be imported.
To use: specify one of the following, and then import this file:
- `--paraview /path/to/paraview/release` argument
- environment variable `TRAME_PARAVIEW=/path/to/paraview/release`
"""
import platform
import sys

from . import utils

PV_LOADED = False

PV_HOME = utils.find_env_setting("--paraview", "TRAME_PARAVIEW")

if PV_HOME is None:
msg = (
"trame.env.paraview was imported, but the paraview location was not "
"defined. Define it with either the argument '--paraview <path>' or "
"the TRAME_PARAVIEW environment variable"
)
raise Exception(msg)


# Each of the following functions returns a list of paths to try
# for the specified OS.
def linux_paths():
py_major, py_minor = sys.version_info[:2]
return [f"lib/python{py_major}.{py_minor}/site-packages"]


def windows_paths():
return ["bin/Lib/site-packages"]


search_paths_dict = {
"Linux": linux_paths,
"Windows": windows_paths,
}

if PV_HOME and platform.system() == "Darwin":
env_paths = {
"PYTHONPATH": ["Contents/Python"],
"DYLD_LIBRARY_PATH": ["Contents/Libraries"],
}
utils.rerun(PV_HOME, env_paths, ["PV_VENV", "VTK_VENV"])
else:
PV_LOADED = utils.prepend_python_path(PV_HOME, search_paths_dict)
if not PV_LOADED:
raise Exception(f"Failed to add paraview python libraries at {PV_HOME}")
125 changes: 125 additions & 0 deletions trame/env/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import os
import platform
import site
import sys
import subprocess


def find_env_setting(arg, env_var_name):
# We check sys.argv for the arg, and os.environ for the env_var_name
# The argument gets precedence
if arg in sys.argv:
return os.path.abspath(sys.argv[sys.argv.index(arg) + 1])

if os.environ.get(env_var_name):
return os.path.abspath(os.environ.get(env_var_name))


def prepend_python_path(root_dir, search_paths_dict):
# root_dir is the root directory which we will search
# search_paths_dict is a dictionary with "Linux", "Darwin" (Mac),
# and "Windows" keys, with niladic functions for the values that
# returns a list of the paths to search. The paths for the current
# OS will be used.

# Returns True on success, False on failure

# Make sure the python lib dir can be found
python_lib_path = find_python_path(root_dir, search_paths_dict)
if python_lib_path is None:
# A warning should be printed already from find_python_path()
return False

# Use site.addsitedir() to automatically process .pth files.
# This also appends the paths to sys.path. We will move the new
# paths to the front of sys.path.
prev_length = len(sys.path)
site.addsitedir(python_lib_path)
sys.path[:] = sys.path[prev_length:] + sys.path[0:prev_length]

return True


def append_path_to_environ(var_name, paths):
result_paths = []
current_var_value = os.environ.get(var_name, "")
sys_path_sepa = ";" if platform.system() == "Windows" else ":"

if len(current_var_value):
result_paths.append(current_var_value)

for path_entry in paths:
if path_entry not in current_var_value:
result_paths.append(path_entry)

if len(result_paths):
os.environ[var_name] = sys_path_sepa.join(result_paths)


def filter_existing_paths(root_dir, paths_to_try):
found_paths = []

for path in paths_to_try:
full_path = os.path.join(root_dir, path)
if os.path.exists(full_path):
found_paths.append(full_path)

return found_paths


def find_python_path(root_dir, search_paths_dict):
# Returns the python path, or None if it was not found

if not os.path.exists(root_dir):
print(f"Warning: path '{root_dir}' does not exist")
return None

if platform.system() not in search_paths_dict:
raise Exception(f"Unhandled system: {platform.system()}")

paths_to_try = search_paths_dict[platform.system()]()
found_paths = filter_existing_paths(root_dir, paths_to_try)

if len(found_paths) != 1:
paths_str = "\n".join(paths_to_try)
print(
"Warning: python library path could not be found in "
f"'{root_dir}'. Tried:\n{paths_str}\n"
)
return None

return found_paths[0]


def rerun(base_path, add_path_vars, remove_vars=[]):
for name, paths in add_path_vars.items():
resolved_paths = filter_existing_paths(base_path, paths)
append_path_to_environ(name, resolved_paths)

clear_environ_variables(*remove_vars)
rerun_with_new_environ(*list(add_path_vars.keys()))


def rerun_with_new_environ(*var_to_print):
if not os.environ.get("__IN_TRAME_RERUN") == "YES":
env = os.environ.copy()
env["__IN_TRAME_RERUN"] = "YES"

# Print env info
if len(var_to_print):
print("-" * 80)
print("Re-excuting with following environment variables:")
for name in var_to_print:
print(f" - {name}={env.get(name)}")
print("-" * 80)

# Re-run the same command with the modified environment
cmd = [sys.executable] + sys.argv
subprocess.run(cmd, stdout=sys.stdout, stderr=sys.stderr, env=env)
sys.exit()


def clear_environ_variables(*names):
for var in names:
if var in os.environ:
os.environ.pop(var)
41 changes: 41 additions & 0 deletions trame/env/venv.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# -*- coding: utf-8 -*-
"""Activate venv for current interpreter:
Use `import trame.env.venv` along one of the following
- `--venv /path/to/venv/base` argument
- environment variable `TRAME_VENV=/path/to/venv/base`
This can be used when you must use an existing Python interpreter, not the venv bin/python.
"""
import os
import site
import sys

VENV_BASE = None
VENV_LOADED = False

if os.environ.get("TRAME_VENV"):
VENV_BASE = os.path.abspath(os.environ.get("TRAME_VENV"))

if "--venv" in sys.argv:
VENV_BASE = os.path.abspath(sys.argv[sys.argv.index("--venv") + 1])

if not VENV_LOADED and VENV_BASE and os.path.exists(VENV_BASE):
VENV_LOADED = True
# Code inspired by virutal-env::bin/active_this.py
bin_dir = os.path.join(VENV_BASE, "bin")
os.environ["PATH"] = os.pathsep.join(
[bin_dir] + os.environ.get("PATH", "").split(os.pathsep)
)
os.environ["VIRTUAL_ENV"] = VENV_BASE
prev_length = len(sys.path)
python_libs = os.path.join(
VENV_BASE,
f"lib/python{sys.version_info.major}.{sys.version_info.minor}/site-packages",
)
site.addsitedir(python_libs)
sys.path[:] = sys.path[prev_length:] + sys.path[0:prev_length]
sys.real_prefix = sys.prefix
sys.prefix = VENV_BASE
#
print(f"Trame is using venv: {VENV_BASE}")

0 comments on commit 89d4149

Please sign in to comment.