-
-
Notifications
You must be signed in to change notification settings - Fork 923
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
Fix version_info cache invalidation, typing, parsing, and serialization #1838
Merged
Conversation
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 also uses assertRaises as a context manager, but that is just for improved clarity.)
This begins to test the established version_info caching behavior.
This independence is also established caching behavior for version_info.
This reorganization is to facilitate using two separate fake git commands with different versions, in forthcoming tests.
The new test doesn't pass yet, as gitpython-developers#1836 is not yet fixed.
For gitpython-developers#1836. This uses a property with the same logic as before for version_info caching, except that the _version_info backing attribute holds the value None, rather than being unset, for the uncomputed state. This rectifies the inconistency between the property's behavior and the way the associated states are represented by its __setstate__ and __getstate__ methods for pickling. Because the Git class only used LazyMixin as an implementation detail of the version_info attribute, it is removed as a subclass.
Instead of directly accessing the _version_info attribute. This fixes a new test failure since the way the public version_info property uses the _version_info backing attribute has changed, and also shows the usage that is documented (accessing _version_info was never guaranteed to work, and now no longer works as before).
Most of these don't pass yet, as such invalidation isn't implemented yet (gitpython-developers#1829).
This is trickier to test than the other cases, but important enough that I think it deserves its own test.
This also makes the xfail marking for Windows correct.
This enables it to run on Windows, removing the xfail marking. + Rename the test. + Add comments and reformat. The test still does not pass (on any platform) because it is one of the tests of the invalidation feature that is not yet implemented.
That is, that its value is not pickle serialized/deserialized, but always recomputed with a subprocess call the first time it is accessed even on a Git instance that is created by unpickling.
+ Put assertion only on the branch where mypy benefits from it.
This broadens the type annoation on the Git.version_info property, for gitpython-developers#1830. It also revises the docstring for clarity, and continues refactoring and comment changes (also for clarity).
This modifies two existing test cases to include an assertion about the length. These test cases are retained as there is value in testing on output from a real git command rather than only with test doubles. More importantly, this also adds a parameterized test method to check parsing of: - All numeric, shorter than the limit - all fields used. - All numeric, at the limit - all fields used. - All numeric, longer than the limit - extra fields dropped. - Has unambiguous non-numeric - dropped from there on. - Has ambiguous non-numeric, negative int - dropped from there on. - Has ambiguous non-numeric, number+letter - dropped from there on. The cases for parsing when a field is not numeric (or not fully or unambiguously numeric) currently all fail, because the existing logic drops intermediate non-numeric fields (gitpython-developers#1833). Parsing should instead stop at (or, *perhaps* in cases like "2a", after) such fields. When the code is changed to stop at them rather than dropping them and presenting the subsequent field as though it were a previous field, these test cases should also pass.
For gitpython-developers#1833. This makes version_info parsing stop including fields after the first non-numeric field, rather than skipping non-numeric fields and including subsequent numeric fields that then wrongly appear to have the original position and significance of the dropped field. This actually stops at (rather than merely after) a non-numeric field, i.e., potentially parseable fields that are not fully numeric, such as "2a", are stopped at, rather than parsed as "2".
This was referenced Feb 23, 2024
Byron
approved these changes
Feb 23, 2024
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.
Thanks so much for this fix, which was planned with incredible consideration.
The explanation done in the fantastic PR text is very helpful, and so are the tests. I read each one of them this time and found them very graspable. The sprinkled-in comments also helped.
Great work!
renovate bot
referenced
this pull request
in allenporter/flux-local
Mar 31, 2024
[![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [GitPython](https://github.com/gitpython-developers/GitPython) | `==3.1.42` -> `==3.1.43` | [![age](https://developer.mend.io/api/mc/badges/age/pypi/GitPython/3.1.43?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/pypi/GitPython/3.1.43?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/pypi/GitPython/3.1.42/3.1.43?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/GitPython/3.1.42/3.1.43?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes <details> <summary>gitpython-developers/GitPython (GitPython)</summary> ### [`v3.1.43`](https://github.com/gitpython-developers/GitPython/releases/tag/3.1.43) [Compare Source](https://github.com/gitpython-developers/GitPython/compare/3.1.42...3.1.43) #### Particularly Important Changes These are likely to affect you, please do take a careful look. - Issue and test deprecation warnings by [@​EliahKagan](https://github.com/EliahKagan) in [https://github.com/gitpython-developers/GitPython/pull/1886](https://github.com/gitpython-developers/GitPython/pull/1886) - Fix version_info cache invalidation, typing, parsing, and serialization by [@​EliahKagan](https://github.com/EliahKagan) in [https://github.com/gitpython-developers/GitPython/pull/1838](https://github.com/gitpython-developers/GitPython/pull/1838) - Document manual refresh path treatment by [@​EliahKagan](https://github.com/EliahKagan) in [https://github.com/gitpython-developers/GitPython/pull/1839](https://github.com/gitpython-developers/GitPython/pull/1839) - Improve static typing and docstrings related to git object types by [@​EliahKagan](https://github.com/EliahKagan) in [https://github.com/gitpython-developers/GitPython/pull/1859](https://github.com/gitpython-developers/GitPython/pull/1859) #### Other Changes - Test in Docker with Alpine Linux on CI by [@​EliahKagan](https://github.com/EliahKagan) in [https://github.com/gitpython-developers/GitPython/pull/1826](https://github.com/gitpython-developers/GitPython/pull/1826) - Build online docs (RTD) with -W and dependencies by [@​EliahKagan](https://github.com/EliahKagan) in [https://github.com/gitpython-developers/GitPython/pull/1843](https://github.com/gitpython-developers/GitPython/pull/1843) - Suggest full-path refresh() in failure message by [@​EliahKagan](https://github.com/EliahKagan) in [https://github.com/gitpython-developers/GitPython/pull/1844](https://github.com/gitpython-developers/GitPython/pull/1844) - `repo.blame` and `repo.blame_incremental` now accept `None` as the `rev` parameter. by [@​Gaubbe](https://github.com/Gaubbe) in [https://github.com/gitpython-developers/GitPython/pull/1846](https://github.com/gitpython-developers/GitPython/pull/1846) - Make sure diff always uses the default diff driver when `create_patch=True` by [@​can-taslicukur](https://github.com/can-taslicukur) in [https://github.com/gitpython-developers/GitPython/pull/1832](https://github.com/gitpython-developers/GitPython/pull/1832) - Revise docstrings, comments, and a few messages by [@​EliahKagan](https://github.com/EliahKagan) in [https://github.com/gitpython-developers/GitPython/pull/1850](https://github.com/gitpython-developers/GitPython/pull/1850) - Expand what is included in the API Reference by [@​EliahKagan](https://github.com/EliahKagan) in [https://github.com/gitpython-developers/GitPython/pull/1855](https://github.com/gitpython-developers/GitPython/pull/1855) - Restore building of documentation downloads by [@​EliahKagan](https://github.com/EliahKagan) in [https://github.com/gitpython-developers/GitPython/pull/1856](https://github.com/gitpython-developers/GitPython/pull/1856) - Revise type annotations slightly by [@​EliahKagan](https://github.com/EliahKagan) in [https://github.com/gitpython-developers/GitPython/pull/1860](https://github.com/gitpython-developers/GitPython/pull/1860) - Updating regex pattern to handle unicode whitespaces. by [@​jcole-crowdstrike](https://github.com/jcole-crowdstrike) in [https://github.com/gitpython-developers/GitPython/pull/1853](https://github.com/gitpython-developers/GitPython/pull/1853) - Use upgraded pip in test fixture virtual environment by [@​EliahKagan](https://github.com/EliahKagan) in [https://github.com/gitpython-developers/GitPython/pull/1864](https://github.com/gitpython-developers/GitPython/pull/1864) - lint: replace `flake8` with `ruff` check by [@​Borda](https://github.com/Borda) in [https://github.com/gitpython-developers/GitPython/pull/1862](https://github.com/gitpython-developers/GitPython/pull/1862) - lint: switch Black with `ruff-format` by [@​Borda](https://github.com/Borda) in [https://github.com/gitpython-developers/GitPython/pull/1865](https://github.com/gitpython-developers/GitPython/pull/1865) - Update readme and tox.ini for recent tooling changes by [@​EliahKagan](https://github.com/EliahKagan) in [https://github.com/gitpython-developers/GitPython/pull/1868](https://github.com/gitpython-developers/GitPython/pull/1868) - Split tox lint env into three envs, all safe by [@​EliahKagan](https://github.com/EliahKagan) in [https://github.com/gitpython-developers/GitPython/pull/1870](https://github.com/gitpython-developers/GitPython/pull/1870) - Slightly broaden Ruff, and update and clarify tool configuration by [@​EliahKagan](https://github.com/EliahKagan) in [https://github.com/gitpython-developers/GitPython/pull/1871](https://github.com/gitpython-developers/GitPython/pull/1871) - Add a "doc" extra for documentation build dependencies by [@​EliahKagan](https://github.com/EliahKagan) in [https://github.com/gitpython-developers/GitPython/pull/1872](https://github.com/gitpython-developers/GitPython/pull/1872) - Describe `Submodule.__init__` parent_commit parameter by [@​EliahKagan](https://github.com/EliahKagan) in [https://github.com/gitpython-developers/GitPython/pull/1877](https://github.com/gitpython-developers/GitPython/pull/1877) - Include TagObject in git.types.Tree_ish by [@​EliahKagan](https://github.com/EliahKagan) in [https://github.com/gitpython-developers/GitPython/pull/1878](https://github.com/gitpython-developers/GitPython/pull/1878) - Improve Sphinx role usage, including linking Git manpages by [@​EliahKagan](https://github.com/EliahKagan) in [https://github.com/gitpython-developers/GitPython/pull/1879](https://github.com/gitpython-developers/GitPython/pull/1879) - Replace all wildcard imports with explicit imports by [@​EliahKagan](https://github.com/EliahKagan) in [https://github.com/gitpython-developers/GitPython/pull/1880](https://github.com/gitpython-developers/GitPython/pull/1880) - Clarify how tag objects are usually tree-ish and commit-ish by [@​EliahKagan](https://github.com/EliahKagan) in [https://github.com/gitpython-developers/GitPython/pull/1881](https://github.com/gitpython-developers/GitPython/pull/1881) #### New Contributors - [@​Gaubbe](https://github.com/Gaubbe) made their first contribution in [https://github.com/gitpython-developers/GitPython/pull/1846](https://github.com/gitpython-developers/GitPython/pull/1846) - [@​can-taslicukur](https://github.com/can-taslicukur) made their first contribution in [https://github.com/gitpython-developers/GitPython/pull/1832](https://github.com/gitpython-developers/GitPython/pull/1832) - [@​jcole-crowdstrike](https://github.com/jcole-crowdstrike) made their first contribution in [https://github.com/gitpython-developers/GitPython/pull/1853](https://github.com/gitpython-developers/GitPython/pull/1853) - [@​Borda](https://github.com/Borda) made their first contribution in [https://github.com/gitpython-developers/GitPython/pull/1862](https://github.com/gitpython-developers/GitPython/pull/1862) **Full Changelog**: gitpython-developers/GitPython@3.1.42...3.1.43 </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://developer.mend.io/github/allenporter/flux-local). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy4yNjkuMiIsInVwZGF0ZWRJblZlciI6IjM3LjI2OS4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiJ9--> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
lettuce-bot bot
referenced
this pull request
in lettuce-financial/github-bot-signed-commit
Apr 1, 2024
[![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [GitPython](https://github.com/gitpython-developers/GitPython) | `==3.1.42` -> `==3.1.43` | [![age](https://developer.mend.io/api/mc/badges/age/pypi/GitPython/3.1.43?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/pypi/GitPython/3.1.43?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/pypi/GitPython/3.1.42/3.1.43?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/GitPython/3.1.42/3.1.43?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes <details> <summary>gitpython-developers/GitPython (GitPython)</summary> ### [`v3.1.43`](https://github.com/gitpython-developers/GitPython/releases/tag/3.1.43) [Compare Source](https://github.com/gitpython-developers/GitPython/compare/3.1.42...3.1.43) #### Particularly Important Changes These are likely to affect you, please do take a careful look. - Issue and test deprecation warnings by [@​EliahKagan](https://github.com/EliahKagan) in [https://github.com/gitpython-developers/GitPython/pull/1886](https://github.com/gitpython-developers/GitPython/pull/1886) - Fix version_info cache invalidation, typing, parsing, and serialization by [@​EliahKagan](https://github.com/EliahKagan) in [https://github.com/gitpython-developers/GitPython/pull/1838](https://github.com/gitpython-developers/GitPython/pull/1838) - Document manual refresh path treatment by [@​EliahKagan](https://github.com/EliahKagan) in [https://github.com/gitpython-developers/GitPython/pull/1839](https://github.com/gitpython-developers/GitPython/pull/1839) - Improve static typing and docstrings related to git object types by [@​EliahKagan](https://github.com/EliahKagan) in [https://github.com/gitpython-developers/GitPython/pull/1859](https://github.com/gitpython-developers/GitPython/pull/1859) #### Other Changes - Test in Docker with Alpine Linux on CI by [@​EliahKagan](https://github.com/EliahKagan) in [https://github.com/gitpython-developers/GitPython/pull/1826](https://github.com/gitpython-developers/GitPython/pull/1826) - Build online docs (RTD) with -W and dependencies by [@​EliahKagan](https://github.com/EliahKagan) in [https://github.com/gitpython-developers/GitPython/pull/1843](https://github.com/gitpython-developers/GitPython/pull/1843) - Suggest full-path refresh() in failure message by [@​EliahKagan](https://github.com/EliahKagan) in [https://github.com/gitpython-developers/GitPython/pull/1844](https://github.com/gitpython-developers/GitPython/pull/1844) - `repo.blame` and `repo.blame_incremental` now accept `None` as the `rev` parameter. by [@​Gaubbe](https://github.com/Gaubbe) in [https://github.com/gitpython-developers/GitPython/pull/1846](https://github.com/gitpython-developers/GitPython/pull/1846) - Make sure diff always uses the default diff driver when `create_patch=True` by [@​can-taslicukur](https://github.com/can-taslicukur) in [https://github.com/gitpython-developers/GitPython/pull/1832](https://github.com/gitpython-developers/GitPython/pull/1832) - Revise docstrings, comments, and a few messages by [@​EliahKagan](https://github.com/EliahKagan) in [https://github.com/gitpython-developers/GitPython/pull/1850](https://github.com/gitpython-developers/GitPython/pull/1850) - Expand what is included in the API Reference by [@​EliahKagan](https://github.com/EliahKagan) in [https://github.com/gitpython-developers/GitPython/pull/1855](https://github.com/gitpython-developers/GitPython/pull/1855) - Restore building of documentation downloads by [@​EliahKagan](https://github.com/EliahKagan) in [https://github.com/gitpython-developers/GitPython/pull/1856](https://github.com/gitpython-developers/GitPython/pull/1856) - Revise type annotations slightly by [@​EliahKagan](https://github.com/EliahKagan) in [https://github.com/gitpython-developers/GitPython/pull/1860](https://github.com/gitpython-developers/GitPython/pull/1860) - Updating regex pattern to handle unicode whitespaces. by [@​jcole-crowdstrike](https://github.com/jcole-crowdstrike) in [https://github.com/gitpython-developers/GitPython/pull/1853](https://github.com/gitpython-developers/GitPython/pull/1853) - Use upgraded pip in test fixture virtual environment by [@​EliahKagan](https://github.com/EliahKagan) in [https://github.com/gitpython-developers/GitPython/pull/1864](https://github.com/gitpython-developers/GitPython/pull/1864) - lint: replace `flake8` with `ruff` check by [@​Borda](https://github.com/Borda) in [https://github.com/gitpython-developers/GitPython/pull/1862](https://github.com/gitpython-developers/GitPython/pull/1862) - lint: switch Black with `ruff-format` by [@​Borda](https://github.com/Borda) in [https://github.com/gitpython-developers/GitPython/pull/1865](https://github.com/gitpython-developers/GitPython/pull/1865) - Update readme and tox.ini for recent tooling changes by [@​EliahKagan](https://github.com/EliahKagan) in [https://github.com/gitpython-developers/GitPython/pull/1868](https://github.com/gitpython-developers/GitPython/pull/1868) - Split tox lint env into three envs, all safe by [@​EliahKagan](https://github.com/EliahKagan) in [https://github.com/gitpython-developers/GitPython/pull/1870](https://github.com/gitpython-developers/GitPython/pull/1870) - Slightly broaden Ruff, and update and clarify tool configuration by [@​EliahKagan](https://github.com/EliahKagan) in [https://github.com/gitpython-developers/GitPython/pull/1871](https://github.com/gitpython-developers/GitPython/pull/1871) - Add a "doc" extra for documentation build dependencies by [@​EliahKagan](https://github.com/EliahKagan) in [https://github.com/gitpython-developers/GitPython/pull/1872](https://github.com/gitpython-developers/GitPython/pull/1872) - Describe `Submodule.__init__` parent_commit parameter by [@​EliahKagan](https://github.com/EliahKagan) in [https://github.com/gitpython-developers/GitPython/pull/1877](https://github.com/gitpython-developers/GitPython/pull/1877) - Include TagObject in git.types.Tree_ish by [@​EliahKagan](https://github.com/EliahKagan) in [https://github.com/gitpython-developers/GitPython/pull/1878](https://github.com/gitpython-developers/GitPython/pull/1878) - Improve Sphinx role usage, including linking Git manpages by [@​EliahKagan](https://github.com/EliahKagan) in [https://github.com/gitpython-developers/GitPython/pull/1879](https://github.com/gitpython-developers/GitPython/pull/1879) - Replace all wildcard imports with explicit imports by [@​EliahKagan](https://github.com/EliahKagan) in [https://github.com/gitpython-developers/GitPython/pull/1880](https://github.com/gitpython-developers/GitPython/pull/1880) - Clarify how tag objects are usually tree-ish and commit-ish by [@​EliahKagan](https://github.com/EliahKagan) in [https://github.com/gitpython-developers/GitPython/pull/1881](https://github.com/gitpython-developers/GitPython/pull/1881) #### New Contributors - [@​Gaubbe](https://github.com/Gaubbe) made their first contribution in [https://github.com/gitpython-developers/GitPython/pull/1846](https://github.com/gitpython-developers/GitPython/pull/1846) - [@​can-taslicukur](https://github.com/can-taslicukur) made their first contribution in [https://github.com/gitpython-developers/GitPython/pull/1832](https://github.com/gitpython-developers/GitPython/pull/1832) - [@​jcole-crowdstrike](https://github.com/jcole-crowdstrike) made their first contribution in [https://github.com/gitpython-developers/GitPython/pull/1853](https://github.com/gitpython-developers/GitPython/pull/1853) - [@​Borda](https://github.com/Borda) made their first contribution in [https://github.com/gitpython-developers/GitPython/pull/1862](https://github.com/gitpython-developers/GitPython/pull/1862) **Full Changelog**: gitpython-developers/GitPython@3.1.42...3.1.43 </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about these updates again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://developer.mend.io/github/lettuce-financial/github-bot-signed-commit). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy4yNjkuMiIsInVwZGF0ZWRJblZlciI6IjM3LjI2OS4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiJ9-->
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
📣highlight-in-changelog📣
Specifically highlight this PR in the changelog after it was created
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.
Fixes #1829 - cache invalidation
Fixes #1830 - typing
Fixes #1833 - parsing
Fixes #1836 - serialization
Much of the design in the fixes for #1830, #1833, and #1836, as well as why I think it makes sense to include them here with #1829, is already largely covered in the discussion/comments in those three issues.
Design goals for #1829
For #1829, which I would regard to be the biggest of the changes here, and which is the change for which the most additional code is added to the test suite, I made sure to preserve three important properties of the code:
Git
instances. Changing the way refreshing itself fundamentally works is beyond the scope of this PR and would also be a breaking change that I think could only be made in a new major release, and there are good reasons for refreshing to be global. Allowing a per-instance overriding refresh might be useful, but would be much more complicated than the current system unless accompanied by other design changes that would likely be breaking.version_info
attributes. This has been explicitly promised in theversion_info
docstring for a long time, with the intention that accessingversion_info
be understood as cheap, and it is likely that substantial code exists that assumes it is cheap (or that throttles parts of GitPython that use it and benefit from it being cheap).Git
instances, and accessingversion_info
on oneGit
instance never has any effect on what happens whenversion_info
is accessed on anotherGit
instance. Since the actual validity of cached version information depends on when the global operation of refreshing was last done, it may seem like the caching should be made global as well. But this can lead to some new problems, such that I suggest it either be put off until later or never done.Why not cache globally?
To expand on why the that third property is something I've taken care to preserve, these are the three problems I anticipate will arise if the caching were to be made global, in increasing order of significance:
Git().version_info
always makes a subprocess call to get fresh information. Besides being one of the ways this behavior may have been relied on already, changing it would also, in practice, lead to code that uses GitPython being written to refresh more often, which would have the opposite effect on speed and resource usage than is intended by caching.The cache invalidation implementation
Rather than having the refresh operation reach out to all
Git
instances to invalidate their caches, I've added a_refresh_token
class attribute that is set and reset along withGIT_PYTHON_GIT_EXECUTABLE
during a refresh, and added a_version_info_token
instance attribute (that, like_version_info
, is excluded from pickle serialization).When
version_info
is accessed, if_version_info_token
is the same object as_refresh_token
, then the cache is valid and the cached value in_version_info
is returned. Otherwise, the cache is invalid, andgit version
is run to obtain the version; the version information is cached in_version_info
,_version_info_token
is updated to_refresh_token
, and the newly computed value is returned.The
_version_info_token
instance attribute starts out asNone
to simplify debugging and unpickling. Its value is always eitherNone
or a value that has at some point been the value of the_refresh_token
class attribute. The_refresh_token
class attribute is neverNone
, but always a direct instance ofobject
, even before the first refresh, which ensures it never wrongly matches the initialNone
value of a_version_info_token
instance attribute.A successful refresh always causes
_refresh_token
to differ from any_version_info_token
that exists at that time. This is important--and, in particular, these tokens must not be tied to the value ofGit.GIT_PYTHON_GIT_EXECUTABLE
--because refreshing must properly update for a change to which git implementation is accessed by the same command or even via the same path. The most common and important such case is probably whenGIT_PYTHON_GIT_EXECUTABLE
is the default value of"git"
, and git has been upgraded or a new version installed in a$PATH
directory.Dropping the
LazyMixin
base classAn aspect of this PR that I recommend be double-checked in review is my assumption that
Git
havingLazyMixin
as a base class can be considered a mere implementation detail ofGit
, and thus that it is non-breaking to remove inheritance from that base class.I removed it because it was only being used to implement caching for the
version_info
property. It is well-suited to some forms of caching elsewhere in GitPython, but not well-suited to the changes needed inversion_info
for #1829 and #1836 (as discussed in #1836). Because I stopped usingLazyMixin
for this, it was no longer used for anything. Removing it simplified the code, though if necessary it could be brought back and just not used for anything. (The newversion_info
implementation would still work withLazyMixin
present but unused.)Other considerations
Keeping the
super().__init__
callGit.__init__
contains this line:GitPython/git/cmd.py
Line 778 in afa5754
This superficially appears related to the use of
LazyMixin
, but I believe that is not the case.LazyMixin
, which is provided by the gitdb dependency, at least currently does not define an__init__
method. Furthermore, such asuper()
call was present even beforeLazyMixin
was brought in as a base class in e583a9e to provide caching for theversion_info
property (which was also introduced at that time). At that time,Git
had no base class besidesobject
, yet this was still present.Calling
super().__init__()
helps with cooperative multiple inheritance in some cases. It is sometimes done even in the absence of a specific need, though sometimes it's not the correct logic, if the next class in the MRO has an__init__
that is not callable with no arguments (or, rather, with only aself
argument). Furthermore, you've given feedback that I have understood to mean that havingGit
support inheritance is not a design priority.So I don't think this
super().__init__()
is present based on a general preference for it. Instead, looking back to when it was first introduced, this was in the first commit that had theGit
class, 039bfe3. At that time,Git
did have a base class,MethodMissingMixin
.It may be that it should either be removed or commented with an explanation. But I think it is sufficiently unconnected to
LazyMixin
(andversion_info
) that no change should be made to it in connection with the changes in this PR.Effect of directly accessing
_version_info
has changedWhen
LazyMixin
was used, reading from the nonpublic_version_info
attribute behaved the same as reading fromversion_info
. Code outside theGit
class should not do that, but there is one place in GitPython's own tests where it did:GitPython/test/test_index.py
Line 531 in afa5754
That had to be changed to use
version_info
instead. If necessary, a different backing attribute could be used, and_version_info
could be made an undocumented alternative toversion_info
that issues a warning but otherwise behaves the same. However, it seems to me that this is not necessary;_version_info
was never advertised as part of the public interface ofGit
, as far as I can tell.GIT_PYTHON_GIT_EXECUTABLE
as an instance attribute is not supportedIf
Git
instances could have their ownGIT_PYTHON_GIT_EXECUTABLE
attributes, then they would be used instead of the same-named class attribute that is written in a refresh. This cannot happen on a directGit
instance, becauseGit
is slotted and has no such slot (and cannot, since the descriptor would conflict with the class attribute). But it is possible to make a subclass ofGit
whereGIT_PYTHON_GIT_EXECUTABLE
is an instance attribute. This has never been supported and should not be done, and will likely work poorly in other ways, but it is possible for caching to "support" it by detecting that this is the case and just never cachingversion_info
.I have neither done this nor commented about it, and even this mention of it may be gratuitous. However, in general the effect of attempting to set what is assumed to be a class attribute on an instance should be considered. My reasoning for not dealing with this at all is that, even if a reasonable use case arises to derive from
Git
and shadow base-class class attributes as instance attributes (which seems unlikely), the onus is then on the author of the derived class to override base-class members likeversion_info
accordingly.