diff mercurial/hook.py @ 50923:c642c03969ff

dynamic-import: use sysstr for importing extension and others This logic is used by extensions, and python hooks and merge-tools. All this logic eventually deals with native string (unicode in Python 3). This patch makes it handle `str` directly instead of relying on some pycompat low lever layer to do the conversion at the last minutes. We adjust the Python version filtering of a test as the output seems to be present with Python 3.7 too.
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Thu, 31 Aug 2023 02:41:33 +0200
parents 2761ce777fc4
children 18c8c18993f0
line wrap: on
line diff
--- a/mercurial/hook.py	Thu Aug 31 01:54:48 2023 +0200
+++ b/mercurial/hook.py	Thu Aug 31 02:41:33 2023 +0200
@@ -40,13 +40,14 @@
 
     if callable(funcname):
         obj = funcname
-        funcname = pycompat.sysbytes(obj.__module__ + "." + obj.__name__)
+        funcname = obj.__module__ + "." + obj.__name__
     else:
-        d = funcname.rfind(b'.')
+        funcname = pycompat.sysstr(funcname)
+        d = funcname.rfind('.')
         if d == -1:
             raise error.HookLoadError(
                 _(b'%s hook is invalid: "%s" not in a module')
-                % (hname, funcname)
+                % (hname, stringutil.forcebytestr(funcname))
             )
         modname = funcname[:d]
         oldpaths = sys.path
@@ -89,27 +90,30 @@
                         )
                     else:
                         tracebackhint = None
-                    raise error.HookLoadError(
-                        _(b'%s hook is invalid: import of "%s" failed')
-                        % (hname, modname),
-                        hint=tracebackhint,
+                    msg = _(b'%s hook is invalid: import of "%s" failed')
+                    msg %= (
+                        stringutil.forcebytestr(hname),
+                        stringutil.forcebytestr(modname),
                     )
+                    raise error.HookLoadError(msg, hint=tracebackhint)
         sys.path = oldpaths
         try:
-            for p in funcname.split(b'.')[1:]:
+            for p in funcname.split('.')[1:]:
                 obj = getattr(obj, p)
         except AttributeError:
             raise error.HookLoadError(
                 _(b'%s hook is invalid: "%s" is not defined')
-                % (hname, funcname)
+                % (hname, stringutil.forcebytestr(funcname))
             )
         if not callable(obj):
             raise error.HookLoadError(
                 _(b'%s hook is invalid: "%s" is not callable')
-                % (hname, funcname)
+                % (hname, stringutil.forcebytestr(funcname))
             )
 
-    ui.note(_(b"calling hook %s: %s\n") % (hname, funcname))
+    ui.note(
+        _(b"calling hook %s: %s\n") % (hname, stringutil.forcebytestr(funcname))
+    )
     starttime = util.timer()
 
     try:
@@ -134,7 +138,7 @@
             b'pythonhook',
             b'pythonhook-%s: %s finished in %0.2f seconds\n',
             htype,
-            funcname,
+            stringutil.forcebytestr(funcname),
             duration,
         )
     if r:
@@ -347,11 +351,12 @@
                     if repo:
                         path = os.path.join(repo.root, path)
                     try:
-                        mod = extensions.loadpath(path, b'hghook.%s' % hname)
+                        mod_name = 'hghook.%s' % pycompat.sysstr(hname)
+                        mod = extensions.loadpath(path, mod_name)
                     except Exception:
                         ui.write(_(b"loading %s hook failed:\n") % hname)
                         raise
-                    hookfn = getattr(mod, cmd)
+                    hookfn = getattr(mod, pycompat.sysstr(cmd))
                 else:
                     hookfn = cmd[7:].strip()
                 r, raised = pythonhook(