Skip to main content
Glama
run_inplace.py.in7.93 kB
#!<PYTHON> <PYTHON_INTERPRETER_FLAGS> # Copyright (c) Meta Platforms, Inc. and affiliates. # # This source code is licensed under both the MIT license found in the # LICENSE-MIT file in the root directory of this source tree and the Apache # License, Version 2.0 found in the LICENSE-APACHE file in the root directory # of this source tree. # LINKTREEDIR=<MODULES_DIR> main_module = "<MAIN_MODULE>" main_function = "<MAIN_FUNCTION>" modules_dir = "<MODULES_DIR>" native_libs_env_var = "<NATIVE_LIBS_ENV_VAR>" native_libs_dirs = <NATIVE_LIBS_DIRS> native_libs_preload_env_var = "<NATIVE_LIBS_PRELOAD_ENV_VAR>" native_libs_preload = <NATIVE_LIBS_PRELOAD> interpreter_flags = "<PYTHON_INTERPRETER_FLAGS>" unc_prefix = "\\\\?\\" import os import platform import signal import subprocess import sys import time os.environ["PAR_LAUNCH_TIMESTAMP"] = str(time.time()) dirpath = os.path.dirname(os.path.realpath(__file__)) # Enable long path support on Windows if platform.system() == "Windows" and not dirpath.startswith(unc_prefix): dirpath = unc_prefix + dirpath env_vals_to_restore = {} # Update the environment variable for the dynamic loader to the native # libraries location. if native_libs_dirs is not None: old_native_libs_dirs = os.environ.get(native_libs_env_var) os.environ[native_libs_env_var] = os.pathsep.join([ os.path.join(dirpath, native_libs_dir) for native_libs_dir in native_libs_dirs ]) env_vals_to_restore[native_libs_env_var] = old_native_libs_dirs if os.environ.get("PAR_APPEND_LD_LIBRARY_PATH") is not None: os.environ[native_libs_env_var] = ( (os.environ[native_libs_env_var] + ":" + os.environ["PAR_APPEND_LD_LIBRARY_PATH"]) if os.environ.get(native_libs_env_var) is not None else os.environ["PAR_APPEND_LD_LIBRARY_PATH"] ) # Update the environment variable for the dynamic loader to find libraries # to preload. if native_libs_preload is not None: old_native_libs_preload = os.environ.get(native_libs_preload_env_var) env_vals_to_restore[native_libs_preload_env_var] = old_native_libs_preload # On macos, preloaded libs are found via paths. if platform.system() == "Darwin": full_path_preloads = [] for lib in native_libs_preload: for native_libs_dir in native_libs_dirs: fpath = os.path.join(dirpath, native_libs_dir, lib) if os.path.exists(fpath): full_path_preloads.append(fpath) break else: raise Exception( "cannot find preload lib {!r} in paths {!r}".format( lib, native_libs_dirs, ), ) native_libs_preload = full_path_preloads os.environ[native_libs_preload_env_var] = os.pathsep.join(native_libs_preload) <ENV> # Note: this full block of code will be included as the argument to Python, # and will be the first thing that shows up in the process arguments as displayed # by programs like ps and top. # # We include sys.argv[0] at the start of this comment just to make it more visible what program # is being run in the ps and top output. STARTUP = f"""\ # {sys.argv[0]} # Wrap everything in a private function to prevent globals being captured by # the `runpy._run_module_as_main` below. def __run(): import sys # We set the paths beforehand to have a minimal amount of imports before # nuking PWD from sys.path. Otherwise, there can be problems if someone runs # from a directory with a similarly named file, even if their code is properly # namespaced. e.g. if one has foo/bar/contextlib.py and while in foo/bar runs # `buck run foo/bar:bin`, runpy will fail as it tries to import # foo/bar/contextlib.py. You're just out of luck if you have sys.py # Set `argv[0]` to the executing script. assert sys.argv[0] == '-c' sys.argv[0] = {sys.argv[0]!r} # Remove the working directory. assert sys.path[0] == '' del sys.path[0] import os import runpy def setenv(var, val): if val is None: os.environ.pop(var, None) else: os.environ[var] = val def restoreenv(d): for k, v in d.items(): setenv(k, v) restoreenv({env_vals_to_restore!r}) # On windows, adjust os.add_dll_directory and PATH (for `ctypes.util.find_library`) # so that native libraries can be found by the dynamic linker or ctypes if sys.platform.startswith("win"): path = os.environ.get("PATH", "") for native_libs_dir in {native_libs_dirs!r}: d = os.path.join({dirpath!r}, native_libs_dir) os.add_dll_directory(d) if path and not path.endswith(os.pathsep): path += os.pathsep path += d setenv("PATH", path) from <MAIN_RUNNER_MODULE> import <MAIN_RUNNER_FUNCTION> as run_as_main run_as_main({main_module!r}, {main_function!r}) __run() """ args = [sys.executable] if interpreter_flags: args.append(interpreter_flags) args.extend(["-c", STARTUP]) # Default to 'd' warnings, but allow users to control this via PYTHONWARNINGS # The -E causes python to ignore all PYTHON* environment vars so we have to # pass this down using the command line. warnings = os.environ.get("PYTHONWARNINGS", "d").split(",") for item in reversed(warnings): args.insert(1, f"-W{item.strip()}") # Allow users to disable byte code generation by setting the standard environment var. # Same as above, because of -E we have to pass this down using the command line. if "PYTHONDONTWRITEBYTECODE" in os.environ: args.insert(1, "-B") # Python 3.7 allows benchmarking import time with this variable. Similar issues to # PYTHONDONTWRITEBYTECODE above. If using an earlier version of python... dont set this # Make sure we only run this on cpython where it's supported (python2 will fail # if given an unknown -X) if ( "PYTHONPROFILEIMPORTTIME" in os.environ and platform.python_implementation() == "CPython" and (sys.version_info[0], sys.version_info[1]) >= (3, 7) ): args[1:1] = ["-X", "importtime"] # Save the variables that will be restored back into the environment by # fbcode/buck2/prelude/python/tools/make_par/sitecustomize.py for env in ("PYTHONPATH", "LD_LIBRARY_PATH", "LD_PRELOAD", "DYLD_LIBRARY_PATH", "DYLD_INSERT_LIBRARIES"): if env in os.environ: os.environ["FB_SAVED_" + env] = os.environ[env] path = os.path.join(dirpath, modules_dir) os.environ["PYTHONPATH"] = path if "PAR_APPEND_PYTHONPATH" in os.environ: os.environ["PYTHONPATH"] += ":" + os.environ["PAR_APPEND_PYTHONPATH"] # This environment variable is immediately unset on startup but will also appear # in e.g. `multiprocessing` workers, and so serves as an audit trail back to # the originating PAR (and can be read via e.g. `/proc/<pid>/environ`). os.environ["PAR_INVOKED_NAME_TAG"] = sys.argv[0] if platform.system() == "Windows": # exec on Windows is not true exec - there is only 'spawn' ('CreateProcess'). # However, creating processes unnecessarily is painful, so we only do the spawn # path if we have to, which is on Windows. That said, this complicates signal # handling, so we need to set up some signal forwarding logic. p = subprocess.Popen(args + sys.argv[1:]) def handler(signum, frame): # If we're getting this, we need to forward signum to subprocesses if signum == signal.SIGINT: p.send_signal(signal.CTRL_C_EVENT) elif signum == signal.SIGBREAK: p.send_signal(signal.CTRL_BREAK_EVENT) else: # shouldn't happen, we should be killed instead p.terminate() signal.signal(signal.SIGINT, handler) signal.signal(signal.SIGBREAK, handler) p.wait() sys.exit(p.returncode) else: os.execv(sys.executable, args + sys.argv[1:])

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/systeminit/si'

If you have feedback or need assistance with the MCP directory API, please join our Discord server