Skip to content

Commit eb1ae41

Browse files
authored
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.
1 parent c9bb66e commit eb1ae41

File tree

1 file changed

+39
-40
lines changed

1 file changed

+39
-40
lines changed

python/private/python_bootstrap_template.txt

Lines changed: 39 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -66,21 +66,21 @@ else:
6666

6767
ADDITIONAL_INTERPRETER_ARGS = os.environ.get("RULES_PYTHON_ADDITIONAL_INTERPRETER_ARGS", "")
6868

69-
def IsRunningFromZip():
69+
def is_running_from_zip():
7070
return IS_ZIPFILE
7171

72-
if IsRunningFromZip():
72+
if is_running_from_zip():
7373
import shutil
7474
import tempfile
7575
import zipfile
7676
else:
7777
import re
7878

7979
# Return True if running on Windows
80-
def IsWindows():
80+
def is_windows():
8181
return os.name == 'nt'
8282

83-
def GetWindowsPathWithUNCPrefix(path):
83+
def get_windows_path_with_unc_prefix(path):
8484
"""Adds UNC prefix after getting a normalized absolute Windows path.
8585
8686
No-op for non-Windows platforms or if running under python2.
@@ -89,7 +89,7 @@ def GetWindowsPathWithUNCPrefix(path):
8989

9090
# No need to add prefix for non-Windows platforms.
9191
# And \\?\ doesn't work in python 2 or on mingw
92-
if not IsWindows() or sys.version_info[0] < 3:
92+
if not is_windows() or sys.version_info[0] < 3:
9393
return path
9494

9595
# Starting in Windows 10, version 1607(OS build 14393), MAX_PATH limitations have been
@@ -120,13 +120,13 @@ def GetWindowsPathWithUNCPrefix(path):
120120
# os.path.abspath returns a normalized absolute path
121121
return unicode_prefix + os.path.abspath(path)
122122

123-
def HasWindowsExecutableExtension(path):
123+
def has_windows_executable_extension(path):
124124
return path.endswith('.exe') or path.endswith('.com') or path.endswith('.bat')
125125

126-
if PYTHON_BINARY and IsWindows() and not HasWindowsExecutableExtension(PYTHON_BINARY):
126+
if PYTHON_BINARY and is_windows() and not has_windows_executable_extension(PYTHON_BINARY):
127127
PYTHON_BINARY = PYTHON_BINARY + '.exe'
128128

129-
def SearchPath(name):
129+
def search_path(name):
130130
"""Finds a file in a given search path."""
131131
search_path = os.getenv('PATH', os.defpath).split(os.pathsep)
132132
for directory in search_path:
@@ -136,12 +136,12 @@ def SearchPath(name):
136136
return path
137137
return None
138138

139-
def FindPythonBinary(runfiles_root):
139+
def find_python_binary(runfiles_root):
140140
"""Finds the real Python binary if it's not a normal absolute path."""
141141
if PYTHON_BINARY:
142-
return FindBinary(runfiles_root, PYTHON_BINARY)
142+
return find_binary(runfiles_root, PYTHON_BINARY)
143143
else:
144-
return FindBinary(runfiles_root, PYTHON_BINARY_ACTUAL)
144+
return find_binary(runfiles_root, PYTHON_BINARY_ACTUAL)
145145

146146

147147
def print_verbose(*args, mapping=None, values=None):
@@ -165,7 +165,7 @@ def print_verbose(*args, mapping=None, values=None):
165165
else:
166166
print("bootstrap: stage 1:", *args, file=sys.stderr, flush=True)
167167

168-
def FindBinary(runfiles_root, bin_name):
168+
def find_binary(runfiles_root, bin_name):
169169
"""Finds the real binary if it's not a normal absolute path."""
170170
if not bin_name:
171171
return None
@@ -183,7 +183,7 @@ def FindBinary(runfiles_root, bin_name):
183183
return os.path.join(runfiles_root, bin_name)
184184
else:
185185
# Case 4: Path has to be looked up in the search path.
186-
return SearchPath(bin_name)
186+
return search_path(bin_name)
187187

188188
def find_runfiles_root(main_rel_path):
189189
"""Finds the runfiles tree."""
@@ -207,18 +207,18 @@ def find_runfiles_root(main_rel_path):
207207
# On Windows, the path may contain both forward and backslashes.
208208
# Normalize to the OS separator because the regex used later assumes
209209
# the OS-specific separator.
210-
if IsWindows:
210+
if is_windows():
211211
stub_filename = stub_filename.replace("/", os.sep)
212212

