-
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
Gazelle extension for Python #514
Conversation
All (the pull request submitter and all commit authors) CLAs are signed, but one or more commits were authored or co-authored by someone other than the pull request submitter. We need to confirm that all authors are ok with their commits being contributed to this project. Please have them confirm that by leaving a comment that contains only Note to project maintainer: There may be cases where the author cannot leave a comment, or the comment is not properly detected as consent. In those cases, you can manually confirm consent of the commit author(s), and set the ℹ️ Googlers: Go here for more info. |
@googlebot I consent. I'm co-authoring this with Thulio. |
b548584
to
b48b1c8
Compare
Thanks @f0rmiga can you add bazel-contrib/bazel-gazelle#1030 to the PR description? Looks like something reviewers should read through given discussion in the bazelbuild Slack (note that Slack link will eventually die as the workspace has free-tier limited history). |
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.
Reviewed the "starting point for reviewing" stuff so far. Good stuff. Will continue on tomorrow or day after.
Edit: Alright I'm back... 6 days later.
modules_mapping( | ||
name = "modules_map", | ||
# This should point to wherever we declare our python dependencies | ||
requirements = "//:requirements_lock.txt", |
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.
This is a 'lock' file. Does it require the requirements file to be transitively locked? If yes, it should be called out I think.
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.
FWIW the public doc for the repo doesn't call this out (but maybe it should?)
The public doc also use "//path/to:requirements_lock.txt"
so maybe we should use that here as well for consistency? (and down below in gazelle_python_manifest)
|
||
Finally, you create a target that you'll invoke to run the Gazelle tool | ||
with the rules_python extension included. This typically goes in your root | ||
`/BUILD.bazel` file: |
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.
nit: Could be clearer to just say "target typically goes in your workspace root package, //:gazelle
.
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.
Had a scan through the Golang, and the testing looks nice and thorough. As I'm not the best person to do ongoing review of Golang code, can we get an ongoing reviewer added to .github/CODEOWNERS
. They'll get assigned by Github as appropriate.
cb39cbc
to
a795f91
Compare
.bazelversion
Outdated
@@ -1 +1 @@ | |||
3.3.1 | |||
4.1.0 |
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.
Do we need this change? We have #533 bumping the version.
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.
that just landed, so no we shouldn't need this anymore
All (the pull request submitter and all commit authors) CLAs are signed, but one or more commits were authored or co-authored by someone other than the pull request submitter. We need to confirm that all authors are ok with their commits being contributed to this project. Please have them confirm that by leaving a comment that contains only Note to project maintainer: There may be cases where the author cannot leave a comment, or the comment is not properly detected as consent. In those cases, you can manually confirm consent of the commit author(s), and set the ℹ️ Googlers: Go here for more info. |
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.
👋 Howdy! Very excited to see this PR, as someone who build-engineers at a company with way too much hand-maintained Python BUILD
files 😁
In fact, ignoring all the other challenges we face with Bazel+Python, this is the largest IMO.
One high-level suggestion I have (possibly out of scope, but would love to see it): super-fine grained generation. This mode would be the default and essentially boils down to roughly one rule-per-file.
This would make builds/tests as fast as possible within Bazel. It'll also make the BUILD
files noisy, but it's also generated so "meh".
To demonstrate it with an example:
Take this directory structure:
cheese_shop/
├─ __init__.py # Just imports and re-exports from the _<cheese> files
├─ _caerphilly.py
├─ _caerphilly_test.py
├─ _emmental.py
├─ _emmental_test.py
├─ _japanese_sage_darby.py
├─ _japanese_sage_darby_test.py
├─ mister_wensleydale.py # public subpackage
├─ mister_wensleydale_test.py
Ideally, there'd be:
- 5
py_library
s:- One for each
_<cheese>.py
(Maybe this could even has it's visibility marked, due to the leading-underscore convention?) - One for
__init__.py
. This would be the one that other libraries depend on. - One for
mister_wensleydale.py
, a public subpackage
- One for each
- 4
py_test
s. One for each*_test.py
That way if I only edit _caerphilly.py
, Ideally only the _caerphilly_test.py
test rule will need to be run (and not the other tests).
|
||
### Tests | ||
|
||
Python test files are those ending in `_test.py`. |
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.
I think it'd be prudent to also look for other standard patterns.
unittest
's discovery's pattern is test*
by default: https://docs.python.org/3/library/unittest.html#cmdoption-unittest-discover-p
pytest
allows both test_
and _test
: https://docs.pytest.org/en/6.2.x/goodpractices.html#test-discovery
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.
And/or allow me to specify the pattern (through a directive?) 😁
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.
This is already supported! https://github.com/bazelbuild/rules_python/pull/514/files#diff-56956604a1d66006e9135f231c19bf1799aa19370f382ccd94842a88856bce78R86
We only need to update the documentation to be clear. unittest
should be supported if you write a template for it and use the target output as __test__.py
and the generation target named __test__
.
modules_mapping( | ||
name = "modules_map", | ||
# This should point to wherever we declare our python dependencies | ||
requirements = "//:requirements_lock.txt", |
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.
FWIW the public doc for the repo doesn't call this out (but maybe it should?)
The public doc also use "//path/to:requirements_lock.txt"
so maybe we should use that here as well for consistency? (and down below in gazelle_python_manifest)
|
||
Python test files are those ending in `_test.py`. | ||
|
||
A `py_test` target is added containing all test files as `srcs`. |
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.
This might be out of scope for this PR, but this might be a nonstarter for projects using a custom test rule (which is suuuuuuuper common, since rules_python
lacks pytest
support today and pytest
is the ubiquitous Python test library/runner).
Is this possible to customize through directives?
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.
I'll expand this section. It's more complicated than what we stated so far.
modules_mapping = "@modules_map//:modules_mapping.json", | ||
# This is what we called our `pip_install` rule, where third-party | ||
# python libraries are loaded in BUILD files. | ||
pip_deps_repository_name = "pip", |
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.
The public doc for this repo uses my_deps
, let's be consistent?
@joshua-cannon-techlabs Thanks for your input. I considered the file-grained approach, but not as default. I shall change a bit the generation mode options before landing this. I won't add the file-grained mode before landing, but will leave space for it to be added in the near future. So the options supported now would be: # gazelle:python_generation_mode package
# gazelle:python_generation_mode project and then for the future: # gazelle:python_generation_mode file |
All (the pull request submitter and all commit authors) CLAs are signed, but one or more commits were authored or co-authored by someone other than the pull request submitter. We need to confirm that all authors are ok with their commits being contributed to this project. Please have them confirm that by leaving a comment that contains only Note to project maintainer: There may be cases where the author cannot leave a comment, or the comment is not properly detected as consent. In those cases, you can manually confirm consent of the commit author(s), and set the ℹ️ Googlers: Go here for more info. |
1 similar comment
All (the pull request submitter and all commit authors) CLAs are signed, but one or more commits were authored or co-authored by someone other than the pull request submitter. We need to confirm that all authors are ok with their commits being contributed to this project. Please have them confirm that by leaving a comment that contains only Note to project maintainer: There may be cases where the author cannot leave a comment, or the comment is not properly detected as consent. In those cases, you can manually confirm consent of the commit author(s), and set the ℹ️ Googlers: Go here for more info. |
@googlebot I consent. |
All (the pull request submitter and all commit authors) CLAs are signed, but one or more commits were authored or co-authored by someone other than the pull request submitter. We need to confirm that all authors are ok with their commits being contributed to this project. Please have them confirm that by leaving a comment that contains only Note to project maintainer: There may be cases where the author cannot leave a comment, or the comment is not properly detected as consent. In those cases, you can manually confirm consent of the commit author(s), and set the ℹ️ Googlers: Go here for more info. |
All (the pull request submitter and all commit authors) CLAs are signed, but one or more commits were authored or co-authored by someone other than the pull request submitter. We need to confirm that all authors are ok with their commits being contributed to this project. Please have them confirm that by leaving a comment that contains only Note to project maintainer: There may be cases where the author cannot leave a comment, or the comment is not properly detected as consent. In those cases, you can manually confirm consent of the commit author(s), and set the ℹ️ Googlers: Go here for more info. |
@thundergolfer The MacOS Buildkite runner is missing the |
All (the pull request submitter and all commit authors) CLAs are signed, but one or more commits were authored or co-authored by someone other than the pull request submitter. We need to confirm that all authors are ok with their commits being contributed to this project. Please have them confirm that by leaving a comment that contains only Note to project maintainer: There may be cases where the author cannot leave a comment, or the comment is not properly detected as consent. In those cases, you can manually confirm consent of the commit author(s), and set the ℹ️ Googlers: Go here for more info. |
Co-authored-by: Jonathon Belotti <[email protected]>
Signed-off-by: Thulio Ferraz Assis <[email protected]>
Co-authored-by: Jonathon Belotti <[email protected]>
Signed-off-by: Thulio Ferraz Assis <[email protected]>
With the recent change in pypa/setuptools#2769, some wheels started to fail build immediately with an unpinned setuptools in isolation mode. Signed-off-by: Thulio Ferraz Assis <[email protected]>
Signed-off-by: Thulio Ferraz Assis <[email protected]>
Signed-off-by: Thulio Ferraz Assis <[email protected]>
Signed-off-by: Thulio Ferraz Assis <[email protected]>
Also add the python_generation_mode directive. Signed-off-by: Thulio Ferraz Assis <[email protected]>
Signed-off-by: Thulio Ferraz Assis <[email protected]>
Signed-off-by: Thulio Ferraz Assis <[email protected]>
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.
LGTM. A few nits that can be addressed in a follow up.
|
||
|
||
def build(wheel): | ||
print("{}: building {}".format(datetime.now(), wheel), file=sys.stderr) |
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.
prefer an f-string here
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.
f-strings are Python 3.6 only. Don't we care about earlier Python versions?
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.
I agree we should avoid depending on interpreter version where possible/convenient. I don't know what assertions we have to keep ourselves honest about it.
print("STDOUT:", file=sys.stderr) | ||
print(process.stdout, file=sys.stderr) | ||
print("STDERR:", file=sys.stderr) | ||
print(process.stderr, file=sys.stderr) |
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.
this could be turned into a more readable multi-line string
def build(wheel): | ||
print("{}: building {}".format(datetime.now(), wheel), file=sys.stderr) | ||
process = subprocess.run( | ||
[sys.executable, "-m", "build", "--wheel", "--no-isolation"], cwd=wheel |
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.
Is assuming that .tar.gz packages have a build module a packaging standard? Do some need setup.py run?
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.
I'm not sure I understand this question. The build module here is provided by https://packaging.python.org/key_projects/#build, which implements https://www.python.org/dev/peps/pep-0517/.
After it builds the wheel from the source, we dig the file with generator.py
in this same Python package.
Is your question around needing to run setup.py
instead of looking at the packaged wheel only?
Signed-off-by: Thulio Ferraz Assis <[email protected]>
Signed-off-by: Thulio Ferraz Assis <[email protected]>
Signed-off-by: Thulio Ferraz Assis <[email protected]>
Performing the check last is more correct and yields better performance, noticeable on large repositories. Signed-off-by: Thulio Ferraz Assis <[email protected]>
Hi there! 👋
This is the initial Gazelle extension for Python.
A good starting point for reviewing is the added README file under
gazelle/
, the example workspace and thetestdata
directory.More discussion on where Gazelle extensions should live here: bazel-contrib/bazel-gazelle#1030.