bazel-contrib / bazel-contrib/rules_python

py_binary system_python bootstrap can import target outputs instead of stdlib modules

Đang mở
#3,853 0 bình luận 0 reaction 0 người được giao Xem trên GitHub
Ngôn ngữ chính
Starlark
Star
688
Fork
721
Merge trung bình
15 giờ 7 phút
Pull request đã merge (30 ngày)
76

Mô tả

# 🐞 bug report

### Affected Rule

The issue is caused by the rule:

`py_binary` when using the Python stage1 bootstrap selected by
`--@rules_python//python/config_settings:bootstrap_impl=system_python`.

The problem is in `python/private/python_bootstrap_template.txt`: stage1 imports
stdlib modules before removing the launcher's directory from `sys.path[0]`.

### Is this a regression?

Unknown. Reproduced with rules_python `main` at
`2.1.0-rc0-11-g1a15c3b4`.

### Description

A clear and concise description of the problem...

The generated Python stage1 bootstrap imports stdlib modules while Python still
has the launcher directory at `sys.path[0]`. If the target package has generated
outputs next to the launcher with stdlib module names, those target files can be
imported instead of the Python standard library before rules_python finishes
bootstrap setup.

In the minimal reproduction below, the target generates `shutil.py` and
`types.py` next to the launcher in `bazel-bin/shadow_pkg/`. When stage1 executes,
its `import shutil` resolves to the generated target output instead of stdlib
`shutil`.

This is similar in root cause to
https://github.com/bazel-contrib/rules_python/issues/382, but this report is
specifically about stdlib shadowing inside the generated stage1 bootstrap before
the user's program runs.

## 🔬 Minimal Reproduction

Minimal local reproduction:

```text
/av/develop/tmp/rules_python_reproductions/stdlib_shadowing
```

The repro uses `local_path_override` to point at:

```text
/av/develop/tmp/rules_python
```

Relevant files:

```starlark
# .bazelrc
build --@rules_python//python/config_settings:bootstrap_impl=system_python
```

```starlark
# shadow_pkg/BUILD.bazel
load("@rules_python//python:py_binary.bzl", "py_binary")

genrule(
name = "generated_stdlib_modules",
outs = [
"shutil.py",
"types.py",
],
cmd = """
cat > $(@D)/shutil.py <<'PY'
raise RuntimeError('target output shutil.py shadowed the stdlib shutil module')
PY
cat > $(@D)/types.py <<'PY'
raise RuntimeError('target output types.py shadowed the stdlib types module')
PY
""",
)

py_binary(
name = "hello",
srcs = [
"main.py",
":generated_stdlib_modules",
],
main = "main.py",
)
```

```python
# shadow_pkg/main.py
print("hello from main")
```

Run:

```bash
bazel run //shadow_pkg:hello
```

Expected result:

```text
hello from main
```

Actual result:

The bootstrap fails before `main.py` runs because it imports generated
`bazel-bin/shadow_pkg/shutil.py` instead of stdlib `shutil`.

## 🔥 Exception or Error



Traceback (most recent call last):
File ".../execroot/_main/bazel-out/k8-fastbuild/bin/shadow_pkg/hello", line 12, in <module>
import shutil
File ".../execroot/_main/bazel-out/k8-fastbuild/bin/shadow_pkg/shutil.py", line 1, in <module>
raise RuntimeError('target output shutil.py shadowed the stdlib shutil module')
RuntimeError: target output shutil.py shadowed the stdlib shutil module

## 🌍 Your Environment

**Operating System:**

  

Linux gkolobkov 6.8.0-124-generic #124-Ubuntu SMP PREEMPT_DYNAMIC Tue May 26 13:00:45 UTC 2026 x86_64 x86_64 x86_64 GNU/Linux

**Output of `bazel version`:**

  

Bazelisk version: v1.27.0
Build label: 9.1.1
Build target: @@//src/main/java/com/google/devtools/build/lib/bazel:BazelServer
Build time: Wed Jun 03 15:41:13 2026 (1780501273)
Build timestamp: 1780501273
Build timestamp as int: 1780501273

**Rules_python version:**

  

rules_python main at 2.1.0-rc0-11-g1a15c3b4

**Anything else relevant?**

The issue is avoided if Python safe-path mode is enabled:

```bash
PYTHONSAFEPATH=1 bazel run //shadow_pkg:hello
```

That succeeds and prints:

```text
hello from main
```

This suggests the stage1 bootstrap should remove the unsafe `sys.path[0]` entry
before importing any stdlib modules, or otherwise ensure safe-path behavior for
the stage1 process.

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Hướng nghiên cứu

Bắt đầu với python/private/python_bootstrap_template.txt và bootstrap system_python được chọn bởi thiết lập .bazelrc. Tái hiện bằng bazel run //shadow_pkg:hello, sử dụng các đầu ra shutil.py và types.py đã được tạo, sau đó so sánh với PYTHONSAFEPATH=1. Hoàn tất khi bootstrap không còn import các module được target tạo ra và lệnh in ra "hello from main".

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
python
Lĩnh vực
build-system
Loại issue
Lỗi
Độ khó
3/5
Thời gian dự kiến
1-2 ngày
Mức độ hoạt động
Ít trao đổi
Độ rõ ràng
Đặc tả rõ ràng
Mức phù hợp với người mới
74/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.