Skip to content

Conversation

chrisirhc
Copy link
Contributor

@chrisirhc chrisirhc commented Sep 19, 2025

Update: I was reading a thread in #python and saw that this set to True when setting --incompatible_default_to_explicit_init_py is actually desirable and forward-looking.

So perhaps this PR is unnecessary for my use case, unless somebody runs into issues and needs to toggle it for some packages/wheels.

Other note: perhaps the enable_implicit_namespace_pkgs documentation can be further clarified.


As part of investigating aspect-build/rules_py#611 which requires enable_implicit_namespace_pkgs = True as a workaround to unblock PEX creation, I looked into how to only toggle on this flag per wheel, as per aspect-build/rules_py#611 (comment) .

The goal of this is to reduce reliance on this flag where it's not necessary.

This PR is a proof-of-concept to gather if there's any interest in this feature. The commits aren't cleaned up yet.

Not yet done:

  • Update CHANGELOG.md
  • Update documentation for whl_mods

Copy link
Contributor

Summary of Changes

Hello @chrisirhc, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a significant feature to rules_py by enabling the enable_implicit_namespace_pkgs flag to be set individually for each wheel via whl_mods. This change aims to provide more precise control over how namespace packages are handled, specifically addressing issues related to PEX creation by allowing the flag to be enabled only where necessary, thereby reducing its global reliance. This is currently a proof-of-concept to gather feedback on the approach.

Highlights

  • Per-wheel Namespace Package Control: Introduced a new enable_implicit_namespace_pkgs attribute to whl_mods and package_annotation, allowing granular control over __init__.py file generation for namespace packages on a per-wheel basis.
  • Configuration Propagation: The new enable_implicit_namespace_pkgs setting is now propagated through the pypi extension and utilized when generating whl_library build rules, ensuring the per-wheel configuration is applied.
  • Test Coverage: New test cases have been added in extension_tests.bzl to verify the correct handling and propagation of the enable_implicit_namespace_pkgs attribute within whl_mods, and existing tests in generate_whl_library_build_bazel_tests.bzl were updated to include this new parameter.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a valuable feature to control enable_implicit_namespace_pkgs on a per-wheel basis. The implementation is mostly correct, but there's a significant issue with using attr.bool for what should be a tri-state option in the bzlmod extension. This will cause the feature to not work as intended, as it will always override the global setting. My review includes suggestions to fix this by using attr.string instead, along with necessary adjustments in the consuming code and tests. I've also included a minor suggestion to improve a docstring for clarity.

Comment on lines +746 to +751
"enable_implicit_namespace_pkgs": attr.bool(
doc = """\
(bool, optional): Override the global setting for generating __init__.py
files for namespace packages. If None, uses the repository-level setting.
""",
),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Using attr.bool here will not work as intended. The goal is to have a tri-state value (True, False, or not set to use the global default), but attr.bool only supports True and False. If a user does not specify this attribute, it will default to False, incorrectly overriding the global setting.

To correctly implement the tri-state logic, I suggest using attr.string with a set of allowed values, for example "True", "False", and "auto" (for the default when not set).

You will also need to update the code that consumes this attribute to handle string values, which I've commented on in python/private/pypi/generate_whl_library_build_bazel.bzl.

        "enable_implicit_namespace_pkgs": attr.string(
            doc = """\
(string, optional): Override the global setting for generating __init__.py
files for namespace packages. Can be "True", "False", or "auto".
If "auto", uses the repository-level setting.
""",
            default = "auto",
            values = ["True", "False", "auto"],
        ),

Comment on lines +112 to +113
if hasattr(annotation, "enable_implicit_namespace_pkgs") and annotation.enable_implicit_namespace_pkgs != None:
kwargs["enable_implicit_namespace_pkgs"] = annotation.enable_implicit_namespace_pkgs
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

To accommodate the change from attr.bool to attr.string for enable_implicit_namespace_pkgs in whl_mods, and to correctly handle values from package_annotation (which can be boolean or None), this logic needs to be updated.

The new logic should check for None (from package_annotation), "auto" (the new default for whl_mods), and then convert string "True"/"False" or boolean True/False to the final boolean value that whl_library_targets expects.

