Skip to content

Commit 79288e6

Browse files
committed
Merge branch 'main' of https://github.com/bazel-contrib/rules_python into feat.pypi.all.files
2 parents 8b820e1 + 466ac33 commit 79288e6

File tree

138 files changed

+1686
-430
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

138 files changed

+1686
-430
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_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,tests/modules/another_module,tests/modules/other,tests/modules/other/nspkg_delta,tests/modules/other/nspkg_gamma,tests/modules/other/nspkg_single,tests/modules/other/simple_v1,tests/modules/other/simple_v2,tests/modules/other/with_external_data
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,tests/modules/another_module,tests/modules/other,tests/modules/other/nspkg_delta,tests/modules/other/nspkg_gamma,tests/modules/other/nspkg_single,tests/modules/other/simple_v1,tests/modules/other/simple_v2,tests/modules/other/with_external_data
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,rules_python-repro,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,tests/modules/another_module,tests/modules/other,tests/modules/other/nspkg_delta,tests/modules/other/nspkg_gamma,tests/modules/other/nspkg_single,tests/modules/other/simple_v1,tests/modules/other/simple_v2,tests/modules/other/with_external_data,tests/whl_with_build_files/testdata,tests/whl_with_build_files/testdata/somepkg,tests/whl_with_build_files/testdata/somepkg-1.0.dist-info,tests/whl_with_build_files/testdata/somepkg/subpkg
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,rules_python-repro,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,tests/modules/another_module,tests/modules/other,tests/modules/other/nspkg_delta,tests/modules/other/nspkg_gamma,tests/modules/other/nspkg_single,tests/modules/other/simple_v1,tests/modules/other/simple_v2,tests/modules/other/with_external_data,tests/whl_with_build_files/testdata,tests/whl_with_build_files/testdata/somepkg,tests/whl_with_build_files/testdata/somepkg-1.0.dist-info,tests/whl_with_build_files/testdata/somepkg/subpkg
99

1010
test --test_output=errors
1111

CHANGELOG.md

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,32 @@ END_UNRELEASED_TEMPLATE
5858
to the package path. This is enabled via the
5959
`# gazelle:experimental_allow_relative_imports` true directive ({gh-issue}`2203`).
6060
* (gazelle) Types for exposed members of `python.ParserOutput` are now all public.
61+
* (gazelle) Removed the requirement for `__init__.py`, `__main__.py`, or `__test__.py` files to be
62+
present in a directory to generate a `BUILD.bazel` file.
63+
* (toolchain) Updated the following toolchains to build 20250702 to patch CVE-2025-47273:
64+
* 3.9.23
65+
* 3.10.18
66+
* 3.11.13
67+
* 3.12.11
68+
* 3.14.0b3
69+
* (toolchain) Python 3.13 now references 3.13.5
6170

