Skip to content

Commit 028f9d1

Browse files
committed
always use declare_symlink
1 parent 8a5fce0 commit 028f9d1

File tree

8 files changed

+22
-115
lines changed

8 files changed

+22
-115
lines changed

.bazelrc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
# (Note, we cannot use `common --deleted_packages` because the bazel version command doesn't support it)
55
# To update these lines, execute
66
# `bazel run @rules_bazel_integration_test//tools:update_deleted_packages`
7-
build --deleted_packages=examples/build_file_generation,examples/build_file_generation/random_number_generator,examples/bzlmod,examples/bzlmod/entry_points,examples/bzlmod/entry_points/tests,examples/bzlmod/libs/my_lib,examples/bzlmod/other_module,examples/bzlmod/other_module/other_module/pkg,examples/bzlmod/patches,examples/bzlmod/py_proto_library,examples/bzlmod/py_proto_library/example.com/another_proto,examples/bzlmod/py_proto_library/example.com/proto,examples/bzlmod/runfiles,examples/bzlmod/tests,examples/bzlmod/tests/other_module,examples/bzlmod/whl_mods,examples/bzlmod_build_file_generation,examples/bzlmod_build_file_generation/other_module/other_module/pkg,examples/bzlmod_build_file_generation/runfiles,examples/multi_python_versions/libs/my_lib,examples/multi_python_versions/requirements,examples/multi_python_versions/tests,examples/pip_parse,examples/pip_parse_vendored,examples/pip_repository_annotations,examples/py_proto_library,examples/py_proto_library/example.com/another_proto,examples/py_proto_library/example.com/proto,gazelle,gazelle/manifest,gazelle/manifest/generate,gazelle/manifest/hasher,gazelle/manifest/test,gazelle/modules_mapping,gazelle/python,gazelle/python/private,gazelle/pythonconfig,tests/integration/compile_pip_requirements,tests/integration/compile_pip_requirements_test_from_external_repo,tests/integration/custom_commands,tests/integration/ignore_root_user_error,tests/integration/ignore_root_user_error/submodule,tests/integration/local_toolchains,tests/integration/pip_parse,tests/integration/pip_parse/empty,tests/integration/py_cc_toolchain_registered
8-
query --deleted_packages=examples/build_file_generation,examples/build_file_generation/random_number_generator,examples/bzlmod,examples/bzlmod/entry_points,examples/bzlmod/entry_points/tests,examples/bzlmod/libs/my_lib,examples/bzlmod/other_module,examples/bzlmod/other_module/other_module/pkg,examples/bzlmod/patches,examples/bzlmod/py_proto_library,examples/bzlmod/py_proto_library/example.com/another_proto,examples/bzlmod/py_proto_library/example.com/proto,examples/bzlmod/runfiles,examples/bzlmod/tests,examples/bzlmod/tests/other_module,examples/bzlmod/whl_mods,examples/bzlmod_build_file_generation,examples/bzlmod_build_file_generation/other_module/other_module/pkg,examples/bzlmod_build_file_generation/runfiles,examples/multi_python_versions/libs/my_lib,examples/multi_python_versions/requirements,examples/multi_python_versions/tests,examples/pip_parse,examples/pip_parse_vendored,examples/pip_repository_annotations,examples/py_proto_library,examples/py_proto_library/example.com/another_proto,examples/py_proto_library/example.com/proto,gazelle,gazelle/manifest,gazelle/manifest/generate,gazelle/manifest/hasher,gazelle/manifest/test,gazelle/modules_mapping,gazelle/python,gazelle/python/private,gazelle/pythonconfig,tests/integration/compile_pip_requirements,tests/integration/compile_pip_requirements_test_from_external_repo,tests/integration/custom_commands,tests/integration/ignore_root_user_error,tests/integration/ignore_root_user_error/submodule,tests/integration/local_toolchains,tests/integration/pip_parse,tests/integration/pip_parse/empty,tests/integration/py_cc_toolchain_registered
7+
build --deleted_packages=examples/build_file_generation,examples/build_file_generation/random_number_generator,examples/bzlmod,examples/bzlmod_build_file_generation,examples/bzlmod_build_file_generation/other_module/other_module/pkg,examples/bzlmod_build_file_generation/runfiles,examples/bzlmod/entry_points,examples/bzlmod/entry_points/tests,examples/bzlmod/libs/my_lib,examples/bzlmod/other_module,examples/bzlmod/other_module/other_module/pkg,examples/bzlmod/patches,examples/bzlmod/py_proto_library,examples/bzlmod/py_proto_library/example.com/another_proto,examples/bzlmod/py_proto_library/example.com/proto,examples/bzlmod/runfiles,examples/bzlmod/tests,examples/bzlmod/tests/other_module,examples/bzlmod/whl_mods,examples/multi_python_versions/libs/my_lib,examples/multi_python_versions/requirements,examples/multi_python_versions/tests,examples/pip_parse,examples/pip_parse_vendored,examples/pip_repository_annotations,examples/py_proto_library,examples/py_proto_library/example.com/another_proto,examples/py_proto_library/example.com/proto,gazelle,gazelle/manifest,gazelle/manifest/generate,gazelle/manifest/hasher,gazelle/manifest/test,gazelle/modules_mapping,gazelle/python,gazelle/pythonconfig,gazelle/python/private,tests/integration/compile_pip_requirements,tests/integration/compile_pip_requirements_test_from_external_repo,tests/integration/custom_commands,tests/integration/ignore_root_user_error,tests/integration/ignore_root_user_error/submodule,tests/integration/local_toolchains,tests/integration/pip_parse,tests/integration/pip_parse/empty,tests/integration/py_cc_toolchain_registered
8+
query --deleted_packages=examples/build_file_generation,examples/build_file_generation/random_number_generator,examples/bzlmod,examples/bzlmod_build_file_generation,examples/bzlmod_build_file_generation/other_module/other_module/pkg,examples/bzlmod_build_file_generation/runfiles,examples/bzlmod/entry_points,examples/bzlmod/entry_points/tests,examples/bzlmod/libs/my_lib,examples/bzlmod/other_module,examples/bzlmod/other_module/other_module/pkg,examples/bzlmod/patches,examples/bzlmod/py_proto_library,examples/bzlmod/py_proto_library/example.com/another_proto,examples/bzlmod/py_proto_library/example.com/proto,examples/bzlmod/runfiles,examples/bzlmod/tests,examples/bzlmod/tests/other_module,examples/bzlmod/whl_mods,examples/multi_python_versions/libs/my_lib,examples/multi_python_versions/requirements,examples/multi_python_versions/tests,examples/pip_parse,examples/pip_parse_vendored,examples/pip_repository_annotations,examples/py_proto_library,examples/py_proto_library/example.com/another_proto,examples/py_proto_library/example.com/proto,gazelle,gazelle/manifest,gazelle/manifest/generate,gazelle/manifest/hasher,gazelle/manifest/test,gazelle/modules_mapping,gazelle/python,gazelle/pythonconfig,gazelle/python/private,tests/integration/compile_pip_requirements,tests/integration/compile_pip_requirements_test_from_external_repo,tests/integration/custom_commands,tests/integration/ignore_root_user_error,tests/integration/ignore_root_user_error/submodule,tests/integration/local_toolchains,tests/integration/pip_parse,tests/integration/pip_parse/empty,tests/integration/py_cc_toolchain_registered
99

