[PATCH] win32mbcs: add reversing wrapper for some unicode-incompatible functions

Shun-ichi Goto shunichi.goto at gmail.com
Mon Sep 24 07:27:37 CDT 2012


# HG changeset patch
# User Shun-ichi GOTO <shunichi.goto at gmail.com>
# Date 1347635617 -32400
# Node ID 2b017d07ef7cd11137f20d668bece48937172264
# Parent  453d790fe0896cb7c62ecd8cc013128b3994fcb4
win32mbcs: add reversing wrapper for some unicode-incompatible functions.

This changeset add new reverse-action wrapper to encode unicode string
argument to byte string argument, and apply to encoding.lower() and
encoding.upper() which does not allow unicode argument.

diff -r 453d790fe089 -r 2b017d07ef7c hgext/win32mbcs.py
--- a/hgext/win32mbcs.py	Thu Sep 13 17:00:56 2012 -0700
+++ b/hgext/win32mbcs.py	Sat Sep 15 00:13:37 2012 +0900
@@ -89,19 +89,20 @@
         s += os.sep
     return s
 
-def wrapper(func, args, kwds):
-    # check argument is unicode, then call original
-    for arg in args:
-        if isinstance(arg, unicode):
-            return func(*args, **kwds)
-
-    try:
-        # convert arguments to unicode, call func, then convert back
-        return encode(func(*decode(args), **decode(kwds)))
-    except UnicodeError:
-        raise util.Abort(_("[win32mbcs] filename conversion failed with"
-                         " %s encoding\n") % (_encoding))
-
+def makewrapper(argconv, retconv, type):
+    def wrapper(func, args, kwds):
+        # check argument is unicode, then call original
+        ret = None
+        for arg in args:
+            if isinstance(arg, type):
+                return func(*args, **kwds)
+        try:
+            return retconv(func(*argconv(args), **argconv(kwds)))
+        except UnicodeError:
+            raise util.Abort(_("[win32mbcs] filename conversion failed with"
+                               " %s encoding\n") % (_encoding))
+    return wrapper
+        
 def wrapperforlistdir(func, args, kwds):
     # Ensure 'path' argument ends with os.sep to avoids
     # misinterpreting last 0x5c of MBCS 2nd byte as path separator.
@@ -133,6 +134,10 @@
  mercurial.util.fspath mercurial.util.pconvert mercurial.util.normpath
  mercurial.util.checkwinfilename mercurial.util.checkosfilename'''
 
+# List of functions to be wrapped with reversing wrapper
+# because they expects byte string argument.
+rfuncs = '''mercurial.encoding.upper mercurial.encoding.lower'''
+
 # List of Windows specific functions to be wrapped.
 winfuncs = '''os.path.splitunc'''
 
@@ -153,12 +158,17 @@
     _encoding = ui.config('win32mbcs', 'encoding', encoding.encoding)
     # fake is only for relevant environment.
     if _encoding.lower() in problematic_encodings.split():
+        # wrap functions to be called with unicode arguments
+        wrapper = makewrapper(decode, encode, unicode)
         for f in funcs.split():
             wrapname(f, wrapper)
         if os.name == 'nt':
             for f in winfuncs.split():
                 wrapname(f, wrapper)
         wrapname("mercurial.osutil.listdir", wrapperforlistdir)
+        # wrap functions to be called with local byte string arguments
+        for f in rfuncs.split():
+            wrapname(f, makewrapper(encode, decode, str))
         # Check sys.args manually instead of using ui.debug() because
         # command line options is not yet applied when
         # extensions.loadall() is called.


More information about the Mercurial-devel mailing list