data files aren't copied / symlinked from the execroot to the sandbox
Description of the bug:
~Files with names containing spaces~ "data" / non-source files aren't copied / symlinked from the execroot to the sandbox.
~This is somewhat similar to https://github.com/bazelbuild/bazel/issues/4327 except this is specific to the sandbox execroot.~
See below:
$ ls -al /home/aaron/.cache/bazel/_bazel_aaron/427160bfde955c722f62691f0f59a325/sandbox/linux-sandbox/1265/execroot/com_google_protobuf/external/protobuf_pip_deps_setuptools/site-packages/setuptools/_vendor/jaraco/text
total 36
drwxr-xr-x 3 aaron aaron 4096 Jun 11 02:43 .
drwxr-xr-x 6 aaron aaron 4096 Jun 11 02:43 ..
lrwxrwxrwx 1 aaron aaron 194 Jun 11 00:34 __init__.py -> /home/aaron/.cache/bazel/_bazel_aaron/427160bfde955c722f62691f0f59a325/execroot/com_google_protobuf/external/protobuf_pip_deps_setuptools/site-packages/setuptools/_vendor/jaraco/text/__init__.py
drwxr-xr-x 2 aaron aaron 4096 Jun 11 02:43 __pycache__
lrwxrwxrwx 1 aaron aaron 193 Jun 11 00:34 layouts.py -> /home/aaron/.cache/bazel/_bazel_aaron/427160bfde955c722f62691f0f59a325/execroot/com_google_protobuf/external/protobuf_pip_deps_setuptools/site-packages/setuptools/_vendor/jaraco/text/layouts.py
lrwxrwxrwx 1 aaron aaron 199 Jun 11 00:34 show-newlines.py -> /home/aaron/.cache/bazel/_bazel_aaron/427160bfde955c722f62691f0f59a325/execroot/com_google_protobuf/external/protobuf_pip_deps_setuptools/site-packages/setuptools/_vendor/jaraco/text/show-newlines.py
lrwxrwxrwx 1 aaron aaron 198 Jun 11 00:34 strip-prefix.py -> /home/aaron/.cache/bazel/_bazel_aaron/427160bfde955c722f62691f0f59a325/execroot/com_google_protobuf/external/protobuf_pip_deps_setuptools/site-packages/setuptools/_vendor/jaraco/text/strip-prefix.py
lrwxrwxrwx 1 aaron aaron 195 Jun 11 00:34 to-dvorak.py -> /home/aaron/.cache/bazel/_bazel_aaron/427160bfde955c722f62691f0f59a325/execroot/com_google_protobuf/external/protobuf_pip_deps_setuptools/site-packages/setuptools/_vendor/jaraco/text/to-dvorak.py
lrwxrwxrwx 1 aaron aaron 195 Jun 11 00:34 to-qwerty.py -> /home/aaron/.cache/bazel/_bazel_aaron/427160bfde955c722f62691f0f59a325/execroot/com_google_protobuf/external/protobuf_pip_deps_setuptools/site-packages/setuptools/_vendor/jaraco/text/to-qwerty.py
versus:
aaron@instance-20250307-185451:~/protobuf$ ls -al /home/aaron/.cache/bazel/_bazel_aaron/427160bfde955c722f62691f0f59a325/execroot/com_google_protobuf/external/protobuf_pip_deps_setuptools/site-packages/setuptools/_vendor/jaraco/text
total 48
drwxr-xr-x 2 aaron aaron 4096 Jun 10 22:22 .
drwxr-xr-x 5 aaron aaron 4096 Jun 10 22:22 ..
-rw-r--r-- 1 aaron aaron 1335 Jun 10 22:22 'Lorem ipsum.txt'
-rw-r--r-- 1 aaron aaron 16250 Jun 10 22:22 __init__.py
-rw-r--r-- 1 aaron aaron 643 Jun 10 22:22 layouts.py
-rw-r--r-- 1 aaron aaron 904 Jun 10 22:22 show-newlines.py
-rw-r--r-- 1 aaron aaron 412 Jun 10 22:22 strip-prefix.py
-rw-r--r-- 1 aaron aaron 119 Jun 10 22:22 to-dvorak.py
-rw-r--r-- 1 aaron aaron 119 Jun 10 22:22 to-qwerty.py
You can see that the original execroot contains 'Lorem ipsum.txt' but the sandbox one doesn't. This is reproducible with both Linux and macOS sandboxes — I have not tried Windows or any others.
Which category does this issue belong to?
No response
What's the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.
Try and build my fork of Protobuf where I have updated the version of setuptools and Bazel https://github.com/aaronmaxlevy/protobuf/tree/aaron_update_setuptools .
Then try to run bazel test //python/... //python:python_version_test --noenable_bzlmod --sandbox_debug
You will get an error that looks something like this:
Traceback (most recent call last):
File "/home/aaron/.cache/bazel/_bazel_aaron/427160bfde955c722f62691f0f59a325/sandbox/linux-sandbox/1262/execroot/com_google_protobuf/protobuf/setup.py", line 15, in <module>
from setuptools import setup, Extension, find_namespace_packages
File "/home/aaron/.cache/bazel/_bazel_aaron/427160bfde955c722f62691f0f59a325/sandbox/linux-sandbox/1262/execroot/com_google_protobuf/external/protobuf_pip_deps_setuptools/site-packages/setuptools/__init__.py", line 27, in <module>
from .dist import Distribution
File "/home/aaron/.cache/bazel/_bazel_aaron/427160bfde955c722f62691f0f59a325/sandbox/linux-sandbox/1262/execroot/com_google_protobuf/external/protobuf_pip_deps_setuptools/site-packages/setuptools/dist.py", line 20, in <module>
from . import (
File "/home/aaron/.cache/bazel/_bazel_aaron/427160bfde955c722f62691f0f59a325/sandbox/linux-sandbox/1262/execroot/com_google_protobuf/external/protobuf_pip_deps_setuptools/site-packages/setuptools/_entry_points.py", line 6, in <module>
from jaraco.text import yield_lines
File "/home/aaron/.cache/bazel/_bazel_aaron/427160bfde955c722f62691f0f59a325/sandbox/linux-sandbox/1262/execroot/com_google_protobuf/external/protobuf_pip_deps_setuptools/site-packages/setuptools/_vendor/jaraco/text/__init__.py", line 231, in <module>
files(__name__).joinpath('Lorem ipsum.txt').read_text(encoding='utf-8')
File "/usr/lib/python3.11/pathlib.py", line 1059, in read_text
with self.open(mode='r', encoding=encoding, errors=errors) as f:
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/pathlib.py", line 1045, in open
return io.open(self, mode, buffering, encoding, errors, newline)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: '/home/aaron/.cache/bazel/_bazel_aaron/427160bfde955c722f62691f0f59a325/sandbox/linux-sandbox/1262/execroot/com_google_protobuf/external/protobuf_pip_deps_setuptools/site-packages/setuptools/_vendor/jaraco/text/Lorem ipsum.txt'
Which operating system are you running Bazel on?
Debian 12 / macOS 15 (tested on both)
What is the output of bazel info release?
release 7.4.0
If bazel info release returns development version or (@non-git), tell us how you built Bazel.
No response
What's the output of git remote get-url origin; git rev-parse HEAD ?
If this is a regression, please try to identify the Bazel commit where the bug was introduced with bazelisk --bisect.
No response
Have you found anything relevant by searching the web?
No response
Any other information, logs, or outputs that you want to share?
No response
Could you check whether this still reproduces with Bazel 8.2.1?
Could you check whether this still reproduces with Bazel 8.2.1?
@fmeum It is still reproducible with Bazel 8.2.1.
I created a separate branch on my Protobuf fork with changes required for Bazel 8 — see https://github.com/aaronmaxlevy/protobuf/tree/aaron_test_bazel_8
If you run bazel build //python/dist:source_wheel --noenable_bzlmod --enable_workspace --incompatible_autoload_externally= it will yield this same error / behavior.
On macOS with Bazel 8.2.1: Sandbox Execroot:
% ls -al /private/var/tmp/_bazel_aaron/8417658af7f5a2267a860834e5d6e1a1/sandbox/darwin-sandbox/1054/execroot/com_google_protobuf/external/protobuf_pip_deps_setuptools/site-packages/setuptools/_vendor/jaraco/text/
total 0
lrwxr-xr-x 1 aaron wheel 186 Jun 11 10:37 __init__.py -> /private/var/tmp/_bazel_aaron/8417658af7f5a2267a860834e5d6e1a1/execroot/com_google_protobuf/external/protobuf_pip_deps_setuptools/site-packages/setuptools/_vendor/jaraco/text/__init__.py
drwxr-xr-x 3 aaron wheel 96 Jun 11 10:44 __pycache__
drwxr-xr-x 9 aaron wheel 288 Jun 11 10:44 .
drwxr-xr-x 8 aaron wheel 256 Jun 11 10:44 ..
lrwxr-xr-x 1 aaron wheel 185 Jun 11 10:37 layouts.py -> /private/var/tmp/_bazel_aaron/8417658af7f5a2267a860834e5d6e1a1/execroot/com_google_protobuf/external/protobuf_pip_deps_setuptools/site-packages/setuptools/_vendor/jaraco/text/layouts.py
lrwxr-xr-x 1 aaron wheel 191 Jun 11 10:37 show-newlines.py -> /private/var/tmp/_bazel_aaron/8417658af7f5a2267a860834e5d6e1a1/execroot/com_google_protobuf/external/protobuf_pip_deps_setuptools/site-packages/setuptools/_vendor/jaraco/text/show-newlines.py
lrwxr-xr-x 1 aaron wheel 190 Jun 11 10:37 strip-prefix.py -> /private/var/tmp/_bazel_aaron/8417658af7f5a2267a860834e5d6e1a1/execroot/com_google_protobuf/external/protobuf_pip_deps_setuptools/site-packages/setuptools/_vendor/jaraco/text/strip-prefix.py
lrwxr-xr-x 1 aaron wheel 187 Jun 11 10:37 to-dvorak.py -> /private/var/tmp/_bazel_aaron/8417658af7f5a2267a860834e5d6e1a1/execroot/com_google_protobuf/external/protobuf_pip_deps_setuptools/site-packages/setuptools/_vendor/jaraco/text/to-dvorak.py
lrwxr-xr-x 1 aaron wheel 187 Jun 11 10:37 to-qwerty.py -> /private/var/tmp/_bazel_aaron/8417658af7f5a2267a860834e5d6e1a1/execroot/com_google_protobuf/external/protobuf_pip_deps_setuptools/site-packages/setuptools/_vendor/jaraco/text/to-qwerty.py
Original Execroot:
% ls -al /private/var/tmp/_bazel_aaron/8417658af7f5a2267a860834e5d6e1a1/execroot/com_google_protobuf/external/protobuf_pip_deps_setuptools/site-packages/setuptools/_vendor/jaraco/text/
total 80
-rw-r--r-- 1 aaron wheel 16250 Jun 11 10:37 __init__.py
drwxr-xr-x 9 aaron wheel 288 Jun 11 10:37 .
drwxr-xr-x 7 aaron wheel 224 Jun 11 10:37 ..
-rw-r--r-- 1 aaron wheel 643 Jun 11 10:37 layouts.py
-rw-r--r-- 1 aaron wheel 1335 Jun 11 10:37 Lorem ipsum.txt
-rw-r--r-- 1 aaron wheel 904 Jun 11 10:37 show-newlines.py
-rw-r--r-- 1 aaron wheel 412 Jun 11 10:37 strip-prefix.py
-rw-r--r-- 1 aaron wheel 119 Jun 11 10:37 to-dvorak.py
-rw-r--r-- 1 aaron wheel 119 Jun 11 10:37 to-qwerty.py
So interestingly — while https://github.com/bazelbuild/bazel/issues/4327 gave me the initial impression that this was related to there being a space in the filename, the actual cause appears to be different, after spending some time with a debugger attached to Bazel.
Specifically, the issue seems to be that only .py / source files are being copied into the execroot. Lorem ipsum.txt on the other hand is considered a data file and so it is not copied to the Sandbox execroot.
I am not sure to what extent this is a Bazel issue vs. a rules_python issue, or what a good fix / workaround would look like here, do you have any thoughts or suggestions?
This looks like a protobuf issue to me.
When a target appears in the tools attribute of a genrule, its data files are only placed in the execroot if the label is executable.
protobuf is using the system python in a genrule here, and placing the setuptools (a py_library, not a py_binary) into the tools attribute. Therefore bazel doesn't add any data to the execroot.
Probably what should happen is that setup.py should be wrapped in a sh_binary that has setuptools in its data, and then the genrule should call the wrapper instead.
@pcjanzen thanks for that guidance! I implemented your suggested fix and it worked.