Suggested change
if hasattr(annotation, "enable_implicit_namespace_pkgs") and annotation.enable_implicit_namespace_pkgs != None:
kwargs["enable_implicit_namespace_pkgs"] = annotation.enable_implicit_namespace_pkgs
val = getattr(annotation, "enable_implicit_namespace_pkgs", None)
if val == True or val == "True":
kwargs["enable_implicit_namespace_pkgs"] = True
elif val == False or val == "False":
kwargs["enable_implicit_namespace_pkgs"] = False

Comment on lines +39 to +40
enable_implicit_namespace_pkgs (bool, optional): Override the global setting for generating __init__.py
files for namespace packages. If None, uses the repository-level setting.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The type hint (bool, optional) is slightly misleading as the function also accepts None to use the repository-level setting. It would be clearer to specify that None is a valid type.

Suggested change
enable_implicit_namespace_pkgs (bool, optional): Override the global setting for generating __init__.py
files for namespace packages. If None, uses the repository-level setting.
enable_implicit_namespace_pkgs (bool | None, optional): Override the global setting for generating __init__.py
files for namespace packages. If None, uses the repository-level setting.

Comment on lines +52 to +64
def _whl_mod(*, hub_name, whl_name, additive_build_content = None, additive_build_content_file = None, copy_executables = {}, copy_files = {}, data = [], data_exclude_glob = [], srcs_exclude_glob = [], enable_implicit_namespace_pkgs = None):
return struct(
hub_name = hub_name,
whl_name = whl_name,
additive_build_content = additive_build_content,
additive_build_content_file = additive_build_content_file,
copy_executables = copy_executables,
copy_files = copy_files,
data = data,
data_exclude_glob = data_exclude_glob,
srcs_exclude_glob = srcs_exclude_glob,
enable_implicit_namespace_pkgs = enable_implicit_namespace_pkgs,
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

To align with the suggested change of using attr.string for enable_implicit_namespace_pkgs, this test helper should be updated to use string values. The default should be "auto".

Suggested change
def _whl_mod(*, hub_name, whl_name, additive_build_content = None, additive_build_content_file = None, copy_executables = {}, copy_files = {}, data = [], data_exclude_glob = [], srcs_exclude_glob = [], enable_implicit_namespace_pkgs = None):
return struct(
hub_name = hub_name,
whl_name = whl_name,
additive_build_content = additive_build_content,
additive_build_content_file = additive_build_content_file,
copy_executables = copy_executables,
copy_files = copy_files,
data = data,
data_exclude_glob = data_exclude_glob,
srcs_exclude_glob = srcs_exclude_glob,
enable_implicit_namespace_pkgs = enable_implicit_namespace_pkgs,
)
def _whl_mod(*, hub_name, whl_name, additive_build_content = None, additive_build_content_file = None, copy_executables = {}, copy_files = {}, data = [], data_exclude_glob = [], srcs_exclude_glob = [], enable_implicit_namespace_pkgs = "auto"):
return struct(
hub_name = hub_name,
whl_name = whl_name,
additive_build_content = additive_build_content,
additive_build_content_file = additive_build_content_file,
copy_executables = copy_executables,
copy_files = copy_files,
data = data,
data_exclude_glob = data_exclude_glob,
srcs_exclude_glob = srcs_exclude_glob,
enable_implicit_namespace_pkgs = enable_implicit_namespace_pkgs,
)

hub_name = "pypi",
whl_name = "simple",
additive_build_content = "# Custom build content",
enable_implicit_namespace_pkgs = True,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

To align with the suggested change of using attr.string for enable_implicit_namespace_pkgs, this should be a string.

Suggested change
enable_implicit_namespace_pkgs = True,
enable_implicit_namespace_pkgs = "True",

data = [],
data_exclude_glob = [],
srcs_exclude_glob = [],
enable_implicit_namespace_pkgs = True,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The parse_modules function passes the attribute value through without conversion. With the suggested change to attr.string, this assertion should check for a string value.

Suggested change
enable_implicit_namespace_pkgs = True,
enable_implicit_namespace_pkgs = "True",

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant