changeset 17798:4091b0322918

win32mbcs: add reversing wrapper for some unicode-incompatible functions. This changeset fix the problem to use win32mbcs with mercurial 2.3 or later. The problem is brought by side effect of modification of encoding.upper() (changeset 17236:9fb8312dbdbd) because upper() does not accept unicode string argument. So wrapped util.normcase() which uses upper() will fail. In other words, upper() and lower() are unicode incompatible. To fix this issue, this changeset adds new wrapper for reversed conversion (unicode to str) for lower() and upper() to use them safely.
author Shun-ichi GOTO <shunichi.goto@gmail.com>
date Wed, 17 Oct 2012 18:09:00 +0900
parents e4da793998bf
children 327fbe0b84fd
files hgext/win32mbcs.py
diffstat 1 files changed, 22 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/hgext/win32mbcs.py	Fri Oct 05 16:27:34 2012 -0700
+++ b/hgext/win32mbcs.py	Wed Oct 17 18:09:00 2012 +0900
@@ -89,19 +89,28 @@
         s += os.sep
     return s
 
-def wrapper(func, args, kwds):
-    # check argument is unicode, then call original
+
+def basewrapper(func, argtype, enc, dec, args, kwds):
+    # check check already converted, then call original
     for arg in args:
-        if isinstance(arg, unicode):
+        if isinstance(arg, argtype):
             return func(*args, **kwds)
 
     try:
-        # convert arguments to unicode, call func, then convert back
-        return encode(func(*decode(args), **decode(kwds)))
+        # convert string arguments, call func, then convert back the
+        # return value.
+        return enc(func(*dec(args), **dec(kwds)))
     except UnicodeError:
         raise util.Abort(_("[win32mbcs] filename conversion failed with"
                          " %s encoding\n") % (_encoding))
 
+def wrapper(func, args, kwds):
+    return basewrapper(func, unicode, encode, decode, args, kwds)
+
+
+def reversewrapper(func, args, kwds):
+    return basewrapper(func, str, decode, encode, args, kwds)
+
 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 +142,11 @@
  mercurial.util.fspath mercurial.util.pconvert mercurial.util.normpath
  mercurial.util.checkwinfilename mercurial.util.checkosfilename'''
 
+# These functions are required to be called with local encoded string
+# because they expects argument is local encoded string and cause
+# problem with unicode string.
+rfuncs = '''mercurial.encoding.upper mercurial.encoding.lower'''
+
 # List of Windows specific functions to be wrapped.
 winfuncs = '''os.path.splitunc'''
 
@@ -159,6 +173,9 @@
             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, reversewrapper)
         # Check sys.args manually instead of using ui.debug() because
         # command line options is not yet applied when
         # extensions.loadall() is called.