comparison mercurial/hook.py @ 20548:5bd6a9fec103

hooks: for python hooks, consistently use __name__ etc as name, not the repr There is no reason to expose unnecessary Python implementation details and memory locations, also not in debug mode. readablefunc was already creating a nice name - we move that functionality up and reuse it. We consider having a __call__ and being types.FunctionType sufficiently similar and unify these two to just using the existing check for __call__.
author Mads Kiilerich <madski@unity3d.com>
date Sat, 15 Feb 2014 01:23:12 +0100
parents 9d9f8ccffead
children b009dd135aa0
comparison
equal deleted inserted replaced
20547:9d9f8ccffead 20548:5bd6a9fec103
4 # 4 #
5 # This software may be used and distributed according to the terms of the 5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version. 6 # GNU General Public License version 2 or any later version.
7 7
8 from i18n import _ 8 from i18n import _
9 import os, sys, time, types 9 import os, sys, time
10 import extensions, util, demandimport 10 import extensions, util, demandimport
11 11
12 def _pythonhook(ui, repo, name, hname, funcname, args, throw): 12 def _pythonhook(ui, repo, name, hname, funcname, args, throw):
13 '''call python hook. hook is callable object, looked up as 13 '''call python hook. hook is callable object, looked up as
14 name in python module. if callable returns "true", hook 14 name in python module. if callable returns "true", hook
17 17
18 reason for "true" meaning "hook failed" is so that 18 reason for "true" meaning "hook failed" is so that
19 unmodified commands (e.g. mercurial.commands.update) can 19 unmodified commands (e.g. mercurial.commands.update) can
20 be run as hooks without wrappers to convert return values.''' 20 be run as hooks without wrappers to convert return values.'''
21 21
22 obj = funcname 22 if util.safehasattr(funcname, '__call__'):
23 if not util.safehasattr(obj, '__call__'): 23 obj = funcname
24 funcname = obj.__module__ + "." + obj.__name__
25 else:
24 d = funcname.rfind('.') 26 d = funcname.rfind('.')
25 if d == -1: 27 if d == -1:
26 raise util.Abort(_('%s hook is invalid ("%s" not in ' 28 raise util.Abort(_('%s hook is invalid ("%s" not in '
27 'a module)') % (hname, funcname)) 29 'a module)') % (hname, funcname))
28 modname = funcname[:d] 30 modname = funcname[:d]
99 ui.traceback() 101 ui.traceback()
100 return True 102 return True
101 finally: 103 finally:
102 sys.stdout, sys.stderr, sys.stdin = old 104 sys.stdout, sys.stderr, sys.stdin = old
103 duration = time.time() - starttime 105 duration = time.time() - starttime
104 readablefunc = funcname
105 if isinstance(funcname, types.FunctionType):
106 readablefunc = funcname.__module__ + "." + funcname.__name__
107 ui.log('pythonhook', 'pythonhook-%s: %s finished in %0.2f seconds\n', 106 ui.log('pythonhook', 'pythonhook-%s: %s finished in %0.2f seconds\n',
108 name, readablefunc, duration) 107 name, funcname, duration)
109 if r: 108 if r:
110 if throw: 109 if throw:
111 raise util.Abort(_('%s hook failed') % hname) 110 raise util.Abort(_('%s hook failed') % hname)
112 ui.warn(_('warning: %s hook failed\n') % hname) 111 ui.warn(_('warning: %s hook failed\n') % hname)
113 return r 112 return r