Show More
@@ -84,9 +84,8 b' def find(name):' | |||||
84 |
|
84 | |||
85 |
|
85 | |||
86 | def loadpath(path, module_name): |
|
86 | def loadpath(path, module_name): | |
87 |
module_name = module_name.replace( |
|
87 | module_name = module_name.replace('.', '_') | |
88 | path = util.normpath(util.expandpath(path)) |
|
88 | path = util.normpath(util.expandpath(path)) | |
89 | module_name = pycompat.fsdecode(module_name) |
|
|||
90 | path = pycompat.fsdecode(path) |
|
89 | path = pycompat.fsdecode(path) | |
91 | if os.path.isdir(path): |
|
90 | if os.path.isdir(path): | |
92 | # module/__init__.py style |
|
91 | # module/__init__.py style | |
@@ -106,30 +105,31 b' def loadpath(path, module_name):' | |||||
106 |
|
105 | |||
107 | def _importh(name): |
|
106 | def _importh(name): | |
108 | """import and return the <name> module""" |
|
107 | """import and return the <name> module""" | |
109 |
mod = __import__( |
|
108 | mod = __import__(name) | |
110 |
components = name.split( |
|
109 | components = name.split('.') | |
111 | for comp in components[1:]: |
|
110 | for comp in components[1:]: | |
112 | mod = getattr(mod, comp) |
|
111 | mod = getattr(mod, comp) | |
113 | return mod |
|
112 | return mod | |
114 |
|
113 | |||
115 |
|
114 | |||
116 | def _importext(name, path=None, reportfunc=None): |
|
115 | def _importext(name, path=None, reportfunc=None): | |
|
116 | name = pycompat.fsdecode(name) | |||
117 | if path: |
|
117 | if path: | |
118 | # the module will be loaded in sys.modules |
|
118 | # the module will be loaded in sys.modules | |
119 | # choose an unique name so that it doesn't |
|
119 | # choose an unique name so that it doesn't | |
120 | # conflicts with other modules |
|
120 | # conflicts with other modules | |
121 |
mod = loadpath(path, |
|
121 | mod = loadpath(path, 'hgext.%s' % name) | |
122 | else: |
|
122 | else: | |
123 | try: |
|
123 | try: | |
124 |
mod = _importh( |
|
124 | mod = _importh("hgext.%s" % name) | |
125 | except ImportError as err: |
|
125 | except ImportError as err: | |
126 | if reportfunc: |
|
126 | if reportfunc: | |
127 |
reportfunc(err, |
|
127 | reportfunc(err, "hgext.%s" % name, "hgext3rd.%s" % name) | |
128 | try: |
|
128 | try: | |
129 |
mod = _importh( |
|
129 | mod = _importh("hgext3rd.%s" % name) | |
130 | except ImportError as err: |
|
130 | except ImportError as err: | |
131 | if reportfunc: |
|
131 | if reportfunc: | |
132 |
reportfunc(err, |
|
132 | reportfunc(err, "hgext3rd.%s" % name, name) | |
133 | mod = _importh(name) |
|
133 | mod = _importh(name) | |
134 | return mod |
|
134 | return mod | |
135 |
|
135 | |||
@@ -140,9 +140,9 b' def _reportimporterror(ui, err, failed, ' | |||||
140 | ui.log( |
|
140 | ui.log( | |
141 | b'extension', |
|
141 | b'extension', | |
142 | b' - could not import %s (%s): trying %s\n', |
|
142 | b' - could not import %s (%s): trying %s\n', | |
143 | failed, |
|
143 | stringutil.forcebytestr(failed), | |
144 | stringutil.forcebytestr(err), |
|
144 | stringutil.forcebytestr(err), | |
145 | next, |
|
145 | stringutil.forcebytestr(next), | |
146 | ) |
|
146 | ) | |
147 | if ui.debugflag and ui.configbool(b'devel', b'debug.extensions'): |
|
147 | if ui.debugflag and ui.configbool(b'devel', b'debug.extensions'): | |
148 | ui.traceback() |
|
148 | ui.traceback() |
@@ -834,12 +834,13 b' def _xmerge(repo, mynode, local, other, ' | |||||
834 | # avoid cycle cmdutil->merge->filemerge->extensions->cmdutil |
|
834 | # avoid cycle cmdutil->merge->filemerge->extensions->cmdutil | |
835 | from . import extensions |
|
835 | from . import extensions | |
836 |
|
836 | |||
837 |
mod = |
|
837 | mod_name = 'hgmerge.%s' % pycompat.sysstr(tool) | |
|
838 | mod = extensions.loadpath(toolpath, mod_name) | |||
838 | except Exception: |
|
839 | except Exception: | |
839 | raise error.Abort( |
|
840 | raise error.Abort( | |
840 | _(b"loading python merge script failed: %s") % toolpath |
|
841 | _(b"loading python merge script failed: %s") % toolpath | |
841 | ) |
|
842 | ) | |
842 | mergefn = getattr(mod, scriptfn, None) |
|
843 | mergefn = getattr(mod, pycompat.sysstr(scriptfn), None) | |
843 | if mergefn is None: |
|
844 | if mergefn is None: | |
844 | raise error.Abort( |
|
845 | raise error.Abort( | |
845 | _(b"%s does not have function: %s") % (toolpath, scriptfn) |
|
846 | _(b"%s does not have function: %s") % (toolpath, scriptfn) |
@@ -40,13 +40,14 b' def pythonhook(ui, repo, htype, hname, f' | |||||
40 |
|
40 | |||
41 | if callable(funcname): |
|
41 | if callable(funcname): | |
42 | obj = funcname |
|
42 | obj = funcname | |
43 |
funcname = |
|
43 | funcname = obj.__module__ + "." + obj.__name__ | |
44 | else: |
|
44 | else: | |
45 | d = funcname.rfind(b'.') |
|
45 | funcname = pycompat.sysstr(funcname) | |
|
46 | d = funcname.rfind('.') | |||
46 | if d == -1: |
|
47 | if d == -1: | |
47 | raise error.HookLoadError( |
|
48 | raise error.HookLoadError( | |
48 | _(b'%s hook is invalid: "%s" not in a module') |
|
49 | _(b'%s hook is invalid: "%s" not in a module') | |
49 | % (hname, funcname) |
|
50 | % (hname, stringutil.forcebytestr(funcname)) | |
50 | ) |
|
51 | ) | |
51 | modname = funcname[:d] |
|
52 | modname = funcname[:d] | |
52 | oldpaths = sys.path |
|
53 | oldpaths = sys.path | |
@@ -89,27 +90,30 b' def pythonhook(ui, repo, htype, hname, f' | |||||
89 | ) |
|
90 | ) | |
90 | else: |
|
91 | else: | |
91 | tracebackhint = None |
|
92 | tracebackhint = None | |
92 | raise error.HookLoadError( |
|
93 | msg = _(b'%s hook is invalid: import of "%s" failed') | |
93 | _(b'%s hook is invalid: import of "%s" failed') |
|
94 | msg %= ( | |
94 |
|
|
95 | stringutil.forcebytestr(hname), | |
95 |
|
|
96 | stringutil.forcebytestr(modname), | |
96 | ) |
|
97 | ) | |
|
98 | raise error.HookLoadError(msg, hint=tracebackhint) | |||
97 | sys.path = oldpaths |
|
99 | sys.path = oldpaths | |
98 | try: |
|
100 | try: | |
99 |
for p in funcname.split( |
|
101 | for p in funcname.split('.')[1:]: | |
100 | obj = getattr(obj, p) |
|
102 | obj = getattr(obj, p) | |
101 | except AttributeError: |
|
103 | except AttributeError: | |
102 | raise error.HookLoadError( |
|
104 | raise error.HookLoadError( | |
103 | _(b'%s hook is invalid: "%s" is not defined') |
|
105 | _(b'%s hook is invalid: "%s" is not defined') | |
104 | % (hname, funcname) |
|
106 | % (hname, stringutil.forcebytestr(funcname)) | |
105 | ) |
|
107 | ) | |
106 | if not callable(obj): |
|
108 | if not callable(obj): | |
107 | raise error.HookLoadError( |
|
109 | raise error.HookLoadError( | |
108 | _(b'%s hook is invalid: "%s" is not callable') |
|
110 | _(b'%s hook is invalid: "%s" is not callable') | |
109 | % (hname, funcname) |
|
111 | % (hname, stringutil.forcebytestr(funcname)) | |
110 | ) |
|
112 | ) | |
111 |
|
113 | |||
112 | ui.note(_(b"calling hook %s: %s\n") % (hname, funcname)) |
|
114 | ui.note( | |
|
115 | _(b"calling hook %s: %s\n") % (hname, stringutil.forcebytestr(funcname)) | |||
|
116 | ) | |||
113 | starttime = util.timer() |
|
117 | starttime = util.timer() | |
114 |
|
118 | |||
115 | try: |
|
119 | try: | |
@@ -134,7 +138,7 b' def pythonhook(ui, repo, htype, hname, f' | |||||
134 | b'pythonhook', |
|
138 | b'pythonhook', | |
135 | b'pythonhook-%s: %s finished in %0.2f seconds\n', |
|
139 | b'pythonhook-%s: %s finished in %0.2f seconds\n', | |
136 | htype, |
|
140 | htype, | |
137 | funcname, |
|
141 | stringutil.forcebytestr(funcname), | |
138 | duration, |
|
142 | duration, | |
139 | ) |
|
143 | ) | |
140 | if r: |
|
144 | if r: | |
@@ -347,11 +351,12 b' def runhooks(ui, repo, htype, hooks, thr' | |||||
347 | if repo: |
|
351 | if repo: | |
348 | path = os.path.join(repo.root, path) |
|
352 | path = os.path.join(repo.root, path) | |
349 | try: |
|
353 | try: | |
350 |
mod = |
|
354 | mod_name = 'hghook.%s' % pycompat.sysstr(hname) | |
|
355 | mod = extensions.loadpath(path, mod_name) | |||
351 | except Exception: |
|
356 | except Exception: | |
352 | ui.write(_(b"loading %s hook failed:\n") % hname) |
|
357 | ui.write(_(b"loading %s hook failed:\n") % hname) | |
353 | raise |
|
358 | raise | |
354 | hookfn = getattr(mod, cmd) |
|
359 | hookfn = getattr(mod, pycompat.sysstr(cmd)) | |
355 | else: |
|
360 | else: | |
356 | hookfn = cmd[7:].strip() |
|
361 | hookfn = cmd[7:].strip() | |
357 | r, raised = pythonhook( |
|
362 | r, raised = pythonhook( |
@@ -991,7 +991,7 b' test python hooks' | |||||
991 | Traceback (most recent call last): |
|
991 | Traceback (most recent call last): | |
992 | ModuleNotFoundError: No module named 'hgext_syntaxerror' |
|
992 | ModuleNotFoundError: No module named 'hgext_syntaxerror' | |
993 | Traceback (most recent call last): |
|
993 | Traceback (most recent call last): | |
994 |
raise error.HookLoadError( |
|
994 | raise error.HookLoadError(msg, hint=tracebackhint) (py37 !) | |
995 | mercurial.error.HookLoadError: preoutgoing.syntaxerror hook is invalid: import of "syntaxerror" failed |
|
995 | mercurial.error.HookLoadError: preoutgoing.syntaxerror hook is invalid: import of "syntaxerror" failed | |
996 | abort: preoutgoing.syntaxerror hook is invalid: import of "syntaxerror" failed |
|
996 | abort: preoutgoing.syntaxerror hook is invalid: import of "syntaxerror" failed | |
997 |
|
997 | |||
@@ -1156,7 +1156,7 b' make sure --traceback works on hook impo' | |||||
1156 | Traceback (most recent call last): |
|
1156 | Traceback (most recent call last): | |
1157 | ModuleNotFoundError: No module named 'hgext_importfail' |
|
1157 | ModuleNotFoundError: No module named 'hgext_importfail' | |
1158 | Traceback (most recent call last): |
|
1158 | Traceback (most recent call last): | |
1159 |
raise error.HookLoadError( (py3 |
|
1159 | raise error.HookLoadError(msg, hint=tracebackhint) (py37 !) | |
1160 | mercurial.error.HookLoadError: precommit.importfail hook is invalid: import of "importfail" failed |
|
1160 | mercurial.error.HookLoadError: precommit.importfail hook is invalid: import of "importfail" failed | |
1161 | abort: precommit.importfail hook is invalid: import of "importfail" failed |
|
1161 | abort: precommit.importfail hook is invalid: import of "importfail" failed | |
1162 |
|
1162 |
General Comments 0
You need to be logged in to leave comments.
Login now