chore(bigframes): refactor "generate_bigframes_bigquery.py" - #17904
chore(bigframes): refactor "generate_bigframes_bigquery.py"#17904sycai wants to merge 27 commits into
Conversation
There was a problem hiding this comment.
Code Review
This pull request refactors the BigQuery code generator by modularizing the monolithic generate_bigframes_bigquery.py script into a structured package under bigquery_generator/. The feedback is highly constructive and focuses on improving the refactored code. Key recommendations include fixing the relative script path calculation to preserve descriptive headers in generated files, using relative imports for sibling modules within the new package, explicitly specifying UTF-8 encoding when opening files, adding or correcting type hints (including a type mismatch in render_accessor), and adjusting the sys.path modification to import the generator as a proper package.
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
…r.py Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
…r.py Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
…r.py Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
|
Please could you merge main into this branch to resolve the |
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. | ||
|
|
||
|
|
There was a problem hiding this comment.
Since this is the main entrypoint for the script, please include instructions on how to run it in a docstring.
Optionally, when run with -h or --help, also display this newly created docstring.
There was a problem hiding this comment.
File removed. I will make this package un-executable on its own.
There was a problem hiding this comment.
Since this is redundant with the __main__.py file you have created, please remove this file altogether and update references in our internal docs such as https://github.com/googleapis/google-cloud-python/blob/main/packages/bigframes/specs/bigframes-bigquery-generator.md with the new way to run the script.
There was a problem hiding this comment.
On the second thought, I want to preserve this file while removing "main.py".
Pros:
- We don't need to update the https://github.com/googleapis/google-cloud-python/blob/main/packages/bigframes/specs/bigframes-bigquery-generator.md
- We won't introduce changes of script references in the generated code like this:
| ] + RUFF_COMMON_ARGS | ||
|
|
||
|
|
||
| TEMPLATES: dict[str, jinja2.Template] # Lazily-loaded global variable |
There was a problem hiding this comment.
It would be helpful to have a comment explaining why we want this to be lazily loaded.
There was a problem hiding this comment.
Nit (Optional): We don't have to put all constants here. I would prefer that they be defined closer to where they are used or in a purpose-specific module, such as with the templates logic or list of Python built-ins, but that's mostly just a personal preference.
| from . import constants | ||
|
|
||
|
|
||
| @dataclasses.dataclass |
There was a problem hiding this comment.
Ideally we'd use frozen=True on the dataclasses in this file.
Or is there a reason they need to be mutable? If so, let's document that in a comment/docstring.
| bq_module: data_models.BQModule, | ||
| ) -> str: | ||
| if not bq_module.functions: | ||
| # If there are no function definitions, do not generate an empty file. |
There was a problem hiding this comment.
I'm guessing the "do not generate an empty file" part happens at a layer above this? From what I can tell here, it's returning an empty string for the file contents. I think this comment could be reworded to make that more clear (e.g. If there are no function definitions, don't generate any boilerplate so that the caller can determine that this file should be skipped.)
|
|
||
| def render_tests(bq_module: data_models.BQModule) -> str: | ||
| if not bq_module.functions: | ||
| # If there are no function definitions, do not generate an empty test file. |
There was a problem hiding this comment.
Same here regarding a somewhat confusing comment.
|
|
||
| def _to_snake_case(name: str) -> str: | ||
| # Replace dots with underscores | ||
| name = name.replace(".", "_") |
There was a problem hiding this comment.
Why the dots to underscores part? Could you provide some examples where this logic was necessary? Some parametrized unit tests or doctests could be especiallly helpful.
| # Handle CamelCase to snake_case | ||
| name = re.sub(r"(?<!^)(?=[A-Z])", "_", name).lower() | ||
| # Replace multiple underscores with one | ||
| name = re.sub(r"_+", "_", name) |
There was a problem hiding this comment.
Same here. It would be helpful to see some concrete examples where this was needed.
| return name | ||
|
|
||
|
|
||
| def _parse_func_arg(arg_data: Any) -> data_models.BQFuncArg: |
There was a problem hiding this comment.
Nit: parse is sorta the wrong verb here. I imagine parse as the first step of going from unstructured text to some sort of structure. We're somewhere in the (symbol -> type -> resource) phases per the terminology in https://www.cs.mcgill.ca/~cs520/2018/slides/4-ast.pdf More accurate name would be _build_func_arg_ir Likewise for the other functions in this file.
Changes:
generate_bigframes_bigquery.pycall the new Python moduleThe old code generation CLI still works.
I generated all the code files and checked the results. The only thing changed in the output are the relative order of AI and AEAD code