-
Notifications
You must be signed in to change notification settings - Fork 74
fix: generate version when prepare and read in setup.py #1375
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
Conversation
Reviewer's GuideThis PR wires the setuptools_scm-generated version into the Python package by generating a robust _version.py during the build script and reading it from setup.py, including safe fallbacks when version derivation fails. Sequence diagram for Python package version generation and usagesequenceDiagram
actor Developer
participant prepare_python_build_sh
participant python3_version_snippet
participant setuptools_scm
participant filesystem
participant setup_py
Developer->>prepare_python_build_sh: run
prepare_python_build_sh->>python3_version_snippet: execute inline Python
python3_version_snippet->>setuptools_scm: get_version(root, version_scheme, local_scheme)
alt version_resolved
setuptools_scm-->>python3_version_snippet: version string
else error_or_failure
setuptools_scm-->>python3_version_snippet: raise exception
python3_version_snippet->>python3_version_snippet: set version = 0.0.0
end
python3_version_snippet->>filesystem: write python/pyvsag/_version.py with __version__
filesystem-->>prepare_python_build_sh: _version.py created
Developer->>setup_py: run setup
setup_py->>filesystem: locate python/pyvsag/_version.py
alt version_file_exists
setup_py->>filesystem: read _version.py
filesystem-->>setup_py: __version__ definition
setup_py->>setup_py: exec file into namespace
setup_py->>setup_py: version = ns.__version__
else version_file_missing
setup_py->>setup_py: version = 0.0.0
end
setup_py-->>Developer: package built with resolved version
File-Level Changes
Assessment against linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
Summary of ChangesHello @jac0626, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request refines the package versioning mechanism by introducing a more robust way to generate and read the package version during the build process. It ensures that the Python package's version is consistently derived from source control metadata and made available to Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
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.
Hey there - I've reviewed your changes - here's some feedback:
- The imported
sysmodule inpython/setup.pyis unused and can be removed to keep the file minimal. - In
prepare_python_build.sh, the broadexcept Exception:aroundsetuptools_scm.get_versioncould mask real issues; consider catching only expected errors and/or emitting a clear warning when falling back to0.0.0.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The imported `sys` module in `python/setup.py` is unused and can be removed to keep the file minimal.
- In `prepare_python_build.sh`, the broad `except Exception:` around `setuptools_scm.get_version` could mask real issues; consider catching only expected errors and/or emitting a clear warning when falling back to `0.0.0`.
## Individual Comments
### Comment 1
<location> `python/setup.py:15` </location>
<code_context>
+ ns = {}
+ with open(_version_file) as f:
+ exec(f.read(), ns)
+ return ns.get('__version__')
+ return '0.0.0'
+
</code_context>
<issue_to_address>
**suggestion:** Provide a default when '__version__' is missing to avoid returning None.
If `_version.py` loads but `__version__` is missing or malformed, `ns.get('__version__')` returns `None`, so `setup(version=None, ...)` is used. This is inconsistent with the `'0.0.0'` fallback when the file is missing and can hide version-generation issues. Consider `ns.get('__version__', '0.0.0')` so all failure modes use a clear default.
Suggested implementation:
```python
ns = {}
with open(_version_file) as f:
exec(f.read(), ns)
return ns.get('__version__', '0.0.0')
return '0.0.0'
```
From the snippet you shared, it looks like `_read_version` is duplicated and the `return` statements are missing in both copies. You should ensure that:
1) There is only a single definition of `_read_version` in `python/setup.py`.
2) That definition includes the full logic:
- Compute `here` and `_version_file`.
- If the file exists, load it into `ns` and `return ns.get('__version__', '0.0.0')`.
- If the file does not exist, `return '0.0.0'`.
If any other code currently expects `_read_version` to possibly return `None`, update those call sites (if any) to no longer rely on that behavior, since it will now always return a string version.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
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.
Code Review
This pull request introduces a mechanism to statically generate a version file during the build preparation and then read this version in setup.py. The changes are logical, but I have a few suggestions for improvement. In setup.py, the use of exec() to read the version file poses a security risk and should be replaced with safer file parsing, like using regular expressions. I've also noted an unused import. In prepare_python_build.sh, the exception handling for version generation is too broad and should be more specific, and there's also an unused import in the Python snippet. Addressing these points will improve the security, robustness, and cleanliness of the code.
| if os.path.exists(_version_file): | ||
| ns = {} | ||
| with open(_version_file) as f: | ||
| exec(f.read(), ns) | ||
| return ns.get('__version__') | ||
| return '0.0.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.
Using exec() on file contents can be a security risk as it can execute arbitrary code. Additionally, if _version.py exists but does not define __version__, ns.get('__version__') will return None, which might cause issues in setup(). A safer and more robust approach is to parse the file using a regular expression. This avoids exec and correctly handles the case where the version string is not found in the file by falling back to the default version.
| if os.path.exists(_version_file): | |
| ns = {} | |
| with open(_version_file) as f: | |
| exec(f.read(), ns) | |
| return ns.get('__version__') | |
| return '0.0.0' | |
| if os.path.exists(_version_file): | |
| with open(_version_file) as f: | |
| content = f.read() | |
| match = re.search(r'__version__ = "([^"]+)"', content) | |
| if match: | |
| return match.group(1) | |
| return '0.0.0' |
python/setup.py
Outdated
| import os | ||
| import sys |
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.
| python3 -c " | ||
| import setuptools_scm | ||
| version = setuptools_scm.get_version() | ||
| import os |
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.
| version_scheme='release-branch-semver', | ||
| local_scheme='no-local-version' | ||
| ) | ||
| except Exception: |
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.
Catching a broad Exception is generally discouraged as it can mask unexpected errors. It's better to catch a more specific exception. setuptools_scm.get_version() raises a LookupError when it cannot determine the version. You should catch LookupError instead.
| except Exception: | |
| except LookupError: |
Signed-off-by: jac <[email protected]>
0d1d4d9 to
b446cea
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. @@ Coverage Diff @@
## main #1375 +/- ##
==========================================
+ Coverage 91.72% 92.43% +0.71%
==========================================
Files 320 322 +2
Lines 17874 20089 +2215
==========================================
+ Hits 16395 18570 +2175
- Misses 1479 1519 +40
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report in Codecov by Sentry.
🚀 New features to boost your workflow:
|
wxyucs
left a comment
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
594dac7 to
b446cea
Compare
LHT129
left a comment
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
close #1359
Summary by Sourcery
Generate and embed a static Python package version during the build process.
New Features:
Bug Fixes:
Enhancements: