##// END OF EJS Templates
dynamic-import: use sysstr for importing extension and others...
marmoute -
r51816:c642c039 default
parent child Browse files
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(b'.', b'_')
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__(pycompat.sysstr(name))
108 mod = __import__(name)
110 components = name.split(b'.')
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, b'hgext.%s' % name)
121 mod = loadpath(path, 'hgext.%s' % name)
122 else:
122 else:
123 try:
123 try:
124 mod = _importh(b"hgext.%s" % name)
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, b"hgext.%s" % name, b"hgext3rd.%s" % name)
127 reportfunc(err, "hgext.%s" % name, "hgext3rd.%s" % name)
128 try:
128 try:
129 mod = _importh(b"hgext3rd.%s" % name)
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, b"hgext3rd.%s" % name, name)
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 = extensions.loadpath(toolpath, b'hgmerge.%s' % tool)
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 = pycompat.sysbytes(obj.__module__ + "." + obj.__name__)
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 % (hname, modname),
95 stringutil.forcebytestr(hname),
95 hint=tracebackhint,
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(b'.')[1:]:
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 = extensions.loadpath(path, b'hghook.%s' % hname)
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( (py38 !)
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( (py38 !)
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