##// END OF EJS Templates
extensions: copy __module__ for wrapped commands
Dirkjan Ochtman -
r7373:d9e9dd2b default
parent child Browse files
Show More
@@ -1,114 +1,115 b''
1 # extensions.py - extension handling for mercurial
1 # extensions.py - extension handling for mercurial
2 #
2 #
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms
5 # This software may be used and distributed according to the terms
6 # of the GNU General Public License, incorporated herein by reference.
6 # of the GNU General Public License, incorporated herein by reference.
7
7
8 import imp, os
8 import imp, os
9 import util, cmdutil
9 import util, cmdutil
10 from i18n import _
10 from i18n import _
11
11
12 _extensions = {}
12 _extensions = {}
13 _order = []
13 _order = []
14
14
15 def extensions():
15 def extensions():
16 for name in _order:
16 for name in _order:
17 module = _extensions[name]
17 module = _extensions[name]
18 if module:
18 if module:
19 yield name, module
19 yield name, module
20
20
21 def find(name):
21 def find(name):
22 '''return module with given extension name'''
22 '''return module with given extension name'''
23 try:
23 try:
24 return _extensions[name]
24 return _extensions[name]
25 except KeyError:
25 except KeyError:
26 for k, v in _extensions.iteritems():
26 for k, v in _extensions.iteritems():
27 if k.endswith('.' + name) or k.endswith('/' + name):
27 if k.endswith('.' + name) or k.endswith('/' + name):
28 return v
28 return v
29 raise KeyError(name)
29 raise KeyError(name)
30
30
31 def load(ui, name, path):
31 def load(ui, name, path):
32 if name.startswith('hgext.') or name.startswith('hgext/'):
32 if name.startswith('hgext.') or name.startswith('hgext/'):
33 shortname = name[6:]
33 shortname = name[6:]
34 else:
34 else:
35 shortname = name
35 shortname = name
36 if shortname in _extensions:
36 if shortname in _extensions:
37 return
37 return
38 _extensions[shortname] = None
38 _extensions[shortname] = None
39 if path:
39 if path:
40 # the module will be loaded in sys.modules
40 # the module will be loaded in sys.modules
41 # choose an unique name so that it doesn't
41 # choose an unique name so that it doesn't
42 # conflicts with other modules
42 # conflicts with other modules
43 module_name = "hgext_%s" % name.replace('.', '_')
43 module_name = "hgext_%s" % name.replace('.', '_')
44 if os.path.isdir(path):
44 if os.path.isdir(path):
45 # module/__init__.py style
45 # module/__init__.py style
46 d, f = os.path.split(path)
46 d, f = os.path.split(path)
47 fd, fpath, desc = imp.find_module(f, [d])
47 fd, fpath, desc = imp.find_module(f, [d])
48 mod = imp.load_module(module_name, fd, fpath, desc)
48 mod = imp.load_module(module_name, fd, fpath, desc)
49 else:
49 else:
50 mod = imp.load_source(module_name, path)
50 mod = imp.load_source(module_name, path)
51 else:
51 else:
52 def importh(name):
52 def importh(name):
53 mod = __import__(name)
53 mod = __import__(name)
54 components = name.split('.')
54 components = name.split('.')
55 for comp in components[1:]:
55 for comp in components[1:]:
56 mod = getattr(mod, comp)
56 mod = getattr(mod, comp)
57 return mod
57 return mod
58 try:
58 try:
59 mod = importh("hgext.%s" % name)
59 mod = importh("hgext.%s" % name)
60 except ImportError:
60 except ImportError:
61 mod = importh(name)
61 mod = importh(name)
62 _extensions[shortname] = mod
62 _extensions[shortname] = mod
63 _order.append(shortname)
63 _order.append(shortname)
64
64
65 uisetup = getattr(mod, 'uisetup', None)
65 uisetup = getattr(mod, 'uisetup', None)
66 if uisetup:
66 if uisetup:
67 uisetup(ui)
67 uisetup(ui)
68
68
69 def loadall(ui):
69 def loadall(ui):
70 result = ui.configitems("extensions")
70 result = ui.configitems("extensions")
71 for i, (name, path) in enumerate(result):
71 for i, (name, path) in enumerate(result):
72 if path:
72 if path:
73 if path[0] == '!':
73 if path[0] == '!':
74 continue
74 continue
75 path = os.path.expanduser(path)
75 path = os.path.expanduser(path)
76 try:
76 try:
77 load(ui, name, path)
77 load(ui, name, path)
78 except (util.SignalInterrupt, KeyboardInterrupt):
78 except (util.SignalInterrupt, KeyboardInterrupt):
79 raise
79 raise
80 except Exception, inst:
80 except Exception, inst:
81 if path:
81 if path:
82 ui.warn(_("*** failed to import extension %s from %s: %s\n")
82 ui.warn(_("*** failed to import extension %s from %s: %s\n")
83 % (name, path, inst))
83 % (name, path, inst))
84 else:
84 else:
85 ui.warn(_("*** failed to import extension %s: %s\n")
85 ui.warn(_("*** failed to import extension %s: %s\n")
86 % (name, inst))
86 % (name, inst))
87 if ui.print_exc():
87 if ui.print_exc():
88 return 1
88 return 1
89
89
90 def wrapcommand(table, command, wrapper):
90 def wrapcommand(table, command, wrapper):
91 aliases, entry = cmdutil.findcmd(command, table)
91 aliases, entry = cmdutil.findcmd(command, table)
92 for alias, e in table.iteritems():
92 for alias, e in table.iteritems():
93 if e is entry:
93 if e is entry:
94 key = alias
94 key = alias
95 break
95 break
96
96
97 origfn = entry[0]
97 origfn = entry[0]
98 def wrap(*args, **kwargs):
98 def wrap(*args, **kwargs):
99 return wrapper(origfn, *args, **kwargs)
99 return wrapper(origfn, *args, **kwargs)
100
100
101 wrap.__doc__ = getattr(origfn, '__doc__')
101 wrap.__doc__ = getattr(origfn, '__doc__')
102 wrap.__module__ = getattr(origfn, '__module__')
102
103
103 newentry = list(entry)
104 newentry = list(entry)
104 newentry[0] = wrap
105 newentry[0] = wrap
105 table[key] = tuple(newentry)
106 table[key] = tuple(newentry)
106 return entry
107 return entry
107
108
108 def wrapfunction(container, funcname, wrapper):
109 def wrapfunction(container, funcname, wrapper):
109 def wrap(*args, **kwargs):
110 def wrap(*args, **kwargs):
110 return wrapper(origfn, *args, **kwargs)
111 return wrapper(origfn, *args, **kwargs)
111
112
112 origfn = getattr(container, funcname)
113 origfn = getattr(container, funcname)
113 setattr(container, funcname, wrap)
114 setattr(container, funcname, wrap)
114 return origfn
115 return origfn
General Comments 0
You need to be logged in to leave comments. Login now