6271
{#v0-0-0-fixed}
6372
### Fixed
6473
* (pypi) Fixes an issue where builds using a `bazel vendor` vendor directory
6574
would fail if the constraints file contained environment markers. Fixes
6675
[#2996](https://github.com/bazel-contrib/rules_python/issues/2996).
76+
* (pypi) Wheels with BUILD.bazel (or other special Bazel files) no longer
77+
result in missing files at runtime
78+
([#2782](https://github.com/bazel-contrib/rules_python/issues/2782)).
79+
* (runfiles) The pypi runfiles package now includes `py.typed` to indicate it
80+
supports type checking
81+
([#2503](https://github.com/bazel-contrib/rules_python/issues/2503)).
82+
* (toolchains) `local_runtime_repo` now checks if the include directory exists
83+
before attempting to watch it, fixing issues on macOS with system Python
84+
({gh-issue}`3043`).
85+
* (pypi) The pipstar `defaults` configuration now supports any custom platform
86+
name.
6787

6888
{#v0-0-0-added}
6989
### Added
@@ -74,11 +94,31 @@ END_UNRELEASED_TEMPLATE
7494
of all the files extracted from the wheel. This can be used in lieu of
7595
{obj}`whl_filegroup` to avoid copying/extracting wheel multiple times to
7696
get a subset of their files.
97+
* (gazelle) New directive `gazelle:python_generate_pyi_deps`; when `true`,
98+
dependencies added to satisfy type-only imports (`if TYPE_CHECKING`) and type
99+
stub packages are added to `pyi_deps` instead of `deps`.
100+
* (toolchain) Add toolchains for aarch64 windows for
101+
* 3.11.13
102+
* 3.12.11
103+
* 3.13.5
104+
* 3.14.0b3
77105

78106
{#v0-0-0-removed}
79107
### Removed
80108
* Nothing removed.
81109

110+
{#1-5-1}
111+
## [1.5.1] - 2025-07-06
112+
113+
[1.5.1]: https://github.com/bazel-contrib/rules_python/releases/tag/1.5.1
114+
115+
{#v1-5-1-fixed}
116+
### Fixed
117+
118+
* (pypi) Namespace packages work by default (pkgutil shims are generated
119+
by default again)
120+
([#3038](https://github.com/bazel-contrib/rules_python/issues/3038)).
121+
82122
{#1-5-0}
83123
## [1.5.0] - 2025-06-11
84124

@@ -102,7 +142,8 @@ END_UNRELEASED_TEMPLATE
102142
* (py_wheel) py_wheel always creates zip64-capable wheel zips
103143
* (providers) (experimental) {obj}`PyInfo.venv_symlinks` replaces
104144
`PyInfo.site_packages_symlinks`
105-
* (deps) Updating setuptools to patch CVE-2025-47273.
145+
* (deps) Updated setuptools to 78.1.1 to patch CVE-2025-47273. This effectively makes
146+
Python 3.9 the minimum supported version for using `pip_parse`.
106147

107148
{#1-5-0-fixed}
108149
### Fixed

CONTRIBUTING.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,25 @@ Not breaking changes:
318318
* Changing internal details, such as renaming an internal file.
319319
* Changing a rule to a macro.
320320

321+
## AI-assisted Contributions
322+
323+
Contributions assisted by AI tools are allowed. However, the human author
324+
submitting the pull request is responsible for the contributed code as if they
325+
had written it entirely themselves. This means:
326+
327+
* **Understanding the code:** You must be able to explain what the code does
328+
and why it's implemented that way. This includes discussing its
329+
implications, and any trade-offs made during its development, just as if you
330+
had written it entirely yourself.
331+
* **Vetting the correctness and functionality:** You are responsible for
332+
thoroughly testing and verifying that the code is correct, functional, and
333+
meets all project requirements and standards.
334+
335+
If the human PR author cannot fulfill these responsibilities, the `rules_python`
336+
maintainers will not spend time reviewing or merging the PR. The goal is to
337+
ensure that all contributions, regardless of their origin, maintain the quality
338+
and integrity of the project and do not place an undue burden on maintainers.
339+
321340
## FAQ
322341

323342
### Installation errors when during `git commit`

MODULE.bazel

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,62 @@ register_toolchains("@pythons_hub//:all")
6060
# Install twine for our own runfiles wheel publishing and allow bzlmod users to use it.
6161

6262
pip = use_extension("//python/extensions:pip.bzl", "pip")
63+
64+
# NOTE @aignas 2025-07-06: we define these platforms to keep backwards compatibility with the
65+
# current `experimental_index_url` implementation. Whilst we stabilize the API this list may be
66+
# updated with a mention in the CHANGELOG.
67+
[
68+
pip.default(
69+
arch_name = cpu,
70+
config_settings = [
71+
"@platforms//cpu:{}".format(cpu),
72+
"@platforms//os:linux",
73+
],
74+
env = {"platform_version": "0"},
75+
os_name = "linux",
76+
platform = "linux_{}".format(cpu),
77+
)
78+
for cpu in [
79+
"x86_64",
80+
"aarch64",
81+
# TODO @aignas 2025-05-19: only leave tier 0-1 cpus when stabilizing the
82+
# `pip.default` extension. i.e. drop the below values - users will have to
83+
# define themselves if they need them.
84+
"arm",
85+
"ppc",
86+
"s390x",
87+
]
88+
]
89+
90+
[
91+
pip.default(
92+
arch_name = cpu,
93+
config_settings = [
94+
"@platforms//cpu:{}".format(cpu),
95+
"@platforms//os:osx",
96+
],
97+
# We choose the oldest non-EOL version at the time when we release `rules_python`.
98+
# See https://endoflife.date/macos
99+
env = {"platform_version": "14.0"},
100+
os_name = "osx",
101+
platform = "osx_{}".format(cpu),
102+
)
103+
for cpu in [
104+
"aarch64",
105+
"x86_64",
106+
]
107+
]
108+
109+
pip.default(
110+
arch_name = "x86_64",
111+
config_settings = [
112+
"@platforms//cpu:x86_64",
113+
"@platforms//os:windows",
114+
],
115+
env = {"platform_version": "0"},
116+
os_name = "windows",
117+
platform = "windows_x86_64",
118+
)
63119
pip.parse(
64120
# NOTE @aignas 2024-10-26: We have an integration test that depends on us
65121
# being able to build sdists for this hub, so explicitly set this to False.
@@ -102,7 +158,11 @@ internal_dev_deps = use_extension(
102158
use_repo(
103159
internal_dev_deps,
104160
"buildkite_config",
161+
"implicit_namespace_ns_sub1",
162+
"implicit_namespace_ns_sub2",
105163
"rules_python_runtime_env_tc_info",
164+
"somepkg_with_build_files",
165+
"whl_with_build_files",
106166
)
107167

108168
# Add gazelle plugin so that we can run the gazelle example as an e2e integration

docs/requirements.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,7 @@ typing-extensions==4.13.2 \
356356
# via
357357
# rules-python-docs (docs/pyproject.toml)
358358
# sphinx-autodoc2
359-
urllib3==2.4.0 \
360-
--hash=sha256:414bc6535b787febd7567804cc015fee39daab8ad86268f1310a9250697de466 \
361-
--hash=sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813
359+
urllib3==2.5.0 \
360+
--hash=sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760 \
361+
--hash=sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc
362362
# via requests

gazelle/README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ The following documentation covers using bzlmod.
2424

2525
## Adding Gazelle to your project
2626

27-
First, you'll need to add Gazelle to your `MODULES.bazel` file.
27+
First, you'll need to add Gazelle to your `MODULE.bazel` file.
2828
Get the current version of Gazelle from there releases here: https://github.com/bazelbuild/bazel-gazelle/releases/.
2929

3030

@@ -222,6 +222,8 @@ Python-specific directives are as follows:
222222
| Controls how distribution names in labels to third-party deps are normalized. Useful for using Gazelle plugin with other rules with different label conventions (e.g. `rules_pycross` uses PEP-503). Can be "snake_case", "none", or "pep503". |
223223
| `# gazelle:experimental_allow_relative_imports` | `false` |
224224
| Controls whether Gazelle resolves dependencies for import statements that use paths relative to the current package. Can be "true" or "false".|
225+
| `# gazelle:python_generate_pyi_deps` | `false` |
226+
| Controls whether to generate a separate `pyi_deps` attribute for type-checking dependencies or merge them into the regular `deps` attribute. When `false` (default), type-checking dependencies are merged into `deps` for backward compatibility. When `true`, generates separate `pyi_deps`. Imports in blocks with the format `if typing.TYPE_CHECKING:`/`if TYPE_CHECKING:` and type-only stub packages (eg. boto3-stubs) are recognized as type-checking dependencies. |
225227

226228
#### Directive: `python_root`:
227229

gazelle/python/configure.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ func (py *Configurer) KnownDirectives() []string {
6868
pythonconfig.TestFilePattern,
6969
pythonconfig.LabelConvention,
7070
pythonconfig.LabelNormalization,
71+
pythonconfig.GeneratePyiDeps,
7172
pythonconfig.ExperimentalAllowRelativeImports,
7273
}
7374
}
@@ -230,6 +231,12 @@ func (py *Configurer) Configure(c *config.Config, rel string, f *rule.File) {
230231
pythonconfig.ExperimentalAllowRelativeImports, rel, d.Value)
231232
}
232233
config.SetExperimentalAllowRelativeImports(v)
234+
case pythonconfig.GeneratePyiDeps:
235+
v, err := strconv.ParseBool(strings.TrimSpace(d.Value))
236+
if err != nil {
237+
log.Fatal(err)
238+
}
239+
config.SetGeneratePyiDeps(v)
233240
}
234241
}
235242

gazelle/python/file_parser.go

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,10 @@ type ParserOutput struct {
4747
}
4848

4949
type FileParser struct {
50-
code []byte
51-
relFilepath string
52-
output ParserOutput
50+
code []byte
51+
relFilepath string
52+
output ParserOutput
53+
inTypeCheckingBlock bool
5354
}
5455

5556
func NewFileParser() *FileParser {
@@ -158,6 +159,7 @@ func (p *FileParser) parseImportStatements(node *sitter.Node) bool {
158159
continue
159160
}
160161
m.Filepath = p.relFilepath
162+
m.TypeCheckingOnly = p.inTypeCheckingBlock
161163
if strings.HasPrefix(m.Name, ".") {
162164
continue
163165
}
@@ -178,6 +180,7 @@ func (p *FileParser) parseImportStatements(node *sitter.Node) bool {
178180
m.Filepath = p.relFilepath
179181
m.From = from
180182
m.Name = fmt.Sprintf("%s.%s", from, m.Name)
183+
m.TypeCheckingOnly = p.inTypeCheckingBlock
181184
p.output.Modules = append(p.output.Modules, m)
182185
}
183186
} else {
@@ -202,10 +205,43 @@ func (p *FileParser) SetCodeAndFile(code []byte, relPackagePath, filename string
202205
p.output.FileName = filename
203206
}
204207

208+
// isTypeCheckingBlock returns true if the given node is an `if TYPE_CHECKING:` block.
209+
func (p *FileParser) isTypeCheckingBlock(node *sitter.Node) bool {
210+
if node.Type() != sitterNodeTypeIfStatement || node.ChildCount() < 2 {
211+
return false
212+
}
213+
214+
condition := node.Child(1)
215+
216+
// Handle `if TYPE_CHECKING:`
217+
if condition.Type() == sitterNodeTypeIdentifier && condition.Content(p.code) == "TYPE_CHECKING" {
218+
return true
219+
}
220+
221+
// Handle `if typing.TYPE_CHECKING:`
222+
if condition.Type() == "attribute" && condition.ChildCount() >= 3 {
223+
object := condition.Child(0)
224+
attr := condition.Child(2)
225+
if object.Type() == sitterNodeTypeIdentifier && object.Content(p.code) == "typing" &&
226+
attr.Type() == sitterNodeTypeIdentifier && attr.Content(p.code) == "TYPE_CHECKING" {
227+
return true
228+
}
229+
}
230+
231+
return false
232+
}
233+
205234
func (p *FileParser) parse(ctx context.Context, node *sitter.Node) {
206235
if node == nil {
207236
return
208237
}
238+
239+
// Check if this is a TYPE_CHECKING block
240+
wasInTypeCheckingBlock := p.inTypeCheckingBlock
241+
if p.isTypeCheckingBlock(node) {
242+
p.inTypeCheckingBlock = true
243+
}
244+
209245
for i := 0; i < int(node.ChildCount()); i++ {
210246
if err := ctx.Err(); err != nil {
211247
return
@@ -219,6 +255,9 @@ func (p *FileParser) parse(ctx context.Context, node *sitter.Node) {
219255
}
220256
p.parse(ctx, child)
221257
}
258+
259+
// Restore the previous state
260+
p.inTypeCheckingBlock = wasInTypeCheckingBlock
222261
}
223262

224263
func (p *FileParser) Parse(ctx context.Context) (*ParserOutput, error) {

0 commit comments

Comments
 (0)