1010
test --test_output=errors
1111

CHANGELOG.md

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@ Other changes:
100100
for the latest toolchain versions for each minor Python version. You can control
101101
the toolchain selection by using the
102102
{bzl:obj}`//python/config_settings:py_linux_libc` build flag.
103+
* (providers) Added {obj}`py_runtime_info.site_init_template` and
104+
{obj}`PyRuntimeInfo.site_init_template` for specifying the template to use to
105+
initialize the interpreter via venv startup hooks.
103106

104107
{#v0-0-0-removed}
105108
### Removed
@@ -124,13 +127,7 @@ Other changes:
124127

125128
{#v0-40-added}
126129
### Added
127-
<<<<<<< HEAD
128130
* Nothing added.
129-
=======
130-
* (providers) Added {obj}`py_runtime_info.site_init_template` and
131-
{obj}`PyRuntimeInfo.site_init_template` for specifying the template to use to
132-
initialize the interpreter via venv startup hooks.
133-
>>>>>>> a057e85e (wip: make sys.executable work with script bootstrap)
134131

135132
{#v0-40-removed}
136133
### Removed
@@ -174,9 +171,6 @@ Other changes:
174171
* (precompiling) Skip precompiling (instead of erroring) if the legacy
175172
`@bazel_tools//tools/python:autodetecting_toolchain` is being used
176173
([#2364](https://github.com/bazelbuild/rules_python/issues/2364)).
177-
* (bzlmod) Generate `config_setting` values for all available toolchains instead
178-
of only the registered toolchains, which restores the previous behaviour that
179-
`bzlmod` users would have observed.
180174

181175
{#v0-39-0-added}
182176
### Added

python/private/py_executable_bazel.bzl

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -362,9 +362,14 @@ def _create_venv(ctx, output_prefix, imports, runtime_details):
362362
runtime = runtime_details.effective_runtime
363363
if runtime.interpreter:
364364
py_exe_basename = paths.basename(runtime.interpreter.short_path)
365-
interpreter = ctx.actions.declare_file("{}/bin/{}".format(venv, py_exe_basename))
366-
ctx.actions.symlink(output = interpreter, target_file = runtime.interpreter)
365+
366+
# A real symlink is required to support RBE. RBE may materialize what
367+
# ctx.actions.symlink() points to.
368+
interpreter = ctx.actions.declare_symlink("{}/bin/{}".format(venv, py_exe_basename))
367369
interpreter_actual_path = runtime.interpreter.short_path
370+
parent = "/".join([".."] * (interpreter_actual_path.count("/") + 1))
371+
rel_path = parent + "/" + interpreter_actual_path
372+
ctx.actions.symlink(output = interpreter, target_path = rel_path)
368373
else:
369374
py_exe_basename = paths.basename(runtime.interpreter_path)
370375
interpreter = ctx.actions.declare_symlink("{}/bin/{}".format(venv, py_exe_basename))

python/private/py_runtime_info.bzl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ the same conventions as the standard CPython interpreter.
147147
148148
The runtime's ABI flags, i.e. `sys.abiflags`.
149149
150-
:::{versionadded} 0.39.0
150+
:::{versionadded} 0.41.0
151151
:::
152152
""",
153153
"bootstrap_template": """
@@ -281,7 +281,7 @@ are (only) `"PY2"` and `"PY3"`.
281281
The template to use for the binary-specific site-init hook run by the
282282
interpreter at startup.
283283
284-
:::{versionadded} VERSION_NEXT_FEATURE
284+
:::{versionadded} 0.41.0
285285
:::
286286
""",
287287
"stage2_bootstrap_template": """

python/private/py_runtime_rule.bzl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ value.
324324
The template to use for the binary-specific site-init hook run by the
325325
interpreter at startup.
326326
327-
:::{versionadded} VERSION_NEXT_FEATURE
327+
:::{versionadded} 0.41.0
328328
:::
329329
""",
330330
),

python/private/stage1_bootstrap_template.sh

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,10 +129,11 @@ if [[ "$IS_ZIPFILE" == "1" ]]; then
129129
mkdir -p "$(dirname $python_exe)"
130130
ln -s "$symlink_to" "$python_exe"
131131
else
132-
set -x
133-
stat "$python_exe"
134-
ls -l $(dirname $python_exe)
135-
set +x
132+
:
133+
#set -x
134+
#stat "$python_exe"
135+
#ls -l $(dirname $python_exe)
136+
#set +x
136137
fi
137138

138139
# At this point, we should have a valid reference to the interpreter.

python/private/stage2_bootstrap_template.py

Lines changed: 1 addition & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,13 @@
1616
import os
1717
import re
1818
import runpy
19-
import subprocess
2019
import uuid
2120

2221
# ===== Template substitutions start =====
2322
# We just put them in one place so its easy to tell which are used.
2423

2524
# Runfiles-relative path to the main Python source file.
2625
MAIN = "%main%"
27-
# Runfiles-relative path to the coverage tool entry point, if any.
28-
COVERAGE_TOOL = "%coverage_tool%"
2926

3027
# ===== Template substitutions end =====
3128

@@ -114,45 +111,6 @@ def is_verbose_coverage():
114111
return os.environ.get("VERBOSE_COVERAGE") or is_verbose()
115112

116113

117-
##def find_coverage_entry_point(module_space):
118-
## cov_tool = COVERAGE_TOOL
119-
## if cov_tool:
120-
## print_verbose_coverage("Using toolchain coverage_tool %r" % cov_tool)
121-
## else:
122-
## cov_tool = os.environ.get("PYTHON_COVERAGE")
123-
## if cov_tool:
124-
## print_verbose_coverage("PYTHON_COVERAGE: %r" % cov_tool)
125-
## if cov_tool:
126-
## return find_binary(module_space, cov_tool)
127-
## return None
128-
129-
130-
def find_binary(module_space, bin_name):
131-
"""Finds the real binary if it's not a normal absolute path."""
132-
if not bin_name:
133-
return None
134-
if bin_name.startswith("//"):
135-
# Case 1: Path is a label. Not supported yet.
136-
raise AssertionError(
137-
"Bazel does not support execution of Python interpreters via labels yet"
138-
)
139-
elif os.path.isabs(bin_name):
140-
# Case 2: Absolute path.
141-
return bin_name
142-
# Use normpath() to convert slashes to os.sep on Windows.
143-
elif os.sep in os.path.normpath(bin_name):
144-
# Case 3: Path is relative to the repo root.
145-
return os.path.join(module_space, bin_name)
146-
else:
147-
# Case 4: Path has to be looked up in the search path.
148-
return search_path(bin_name)
149-
150-
151-
##def create_python_path_entries(python_imports, module_space):
152-
## parts = python_imports.split(":")
153-
## return [module_space] + ["%s/%s" % (module_space, path) for path in parts]
154-
155-
156114
def find_runfiles_root(main_rel_path):
157115
"""Finds the runfiles tree."""
158116
# When the calling process used the runfiles manifest to resolve the
@@ -197,15 +155,6 @@ def find_runfiles_root(main_rel_path):
197155
raise AssertionError("Cannot find .runfiles directory for %s" % sys.argv[0])
198156

199157

200-
# Returns repository roots to add to the import path.
201-
##def get_repositories_imports(module_space, import_all):
202-
## if import_all:
203-
## repo_dirs = [os.path.join(module_space, d) for d in os.listdir(module_space)]
204-
## repo_dirs.sort()
205-
## return [d for d in repo_dirs if os.path.isdir(d)]
206-
## return [os.path.join(module_space, WORKSPACE_NAME)]
207-
208-
209158
def runfiles_envvar(module_space):
210159
"""Finds the runfiles manifest or the runfiles directory.
211160
@@ -245,15 +194,6 @@ def runfiles_envvar(module_space):
245194
return (None, None)
246195

247196

248-
def deduplicate(items):
249-
"""Efficiently filter out duplicates, keeping the first element only."""
250-
seen = set()
251-
for it in items:
252-
if it not in seen:
253-
seen.add(it)
254-
yield it
255-
256-
257197
def instrumented_file_paths():
258198
"""Yields tuples of realpath of each instrumented file with the relative path."""
259199
manifest_filename = os.environ.get("COVERAGE_MANIFEST")
@@ -424,29 +364,12 @@ def main():
424364
#
425365
# To replicate this behavior, we add main's directory within the runfiles
426366
# when safe path isn't enabled.
427-
python_path_entries = []
428-
prepend_path_entries = []
429367
if not getattr(sys.flags, "safe_path", False):
430368
prepend_path_entries = [
431369
os.path.join(module_space, os.path.dirname(main_rel_path))
432370
]
433371
else:
434372
prepend_path_entries = []
435-
##python_path_entries = create_python_path_entries(IMPORTS_STR, module_space)
436-
##python_path_entries += get_repositories_imports(module_space, IMPORT_ALL)
437-
python_path_entries = [
438-
get_windows_path_with_unc_prefix(d) for d in python_path_entries
439-
]
440-
441-
# Remove duplicates to avoid overly long PYTHONPATH (#10977). Preserve order,
442-
# keep first occurrence only.
443-
python_path_entries = list(deduplicate(python_path_entries))
444-
445-
##if is_windows():
446-
## python_path_entries = [p.replace("/", os.sep) for p in python_path_entries]
447-
##else:
448-
## # deduplicate returns a generator, but we need a list after this.
449-
## python_path_entries = list(python_path_entries)
450373

451374
runfiles_envkey, runfiles_envvalue = runfiles_envvar(module_space)
452375
if runfiles_envkey:
@@ -463,28 +386,12 @@ def main():
463386

464387
sys.stdout.flush()
465388

466-
# Add the user imports after the stdlib, but before the runtime's
467-
# site-packages directory. This gives the stdlib precedence, while allowing
468-
# users to override non-stdlib packages that may have been bundled with
469-
# the runtime (usually pip).
470-
# NOTE: There isn't a good way to identify the stdlib paths, so we just
471-
# expect site-packages comes after it, per
472-
# https://docs.python.org/3/library/sys_path_init.html#sys-path-init
473-
for i, path in enumerate(sys.path):
474-
# dist-packages is a debian convention, see
475-
# https://wiki.debian.org/Python#Deviations_from_upstream
476-
if os.path.basename(path) in ("site-packages", "dist-packages"):
477-
sys.path[i:i] = python_path_entries
478-
break
479-
else:
480-
# Otherwise, no site-packages directory was found, which is odd but ok.
481-
sys.path.extend(python_path_entries)
482-
483389
# NOTE: The sys.path must be modified before coverage is imported/activated
484390
# NOTE: Perform this after the user imports are appended. This avoids a
485391
# user import accidentally triggering the site-packages logic above.
486392
sys.path[0:0] = prepend_path_entries
487393

394+
# todo: also check COVERAGE_DIR env var
488395
import _bazel_site_init
489396

490397
with _maybe_collect_coverage(enable=_bazel_site_init.COVERAGE_SETUP):

tests/bootstrap_impls/sys_path_order_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ def test_sys_path_order(self):
3535
for i, value in enumerate(sys.path):
3636
# The runtime's root repo may be added to sys.path, but it
3737
# counts as a user directory, not stdlib directory.
38-
if value == sys.prefix:
38+
if value in (sys.prefix, sys.base_prefix):
3939
category = "user"
4040
elif value.startswith(sys.base_prefix):
4141
# The runtime's site-package directory might be called

0 commit comments

Comments
 (0)