Skip to content

Commit dcf2c3b

Browse files
committed
config: GitConfigReader now allows to override its lock-type. By default it uses a 'failing' lock file, but now its possible to easily put a blocking lock file in its place
1 parent a38a005 commit dcf2c3b

File tree

3 files changed

+26
-10
lines changed

3 files changed

+26
-10
lines changed

lib/git/config.py

+17-8
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ def flush_changes(self, *args, **kwargs):
7272

7373

7474

75-
class GitConfigParser(cp.RawConfigParser, LockFile):
75+
class GitConfigParser(cp.RawConfigParser, object):
7676
"""
7777
Implements specifics required to read git style configuration files.
7878
@@ -91,6 +91,15 @@ class GitConfigParser(cp.RawConfigParser, LockFile):
9191
"""
9292
__metaclass__ = _MetaParserBuilder
9393

94+
95+
#{ Configuration
96+
# The lock type determines the type of lock to use in new configuration readers.
97+
# They must be compatible to the LockFile interface.
98+
# A suitable alternative would be the BlockingLockFile
99+
t_lock = LockFile
100+
101+
#} END configuration
102+
94103
OPTCRE = re.compile(
95104
r'\s?(?P<option>[^:=\s][^:=]*)' # very permissive, incuding leading whitespace
96105
r'\s*(?P<vi>[:=])\s*' # any number of space/tab,
@@ -102,7 +111,7 @@ class GitConfigParser(cp.RawConfigParser, LockFile):
102111

103112
# list of RawConfigParser methods able to change the instance
104113
_mutating_methods_ = ("add_section", "remove_section", "remove_option", "set")
105-
__slots__ = ("_sections", "_defaults", "_file_or_files", "_read_only","_is_initialized")
114+
__slots__ = ("_sections", "_defaults", "_file_or_files", "_read_only","_is_initialized", '_lock')
106115

107116
def __init__(self, file_or_files, read_only=True):
108117
"""
@@ -125,7 +134,7 @@ def __init__(self, file_or_files, read_only=True):
125134
self._file_or_files = file_or_files
126135
self._read_only = read_only
127136
self._is_initialized = False
128-
137+
self._lock = None
129138

130139
if not read_only:
131140
if isinstance(file_or_files, (tuple, list)):
@@ -136,9 +145,9 @@ def __init__(self, file_or_files, read_only=True):
136145
file_or_files = file_or_files.name
137146
# END get filename from handle/stream
138147
# initialize lock base - we want to write
139-
LockFile.__init__(self, file_or_files)
148+
self._lock = self.t_lock(file_or_files)
140149

141-
self._obtain_lock_or_raise()
150+
self._lock._obtain_lock()
142151
# END read-only check
143152

144153

@@ -148,7 +157,7 @@ def __del__(self):
148157
"""
149158
# checking for the lock here makes sure we do not raise during write()
150159
# in case an invalid parser was created who could not get a lock
151-
if self.read_only or not self._has_lock():
160+
if self.read_only or not self._lock._has_lock():
152161
return
153162

154163
try:
@@ -157,7 +166,7 @@ def __del__(self):
157166
except IOError,e:
158167
print "Exception during destruction of GitConfigParser: %s" % str(e)
159168
finally:
160-
self._release_lock()
169+
self._lock._release_lock()
161170

162171
def optionxform(self, optionstr):
163172
"""
@@ -303,7 +312,7 @@ def write(self):
303312
a file lock
304313
"""
305314
self._assure_writable("write")
306-
self._obtain_lock_or_raise()
315+
self._lock._obtain_lock()
307316

308317

309318
fp = self._file_or_files

lib/git/utils.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -163,13 +163,20 @@ def _obtain_lock_or_raise(self):
163163

164164
self._owns_lock = True
165165

166+
def _obtain_lock(self):
167+
"""
168+
The default implementation will raise if a lock cannot be obtained.
169+
Subclasses may override this method to provide a different implementation
170+
"""
171+
return self._obtain_lock_or_raise()
172+
166173
def _release_lock(self):
167174
"""
168175
Release our lock if we have one
169176
"""
170177
if not self._has_lock():
171178
return
172-
179+
173180
os.remove(self._lock_file_path())
174181
self._owns_lock = False
175182

test/git/test_config.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ def test_read_write(self):
3838
self.failUnlessRaises(IOError, GitConfigParser, file_obj, read_only = False)
3939

4040
# should still have a lock and be able to make changes
41-
assert w_config._has_lock()
41+
assert w_config._lock._has_lock()
4242

4343
# changes should be written right away
4444
sname = "my_section"

0 commit comments

Comments
 (0)