213213
if not os.path.isabs(stub_filename):
214214
stub_filename = os.path.join(os.getcwd(), stub_filename)
215215

216216
while True:
217-
runfiles_root = stub_filename + ('.exe' if IsWindows() else '') + '.runfiles'
217+
runfiles_root = stub_filename + ('.exe' if is_windows() else '') + '.runfiles'
218218
if os.path.isdir(runfiles_root):
219219
return runfiles_root
220220

221-
runfiles_pattern = r'(.*\.runfiles)' + (r'\\' if IsWindows() else '/') + '.*'
221+
runfiles_pattern = r'(.*\.runfiles)' + (r'\\' if is_windows() else '/') + '.*'
222222
matchobj = re.match(runfiles_pattern, stub_filename)
223223
if matchobj:
224224
return matchobj.group(1)
@@ -233,7 +233,7 @@ def find_runfiles_root(main_rel_path):
233233

234234
raise AssertionError('Cannot find .runfiles directory for %s' % sys.argv[0])
235235

236-
def ExtractZip(zip_path, dest_dir):
236+
def extract_zip(zip_path, dest_dir):
237237
"""Extracts the contents of a zip file, preserving the unix file mode bits.
238238
239239
These include the permission bits, and in particular, the executable bit.
@@ -245,8 +245,8 @@ def ExtractZip(zip_path, dest_dir):
245245
zip_path: The path to the zip file to extract
246246
dest_dir: The path to the destination directory
247247
"""
248-
zip_path = GetWindowsPathWithUNCPrefix(zip_path)
249-
dest_dir = GetWindowsPathWithUNCPrefix(dest_dir)
248+
zip_path = get_windows_path_with_unc_prefix(zip_path)
249+
dest_dir = get_windows_path_with_unc_prefix(dest_dir)
250250
with zipfile.ZipFile(zip_path) as zf:
251251
for info in zf.infolist():
252252
zf.extract(info, dest_dir)
@@ -263,12 +263,12 @@ def ExtractZip(zip_path, dest_dir):
263263
# Create the runfiles tree by extracting the zip file
264264
def create_runfiles_root():
265265
temp_dir = tempfile.mkdtemp('', 'Bazel.runfiles_')
266-
ExtractZip(os.path.dirname(__file__), temp_dir)
266+
extract_zip(os.path.dirname(__file__), temp_dir)
267267
# IMPORTANT: Later code does `rm -fr` on dirname(runfiles_root) -- it's
268268
# important that deletion code be in sync with this directory structure
269269
return os.path.join(temp_dir, 'runfiles')
270270

271-
def RunfilesEnvvar(runfiles_root):
271+
def runfiles_envvar(runfiles_root):
272272
"""Finds the runfiles manifest or the runfiles directory.
273273
274274
Returns:
@@ -287,7 +287,7 @@ def RunfilesEnvvar(runfiles_root):
287287
return ('RUNFILES_DIR', runfiles)
288288

289289
# If running from a zip, there's no manifest file.
290-
if IsRunningFromZip():
290+
if is_running_from_zip():
291291
return ('RUNFILES_DIR', runfiles_root)
292292

293293
# Look for the runfiles "output" manifest, argv[0] + ".runfiles_manifest"
@@ -310,7 +310,7 @@ def RunfilesEnvvar(runfiles_root):
310310

311311
return (None, None)
312312

313-
def ExecuteFile(python_program, main_filename, args, env, runfiles_root,
313+
def execute_file(python_program, main_filename, args, env, runfiles_root,
314314
workspace, delete_runfiles_root):
315315
# type: (str, str, list[str], dict[str, str], str, str|None, str|None) -> ...
316316
"""Executes the given Python file using the various environment settings.
@@ -351,8 +351,8 @@ def ExecuteFile(python_program, main_filename, args, env, runfiles_root,
351351
# can't execv because we need control to return here. This only
352352
# happens for targets built in the host config.
353353
#
354-
if not (IsWindows() or workspace or delete_runfiles_root):
355-
_RunExecv(python_program, argv, env)
354+
if not (is_windows() or workspace or delete_runfiles_root):
355+
_run_execv(python_program, argv, env)
356356

357357
ret_code = subprocess.call(
358358
argv,
@@ -367,7 +367,7 @@ def ExecuteFile(python_program, main_filename, args, env, runfiles_root,
367367
shutil.rmtree(os.path.dirname(runfiles_root), True)
368368
sys.exit(ret_code)
369369

370-
def _RunExecv(python_program, argv, env):
370+
def _run_execv(python_program, argv, env):
371371
# type: (str, list[str], dict[str, str]) -> ...
372372
"""Executes the given Python file using the various environment settings."""
373373
os.environ.update(env)
@@ -376,17 +376,16 @@ def _RunExecv(python_program, argv, env):
376376
print_verbose("RunExecv: argv:", values=argv)
377377
os.execv(python_program, argv)
378378

379-
def Main():
380-
print_verbose("initial argv:", values=sys.argv)
381-
print_verbose("initial cwd:", os.getcwd())
382-
print_verbose("initial environ:", mapping=os.environ)
383-
print_verbose("initial sys.path:", values=sys.path)
379+
def main():
384380
print_verbose("STAGE2_BOOTSTRAP:", STAGE2_BOOTSTRAP)
385381
print_verbose("PYTHON_BINARY:", PYTHON_BINARY)
386382
print_verbose("PYTHON_BINARY_ACTUAL:", PYTHON_BINARY_ACTUAL)
387383
print_verbose("IS_ZIPFILE:", IS_ZIPFILE)
388384
print_verbose("RECREATE_VENV_AT_RUNTIME:", RECREATE_VENV_AT_RUNTIME)
389385
print_verbose("WORKSPACE_NAME :", WORKSPACE_NAME )
386+
print_verbose("bootstrap sys.executable:", sys.executable)
387+
print_verbose("bootstrap sys._base_executable:", sys._base_executable)
388+
print_verbose("bootstrap sys.version:", sys.version)
390389

391390
args = sys.argv[1:]
392391

@@ -400,7 +399,7 @@ def Main():
400399
main_rel_path = os.path.normpath(STAGE2_BOOTSTRAP)
401400
print_verbose("main_rel_path:", main_rel_path)
402401

403-
if IsRunningFromZip():
402+
if is_running_from_zip():
404403
runfiles_root = create_runfiles_root()
405404
delete_runfiles_root = True
406405
else:
@@ -412,7 +411,7 @@ def Main():
412411
if os.environ.get("RULES_PYTHON_TESTING_TELL_RUNFILES_ROOT"):
413412
new_env["RULES_PYTHON_TESTING_RUNFILES_ROOT"] = runfiles_root
414413

415-
runfiles_envkey, runfiles_envvalue = RunfilesEnvvar(runfiles_root)
414+
runfiles_envkey, runfiles_envvalue = runfiles_envvar(runfiles_root)
416415
if runfiles_envkey:
417416
new_env[runfiles_envkey] = runfiles_envvalue
418417

@@ -421,13 +420,13 @@ def Main():
421420
new_env['PYTHONSAFEPATH'] = '1'
422421

423422
main_filename = os.path.join(runfiles_root, main_rel_path)
424-
main_filename = GetWindowsPathWithUNCPrefix(main_filename)
423+
main_filename = get_windows_path_with_unc_prefix(main_filename)
425424
assert os.path.exists(main_filename), \
426425
'Cannot exec() %r: file not found.' % main_filename
427426
assert os.access(main_filename, os.R_OK), \
428427
'Cannot exec() %r: file not readable.' % main_filename
429428

430-
program = python_program = FindPythonBinary(runfiles_root)
429+
python_program = find_python_binary(runfiles_root)
431430
if python_program is None:
432431
raise AssertionError("Could not find python binary: {} or {}".format(
433432
repr(PYTHON_BINARY),
@@ -444,7 +443,7 @@ def Main():
444443
new_env.update((key, val) for key, val in os.environ.items() if key not in new_env)
445444

446445
workspace = None
447-
if IsRunningFromZip():
446+
if is_running_from_zip():
448447
# If RUN_UNDER_RUNFILES equals 1, it means we need to
449448
# change directory to the right runfiles directory.
450449
# (So that the data files are accessible)
@@ -453,8 +452,8 @@ def Main():
453452

454453
try:
455454
sys.stdout.flush()
456-
# NOTE: ExecuteFile may call execve() and lines after this will never run.
457-
ExecuteFile(
455+
# NOTE: execute_file may call execve() and lines after this will never run.
456+
execute_file(
458457
python_program, main_filename, args, new_env, runfiles_root,
459458
workspace,
460459
delete_runfiles_root = delete_runfiles_root,
@@ -465,8 +464,8 @@ def Main():
465464
e = sys.exc_info()[1]
466465
# This exception occurs when os.execv() fails for some reason.
467466
if not getattr(e, 'filename', None):
468-
e.filename = program # Add info to error message
467+
e.filename = python_program # Add info to error message
469468
raise
470469

471470
if __name__ == '__main__':
472-
Main()
471+
main()

0 commit comments

Comments
 (0)