Mercurial > hg
comparison mercurial/hook.py @ 43076:2372284d9457
formatting: blacken the codebase
This is using my patch to black
(https://github.com/psf/black/pull/826) so we don't un-wrap collection
literals.
Done with:
hg files 'set:**.py - mercurial/thirdparty/** - "contrib/python-zstandard/**"' | xargs black -S
# skip-blame mass-reformatting only
# no-check-commit reformats foo_bar functions
Differential Revision: https://phab.mercurial-scm.org/D6971
author | Augie Fackler <augie@google.com> |
---|---|
date | Sun, 06 Oct 2019 09:45:02 -0400 |
parents | 8c8fcb385c46 |
children | 687b865b95ad |
comparison
equal
deleted
inserted
replaced
43075:57875cf423c9 | 43076:2372284d9457 |
---|---|
22 from .utils import ( | 22 from .utils import ( |
23 procutil, | 23 procutil, |
24 stringutil, | 24 stringutil, |
25 ) | 25 ) |
26 | 26 |
27 | |
27 def pythonhook(ui, repo, htype, hname, funcname, args, throw): | 28 def pythonhook(ui, repo, htype, hname, funcname, args, throw): |
28 '''call python hook. hook is callable object, looked up as | 29 '''call python hook. hook is callable object, looked up as |
29 name in python module. if callable returns "true", hook | 30 name in python module. if callable returns "true", hook |
30 fails, else passes. if hook raises exception, treated as | 31 fails, else passes. if hook raises exception, treated as |
31 hook failure. exception propagates if throw is "true". | 32 hook failure. exception propagates if throw is "true". |
40 else: | 41 else: |
41 d = funcname.rfind('.') | 42 d = funcname.rfind('.') |
42 if d == -1: | 43 if d == -1: |
43 raise error.HookLoadError( | 44 raise error.HookLoadError( |
44 _('%s hook is invalid: "%s" not in a module') | 45 _('%s hook is invalid: "%s" not in a module') |
45 % (hname, funcname)) | 46 % (hname, funcname) |
47 ) | |
46 modname = funcname[:d] | 48 modname = funcname[:d] |
47 oldpaths = sys.path | 49 oldpaths = sys.path |
48 if procutil.mainfrozen(): | 50 if procutil.mainfrozen(): |
49 # binary installs require sys.path manipulation | 51 # binary installs require sys.path manipulation |
50 modpath, modfile = os.path.split(modname) | 52 modpath, modfile = os.path.split(modname) |
60 # extensions are loaded with hgext_ prefix | 62 # extensions are loaded with hgext_ prefix |
61 obj = __import__(r"hgext_%s" % pycompat.sysstr(modname)) | 63 obj = __import__(r"hgext_%s" % pycompat.sysstr(modname)) |
62 except (ImportError, SyntaxError): | 64 except (ImportError, SyntaxError): |
63 e2 = sys.exc_info() | 65 e2 = sys.exc_info() |
64 if ui.tracebackflag: | 66 if ui.tracebackflag: |
65 ui.warn(_('exception from first failed import ' | 67 ui.warn( |
66 'attempt:\n')) | 68 _( |
69 'exception from first failed import ' | |
70 'attempt:\n' | |
71 ) | |
72 ) | |
67 ui.traceback(e1) | 73 ui.traceback(e1) |
68 if ui.tracebackflag: | 74 if ui.tracebackflag: |
69 ui.warn(_('exception from second failed import ' | 75 ui.warn( |
70 'attempt:\n')) | 76 _( |
77 'exception from second failed import ' | |
78 'attempt:\n' | |
79 ) | |
80 ) | |
71 ui.traceback(e2) | 81 ui.traceback(e2) |
72 | 82 |
73 if not ui.tracebackflag: | 83 if not ui.tracebackflag: |
74 tracebackhint = _( | 84 tracebackhint = _( |
75 'run with --traceback for stack trace') | 85 'run with --traceback for stack trace' |
86 ) | |
76 else: | 87 else: |
77 tracebackhint = None | 88 tracebackhint = None |
78 raise error.HookLoadError( | 89 raise error.HookLoadError( |
79 _('%s hook is invalid: import of "%s" failed') % | 90 _('%s hook is invalid: import of "%s" failed') |
80 (hname, modname), hint=tracebackhint) | 91 % (hname, modname), |
92 hint=tracebackhint, | |
93 ) | |
81 sys.path = oldpaths | 94 sys.path = oldpaths |
82 try: | 95 try: |
83 for p in funcname.split('.')[1:]: | 96 for p in funcname.split('.')[1:]: |
84 obj = getattr(obj, p) | 97 obj = getattr(obj, p) |
85 except AttributeError: | 98 except AttributeError: |
86 raise error.HookLoadError( | 99 raise error.HookLoadError( |
87 _('%s hook is invalid: "%s" is not defined') | 100 _('%s hook is invalid: "%s" is not defined') % (hname, funcname) |
88 % (hname, funcname)) | 101 ) |
89 if not callable(obj): | 102 if not callable(obj): |
90 raise error.HookLoadError( | 103 raise error.HookLoadError( |
91 _('%s hook is invalid: "%s" is not callable') | 104 _('%s hook is invalid: "%s" is not callable') |
92 % (hname, funcname)) | 105 % (hname, funcname) |
106 ) | |
93 | 107 |
94 ui.note(_("calling hook %s: %s\n") % (hname, funcname)) | 108 ui.note(_("calling hook %s: %s\n") % (hname, funcname)) |
95 starttime = util.timer() | 109 starttime = util.timer() |
96 | 110 |
97 try: | 111 try: |
98 r = obj(ui=ui, repo=repo, hooktype=htype, **pycompat.strkwargs(args)) | 112 r = obj(ui=ui, repo=repo, hooktype=htype, **pycompat.strkwargs(args)) |
99 except Exception as exc: | 113 except Exception as exc: |
100 if isinstance(exc, error.Abort): | 114 if isinstance(exc, error.Abort): |
101 ui.warn(_('error: %s hook failed: %s\n') % | 115 ui.warn(_('error: %s hook failed: %s\n') % (hname, exc.args[0])) |
102 (hname, exc.args[0])) | |
103 else: | 116 else: |
104 ui.warn(_('error: %s hook raised an exception: ' | 117 ui.warn( |
105 '%s\n') % (hname, stringutil.forcebytestr(exc))) | 118 _('error: %s hook raised an exception: ' '%s\n') |
119 % (hname, stringutil.forcebytestr(exc)) | |
120 ) | |
106 if throw: | 121 if throw: |
107 raise | 122 raise |
108 if not ui.tracebackflag: | 123 if not ui.tracebackflag: |
109 ui.warn(_('(run with --traceback for stack trace)\n')) | 124 ui.warn(_('(run with --traceback for stack trace)\n')) |
110 ui.traceback() | 125 ui.traceback() |
111 return True, True | 126 return True, True |
112 finally: | 127 finally: |
113 duration = util.timer() - starttime | 128 duration = util.timer() - starttime |
114 ui.log('pythonhook', 'pythonhook-%s: %s finished in %0.2f seconds\n', | 129 ui.log( |
115 htype, funcname, duration) | 130 'pythonhook', |
131 'pythonhook-%s: %s finished in %0.2f seconds\n', | |
132 htype, | |
133 funcname, | |
134 duration, | |
135 ) | |
116 if r: | 136 if r: |
117 if throw: | 137 if throw: |
118 raise error.HookAbort(_('%s hook failed') % hname) | 138 raise error.HookAbort(_('%s hook failed') % hname) |
119 ui.warn(_('warning: %s hook failed\n') % hname) | 139 ui.warn(_('warning: %s hook failed\n') % hname) |
120 return r, False | 140 return r, False |
141 | |
121 | 142 |
122 def _exthook(ui, repo, htype, name, cmd, args, throw): | 143 def _exthook(ui, repo, htype, name, cmd, args, throw): |
123 starttime = util.timer() | 144 starttime = util.timer() |
124 env = {} | 145 env = {} |
125 | 146 |
152 else: | 173 else: |
153 cwd = encoding.getcwd() | 174 cwd = encoding.getcwd() |
154 r = ui.system(cmd, environ=env, cwd=cwd, blockedtag='exthook-%s' % (name,)) | 175 r = ui.system(cmd, environ=env, cwd=cwd, blockedtag='exthook-%s' % (name,)) |
155 | 176 |
156 duration = util.timer() - starttime | 177 duration = util.timer() - starttime |
157 ui.log('exthook', 'exthook-%s: %s finished in %0.2f seconds\n', | 178 ui.log( |
158 name, cmd, duration) | 179 'exthook', |
180 'exthook-%s: %s finished in %0.2f seconds\n', | |
181 name, | |
182 cmd, | |
183 duration, | |
184 ) | |
159 if r: | 185 if r: |
160 desc = procutil.explainexit(r) | 186 desc = procutil.explainexit(r) |
161 if throw: | 187 if throw: |
162 raise error.HookAbort(_('%s hook %s') % (name, desc)) | 188 raise error.HookAbort(_('%s hook %s') % (name, desc)) |
163 ui.warn(_('warning: %s hook %s\n') % (name, desc)) | 189 ui.warn(_('warning: %s hook %s\n') % (name, desc)) |
164 return r | 190 return r |
165 | 191 |
192 | |
166 # represent an untrusted hook command | 193 # represent an untrusted hook command |
167 _fromuntrusted = object() | 194 _fromuntrusted = object() |
195 | |
168 | 196 |
169 def _allhooks(ui): | 197 def _allhooks(ui): |
170 """return a list of (hook-id, cmd) pairs sorted by priority""" | 198 """return a list of (hook-id, cmd) pairs sorted by priority""" |
171 hooks = _hookitems(ui) | 199 hooks = _hookitems(ui) |
172 # Be careful in this section, propagating the real commands from untrusted | 200 # Be careful in this section, propagating the real commands from untrusted |
179 (lp, lo, lk, lv) = trustedvalue | 207 (lp, lo, lk, lv) = trustedvalue |
180 hooks[name] = (lp, lo, lk, _fromuntrusted) | 208 hooks[name] = (lp, lo, lk, _fromuntrusted) |
181 # (end of the security sensitive section) | 209 # (end of the security sensitive section) |
182 return [(k, v) for p, o, k, v in sorted(hooks.values())] | 210 return [(k, v) for p, o, k, v in sorted(hooks.values())] |
183 | 211 |
212 | |
184 def _hookitems(ui, _untrusted=False): | 213 def _hookitems(ui, _untrusted=False): |
185 """return all hooks items ready to be sorted""" | 214 """return all hooks items ready to be sorted""" |
186 hooks = {} | 215 hooks = {} |
187 for name, cmd in ui.configitems('hooks', untrusted=_untrusted): | 216 for name, cmd in ui.configitems('hooks', untrusted=_untrusted): |
188 if name.startswith('priority.') or name.startswith('tonative.'): | 217 if name.startswith('priority.') or name.startswith('tonative.'): |
190 | 219 |
191 priority = ui.configint('hooks', 'priority.%s' % name, 0) | 220 priority = ui.configint('hooks', 'priority.%s' % name, 0) |
192 hooks[name] = (-priority, len(hooks), name, cmd) | 221 hooks[name] = (-priority, len(hooks), name, cmd) |
193 return hooks | 222 return hooks |
194 | 223 |
224 | |
195 _redirect = False | 225 _redirect = False |
226 | |
227 | |
196 def redirect(state): | 228 def redirect(state): |
197 global _redirect | 229 global _redirect |
198 _redirect = state | 230 _redirect = state |
231 | |
199 | 232 |
200 def hashook(ui, htype): | 233 def hashook(ui, htype): |
201 """return True if a hook is configured for 'htype'""" | 234 """return True if a hook is configured for 'htype'""" |
202 if not ui.callhooks: | 235 if not ui.callhooks: |
203 return False | 236 return False |
204 for hname, cmd in _allhooks(ui): | 237 for hname, cmd in _allhooks(ui): |
205 if hname.split('.')[0] == htype and cmd: | 238 if hname.split('.')[0] == htype and cmd: |
206 return True | 239 return True |
207 return False | 240 return False |
208 | 241 |
242 | |
209 def hook(ui, repo, htype, throw=False, **args): | 243 def hook(ui, repo, htype, throw=False, **args): |
210 if not ui.callhooks: | 244 if not ui.callhooks: |
211 return False | 245 return False |
212 | 246 |
213 hooks = [] | 247 hooks = [] |
218 res = runhooks(ui, repo, htype, hooks, throw=throw, **args) | 252 res = runhooks(ui, repo, htype, hooks, throw=throw, **args) |
219 r = False | 253 r = False |
220 for hname, cmd in hooks: | 254 for hname, cmd in hooks: |
221 r = res[hname][0] or r | 255 r = res[hname][0] or r |
222 return r | 256 return r |
257 | |
223 | 258 |
224 def runhooks(ui, repo, htype, hooks, throw=False, **args): | 259 def runhooks(ui, repo, htype, hooks, throw=False, **args): |
225 args = pycompat.byteskwargs(args) | 260 args = pycompat.byteskwargs(args) |
226 res = {} | 261 res = {} |
227 oldstdout = -1 | 262 oldstdout = -1 |
243 | 278 |
244 if cmd is _fromuntrusted: | 279 if cmd is _fromuntrusted: |
245 if throw: | 280 if throw: |
246 raise error.HookAbort( | 281 raise error.HookAbort( |
247 _('untrusted hook %s not executed') % hname, | 282 _('untrusted hook %s not executed') % hname, |
248 hint = _("see 'hg help config.trusted'")) | 283 hint=_("see 'hg help config.trusted'"), |
284 ) | |
249 ui.warn(_('warning: untrusted hook %s not executed\n') % hname) | 285 ui.warn(_('warning: untrusted hook %s not executed\n') % hname) |
250 r = 1 | 286 r = 1 |
251 raised = False | 287 raised = False |
252 elif callable(cmd): | 288 elif callable(cmd): |
253 r, raised = pythonhook(ui, repo, htype, hname, cmd, args, | 289 r, raised = pythonhook(ui, repo, htype, hname, cmd, args, throw) |
254 throw) | |
255 elif cmd.startswith('python:'): | 290 elif cmd.startswith('python:'): |
256 if cmd.count(':') >= 2: | 291 if cmd.count(':') >= 2: |
257 path, cmd = cmd[7:].rsplit(':', 1) | 292 path, cmd = cmd[7:].rsplit(':', 1) |
258 path = util.expandpath(path) | 293 path = util.expandpath(path) |
259 if repo: | 294 if repo: |
264 ui.write(_("loading %s hook failed:\n") % hname) | 299 ui.write(_("loading %s hook failed:\n") % hname) |
265 raise | 300 raise |
266 hookfn = getattr(mod, cmd) | 301 hookfn = getattr(mod, cmd) |
267 else: | 302 else: |
268 hookfn = cmd[7:].strip() | 303 hookfn = cmd[7:].strip() |
269 r, raised = pythonhook(ui, repo, htype, hname, hookfn, args, | 304 r, raised = pythonhook( |
270 throw) | 305 ui, repo, htype, hname, hookfn, args, throw |
306 ) | |
271 else: | 307 else: |
272 r = _exthook(ui, repo, htype, hname, cmd, args, throw) | 308 r = _exthook(ui, repo, htype, hname, cmd, args, throw) |
273 raised = False | 309 raised = False |
274 | 310 |
275 res[hname] = r, raised | 311 res[hname] = r, raised |