Skip to content

Add rules_python toolchain to the rule#174

Open
furtib wants to merge 4 commits intoEricsson:mainfrom
furtib:add-rules-python
Open

Add rules_python toolchain to the rule#174
furtib wants to merge 4 commits intoEricsson:mainfrom
furtib:add-rules-python

Conversation

@furtib
Copy link
Contributor

@furtib furtib commented Jan 29, 2026

Why:
Necessary for Bazel 8 support.

What:

  • Added rules_python as a dependency
  • Removed registration of our own toolchain from the MODULE.bazel; if left there, its priority would shadow the rules_python toolchain. Bazel 7, during unittest, seems to prefer our own, while if included by another project, it seems to prefer the rules_python toolchain. (Adding the following flag will reveal the process of toolchain selection: --toolchain_resolution_debug=.*)
    (The logic behind this:
    • Bazel 6 prefers the WORKSPACE, so it finds the old toolchain.
    • Bazel 7 uses the MODULE system, but also checks the WORKSPACE file, so it finds the old toolchain too. In projects including it with only a MODULE file, e.g., zlib-modules, it will use the rules_python toolchain. (My theory for this is that register_toolchains takes the highest precedence in the order of toolchain resolution, and in other projects, we don't register the toolchain)
    • Bazel 8 ignores the WORKSPACE file, so it does not find the old toolchain; they can't interfere with each other.
      )
  • Changed from using shebang to changing the executor. This is necessary, since the interpreter provided by rules_python is inside the sandbox, and we will get a relative path, not an absolute one. This is why we can't use shebang. Also, if use_default_shell_env is enabled, the path to an executable is accepted as executable.
  • Created that absolutely ugly wrapper script for codechecker_test - I have no better idea of how I return an executable that, without any parameters, would execute the script using the interpreter, that maybe inside the sandbox, maybe not. I'm open to any better ideas. (The only idea I have is dropping the template expansion entirely, and using py_binary targets instead)
  • It is possible to set a specific Python version for the rules_python toolchain. I opted not to do this and let the including project decide which version they want to use.

Addresses:
#108

@furtib furtib self-assigned this Jan 29, 2026
@furtib furtib added the enhancement New feature or request label Jan 29, 2026
@furtib furtib force-pushed the add-rules-python branch 6 times, most recently from b64ea51 to b602fbe Compare January 30, 2026 09:55
@furtib furtib marked this pull request as ready for review January 30, 2026 09:59
@furtib furtib requested review from Szelethus and nettle and removed request for nettle January 30, 2026 10:01
Copy link
Contributor

@Szelethus Szelethus left a comment

Choose a reason for hiding this comment

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

Bazel 7, during unittest, seems to prefer our own, while if included by another project, it seems to prefer the rules_python toolchain.
What does "prefer" mean? Does this mean that we are committing to supporting both WORKSPACE and Module system for bazel 7?

I want to know whether this is an actual requirement, because the way you explain it, this seems to be a non-trivial complexity. Would the code look significantly cleaner if we dropped WORKSPACE support for bazel 7?

src/common.bzl Outdated
elif hasattr(py_toolchain, "py3_runtime"):
py_runtime = py_toolchain.py3_runtime
python_path = py_runtime.interpreter_path
if python_path == None: # Bazel 8
Copy link
Contributor

Choose a reason for hiding this comment

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

Thats a vague comment on its own.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

src/common.bzl Outdated

def python_interpreter_tool(ctx):
"""
Returns version specific Python interpreter object in a list
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we have to return a list?

Suggested change
Returns version specific Python interpreter object in a list
Returns version specific Python interpreter object that is appropriate for the Bazel version that is running

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We don't have to return a list, but handling the case where there is no tool to return (Bazel 6) will become very ugly.
Now we have (removing unimportant parts):

    ctx.actions.run(
        executable = python_path(ctx),
        tools = python_interpreter_tool(ctx),
        arguments = [
            ...
            ],
        use_default_shell_env = True,
    )

This would look like:

    ctx.actions.run(
        executable = python_path(ctx),
        tools = [python_interpreter_tool(ctx)] if python_interpreter_tool(ctx) != None else [],
        arguments = [
            ...
            ],
        use_default_shell_env = True,
    )

or we calculate tools ahead of time:

tools = [python_interpreter_tool(ctx)] if python_interpreter_tool(ctx) != None else [],
ctx.actions.run(.....)

Comment on lines +20 to +25
#python = use_extension("@rules_python//python/extensions:python.bzl", "python")
#python.toolchain(
# python_version = "3.10",
# is_default = True,
#)
Copy link
Contributor

Choose a reason for hiding this comment

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

What is the story with these?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried everything to leave the toolchain registration for the old toolchain in the MODULE file, and have rules_python have a higher priority, but I failed.
These options I have come across during that. (I left them in thinking they might be interesting)

@furtib
Copy link
Contributor Author

furtib commented Feb 4, 2026

My explanation might not been the best, mostly it was just noting my experience trying this change out in different environments.
We cannot "drop" support for WORKSPACE files in Bazel 7. Bazel 7 will check the contents of the WORKSPACE file.

The strange behaviour, while I'm not completely sure I understand (which we should before merging), is most likely due to the way the rule is included in a project.

  • In the codechecker_bazel repository, both MODULE and WORKSPACE files are present, and thus the toolchain that is only registered in the WORKSPACE file will be found and used.
  • Other projects that include the rule through the MODULE system will not find it, since WORKSPACE files are non-transitive, but they will find the rules_python included in the MODULE file, since that is transitive.

This theory holds up in FOSS tests:

  • zlib uses our toolchain (registered in its own WORKSPACE file)
  • zlib-module uses the rules_python toolchain.

This would also mean that Bazel 8 will fail on tests using WORKSPACE files (Bazel 8 can be forced to read WORKSPACE files)

@furtib furtib force-pushed the add-rules-python branch 4 times, most recently from 41f71ef to e947e0b Compare February 4, 2026 14:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants