-
Notifications
You must be signed in to change notification settings - Fork 541
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: compile source files at build time #1902
Merged
Merged
Changes from all commits
Commits
Show all changes
27 commits
Select commit
Hold shift + click to select a range
e8760eb
feat: compile source files at build time
rickeylev 78bb5c0
fixup! fix load order, fix wrong toolchain type set, guard tests on b…
rickeylev 7e9ef85
fixup! add missing bzl deps, handle missing releaselevel key
rickeylev 0f1cbef
fixup! add distribution target to precompiler so toolchain tests work
rickeylev e3178c4
make precompiler lazy-load worker-specific imports
rickeylev 180b5d5
fixup! make toolchain integration tests pass when run locally
rickeylev 2d6e17a
Merge branch 'main' of ssh://ssh.github.com:443/bazelbuild/rules_pyth…
rickeylev 733eec9
fixup! fix year in newly added copyright
rickeylev 6531153
fixup! add docs, type annotations
rickeylev 47d4a74
try AEG to fix missing cpp toolchain error in RBE tests
rickeylev 8c4f04c
make cross building work and satisfy RBE CI
rickeylev 0bce7e9
fixup! access launcher attr correctly
rickeylev 3cb76e8
support --action_env=BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1 being set
rickeylev 8281f32
remove defunct file
rickeylev 597d6b2
add missing distribution filegroup
rickeylev 96c8381
fixup! trying to repro mac ci failure
rickeylev d26918b
fixup! debugging mac ci failure
rickeylev 4fe4139
fixup! use build flags intead of test flags
rickeylev e993673
fixup! re-add bzlmod disable
rickeylev 0a1ead0
fixup! further mac ci debug
rickeylev d057930
fixup! register exec tools toolchain under workspace
rickeylev 7e915f6
fixup! remove debug code
rickeylev cf92abc
Merge branch 'main' of ssh://ssh.github.com:443/bazelbuild/rules_pyth…
rickeylev cf8b6a2
remove defunct file
rickeylev b58e20f
add some doc improvements
rickeylev f81d27e
typo fix / noop to retrigger ci for flake
rickeylev 714d025
trigger ci to deflake
rickeylev File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -60,6 +60,7 @@ pypi-dependencies | |
toolchains | ||
pip | ||
coverage | ||
precompiling | ||
gazelle | ||
Contributing <contributing> | ||
support | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
# Precompiling | ||
|
||
Precompiling is compiling Python source files (`.py` files) into byte code (`.pyc` | ||
files) at build | ||
time instead of runtime. Doing it at build time can improve performance by | ||
skipping that work at runtime. | ||
|
||
Precompiling is enabled by default, so there typically isn't anything special | ||
you must do to use it. | ||
|
||
|
||
## Overhead of precompiling | ||
|
||
While precompiling helps runtime performance, it has two main costs: | ||
1. Increasing the size (count and disk usage) of runfiles. It approximately | ||
double the count of the runfiles because for every `.py` file, there is also | ||
a `.pyc` file. Compiled files are generally around the same size as the | ||
source files, so it approximately doubles the disk usage. | ||
2. Precompiling requires running an extra action at build time. While | ||
compiling itself isn't that expensive, the overhead can become noticable | ||
as more files need to be compiled. | ||
|
||
## Binary-level opt-in | ||
|
||
Because of the costs of precompiling, it may not be feasible to globally enable it | ||
for your repo for everything. For example, some binaries may be | ||
particularly large, and doubling the number of runfiles isn't doable. | ||
|
||
If this is the case, there's an alternative way to more selectively and | ||
incrementally control precompiling on a per-binry basis. | ||
|
||
To use this approach, the two basic steps are: | ||
1. Disable pyc files from being automatically added to runfiles: | ||
`--@rules_python//python/config_settings:precompile_add_to_runfiles=decided_elsewhere`, | ||
2. Set the `pyc_collection` attribute on the binaries/tests that should or should | ||
not use precompiling. | ||
|
||
The default for the `pyc_collection` attribute is controlled by a flag, so you | ||
can use an opt-in or opt-out approach by setting the flag: | ||
* targets must opt-out: `--@rules_python//python/config_settings:pyc_collection=include_pyc`, | ||
* targets must opt-in: `--@rules_python//python/config_settings:pyc_collection=disabled`, | ||
|
||
## Advanced precompiler customization | ||
|
||
The default implementation of the precompiler is a persistent, multiplexed, | ||
sandbox-aware, cancellation-enabled, json-protocol worker that uses the same | ||
interpreter as the target toolchain. This works well for local builds, but may | ||
not work as well for remote execution builds. To customize the precompiler, two | ||
mechanisms are available: | ||
|
||
* The exec tools toolchain allows customizing the precompiler binary used with | ||
the `precompiler` attribute. Arbitrary binaries are supported. | ||
* The execution requirements can be customized using | ||
`--@rules_python//tools/precompiler:execution_requirements`. This is a list | ||
flag that can be repeated. Each entry is a key=value that is added to the | ||
execution requirements of the `PyPrecompile` action. Note that this flag | ||
is specific to the rules_python precompiler. If a custom binary is used, | ||
this flag will have to be propagated from the custom binary using the | ||
`testing.ExecutionInfo` provider; refer to the `py_interpreter_program` an | ||
|
||
The default precompiler implementation is an asynchronous/concurrent | ||
implementation. If you find it has bugs or hangs, please report them. In the | ||
meantime, the flag `--worker_extra_flag=PyPrecompile=--worker_impl=serial` can | ||
be used to switch to a synchronous/serial implementation that may not perform | ||
as well, but is less likely to have issues. | ||
|
||
The `execution_requirements` keys of most relevance are: | ||
* `supports-workers`: 1 or 0, to indicate if a regular persistent worker is | ||
desired. | ||
* `supports-multiplex-workers`: 1 o 0, to indicate if a multiplexed persistent | ||
worker is desired. | ||
* `requires-worker-protocol`: json or proto; the rules_python precompiler | ||
currently only supports json. | ||
* `supports-multiplex-sandboxing`: 1 or 0, to indicate if sanboxing is of the | ||
worker is supported. | ||
* `supports-worker-cancellation`: 1 or 1, to indicate if requests to the worker | ||
can be cancelled. | ||
|
||
Note that any execution requirements values can be specified in the flag. | ||
|
||
## Known issues, caveats, and idiosyncracies | ||
|
||
* Precompiling requires Bazel 7+ with the Pystar rule implementation enabled. | ||
* Mixing rules_python PyInfo with Bazel builtin PyInfo will result in pyc files | ||
being dropped. | ||
* Precompiled files may not be used in certain cases prior to Python 3.11. This | ||
occurs due Python adding the directory of the binary's main `.py` file, which | ||
causes the module to be found in the workspace source directory instead of | ||
within the binary's runfiles directory (where the pyc files are). This can | ||
usually be worked around by removing `sys.path[0]` (or otherwise ensuring the | ||
runfiles directory comes before the repos source directory in `sys.path`). | ||
* The pyc filename does not include the optimization level (e.g. | ||
`foo.cpython-39.opt-2.pyc`). This works fine (it's all byte code), but also | ||
means the interpreter `-O` argument can't be used -- doing so will cause the | ||
interpreter to look for the non-existent `opt-N` named files. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PR message and changelog say it's disabled by default?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, thanks for catching that. I've sent a PR to fix the docs here. It is disabled by default for now. After the next release, we can consider enabling it by default