30
30
31
31
# Standard Library
32
32
from contextlib import contextmanager
33
+ from functools import wraps
33
34
34
35
# pygit2
35
36
from ._pygit2 import Oid
@@ -134,18 +135,38 @@ def git_remote_callbacks(callbacks):
134
135
# and keep the exception, to be re-raised later.
135
136
#
136
137
138
+ def callback_proxy (f ):
139
+ @wraps (f )
140
+ def wrapper (* args ):
141
+ data = ffi .from_handle (args [- 1 ])
142
+ args = args [:- 1 ] + (data ,)
143
+ try :
144
+ return f (* args )
145
+ except Passthrough :
146
+ # A user defined callback can raise Passthrough to decline to act;
147
+ # then libgit2 will behave as if there was no callback set in the
148
+ # first place.
149
+ return C .GIT_PASSTHROUGH
150
+ except Exception as e :
151
+ # Keep the exception to be re-raised later, and inform libgit2 that
152
+ # the user defined callback has failed.
153
+ data ._stored_exception = e
154
+ return C .GIT_EUSER
155
+
156
+ return wrapper
157
+
158
+
137
159
@ffi .def_extern ()
160
+ @callback_proxy
138
161
def _certificate_cb (cert_i , valid , host , data ):
139
- self = ffi .from_handle (data )
140
-
141
162
# We want to simulate what should happen if libgit2 supported pass-through for
142
163
# this callback. For SSH, 'valid' is always False, because it doesn't look
143
164
# at known_hosts, but we do want to let it through in order to do what libgit2 would
144
165
# if the callback were not set.
145
166
try :
146
167
is_ssh = cert_i .cert_type == C .GIT_CERT_HOSTKEY_LIBSSH2
147
168
148
- certificate_check = getattr (self , 'certificate_check' , None )
169
+ certificate_check = getattr (data , 'certificate_check' , None )
149
170
if not certificate_check :
150
171
raise Passthrough
151
172
@@ -160,105 +181,71 @@ def _certificate_cb(cert_i, valid, host, data):
160
181
return 0
161
182
else :
162
183
return C .GIT_ECERTIFICATE
163
- except Exception as e :
164
- self ._stored_exception = e
165
- return C .GIT_EUSER
166
184
167
185
return 0
168
186
169
187
170
188
@ffi .def_extern ()
189
+ @callback_proxy
171
190
def _credentials_cb (cred_out , url , username , allowed , data ):
172
- self = ffi .from_handle (data )
173
-
174
- credentials = getattr (self , 'credentials' , None )
191
+ credentials = getattr (data , 'credentials' , None )
175
192
if not credentials :
176
193
return 0
177
194
178
- try :
179
- ccred = get_credentials (credentials , url , username , allowed )
180
- cred_out [0 ] = ccred [0 ]
181
- except Passthrough :
182
- return C .GIT_PASSTHROUGH
183
- except Exception as e :
184
- self ._stored_exception = e
185
- return C .GIT_EUSER
186
-
195
+ ccred = get_credentials (credentials , url , username , allowed )
196
+ cred_out [0 ] = ccred [0 ]
187
197
return 0
188
198
199
+
189
200
@ffi .def_extern ()
201
+ @callback_proxy
190
202
def _push_update_reference_cb (ref , msg , data ):
191
- self = ffi .from_handle (data )
192
-
193
- push_update_reference = getattr (self , 'push_update_reference' , None )
203
+ push_update_reference = getattr (data , 'push_update_reference' , None )
194
204
if not push_update_reference :
195
205
return 0
196
206
197
- try :
198
- refname = ffi .string (ref )
199
- message = maybe_string (msg )
200
- push_update_reference (refname , message )
201
- except Exception as e :
202
- self ._stored_exception = e
203
- return C .GIT_EUSER
204
-
207
+ refname = ffi .string (ref )
208
+ message = maybe_string (msg )
209
+ push_update_reference (refname , message )
205
210
return 0
206
211
212
+
207
213
@ffi .def_extern ()
214
+ @callback_proxy
208
215
def _sideband_progress_cb (string , length , data ):
209
- self = ffi .from_handle (data )
210
-
211
- progress = getattr (self , 'progress' , None )
216
+ progress = getattr (data , 'progress' , None )
212
217
if not progress :
213
218
return 0
214
219
215
- try :
216
- s = ffi .string (string , length ).decode ('utf-8' )
217
- progress (s )
218
- except Exception as e :
219
- self ._stored_exception = e
220
- return C .GIT_EUSER
221
-
220
+ s = ffi .string (string , length ).decode ('utf-8' )
221
+ progress (s )
222
222
return 0
223
223
224
224
225
225
@ffi .def_extern ()
226
+ @callback_proxy
226
227
def _transfer_progress_cb (stats_ptr , data ):
227
228
from .remote import TransferProgress
228
229
229
- self = ffi .from_handle (data )
230
-
231
- transfer_progress = getattr (self , 'transfer_progress' , None )
230
+ transfer_progress = getattr (data , 'transfer_progress' , None )
232
231
if not transfer_progress :
233
232
return 0
234
233
235
- try :
236
- transfer_progress (TransferProgress (stats_ptr ))
237
- except Exception as e :
238
- self ._stored_exception = e
239
- return C .GIT_EUSER
240
-
234
+ transfer_progress (TransferProgress (stats_ptr ))
241
235
return 0
242
236
243
237
244
238
@ffi .def_extern ()
239
+ @callback_proxy
245
240
def _update_tips_cb (refname , a , b , data ):
246
- self = ffi .from_handle (data )
247
-
248
- update_tips = getattr (self , 'update_tips' , None )
241
+ update_tips = getattr (data , 'update_tips' , None )
249
242
if not update_tips :
250
243
return 0
251
244
252
- try :
253
- s = maybe_string (refname )
254
- a = Oid (raw = bytes (ffi .buffer (a )[:]))
255
- b = Oid (raw = bytes (ffi .buffer (b )[:]))
256
-
257
- update_tips (s , a , b )
258
- except Exception as e :
259
- self ._stored_exception = e
260
- return C .GIT_EUSER
261
-
245
+ s = maybe_string (refname )
246
+ a = Oid (raw = bytes (ffi .buffer (a )[:]))
247
+ b = Oid (raw = bytes (ffi .buffer (b )[:]))
248
+ update_tips (s , a , b )
262
249
return 0
263
250
264
251
0 commit comments