-
-
Notifications
You must be signed in to change notification settings - Fork 911
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
We appear to import the submodule version of gitdb (but never do) #1717
Comments
Thanks so much for uncovering this issue and for the analysis of possible solutions! Somehow I thought that the I hope you will feel comfortable enough to go ahead with your preferred solution, with documentation update or not, whatever feels best. Having this documented somewhere (i.e. in README right now) seems good enough. To me it's most important that the sys.path altering code goes away as affecting global interpreter settings as library certainly isn't anything I'd endorse today. |
This removes the logic that, under some circumstances when not using a version from PyPI, would insert the location of the gitdb git-submodule near the front of sys.path. (As noted in gitpython-developers#1717, the specific way this was being done was not causing the git-submodule's version of gitdb to actually be used. But it was still modifying sys.path, which this now prevents.)
This removes the logic that, under some circumstances when not using a version from PyPI, would insert the location of the gitdb git-submodule near the front of sys.path. (As noted in gitpython-developers#1717, the specific way this was being done was not causing the git-submodule's version of gitdb to actually be used. But it was still modifying sys.path, which this now prevents.) The installation test, which had verified the insertion into sys.path, is modified accordingly, except that for now the check that the very first sys.path entry is undisturbed is kept in place.
This removes the logic that, under some (most) circumstances when not using a version from PyPI, would insert the location of the gitdb git-submodule near the front of sys.path. (As noted in gitpython-developers#1717, the specific way this was being done was not causing the git-submodule's version of gitdb to actually be used. But it was still modifying sys.path, which this now prevents.) The installation test, which had verified the insertion into sys.path, is modified accordingly, except that for now the check that the very first sys.path entry is undisturbed is kept in place.
This removes the logic that appended the git submodule directory for smmap to sys.path under most circumstances when the version of gitdb was not from PyPI. Now gitdb does not modify sys.path. See gitpython-developers/GitPython#1717 and gitpython-developers/GitPython#1720 for context. This change is roughly equivalent to the change to GitPython, though as noted the behavior being eliminated is subtly different here and there.
I've opened #1720 and gitdb#102 for this.
#1720 includes an addition to GitPython's I haven't added anything about this to the gitdb documentation (in gitdb#102 or otherwise).
I agree, though fortunately this only happened when non-PyPI versions were used. |
This removes the logic that, under some (most) circumstances when not using a version from PyPI, would insert the location of the gitdb git-submodule near the front of sys.path. (As noted in gitpython-developers#1717, the specific way this was being done was not causing the git-submodule's version of gitdb to actually be used. But it was still modifying sys.path, which this now prevents.) The installation test, which had verified the insertion into sys.path, is modified accordingly, except that for now the check that the very first sys.path entry is undisturbed is kept in place.
Summary
git/__init__.py
imports exceptions indirectly fromgitdb
before it adjustssys.path
, causing the code from thegitdb
git-submodule not to be used under any circumstances.Although this could probably be fixed by moving
gitdb.exc
imports below the_init_externals
call, I recommend against it, because this is an opportunity to further decrease the project's use and dependence on its git-submodules. This is to say that I suggest viewing this as a bug due to the code appearing to do something it doesn't, rather than as a bug due to the code not doing something it should. Even without removing the git-submodule--which GitPython's tests need--the logic to insert it insys.path
could simply be removed.Details
The unit tests use the direct
gitdb
git-submodule as well as the indirectsmmap
git-submodule through it (and for this reason the git-submodules cannot be immediately removed). However,git/__init__.py
also appears to use them by cauisnggitdb
to be imported from thegitdb
git-submodule under some circumstances:GitPython/git/__init__.py
Lines 17 to 38 in 44102f3
The intent is that, then, importing Python modules some of which contain
gitdb
imports should use thegitdb
Python module from thegitdb
git-submodule. Furthermore, it is intended that this happen even if thegitdb
package is installed, as evidenced by how thegit/ext/gitdb
directory is inserted near the beginning ofsys.path
. The idea is that the git-submodule version ofgitdb
would be used in these immediately subsequent imports:GitPython/git/__init__.py
Lines 40 to 62 in 44102f3
However, that does not happen. The code from the
gitdb
git-submodule is actually never used, because before any of that, we importgit.exc
:GitPython/git/__init__.py
Line 8 in 44102f3
git.exc
imports from thegitdb
Python module:GitPython/git/exc.py
Lines 8 to 18 in 44102f3
Although that code was touched in #1659, the change there did not affect this behavior in any way. Furthermore, the imports in
git.exc
fromgitdb.exc
are not the only imports ingit.exc
that causegitdb
to be imported. For example,git.exc
also imports fromgit.util
, which imports fromgitdb.util
.Because the
from git.exc import *
importsgitdb
beforesys.path
is modified, the installedgitdb
dependency is used, rather than the git-submodule version ofgitdb
. Subsequent imports reuse the already importedgitdb
module. That the installedgitdb
is being used can be verified in a REPL by importinggit
and thengitdb
and checkinggitdb.__file__
:It is using
gitdb
from the environment'ssite-packages
directory, which is the installed version. This alternative demonstration (in a new REPL) is no more robust, but it is perhaps more compelling since no code outside of GitPython ever importsgitdb
:sys.path
was modified, just too late to have had an effect. Checking it in the same REPL after importinggit
reveals:Possible solutions
Restoring the behavior of using the git-submodule dependency (not my recommendation)
Because the actual change to
sys.path
does take effect, if it were added before anything were imported fromgitdb
then it would have worked. This experiment, done in a new REPL, verifies this:It was probably working prior to 6752fad, which added that import from
gitdb.exc
. So moving thefrom git.exc import *
line below the_init_externals()
call would probably be sufficient to cause thegitdb
git-submodule to be used, and used under the exact circumstances under which it was intended, and currently wrongly appears, to be used.But I recommend against that. 6752fad was part of #1229, which was merged well over two years ago. At least if this issue has not been discovered before now, then importing
gitdb
from the git-submodule (which is relevant, after all, only to people developing GitPython) is not something anyone is relying on as the default behavior.Restoring that behavior but in a weakened form (not my recommendation)
gitdb
contains similar code, for itssmmap
dependency. That code ingitdb
does work, because there is no direct or indirect import ofsmmap
before it runs. However, its logic is different. Rather than inserting thesmmap
git-submodule directory near the front of the path as GitPython does......it instead inserts it at the end, where a package installed any other way would take precedence:
So we could move the import of exception types below the
_init_externals
call, but also weaken the logic in_init_externals
to match the behavior of the corresponding logic ingitdb
.But I recommend against this, too. I'd much rather do the simpler and, in my opinion, more useful thing of eliminating this logic altogether. I think this is the best approach even if no corresponding change is made in
gitdb
, but that the same thing should be done ingitdb
, and for the same reason.Removing the
_init_externals
logic and documenting editable installation of dependenciesI recommend
_init_externals
be removed, and in the infrequent (but plausible) case that one wants local changes to thegitdb
git-submodule to be used when the local GitPython code is run, one can install thegitdb
dependency by making an editable install with the git-submodule path, rather than allowingpip
to automatically installgitdb
from PyPI. (See related discussion in gitdb#90 and smmap#51.)That is, pass
-e git/ext/gitdb
in apip install
command. For example:More likely than
pip install -e . -e git/ext/gitdb
is that one would want to usepip install -e ".[test]" -e git/ext/gitdb
, which I have also verified works. But I've shown the simpler command because the optional dependencies from thetest
extra make the output quite long.This can be done in a separate
pip install
command, either before or after.
is installed:pip install -e git/ext/gitdb
is run first, thenpip install -e .
orpip install -e .[test]
will use the editably installed git-submodule version ofgitdb
, because the dependency is satisfied already (at least unless GitPython declares a version range for the gitdb dependency that does not include the version in the git-submodule, which I have not tested).pip install -e git/ext/gitdb
is run second, then because the editable install from that path was given explicitly,pip
will uninstall the version from PyPI (thatpip install -e .
installed to satisfy the dependency) and perform the editable install.So it works in one or two commands and in any order.
Of course, if one also wants an editable install of
smmap
from the recursive submodule to be used, then one must tellpip
to do an editable install from its path as well.Having developers who want the git-submodule versions of gitdb and/or smmap to be used just install them editably has the additional advantage that static type checkers, at least if installed in the same environment or otherwise aware of what is installed in it (which they should be), could know that the git-submodule version is being used when it is. (This relates to the topic of #1716, though there is no order dependency for fixing these issues.)
In conclusion...
I recommend that
_init_externals
be removed, imports be regrouped and reordered in a way that makes it easier to understand and edit them, and the technique of making editable installs ofgitdb
and/orsmmap
dependencies from git-submodules be documented somewhere in GitPython's documentation as something that may occasionally be useful when working on GitPython and its dependencies together.Since this would still not commonly be done, I'm not sure it really belongs in
README.md
, and perhaps it should only go in documentation indoc/
. However, that documentation is out of date with respect to installation and development practices, so if this bug is to be fixed before the documentation indoc/
is revised and updated, then it may make sense to add the information about this toREADME.md
, even if it will be moved out ofREADME.md
later. Alternatively, documentation could be omitted until then, or it could be noted in comments ingit/__init__.py
and not otherwise documented, or fixing this could be put off altogether until thedoc/
documentation is revised and updated (though I would least prefer that option).The text was updated successfully, but these errors were encountered: