diff --git a/doc/hgrc.5.txt b/doc/hgrc.5.txt --- a/doc/hgrc.5.txt +++ b/doc/hgrc.5.txt @@ -475,6 +475,7 @@ hooks:: The syntax for Python hooks is as follows: hookname = python:modulename.submodule.callable + hookname = python:/path/to/python/module.py:callable Python hooks are run within the Mercurial process. Each hook is called with at least three keyword arguments: a ui object (keyword diff --git a/mercurial/extensions.py b/mercurial/extensions.py --- a/mercurial/extensions.py +++ b/mercurial/extensions.py @@ -28,6 +28,17 @@ def find(name): return v raise KeyError(name) +def loadpath(path, module_name): + module_name = module_name.replace('.', '_') + path = os.path.expanduser(path) + if os.path.isdir(path): + # module/__init__.py style + d, f = os.path.split(path) + fd, fpath, desc = imp.find_module(f, [d]) + return imp.load_module(module_name, fd, fpath, desc) + else: + return imp.load_source(module_name, path) + def load(ui, name, path): if name.startswith('hgext.') or name.startswith('hgext/'): shortname = name[6:] @@ -40,14 +51,7 @@ def load(ui, name, path): # the module will be loaded in sys.modules # choose an unique name so that it doesn't # conflicts with other modules - module_name = "hgext_%s" % name.replace('.', '_') - if os.path.isdir(path): - # module/__init__.py style - d, f = os.path.split(path) - fd, fpath, desc = imp.find_module(f, [d]) - mod = imp.load_module(module_name, fd, fpath, desc) - else: - mod = imp.load_source(module_name, path) + mod = loadpath(path, 'hgext.%s' % name) else: def importh(name): mod = __import__(name) @@ -72,7 +76,6 @@ def loadall(ui): if path: if path[0] == '!': continue - path = os.path.expanduser(path) try: load(ui, name, path) except KeyboardInterrupt: diff --git a/mercurial/hook.py b/mercurial/hook.py --- a/mercurial/hook.py +++ b/mercurial/hook.py @@ -7,6 +7,7 @@ from i18n import _ import util, os, sys +from mercurial import extensions def _pythonhook(ui, repo, name, hname, funcname, args, throw): '''call python hook. hook is callable object, looked up as @@ -109,8 +110,13 @@ def hook(ui, repo, name, throw=False, ** if callable(cmd): r = _pythonhook(ui, repo, name, hname, cmd, args, throw) or r elif cmd.startswith('python:'): - r = _pythonhook(ui, repo, name, hname, cmd[7:].strip(), - args, throw) or r + if cmd.count(':') == 2: + path, cmd = cmd[7:].split(':') + mod = extensions.loadpath(path, 'hgkook.%s' % hname) + hookfn = getattr(mod, cmd) + else: + hookfn = cmd[7:].strip() + r = _pythonhook(ui, repo, name, hname, hookfn, args, throw) or r else: r = _exthook(ui, repo, hname, cmd, args, throw) or r finally: