Closed
Description
(originally reported in #508)
Index.add()
code relying on destructors leaves stray lock-file if invoked with invalid args in py3.5. The following code reproduces it:
import git
r = git Repo()
def add_bad_blob():
r.index.add([git.Blob(r, b'f' * 20, 'bad-permissions', 'foo')])
try:
## 1st fail on purpose adding into index.
add_bad_blob()
except Exception as ex:
"""
git\index\base.py in add() @799
git\index\base.py in write() @213
git\index\base.py in _serialize() @180
git\index\fun.py in write_cache() @133
"""
assert "required argument is not an integer" in str(ex)
try:
## 2nd time fails due to stray lock-file.
add_bad_blob()
except Exception as ex:
assert "index.lock' could not be obtained" in str(ex)
import gc
gc.collect()
try:
## After GC, lock-file gone.
add_bad_blob()
except Exception as ex:
assert "required argument is not an integer" in str(ex)
The problem originates at git/index/base.py#L211-214
, and can be amended by enclosing them in a try-finally
block:
stream = lfd.open(write=True, stream=True)
ok= False
try:
self._serialize(stream, ignore_extension_data)
ok = True
finally:
if not ok:
lfd.rollback()
This issue is a show-stopper, and impossible to workaround even when applying the advice written in the manual about invokint ``del()manually, because the
LockedFD` variable instance goes out of scope.
So either
a) the project sources are modified, or
b) try-catch and explicitly invoke GC then, which is pretty ugly.
A more proper solution would be to retrifit LockedFD
as a context-manager.