chore(system_python): use snake_case, add some debugging (#3667)
This uses snake_case function names in the system python bootstrap. This
is just to
modernize the code a bit.
Along the way ...
* Add some additional debug logging
* Fix the `if is_windows:` conditional that was always executing
(because it was
referring to a function), but a no-op, on Linux.
diff --git a/python/private/python_bootstrap_template.txt b/python/private/python_bootstrap_template.txt
index 76036bb..f08de8e 100644
--- a/python/private/python_bootstrap_template.txt
+++ b/python/private/python_bootstrap_template.txt
@@ -66,10 +66,10 @@
ADDITIONAL_INTERPRETER_ARGS = os.environ.get("RULES_PYTHON_ADDITIONAL_INTERPRETER_ARGS", "")
-def IsRunningFromZip():
+def is_running_from_zip():
return IS_ZIPFILE
-if IsRunningFromZip():
+if is_running_from_zip():
import shutil
import tempfile
import zipfile
@@ -77,10 +77,10 @@
import re
# Return True if running on Windows
-def IsWindows():
+def is_windows():
return os.name == 'nt'
-def GetWindowsPathWithUNCPrefix(path):
+def get_windows_path_with_unc_prefix(path):
"""Adds UNC prefix after getting a normalized absolute Windows path.
No-op for non-Windows platforms or if running under python2.
@@ -89,7 +89,7 @@
# No need to add prefix for non-Windows platforms.
# And \\?\ doesn't work in python 2 or on mingw
- if not IsWindows() or sys.version_info[0] < 3:
+ if not is_windows() or sys.version_info[0] < 3:
return path
# Starting in Windows 10, version 1607(OS build 14393), MAX_PATH limitations have been
@@ -120,13 +120,13 @@
# os.path.abspath returns a normalized absolute path
return unicode_prefix + os.path.abspath(path)
-def HasWindowsExecutableExtension(path):
+def has_windows_executable_extension(path):
return path.endswith('.exe') or path.endswith('.com') or path.endswith('.bat')
-if PYTHON_BINARY and IsWindows() and not HasWindowsExecutableExtension(PYTHON_BINARY):
+if PYTHON_BINARY and is_windows() and not has_windows_executable_extension(PYTHON_BINARY):
PYTHON_BINARY = PYTHON_BINARY + '.exe'
-def SearchPath(name):
+def search_path(name):
"""Finds a file in a given search path."""
search_path = os.getenv('PATH', os.defpath).split(os.pathsep)
for directory in search_path:
@@ -136,12 +136,12 @@
return path
return None
-def FindPythonBinary(runfiles_root):
+def find_python_binary(runfiles_root):
"""Finds the real Python binary if it's not a normal absolute path."""
if PYTHON_BINARY:
- return FindBinary(runfiles_root, PYTHON_BINARY)
+ return find_binary(runfiles_root, PYTHON_BINARY)
else:
- return FindBinary(runfiles_root, PYTHON_BINARY_ACTUAL)
+ return find_binary(runfiles_root, PYTHON_BINARY_ACTUAL)
def print_verbose(*args, mapping=None, values=None):
@@ -165,7 +165,7 @@
else:
print("bootstrap: stage 1:", *args, file=sys.stderr, flush=True)
-def FindBinary(runfiles_root, bin_name):
+def find_binary(runfiles_root, bin_name):
"""Finds the real binary if it's not a normal absolute path."""
if not bin_name:
return None
@@ -183,7 +183,7 @@
return os.path.join(runfiles_root, bin_name)
else:
# Case 4: Path has to be looked up in the search path.
- return SearchPath(bin_name)
+ return search_path(bin_name)
def find_runfiles_root(main_rel_path):
"""Finds the runfiles tree."""
@@ -207,18 +207,18 @@
# On Windows, the path may contain both forward and backslashes.
# Normalize to the OS separator because the regex used later assumes
# the OS-specific separator.
- if IsWindows:
+ if is_windows():
stub_filename = stub_filename.replace("/", os.sep)
if not os.path.isabs(stub_filename):
stub_filename = os.path.join(os.getcwd(), stub_filename)
while True:
- runfiles_root = stub_filename + ('.exe' if IsWindows() else '') + '.runfiles'
+ runfiles_root = stub_filename + ('.exe' if is_windows() else '') + '.runfiles'
if os.path.isdir(runfiles_root):
return runfiles_root
- runfiles_pattern = r'(.*\.runfiles)' + (r'\\' if IsWindows() else '/') + '.*'
+ runfiles_pattern = r'(.*\.runfiles)' + (r'\\' if is_windows() else '/') + '.*'
matchobj = re.match(runfiles_pattern, stub_filename)
if matchobj:
return matchobj.group(1)
@@ -233,7 +233,7 @@
raise AssertionError('Cannot find .runfiles directory for %s' % sys.argv[0])
-def ExtractZip(zip_path, dest_dir):
+def extract_zip(zip_path, dest_dir):
"""Extracts the contents of a zip file, preserving the unix file mode bits.
These include the permission bits, and in particular, the executable bit.
@@ -245,8 +245,8 @@
zip_path: The path to the zip file to extract
dest_dir: The path to the destination directory
"""
- zip_path = GetWindowsPathWithUNCPrefix(zip_path)
- dest_dir = GetWindowsPathWithUNCPrefix(dest_dir)
+ zip_path = get_windows_path_with_unc_prefix(zip_path)
+ dest_dir = get_windows_path_with_unc_prefix(dest_dir)
with zipfile.ZipFile(zip_path) as zf:
for info in zf.infolist():
zf.extract(info, dest_dir)
@@ -263,12 +263,12 @@
# Create the runfiles tree by extracting the zip file
def create_runfiles_root():
temp_dir = tempfile.mkdtemp('', 'Bazel.runfiles_')
- ExtractZip(os.path.dirname(__file__), temp_dir)
+ extract_zip(os.path.dirname(__file__), temp_dir)
# IMPORTANT: Later code does `rm -fr` on dirname(runfiles_root) -- it's
# important that deletion code be in sync with this directory structure
return os.path.join(temp_dir, 'runfiles')
-def RunfilesEnvvar(runfiles_root):
+def runfiles_envvar(runfiles_root):
"""Finds the runfiles manifest or the runfiles directory.
Returns:
@@ -287,7 +287,7 @@
return ('RUNFILES_DIR', runfiles)
# If running from a zip, there's no manifest file.
- if IsRunningFromZip():
+ if is_running_from_zip():
return ('RUNFILES_DIR', runfiles_root)
# Look for the runfiles "output" manifest, argv[0] + ".runfiles_manifest"
@@ -310,7 +310,7 @@
return (None, None)
-def ExecuteFile(python_program, main_filename, args, env, runfiles_root,
+def execute_file(python_program, main_filename, args, env, runfiles_root,
workspace, delete_runfiles_root):
# type: (str, str, list[str], dict[str, str], str, str|None, str|None) -> ...
"""Executes the given Python file using the various environment settings.
@@ -351,8 +351,8 @@
# can't execv because we need control to return here. This only
# happens for targets built in the host config.
#
- if not (IsWindows() or workspace or delete_runfiles_root):
- _RunExecv(python_program, argv, env)
+ if not (is_windows() or workspace or delete_runfiles_root):
+ _run_execv(python_program, argv, env)
ret_code = subprocess.call(
argv,
@@ -367,7 +367,7 @@
shutil.rmtree(os.path.dirname(runfiles_root), True)
sys.exit(ret_code)
-def _RunExecv(python_program, argv, env):
+def _run_execv(python_program, argv, env):
# type: (str, list[str], dict[str, str]) -> ...
"""Executes the given Python file using the various environment settings."""
os.environ.update(env)
@@ -376,17 +376,16 @@
print_verbose("RunExecv: argv:", values=argv)
os.execv(python_program, argv)
-def Main():
- print_verbose("initial argv:", values=sys.argv)
- print_verbose("initial cwd:", os.getcwd())
- print_verbose("initial environ:", mapping=os.environ)
- print_verbose("initial sys.path:", values=sys.path)
+def main():
print_verbose("STAGE2_BOOTSTRAP:", STAGE2_BOOTSTRAP)
print_verbose("PYTHON_BINARY:", PYTHON_BINARY)
print_verbose("PYTHON_BINARY_ACTUAL:", PYTHON_BINARY_ACTUAL)
print_verbose("IS_ZIPFILE:", IS_ZIPFILE)
print_verbose("RECREATE_VENV_AT_RUNTIME:", RECREATE_VENV_AT_RUNTIME)
print_verbose("WORKSPACE_NAME :", WORKSPACE_NAME )
+ print_verbose("bootstrap sys.executable:", sys.executable)
+ print_verbose("bootstrap sys._base_executable:", sys._base_executable)
+ print_verbose("bootstrap sys.version:", sys.version)
args = sys.argv[1:]
@@ -400,7 +399,7 @@
main_rel_path = os.path.normpath(STAGE2_BOOTSTRAP)
print_verbose("main_rel_path:", main_rel_path)
- if IsRunningFromZip():
+ if is_running_from_zip():
runfiles_root = create_runfiles_root()
delete_runfiles_root = True
else:
@@ -412,7 +411,7 @@
if os.environ.get("RULES_PYTHON_TESTING_TELL_RUNFILES_ROOT"):
new_env["RULES_PYTHON_TESTING_RUNFILES_ROOT"] = runfiles_root
- runfiles_envkey, runfiles_envvalue = RunfilesEnvvar(runfiles_root)
+ runfiles_envkey, runfiles_envvalue = runfiles_envvar(runfiles_root)
if runfiles_envkey:
new_env[runfiles_envkey] = runfiles_envvalue
@@ -421,13 +420,13 @@
new_env['PYTHONSAFEPATH'] = '1'
main_filename = os.path.join(runfiles_root, main_rel_path)
- main_filename = GetWindowsPathWithUNCPrefix(main_filename)
+ main_filename = get_windows_path_with_unc_prefix(main_filename)
assert os.path.exists(main_filename), \
'Cannot exec() %r: file not found.' % main_filename
assert os.access(main_filename, os.R_OK), \
'Cannot exec() %r: file not readable.' % main_filename
- program = python_program = FindPythonBinary(runfiles_root)
+ python_program = find_python_binary(runfiles_root)
if python_program is None:
raise AssertionError("Could not find python binary: {} or {}".format(
repr(PYTHON_BINARY),
@@ -444,7 +443,7 @@
new_env.update((key, val) for key, val in os.environ.items() if key not in new_env)
workspace = None
- if IsRunningFromZip():
+ if is_running_from_zip():
# If RUN_UNDER_RUNFILES equals 1, it means we need to
# change directory to the right runfiles directory.
# (So that the data files are accessible)
@@ -453,8 +452,8 @@
try:
sys.stdout.flush()
- # NOTE: ExecuteFile may call execve() and lines after this will never run.
- ExecuteFile(
+ # NOTE: execute_file may call execve() and lines after this will never run.
+ execute_file(
python_program, main_filename, args, new_env, runfiles_root,
workspace,
delete_runfiles_root = delete_runfiles_root,
@@ -465,8 +464,8 @@
e = sys.exc_info()[1]
# This exception occurs when os.execv() fails for some reason.
if not getattr(e, 'filename', None):
- e.filename = program # Add info to error message
+ e.filename = python_program # Add info to error message
raise
if __name__ == '__main__':
- Main()
+ main()