2011年9月16日

Sublime Text 2的Tortoise插件中文路径问题

今天在使用Sublime Text 2的Tortoise插件的时候,由于svn的路径中有中文,导致Tortoise一直报错:

error: 'ascii' codec can't encode character in position 25-28: ordinal not in range(128)

调试发现是Tortoise.py中如下代码抛出的错误:

proc = subprocess.Popen(self.args, stdin=subprocess.PIPE,stdout=subprocess.PIPE, stderr=subprocess.STDOUT,startupinfo=startupinfo, cwd=self.cwd)

经过一番google,发现这应该是python的bug,具体分析请看subprocess.call fails with unicode strings in command line.
这个bug一直到python2.7都没有fix,而Sublime Text 2用的还是python2.6...

幸好这个页面有人提供了两个解决方案:

  1. 给subprocess.py打patch
  2. 给_subprocess.c打patch

我尝试了第一个patch,原本的修改如下:

--- Lib/subprocess.py.orig    2008-10-01 11:37:34.034500000 -0700  
 +++ Lib/subprocess.py    2008-10-01 12:35:10.018875000 -0700  
 @@ -766,11 +766,15 @@  
               startupinfo, creationflags, shell,  
               p2cread, p2cwrite,  
               c2pread, c2pwrite,  
 -              errread, errwrite):  
 +              errread, errwrite, sys=sys):  
        """Execute program (MS Windows version)"""  
        if not isinstance(args, types.StringTypes):  
          args = list2cmdline(args)  
 +      if isinstance(args, unicode):  
 +        args = args.encode(sys.getfilesystemencoding())  
 +      if isinstance(executable, unicode):  
 +        executable = executable.encode(sys.getfilesystemencoding())  
        # Process startup details  
        if startupinfo is None:  

但是使用这个patch还是报错,这是因为除了args和executable有可能是unicode的,cwd也有可能是unicode。
在这里,Tortoise插件传给subprocess的cwd就是中文路径,所以还要对cwd进行encode,因此还需要加上下面这段:

if isinstance(cwd, unicode):
    cwd = cwd.encode(sys.getfilesystemencoding())

Sublime Text 2是通过python26.zip中的subprocess.pyo来加载subprocess的,把修改过的subprocess.py编译成subprocess.pyo再替换就可以了.
当然直接删掉subprocess.pyo,再添加修改过的subprocess.py也没啥问题.
重启Sublime Text 2就可以顺利使用Tortoise插件了.