diff --git a/CHANGELOG.md b/CHANGELOG.md index 18234744bd..dd3ea63ab9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -69,7 +69,7 @@ END_UNRELEASED_TEMPLATE `//python/config_setting/...` and the `@platforms` package instead. * (binaries/tests) The `PYTHONBREAKPOINT` environment variable is automatically inherited * (binaries/tests) The {obj}`stamp` attribute now transitions the Bazel builtin - {obj}`--stamp` flag. + {flag}`--stamp` flag. * (pypi) Now the RECORD file patches will follow the quoted or unquoted filenames convention in order to make `pytorch` and friends easier to patch. * (wheel) `py_wheel` no longer expands the input depset during analysis, @@ -99,7 +99,7 @@ END_UNRELEASED_TEMPLATE to add to binaries/tests for custom debuggers. * (binaries/tests) Build information is now included in binaries and tests. Use the `bazel_binary_info` module to access it. The {flag}`--stamp` flag will - add {flag}`--workspace_status` information. + add {obj}`--workspace_status_command` information. * (gazelle) A new directive `python_generate_pyi_deps` has been added. When `true`, a `py_*` target's `pyi_srcs` attribute will be set if any `.pyi` files that are associated with the target's `srcs` are present. @@ -176,7 +176,7 @@ END_UNRELEASED_TEMPLATE to pass the `TOOL_VERSIONS` that include 3.8 toolchains or use the `bzlmod` APIs to add them back. This means any hub `pip.parse` calls that target `3.8` will be ignored from now on. ([#2704](https://github.com/bazel-contrib/rules_python/issues/2704)) - {object}`python.single_version_override`, like: + {bzl:obj}`python.single_version_override`, like: ```starlark python = use_extension("@rules_python//python/extensions:python.bzl", "python") @@ -291,10 +291,10 @@ END_UNRELEASED_TEMPLATE [#2949](https://github.com/bazel-contrib/rules_python/issues/2949) if you run into any problems. With this release we are deprecating {obj}`pip.parse.experimental_target_platforms` and - {obj}`pip_repository.experimental_target_platforms`. For users using `WORKSPACE` and + `pip_repository.experimental_target_platforms`. For users using `WORKSPACE` and vendoring the `requirements.bzl` file, please re-vendor so that downstream is unaffected when the APIs get removed. If you need to customize the way the dependencies get - evaluated, see [our docs](/pypi/download.html#customizing-requires-dist-resolution) on customizing `Requires-Dist` resolution. + evaluated, see [our docs](https://rules-python.readthedocs.io/en/latest/pypi/download.html#customizing-requires-dist-resolution) on customizing `Requires-Dist` resolution. * (toolchains) Added Python versions 3.15.0a1, 3.14.0, 3.13.9, 3.12.12, 3.11.14, 3.10.19, and 3.9.24 from the [20251014] release. * (deps) (bzlmod) Upgraded to `bazel-skylib` version @@ -374,7 +374,7 @@ END_UNRELEASED_TEMPLATE the right wheel when there are multiple wheels for the target platform (e.g. `musllinux_1_1_x86_64` and `musllinux_1_2_x86_64`). If the user wants to set the minimum version for the selection algorithm, use the - {attr}`pip.defaults.whl_platform_tags` attribute to configure that. If + {obj}`pip.default.whl_platform_tags` attribute to configure that. If `musllinux_*_x86_64` is specified, we will choose the lowest available wheel version. Fixes [#3250](https://github.com/bazel-contrib/rules_python/issues/3250). diff --git a/docs/BUILD.bazel b/docs/BUILD.bazel index 632c3dd613..656c06b6e1 100644 --- a/docs/BUILD.bazel +++ b/docs/BUILD.bazel @@ -89,6 +89,7 @@ sphinx_stardocs( "//python:features_bzl", "//python:packaging_bzl", "//python:pip_bzl", + "//python:proto_bzl", "//python:py_binary_bzl", "//python:py_cc_link_params_info_bzl", "//python:py_exec_tools_info_bzl", @@ -111,6 +112,7 @@ sphinx_stardocs( "//python/extensions:python_bzl", "//python/local_toolchains:repos_bzl", "//python/private:attr_builders_bzl", + "//python/private:builders_bzl", "//python/private:builders_util_bzl", "//python/private:py_binary_rule_bzl", "//python/private:py_cc_toolchain_rule_bzl", diff --git a/docs/_includes/py_console_script_binary.md b/docs/_includes/py_console_script_binary.md index cae9f9f2f5..c9686f2eee 100644 --- a/docs/_includes/py_console_script_binary.md +++ b/docs/_includes/py_console_script_binary.md @@ -12,7 +12,8 @@ py_console_script_binary( ) ``` -#### Specifying extra dependencies +:::{rubric} Specifying extra dependencies +::: You can also specify extra dependencies and the exact script name you want to call. This is useful for tools like `flake8`, `pylint`, and `pytest`, which have plugin discovery methods and discover @@ -36,7 +37,8 @@ py_console_script_binary( ) ``` -#### Using a specific Python version +:::{rubric} Using a specific Python version +::: A specific Python version can be forced by passing the desired Python version, e.g. to force Python 3.9: ```starlark @@ -49,7 +51,8 @@ py_console_script_binary( ) ``` -#### Adding a Shebang Line +:::{rubric} Adding a Shebang Line +::: You can specify a shebang line for the generated binary. This is useful for Unix-like systems where the shebang line determines which interpreter is used to execute @@ -69,7 +72,8 @@ Note that to execute via the shebang line, you need to ensure the specified Python interpreter is available in the environment. -#### Using a specific Python Version directly from a Toolchain +:::{rubric} Using a specific Python Version directly from a Toolchain +::: :::{deprecated} 1.1.0 The toolchain-specific `py_binary` and `py_test` symbols are aliases to the regular rules. For example, `load("@python_versions//3.11:defs.bzl", "py_binary")` and `load("@python_versions//3.11:defs.bzl", "py_test")` are deprecated. diff --git a/docs/api/rules_python/python/config_settings/index.md b/docs/api/rules_python/python/config_settings/index.md index d92e7d404f..6197cac173 100644 --- a/docs/api/rules_python/python/config_settings/index.md +++ b/docs/api/rules_python/python/config_settings/index.md @@ -169,7 +169,7 @@ If you need to match a version that isn't present, then you have two options: ) ``` -2. Use {obj}`python.single_override` to re-introduce the desired version so +2. Use {obj}`python.single_version_override` to re-introduce the desired version so that the corresponding `//python/config_setting:is_python_XXX` target is generated. ::: diff --git a/docs/conf.py b/docs/conf.py index 671cf23fba..6a7cfe178f 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -107,15 +107,33 @@ primary_domain = None # The default is 'py', which we don't make much use of nitpicky = True +# Ignore nitpicks for missing cross-references to external objects. +# These are typically objects that aren't documented or aren't easily linked +# via intersphinx mapping, so we suppress warnings for them to keep the build clean. nitpick_ignore_regex = [ - # External xrefs aren't setup: ignore missing xref warnings - # External xrefs to sphinx isn't setup: ignore missing xref warnings - ("py:.*", "(sphinx|docutils|ast|enum|collections|typing_extensions).*"), + ("py:class", r"docutils\..*"), + ("py:obj", r"sphinx\.util\.docutils\..*"), + ("py:obj", r"sphinx\.util\.docfields\..*"), + ("py:class", r"sphinx\.util\.typing\..*"), + ("py:class", r"sphinx_bzl\.bzl\..*"), + ("py:class", r"typing_extensions\.TypeAlias"), + ("bzl:obj", r":current_py_cc_headers_abi3"), + ("bzl:obj", r":python"), + ("bzl:type", r"T"), + ("bzl:type", r"input_value"), + ("bzl:type", r"DepsetBuilder"), + ("bzl:type", r"RunfilesBuilder"), + ("bzl:type", r"BuiltinPyInfo"), + ("bzl:type", r".*SentinelInfo"), + ("bzl:type", r".*SphinxDocsLibraryInfo"), + ("bzl:type", r".*_SphinxRunInfo"), ] # --- Intersphinx configuration intersphinx_mapping = { + "python": ("https://docs.python.org/3", None), + "sphinx": ("https://www.sphinx-doc.org/en/master", None), "bazel": ("https://bazel.build/", "bazel_inventory.inv"), } diff --git a/docs/devguide.md b/docs/devguide.md index e7870b5733..e88ed7a612 100644 --- a/docs/devguide.md +++ b/docs/devguide.md @@ -117,6 +117,7 @@ to have everything self-documented, we have a special target, of the requirement-updating scripts in sequence in one go. This can be done once per release as we prepare for releases. +(creating-backport-prs)= ## Creating Backport PRs The steps to create a backport PR are: diff --git a/docs/environment-variables.md b/docs/environment-variables.md index 85cb766344..fb48f434cd 100644 --- a/docs/environment-variables.md +++ b/docs/environment-variables.md @@ -29,7 +29,7 @@ The guide on {any}`How to integrate a debugger` :::{versionadded} 1.3.0 ::: :::{versionchanged} 1.7.0 -Support added for {obj}`--bootstrap_impl=system_python`. +Support added for {bzl:flag}`--bootstrap_impl=system_python`. ::: :::: diff --git a/docs/howto/multi-platform-pypi-deps.md b/docs/howto/multi-platform-pypi-deps.md index 61f3f40580..f329ccdf9e 100644 --- a/docs/howto/multi-platform-pypi-deps.md +++ b/docs/howto/multi-platform-pypi-deps.md @@ -48,7 +48,7 @@ Additional dimensions should be appended and separated with an underscore (e.g. `linux_x86_64_musl_cuda12.9_numpy2`). The platform name should not include the Python version. That is handled by -`pip.parse.python_version` separately. +{attr}`pip.parse.python_version` separately. :::{note} The term _platform_ here has nothing to do with Bazel's `platform()` rule. @@ -56,7 +56,7 @@ The term _platform_ here has nothing to do with Bazel's `platform()` rule. #### Defining custom settings -Because {obj}`pip.parse.config_settings` is a list of arbitrary `config_setting` +Because {attr}`pip.default.config_settings` is a list of arbitrary `config_setting` targets, you can define your own flags or implement custom config matching logic. This allows you to model settings that aren't inherently part of rules_python. @@ -85,7 +85,7 @@ contains commonly used settings for OS and CPU: * `@platforms//cpu:aarch64` Note that these are the raw flag names. In order to use them with `pip.default`, -you must use {obj}`config_setting()` to match a particular value for them. +you must use {obj}`config_setting` to match a particular value for them. ### Associating Requirements to Platforms diff --git a/docs/pypi/download-workspace.md b/docs/pypi/download-workspace.md index 5dfb0f257a..4912f71103 100644 --- a/docs/pypi/download-workspace.md +++ b/docs/pypi/download-workspace.md @@ -41,7 +41,6 @@ re-executed to pick up a non-hermetic change to your environment (e.g., updating your system `python` interpreter), you can force it to re-execute by running `bazel sync --only [pip_parse name]`. -(per-os-arch-requirements)= ## Requirements for a specific OS/Architecture In some cases, you may need to use different requirements files for different OS and architecture combinations. diff --git a/docs/pypi/index.md b/docs/pypi/index.md index 17928898c5..2d17dd5054 100644 --- a/docs/pypi/index.md +++ b/docs/pypi/index.md @@ -1,6 +1,7 @@ :::{default-domain} bzl ::: +(pypi-dependencies)= # Using PyPI Using PyPI packages (aka "pip install") involves the following main steps: diff --git a/docs/support.md b/docs/support.md index 08147f2a15..2d1e21f128 100644 --- a/docs/support.md +++ b/docs/support.md @@ -25,10 +25,9 @@ patch 1.4, version 1.5 must be patched first. Backports can be requested by [creating an issue with the patch release template][patch-release-issue] or by sending a pull request performing the backport. -See the dev guide for [how to create a backport PR][backport-pr]. +See the dev guide for [how to create a backport PR](creating-backport-prs). [patch-release-issue]: https://github.com/bazelbuild/rules_python/issues/new?template=patch_release_request.md -[backport-pr]: devguide.html#creating-backport-prs ## Supported Bazel Versions diff --git a/docs/toolchains.md b/docs/toolchains.md index 1e1e61fde8..09aaed412b 100644 --- a/docs/toolchains.md +++ b/docs/toolchains.md @@ -852,8 +852,7 @@ environment variable automatically. The `//python/bin:python` target will not. The following targets expose the headers and libraries from the currently selected Python C toolchain: -- {obj}`@rules_python//python/cc:` -`current_py_cc_headers` +- {obj}`@rules_python//python/cc:current_py_cc_headers` - {obj}`@rules_python//python/cc:current_py_cc_headers_abi3` - {obj}`@rules_python//python/cc:current_py_cc_libs` @@ -872,5 +871,5 @@ compatibility across different toolchain configurations. :::{seealso} The _How to get Python headres for C extensions_ how-to guide, and the -{obj}`@rules_python//python/cc` package API documentation. +{obj}`//python/cc:BUILD.bazel` package API documentation. ::: diff --git a/gazelle/docs/annotations.md b/gazelle/docs/annotations.md index b6eb96d2cd..b3f06b9991 100644 --- a/gazelle/docs/annotations.md +++ b/gazelle/docs/annotations.md @@ -22,20 +22,20 @@ def bar(): # gazelle:annotation_name value The annotations are: {.glossary} -[`# gazelle:ignore imports`](#ignore) +[`# gazelle:ignore imports`](#annotation-ignore) : Tells Gazelle to ignore import statements. `imports` is a comma-separated list of imports to ignore. * Default: n/a * Allowed Values: A comma-separated string of python package names -[`# gazelle:include_dep targets`](#include-dep) +[`# gazelle:include_dep targets`](#annotation-include-dep) : Tells Gazelle to include a set of dependencies, even if they are not imported in a Python module. `targets` is a comma-separated list of target names to include as dependencies. * Default: n/a * Allowed Values: A comma-separated string of targets -[`# gazelle:include_pytest_conftest bool`](#include-pytest-conftest) +[`# gazelle:include_pytest_conftest bool`](#annotation-include-pytest-conftest) : Whether or not to include a sibling `:conftest` target in the `deps` of a {bzl:obj}`py_test` target. The default behaviour is to include `:conftest` (i.e.: `# gazelle:include_pytest_conftest true`). @@ -43,6 +43,7 @@ The annotations are: * Allowed Values: `true`, `false` +(annotation-ignore)= ## `ignore` This annotation accepts a comma-separated string of values. Values are names of @@ -75,6 +76,7 @@ deps = ["@pypi//numpy"], ``` +(annotation-include-dep)= ## `include_dep` This annotation accepts a comma-separated string of values. Values _must_ diff --git a/gazelle/docs/directives.md b/gazelle/docs/directives.md index 628dce5ae6..cb2bb4929a 100644 --- a/gazelle/docs/directives.md +++ b/gazelle/docs/directives.md @@ -16,58 +16,58 @@ the Python-specific directives in use can be found in the The Python-specific directives are: {.glossary} -[`# gazelle:python_extension value`](#python-extension) +[`# gazelle:python_extension value`](#directive-python-extension) : Controls whether the Python extension is enabled or not. Sub-packages inherit this value. * Default: `enabled` * Allowed Values: `enabled`, `disabled` -[`# gazelle:python_root`](#python-root) +[`# gazelle:python_root`](#directive-python-root) : Sets a Bazel package as a Python root. This is used on monorepos with multiple Python projects that don't share the top-level of the workspace as the root. * Default: n/a * Allowed Values: None. This direcive does not consume values. -[`# gazelle:python_manifest_file_name value`](#python-manifest-file-name) +[`# gazelle:python_manifest_file_name value`](#directive-python-manifest-file-name) : Overrides the default manifest file name. * Default: `gazelle_python.yaml` * Allowed Values: A string -[`# gazelle:python_ignore_files value`](#python-ignore-files) +[`# gazelle:python_ignore_files value`](#directive-python-ignore-files) : Controls the files which are ignored from the generated targets. * Default: n/a * Allowed Values: A comma-separated list of strings. -[`# gazelle:python_ignore_dependencies value`](#python-ignore-dependencies) +[`# gazelle:python_ignore_dependencies value`](#directive-python-ignore-dependencies) : Controls the ignored dependencies from the generated targets. * Default: n/a * Allowed Values: A comma-separated list of strings. -[`# gazelle:python_validate_import_statements bool`](#python-validate-import-statements) +[`# gazelle:python_validate_import_statements bool`](#directive-python-validate-import-statements) : Controls whether the Python import statements should be validated. * Default: `true` * Allowed Values: `true`, `false` -[`# gazelle:python_generation_mode value`](#python-generation-mode) +[`# gazelle:python_generation_mode value`](#directive-python-generation-mode) : Controls the target generation mode. * Default: `package` * Allowed Values: `file`, `package`, `project` -[`# gazelle:python_generation_mode_per_file_include_init bool`](#python-generation-mode-per-file-include-init) +[`# gazelle:python_generation_mode_per_file_include_init bool`](#directive-python-generation-mode-per-file-include-init) : Controls whether `__init__.py` files are included as srcs in each generated target when target generation mode is "file". * Default: `false` * Allowed Values: `true`, `false` -[`# gazelle:python_generation_mode_per_package_require_test_entry_point bool`](python-generation-mode-per-package-require-test-entry-point) +[`# gazelle:python_generation_mode_per_package_require_test_entry_point bool`](#directive-python-generation-mode-per-package-require-test-entry-point) : Controls whether a file called `__test__.py` or a target called `__test__` is required to generate one test target per package in package mode. * Default: `true` * Allowed Values: `true`, `false` -[`# gazelle:python_library_naming_convention value`](#python-library-naming-convention) +[`# gazelle:python_library_naming_convention value`](#directive-python-library-naming-convention) : Controls the {bzl:obj}`py_library` naming convention. It interpolates `$package_name$` with the Bazel package name. E.g. if the Bazel package name is `foo`, setting this to `$package_name$_my_lib` would result in a @@ -75,27 +75,27 @@ The Python-specific directives are: * Default: `$package_name$` * Allowed Values: A string containing `"$package_name$"` -[`# gazelle:python_binary_naming_convention value`](#python-binary-naming-convention) +[`# gazelle:python_binary_naming_convention value`](#directive-python-binary-naming-convention) : Controls the {bzl:obj}`py_binary` naming convention. Follows the same interpolation rules as `python_library_naming_convention`. * Default: `$package_name$_bin` * Allowed Values: A string containing `"$package_name$"` -[`# gazelle:python_test_naming_convention value`](#python-test-naming-convention) +[`# gazelle:python_test_naming_convention value`](#directive-python-test-naming-convention) : Controls the {bzl:obj}`py_test` naming convention. Follows the same interpolation rules as `python_library_naming_convention`. * Default: `$package_name$_test` * Allowed Values: A string containing `"$package_name$"` -[`# gazelle:python_proto_naming_convention value`](#python-proto-naming-convention) +[`# gazelle:python_proto_naming_convention value`](#directive-python-proto-naming-convention) : Controls the {bzl:obj}`py_proto_library` naming convention. It interpolates - `$proto_name$` with the {bzl:obj}`proto_library` rule name, minus any trailing - `_proto`. E.g. if the {bzl:obj}`proto_library` name is `foo_proto`, setting this + `$proto_name$` with the `proto_library` rule name, minus any trailing + `_proto`. E.g. if the `proto_library` name is `foo_proto`, setting this to `$proto_name$_my_lib` would render to `foo_my_lib`. * Default: `$proto_name$_py_pb2` * Allowed Values: A string containing `"$proto_name$"` -[`# gazelle:resolve py import-lang import-string label`](#resolve-py) +[`# gazelle:resolve py import-lang import-string label`](#directive-resolve-py) : Instructs the plugin what target to add as a dependency to satisfy a given import statement. The syntax is `# gazelle:resolve py import-string label` where `import-string` is the symbol in the python `import` statement, @@ -103,25 +103,25 @@ The Python-specific directives are: * Default: n/a * Allowed Values: See the [bazel-gazelle docs][gazelle-directives] -[`# gazelle:python_default_visibility labels`](python-default-visibility) +[`# gazelle:python_default_visibility labels`](#directive-python-default-visibility) : Instructs gazelle to use these visibility labels on all python targets. `labels` is a comma-separated list of labels (without spaces). * Default: `//$python_root$:__subpackages__` * Allowed Values: A string -[`# gazelle:python_visibility label`](python-visibility) +[`# gazelle:python_visibility label`](#directive-python-visibility) : Appends additional visibility labels to each generated target. This r directive can be set multiple times. * Default: n/a * Allowed Values: A string -[`# gazelle:python_test_file_pattern value`](python-test-file-pattern) +[`# gazelle:python_test_file_pattern value`](#directive-python-test-file-pattern) : Filenames matching these comma-separated {command}`glob`s will be mapped to {bzl:obj}`py_test` targets. * Default: `*_test.py,test_*.py` * Allowed Values: A glob string -[`# gazelle:python_label_convention value`](#python-label-convention) +[`# gazelle:python_label_convention value`](#directive-python-label-convention) : Defines the format of the distribution name in labels to third-party deps. Useful for using Gazelle plugin with other rules with different repository conventions (e.g. `rules_pycross`). Full label is always prepended with @@ -131,20 +131,20 @@ The Python-specific directives are: * Default: `$distribution_name$` * Allowed Values: A string -[`# gazelle:python_label_normalization value`](#python-label-normalization) +[`# gazelle:python_label_normalization value`](#directive-python-label-normalization) : 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). * Default: `snake_case` * Allowed Values: `snake_case`, `none`, `pep503` -[`# gazelle:python_experimental_allow_relative_imports bool`](#python-experimental-allow-relative-imports) +[`# gazelle:python_experimental_allow_relative_imports bool`](#directive-python-experimental-allow-relative-imports) : Controls whether Gazelle resolves dependencies for import statements that use paths relative to the current package. * Default: `false` * Allowed Values: `true`, `false` -[`# gazelle:python_generate_pyi_deps bool`](#python-generate-pyi-deps) +[`# gazelle:python_generate_pyi_deps bool`](#directive-python-generate-pyi-deps) : 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 @@ -155,32 +155,33 @@ The Python-specific directives are: * Default: `false` * Allowed Values: `true`, `false` -[`# gazelle:python_generate_pyi_srcs bool`](#python-generate-pyi-srcs) +[`# gazelle:python_generate_pyi_srcs bool`](#directive-python-generate-pyi-srcs) : Controls whether to generate a `pyi_srcs` attribute if a sibling `.pyi` file is found. When `false` (default), the `pyi_srcs` attribute is not added. * Default: `false` * Allowed Values: `true`, `false` -[`# gazelle:python_generate_proto bool`](#python-generate-proto) +[`# gazelle:python_generate_proto bool`](#directive-python-generate-proto) : Controls whether to generate a {bzl:obj}`py_proto_library` for each - {bzl:obj}`proto_library` in the package. By default we load this rule from the + `proto_library` in the package. By default we load this rule from the `@protobuf` repository; use `gazelle:map_kind` if you need to load this from somewhere else. * Default: `false` * Allowed Values: `true`, `false` -[`# gazelle:python_resolve_sibling_imports bool`](#python-resolve-sibling-imports) +[`# gazelle:python_resolve_sibling_imports bool`](#directive-python-resolve-sibling-imports) : Allows absolute imports to be resolved to sibling modules (Python 2's behavior without `absolute_import`). * Default: `false` * Allowed Values: `true`, `false` -[`# gazelle:python_include_ancestor_conftest bool`](#python-include-ancestor-conftest) +[`# gazelle:python_include_ancestor_conftest bool`](#directive-python-include-ancestor-conftest) : Controls whether ancestor conftest targets are added to {bzl:obj}`py_test` target dependencies. * Default: `true` * Allowed Values: `true`, `false` +(directive-python-extension)= ## `python_extension` :::{error} @@ -188,6 +189,7 @@ Detailed docs are not yet written. ::: +(directive-python-root)= ## `python_root` Set this directive within the Bazel package that you want to use as the Python root. @@ -224,6 +226,7 @@ py_libary( [python-packaging-user-guide]: https://github.com/pypa/packaging.python.org/blob/4c86169a/source/tutorials/packaging-projects.rst +(directive-python-manifest-file-name)= ## `python_manifest_file_name` :::{error} @@ -231,6 +234,7 @@ Detailed docs are not yet written. ::: +(directive-python-ignore-files)= ## `python_ignore_files` :::{error} @@ -238,6 +242,7 @@ Detailed docs are not yet written. ::: +(directive-python-ignore-dependencies)= ## `python_ignore_dependencies` :::{error} @@ -245,6 +250,7 @@ Detailed docs are not yet written. ::: +(directive-python-validate-import-statements)= ## `python_validate_import_statements` :::{error} @@ -252,6 +258,7 @@ Detailed docs are not yet written. ::: +(directive-python-generation-mode)= ## `python_generation_mode` :::{error} @@ -259,6 +266,7 @@ Detailed docs are not yet written. ::: +(directive-python-generation-mode-per-file-include-init)= ## `python_generation_mode_per_file_include_init` :::{error} @@ -266,6 +274,7 @@ Detailed docs are not yet written. ::: +(directive-python-generation-mode-per-package-require-test-entry-point)= ## `python_generation_mode_per_package_require_test_entry_point` When `# gazelle:python_generation_mode package`, whether a file called @@ -307,6 +316,7 @@ def py_test(name, main=None, **kwargs): ``` +(directive-python-library-naming-convention)= ## `python_library_naming_convention` :::{error} @@ -314,6 +324,7 @@ Detailed docs are not yet written. ::: +(directive-python-binary-naming-convention)= ## `python_binary_naming_convention` :::{error} @@ -321,6 +332,7 @@ Detailed docs are not yet written. ::: +(directive-python-test-naming-convention)= ## `python_test_naming_convention` :::{error} @@ -328,12 +340,13 @@ Detailed docs are not yet written. ::: +(directive-python-proto-naming-convention)= ## `python_proto_naming_convention` Set this directive to a string pattern to control how the generated {bzl:obj}`py_proto_library` targets are named. When generating new {bzl:obj}`py_proto_library` rules, Gazelle will replace `$proto_name$` in the -pattern with the name of the {bzl:obj}`proto_library` rule, stripping out a +pattern with the name of the `proto_library` rule, stripping out a trailing `_proto`. For example: ```starlark @@ -369,6 +382,7 @@ not able to map said imports, e.g. `import foo_pb2`, to fill in {gh-issue}`1703`. +(directive-resolve-py)= ## `resolve py` :::{error} @@ -376,6 +390,7 @@ Detailed docs are not yet written. ::: +(directive-python-default-visibility)= ## `python_default_visibility` Instructs gazelle to use these visibility labels on all _python_ targets @@ -451,6 +466,7 @@ py_library( These special values can be useful for sub-packages. +(directive-python-visibility)= ## `python_visibility` Appends additional `visibility` labels to each generated target. @@ -508,6 +524,7 @@ py_library( ``` +(directive-python-test-file-pattern)= ## `python_test_file_pattern` This directive adjusts which python files will be mapped to the {bzl:obj}`py_test` rule. @@ -570,6 +587,7 @@ py_library( ``` +(directive-python-label-convention)= ## `python_label_convention` :::{error} @@ -577,6 +595,7 @@ Detailed docs are not yet written. ::: +(directive-python-label-normalization)= ## `python_label_normalization` :::{error} @@ -584,6 +603,7 @@ Detailed docs are not yet written. ::: +(directive-python-experimental-allow-relative-imports)= ## `python_experimental_allow_relative_imports` Enables experimental support for resolving relative imports in @@ -630,6 +650,7 @@ If the directive is set to `true`, gazelle will resolve imports that are relative to the current package. +(directive-python-generate-pyi-deps)= ## `python_generate_pyi_deps` :::{error} @@ -637,7 +658,8 @@ Detailed docs are not yet written. ::: -## `python_generate_pyi_deps` +(directive-python-generate-pyi-srcs)= +## `python_generate_pyi_srcs` When `true`, include any sibling `.pyi` files in the `pyi_srcs` target attribute. @@ -659,10 +681,11 @@ py_library( ``` +(directive-python-generate-proto)= ## `python_generate_proto` When `# gazelle:python_generate_proto true`, Gazelle will generate one -{bzl:obj}`py_proto_library` for each {bzl:obj}`proto_library`, generating Python clients for +{bzl:obj}`py_proto_library` for each `proto_library`, generating Python clients for protobuf in each package. By default this is turned off. Gazelle will also generate a load statement for the {bzl:obj}`py_proto_library` - attempting to detect the configured name for the `@protobuf` / `@com_google_protobuf` repo in your @@ -720,12 +743,14 @@ When `false`, Gazelle will ignore any {bzl:obj}`py_proto_library`, including previously-generated or hand-created rules. +(directive-python-resolve-sibling-imports)= ## `python_resolve_sibling_imports` :::{error} Detailed docs are not yet written. ::: +(directive-python-include-ancestor-conftest)= ## `python_include_ancestor_conftest` Version VERSION_NEXT_FEATURE includes a fix ({gh-pr}`3498`) for a long-standing issue diff --git a/python/private/attr_builders.bzl b/python/private/attr_builders.bzl index ecfc570a2b..8e8a690b8f 100644 --- a/python/private/attr_builders.bzl +++ b/python/private/attr_builders.bzl @@ -592,7 +592,7 @@ def _Label_new(**kwargs): """Creates a builder for `attr.label`. Args: - **kwargs: The same as {obj}`attr.label()`. + **kwargs: The same as {obj}`attr.label`. Returns: {type}`Label` diff --git a/python/private/attributes.bzl b/python/private/attributes.bzl index 362eee8f2e..77b815ec60 100644 --- a/python/private/attributes.bzl +++ b/python/private/attributes.bzl @@ -392,7 +392,7 @@ obtained by calling `str(Label(...))`). Most `@rules_python//python/config_setting` settings can be used here, which allows, for example, making only a certain `py_binary` use -{obj}`--boostrap_impl=script`. +{obj}`--bootstrap_impl=script`. Additional or custom config settings can be registered using the {obj}`add_transition_setting` API. This allows, for example, forcing a @@ -464,7 +464,7 @@ See the [Accessing build information docs] for more information. Stamping can harm build performance by reducing cache hits and should be avoided if possible. -In addition, this transitions the {obj}`--stamp` flag, which can additional +In addition, this transitions the {flag}`--stamp ` flag, which can additional config state overhead. ::: diff --git a/python/private/py_binary_rule.bzl b/python/private/py_binary_rule.bzl index 3df6bd87c4..356af5d9f8 100644 --- a/python/private/py_binary_rule.bzl +++ b/python/private/py_binary_rule.bzl @@ -38,7 +38,7 @@ def create_py_binary_rule_builder(): ::: Returns: - {type}`ruleb.Rule` with the necessary settings + {obj}`ruleb.Rule` with the necessary settings for creating a `py_binary` rule. """ builder = create_executable_rule_builder( diff --git a/python/private/py_executable.bzl b/python/private/py_executable.bzl index 7ff6278e02..19f71c3fae 100644 --- a/python/private/py_executable.bzl +++ b/python/private/py_executable.bzl @@ -1814,7 +1814,7 @@ def create_executable_rule_builder(implementation, **kwargs): ::: Returns: - {type}`ruleb.Rule` with the necessary settings + {obj}`ruleb.Rule` with the necessary settings for creating an executable Python rule. """ builder = ruleb.Rule( diff --git a/python/private/py_library.bzl b/python/private/py_library.bzl index a7419a6eaf..3d8ba4aa71 100644 --- a/python/private/py_library.bzl +++ b/python/private/py_library.bzl @@ -105,10 +105,9 @@ and that only one package version will be included. doc = """ Files whose directories are namespace packages. -When {obj}`--venv_site_packages=yes` is set, this helps inform which directories should be +When {obj}`--venvs_site_packages=yes` is set, this helps inform which directories should be treated as namespace packages and expect files from other targets to be contributed. This allows optimizing the generation of symlinks to be cheaper at analysis time. - :::{versionadded} 1.8.0 ::: """, @@ -283,7 +282,7 @@ def create_py_library_rule_builder(): ::: Returns: - {type}`ruleb.Rule` with the necessary settings + {obj}`ruleb.Rule` with the necessary settings for creating a `py_library` rule. """ builder = ruleb.Rule( diff --git a/python/private/py_test_rule.bzl b/python/private/py_test_rule.bzl index bb35d6974e..5848682deb 100644 --- a/python/private/py_test_rule.bzl +++ b/python/private/py_test_rule.bzl @@ -41,7 +41,7 @@ def create_py_test_rule_builder(): ::: Returns: - {type}`ruleb.Rule` with the necessary settings + {obj}`ruleb.Rule` with the necessary settings for creating a `py_test` rule. """ builder = create_executable_rule_builder( diff --git a/python/private/pypi/extension.bzl b/python/private/pypi/extension.bzl index 7354a67e67..1ec9142bbb 100644 --- a/python/private/pypi/extension.bzl +++ b/python/private/pypi/extension.bzl @@ -823,7 +823,7 @@ the BUILD files for wheels. This tag class allows for more customization of how the configuration for the hub repositories is built. -:::{include} /_includes/experimtal_api.md +:::{include} /_includes/experimental_api.md ::: :::{seealso} diff --git a/python/private/pypi/pkg_aliases.bzl b/python/private/pypi/pkg_aliases.bzl index ac063fac48..e76a139651 100644 --- a/python/private/pypi/pkg_aliases.bzl +++ b/python/private/pypi/pkg_aliases.bzl @@ -181,7 +181,7 @@ def multiplatform_whl_aliases( aliases: {type}`str | dict[struct | str, str]`: The aliases to process. Any aliases that have the filename set will be converted to a dict of config settings to repo names. The - struct is created by {func}`whl_config_setting`. + struct is created by {bzl:obj}`whl_config_setting`. Returns: A dict with of config setting labels to repo names or the repo name itself. diff --git a/python/private/python.bzl b/python/private/python.bzl index 399743c18d..5eb24830cc 100644 --- a/python/private/python.bzl +++ b/python/private/python.bzl @@ -1249,7 +1249,7 @@ The values should be one of the values in `@platforms//cpu` Docs for [Registering custom runtimes] ::: -:::{{versionadded}} 1.5.0 +:::{versionadded} 1.5.0 ::: """, ), @@ -1274,7 +1274,7 @@ The values should be one of the values in `@platforms//os` Docs for [Registering custom runtimes] ::: -:::{{versionadded}} 1.5.0 +:::{versionadded} 1.5.0 ::: """, ), @@ -1329,7 +1329,7 @@ If set, `target_settings`, `os_name`, and `arch` should also be set. Docs for [Registering custom runtimes] ::: -:::{{versionadded}} 1.5.0 +:::{versionadded} 1.5.0 ::: """, ), @@ -1343,7 +1343,7 @@ If set, `target_compatible_with`, `os_name`, and `arch` should also be set. Docs for [Registering custom runtimes] ::: -:::{{versionadded}} 1.5.0 +:::{versionadded} 1.5.0 ::: """, ), diff --git a/python/private/zipapp/py_zipapp_rule.bzl b/python/private/zipapp/py_zipapp_rule.bzl index e97e1a4171..72adbf48ba 100644 --- a/python/private/zipapp/py_zipapp_rule.bzl +++ b/python/private/zipapp/py_zipapp_rule.bzl @@ -266,7 +266,7 @@ obtained by calling `str(Label(...))`). Most `@rules_python//python/config_setting` settings can be used here, which allows, for example, making only a certain `py_binary` use -{obj}`--boostrap_impl=script`. +{obj}`--bootstrap_impl=script`. Additional or custom config settings can be registered using the {obj}`add_transition_setting` API. This allows, for example, forcing a diff --git a/sphinxdocs/docs/index.md b/sphinxdocs/docs/index.md index 2ea1146e1b..43bbc14f60 100644 --- a/sphinxdocs/docs/index.md +++ b/sphinxdocs/docs/index.md @@ -11,7 +11,7 @@ documentation. It comes with: While it is primarily oriented towards docgen for Starlark code, the core of it is agnostic as to what is being documented. -### Optimization +## Optimization Normally, Sphinx keeps various cache files to improve incremental building. Unfortunately, programs performing their own caching don't interact well diff --git a/sphinxdocs/docs/sphinx-bzl.md b/sphinxdocs/docs/sphinx-bzl.md index 8376f60679..da4cd9f293 100644 --- a/sphinxdocs/docs/sphinx-bzl.md +++ b/sphinxdocs/docs/sphinx-bzl.md @@ -265,7 +265,7 @@ Documents a flag. It has the same format as `{bzl:target}` ::::::{rst:directive} .. bzl:typedef:: typename Documents a user-defined structural "type". These are typically generated by -the {obj}`sphinx_stardoc` rule after following [User-defined types] to create a +the {bzl:obj}`sphinx_stardoc` rule after following [User-defined types] to create a struct with a `TYPEDEF` field, but can also be manually defined if there's no natural place for it in code, e.g. some ad-hoc structural type. diff --git a/sphinxdocs/docs/starlark-docgen.md b/sphinxdocs/docs/starlark-docgen.md index ba4ab516f5..b9181ee347 100644 --- a/sphinxdocs/docs/starlark-docgen.md +++ b/sphinxdocs/docs/starlark-docgen.md @@ -81,7 +81,7 @@ still possible to create such objects using `struct` and lambdas. For the purposes of documentation, they can be documented by creating a module-level `struct` with matching fields *and* also a field named `TYPEDEF`. When the `sphinx_stardoc` rule sees a struct with a `TYPEDEF` field, it generates doc -using the {rst:directive}`bzl:typedef` directive and puts all the struct's fields +using the {rst:dir}`bzl:typedef` directive and puts all the struct's fields within the typedef. The net result is the rendered docs look similar to how a class would be documented in other programming languages. diff --git a/sphinxdocs/inventories/bazel_inventory.txt b/sphinxdocs/inventories/bazel_inventory.txt index e704d20d73..866be33886 100644 --- a/sphinxdocs/inventories/bazel_inventory.txt +++ b/sphinxdocs/inventories/bazel_inventory.txt @@ -42,6 +42,7 @@ config.target bzl:function 1 rules/lib/toplevel/config#target - config_common.FeatureFlagInfo bzl:type 1 rules/lib/toplevel/config_common#FeatureFlagInfo - config_common.toolchain_type bzl:function 1 rules/lib/toplevel/config_common#toolchain_type - config_setting bzl:rule 1 reference/be/general#config_setting - +configuration_field bzl:type 1 rules/lib/builtins/configuration_field - ctx bzl:type 1 rules/lib/builtins/repository_ctx - ctx.actions bzl:obj 1 rules/lib/builtins/ctx#actions - ctx.aspect_ids bzl:obj 1 rules/lib/builtins/ctx#aspect_ids - @@ -172,4 +173,4 @@ toolchain.target_settings bzl:attr 1 reference/be/platforms-and-toolchains#toolc toolchain_type bzl:type 1 rules/lib/builtins/toolchain_type.html - transition bzl:type 1 rules/lib/builtins/transition - tuple bzl:type 1 rules/lib/core/tuple - -workspace_status bzl:flag 1 reference/command-line-reference#build-flag--workspace_status_command - +workspace_status_command bzl:flag 1 reference/command-line-reference#build-flag--workspace_status_command - diff --git a/sphinxdocs/src/sphinx_bzl/bzl.py b/sphinxdocs/src/sphinx_bzl/bzl.py index 8303b4d2a5..7d5ec6a68e 100644 --- a/sphinxdocs/src/sphinx_bzl/bzl.py +++ b/sphinxdocs/src/sphinx_bzl/bzl.py @@ -1713,6 +1713,12 @@ def add_object(self, entry: _ObjectEntry, alt_names=None) -> None: ) if entry.full_id in self.data["objects"]: existing = self.data["objects"][entry.full_id] + # If the objects are identical, then it's fine. This can happen + # when a doc is re-parsed (e.g. during a query) or if a symbol + # is documented multiple times in the same file. + if existing.to_get_objects_tuple() == entry.to_get_objects_tuple(): + return + raise Exception( f"Object {entry.full_id} already registered: " + f"existing={existing}, incoming={entry}" @@ -1740,6 +1746,29 @@ def add_object(self, entry: _ObjectEntry, alt_names=None) -> None: self.data["doc_names"].setdefault(docname, {}) self.data["doc_names"][docname][base_name] = entry + @override + def clear_doc(self, docname: str) -> None: + if docname not in self.data["doc_names"]: + return + for base_name, entry in self.data["doc_names"][docname].items(): + if entry.full_id in self.data["objects"]: + del self.data["objects"][entry.full_id] + + if entry.full_id in self.data["objects_by_type"].get( + entry.object_type, {} + ): + del self.data["objects_by_type"][entry.object_type][entry.full_id] + + # We can't easily reverse the mapping for alt_names, so we have + # to iterate over all of them. This is potentially slow, but + # clear_doc isn't called often. + for alt_name, entries in list(self.data["alt_names"].items()): + if entry.full_id in entries: + del entries[entry.full_id] + if not entries: + del self.data["alt_names"][alt_name] + del self.data["doc_names"][docname] + def merge_domaindata( self, docnames: list[str], otherdata: dict[str, typing.Any] ) -> None: @@ -1758,19 +1787,44 @@ def merge_domaindata( def _on_missing_reference(app, env: environment.BuildEnvironment, node, contnode): + """Handle missing references + + There are two main cases this is designed to handle: + 1. Psuedo-types, like None + 2. External references that aren't exact matches, e.g. using + `--stamp=true` to refer to the Bazel builtin stamp flag. + """ + target = node["reftarget"] if node["refdomain"] != "bzl": return None - if node["reftype"] != "type": + if node["reftype"] not in ("type", "flag", "obj"): return None # There's no Bazel docs for None, so prevent missing xrefs warning - if node["reftarget"] == "None": + if target == "None": return contnode - # Any and object are just conventions from Python, but useful for - # indicating what something is in Starlark, so treat them specially. - if node["reftarget"] in ("Any", "object"): + # Useful psuedo-types + if target in ("Any", "object", "collection"): return contnode + + original_target = target + new_target = target + + # Normalize --foo flag references + new_target = new_target.lstrip("-") + # Allow foo() style references + new_target, _, _ = new_target.partition("(") + # Allow --foo=bar references + new_target, _, _ = new_target.partition("=") + + if new_target != original_target: + # Access the intersphinx extension's internal mapping + # we try to resolve the reference again with the stripped name + from sphinx.ext.intersphinx import missing_reference + + node["reftarget"] = new_target + return missing_reference(app, env, node, contnode) return None