Skip to content
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: Creating one py_binary per main module #1584

Merged
merged 13 commits into from Dec 13, 2023
Merged

Conversation

linzhp
Copy link
Contributor

@linzhp linzhp commented Nov 29, 2023

Many existing Python repos don't use __main__.py to indicate the the main module. Instead, they put something like below in any Python files:

if __name__ == "__main__":
  main()

This PR makes the Gazelle extension able to recognize main modules like this, when __main__.py doesn't exist. This reduces the need to create __main__.py when enabling Gazelle extensions in existing Python repos.

The current behavior of creating single py_binary for __main__.py is preserved and takes precedence. So this is a backward-compatible change.

Closes #1566.

@linzhp linzhp requested a review from f0rmiga as a code owner November 29, 2023 20:18
@aignas
Copy link
Collaborator

aignas commented Dec 3, 2023

Thanks for the PR, does this replace #1582? If so does it make to add some test cases from that PR in order to have coverage for:

  • Multiple py_binary targets in the output BUILD.bazel.
  • Ensuring that we are not generating py_binary for test files.

@linzhp
Copy link
Contributor Author

linzhp commented Dec 4, 2023

I think #1582 addresses a different problem, but I added the test cases anyways.

@aignas
Copy link
Collaborator

aignas commented Dec 4, 2023

Sorry, I meant #1566 and thanks for adding the tests. I agree that #1582 addresses a different problem.

@linzhp
Copy link
Contributor Author

linzhp commented Dec 4, 2023

I didn't realize there is already an open PR for this. Yes, this reimplements that, without parsing the Python files again. It also looks at tokens instead of string matches, with would cover cases like if __name__=="__main__" (no spaces) or if __name__ == "__main__" (extra spaces)

Copy link
Collaborator

@aignas aignas left a comment

Choose a reason for hiding this comment

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

I think overall LGTM with a few minor comments.

Comment on lines 255 to 265
if args.File != nil {
for _, t := range args.File.Rules {
if t.Name() == pyBinaryTargetName && t.Kind() != actualPyBinaryKind {
fqTarget := label.New("", args.Rel, pyBinaryTargetName)
log.Printf("failed to generate target %q of kind %q: "+
"a target of kind %q with the same name already exists.",
fqTarget.String(), actualPyBinaryKind, t.Kind())
continue mainModulesLoop
}
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: the readability of this code due to nesting and the code location declarations is getting a little hard to follow. If it was possible to reduce indenting and/or split out to separate functions, it would be great, but not blocking this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

extract it to a new function and reuse it in all places with similar logic

gazelle/python/testdata/binary_without_entrypoint/BUILD.in Outdated Show resolved Hide resolved
)

py_library(
name = "binary_without_entrypoint",
Copy link
Collaborator

Choose a reason for hiding this comment

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

should this be library_without_entrypoint?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

given it a better name

@siddharthab
Copy link
Contributor

Thanks for doing this. I was thinking of adding this myself if I had not discovered your PR through one of mine.

Copy link
Collaborator

@aignas aignas left a comment

Choose a reason for hiding this comment

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

Thanks!

@aignas aignas added this pull request to the merge queue Dec 12, 2023
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Dec 12, 2023
@aignas aignas added this pull request to the merge queue Dec 12, 2023
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Dec 12, 2023
@aignas aignas added this pull request to the merge queue Dec 13, 2023
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Dec 13, 2023
@rickeylev rickeylev added this pull request to the merge queue Dec 13, 2023
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Dec 13, 2023
@aignas aignas added this pull request to the merge queue Dec 13, 2023
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Dec 13, 2023
@aignas aignas added this pull request to the merge queue Dec 13, 2023
Merged via the queue into bazelbuild:main with commit 6ffb04e Dec 13, 2023
3 checks passed
@linzhp linzhp deleted the py_binary branch December 13, 2023 16:29
github-merge-queue bot pushed a commit that referenced this pull request Jan 9, 2024
[This previous PR](#1584)
added the ability to make a `py_binary` target per file if `if __name__
== "__main__"` tokens were found in the file. This works great in the
default case, but when `python_generation_mode` is set to `file`, the
plugin now attempts to make both a `py_binary` and a `py_library` target
for each main file, which results in an error.

This PR modifies the behavior to work properly with per-file target
generation, and adds tests for this case.
wingsofovnia pushed a commit to wingsofovnia/rules_python_gazelle_plugin that referenced this pull request May 3, 2024
[This previous PR](bazelbuild/rules_python#1584)
added the ability to make a `py_binary` target per file if `if __name__
== "__main__"` tokens were found in the file. This works great in the
default case, but when `python_generation_mode` is set to `file`, the
plugin now attempts to make both a `py_binary` and a `py_library` target
for each main file, which results in an error.

This PR modifies the behavior to work properly with per-file target
generation, and adds tests for this case.
wingsofovnia pushed a commit to wingsofovnia/rules_python_gazelle_plugin that referenced this pull request May 3, 2024
[This previous PR](bazelbuild/rules_python#1584)
added the ability to make a `py_binary` target per file if `if __name__
== "__main__"` tokens were found in the file. This works great in the
default case, but when `python_generation_mode` is set to `file`, the
plugin now attempts to make both a `py_binary` and a `py_library` target
for each main file, which results in an error.

This PR modifies the behavior to work properly with per-file target
generation, and adds tests for this case.
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.

None yet

3 participants