3939__all__ = ("stream_copy" ,"join_path" ,"to_native_path_windows" ,"to_native_path_linux" ,
4040"join_path_native" ,"Stats" ,"IndexFileSHA1Writer" ,"Iterable" ,"IterableList" ,
4141"BlockingLockFile" ,"LockFile" ,'Actor' ,'get_user_id' ,'assure_directory_exists' ,
42- 'RemoteProgress' ,'rmtree' ,'WaitGroup' ,'unbare_repo' )
42+ 'RemoteProgress' ,'CallableRemoteProgress' , ' rmtree' ,'WaitGroup' ,'unbare_repo' )
4343
4444#{ Utility Methods
4545
@@ -160,7 +160,6 @@ def finalize_process(proc, **kwargs):
160160
161161
162162class RemoteProgress (object ):
163-
164163"""
165164 Handler providing an interface to parse progress information emitted by git-push
166165 and git-fetch and to dispatch callbacks allowing subclasses to react to the progress.
@@ -174,12 +173,11 @@ class RemoteProgress(object):
174173DONE_TOKEN = 'done.'
175174TOKEN_SEPARATOR = ', '
176175
177- __slots__ = ("_cur_line" ,"_seen_ops" , "__progress_function" )
176+ __slots__ = ("_cur_line" ,"_seen_ops" )
178177re_op_absolute = re .compile (r"(remote: )?([\w\s]+):\s+()(\d+)()(.*)" )
179178re_op_relative = re .compile (r"(remote: )?([\w\s]+):\s+(\d+)% \((\d+)/(\d+)\)(.*)" )
180179
181- def __init__ (self ,progress_function = None ):
182- self .__progress_function = progress_function if progress_function else self .update
180+ def __init__ (self ):
183181self ._seen_ops = list ()
184182self ._cur_line = None
185183
@@ -268,10 +266,10 @@ def _parse_progress_line(self, line):
268266# END end message handling
269267message = message .strip (self .TOKEN_SEPARATOR )
270268
271- self .__progress_function (op_code ,
272- cur_count and float (cur_count ),
273- max_count and float (max_count ),
274- message )
269+ self .update (op_code ,
270+ cur_count and float (cur_count ),
271+ max_count and float (max_count ),
272+ message )
275273# END for each sub line
276274return failed_lines
277275
@@ -314,7 +312,18 @@ def update(self, op_code, cur_count, max_count=None, message=''):
314312
315313 You may read the contents of the current line in self._cur_line"""
316314pass
317-
315+
316+
317+ class CallableRemoteProgress (RemoteProgress ):
318+ """An implementation forwarding updates to any callable"""
319+ __slots__ = ('_callable' )
320+
321+ def __init__ (self ,fn ):
322+ self ._callable = fn
323+
324+ def update (self ,* args ,** kwargs ):
325+ self ._callable (* args ,** kwargs )
326+
318327
319328class Actor (object ):
320329