处理python mkdtemp中的unicode用户名

我被http://bugs.python.org/issue1681974咬了 – 从那里引用:

如果Windows用户名中包含任何非ASCII字符(如ä或ö),则mkdtemp将在Windows上失败。 mkdtemp引发编码错误。 这似乎是因为在Windows中的默认临时目录是"c:\documents and settings\<user name>\local settings\temp"

OP使用的解决方法是:

 try: # workaround for http://bugs.python.org/issue1681974 return tempfile.mkdtemp(prefix=prefix) except UnicodeDecodeError: tempdir = unicode(tempfile.gettempdir(), 'mbcs') return tempfile.mkdtemp(prefix=prefix, dir=tempdir) 

我有两个问题:

  1. 为什么这应该工作?
  2. 这是多么充分的证据? 从类似的问题(请参阅此答案: Python Popen未能在Windows PowerShell中使用正确的编码 )我得到的概念,我可能应该使用sys.stdout.encoding – 我在任何地方附近的标记?

编辑:实际上是行:

 print u"input encoding: %s; output encoding: %s; locale: %s" % ( sys.stdin.encoding,getattr(sys.stdout,'encoding',None), locale.getdefaultlocale()) 

版画

input编码:无; 输出编码:无; 语言环境:('ja_JP','cp932')

所以也许我应该去locale.getpreferredencoding()(例如请参阅subprocess.Popen 与unicodepath )

编辑2:在评论中,build议我用mbcs编码前缀 – 不幸的是这不是一个选项,因为代码库在任何地方都会使用unicode,并且迟早会出现。 发布的代码是一个简化的片段。

Edit3 :我的小解决方法显然没有解决任何问题 – 将尝试:

 fsenc = sys.getfilesystemencoding() or 'mbcs' return tempfile.mkdtemp(prefix=prefix.encode(fsenc)).decode(fsenc) 

如果有任何非ascii用户离开testing是。

同时 – 下面的复制者不适合我:

 C:\_\Python27\python.exe -u C:\__\JetBrains\PyCharm 3.4.1\helpers\pydev\pydevconsole.py 18324 18325 PyDev console: starting.import sys; print('Python %s on %s' % (sys.version, sys.platform)) Python 2.7.8 (default, Jun 30 2014, 16:03:49) [MSC v.1500 32 bit (Intel)] on win32 sys.path.extend(['C:\\Dropbox\\eclipse_workspaces\\python\\wrye-bash']) >>> d = u'ελληνικα'.encode(sys.getfilesystemencoding()); os.environ['TEMP'] = os.path.abspath(d) >>> import tempfile; tempfile.mkdtemp(prefix=u'x') u'c:\\users\\mrd\\appdata\\local\\temp\\xtf3nav' 

和变化…

编辑4 – 目录存在绝对的意义:

 >>> d = u'ελληνικα'.encode(sys.getfilesystemencoding()); os.path.abspath(d) 'C:\\Dropbox\\eclipse_workspaces\\python\\wrye-bash\\e??????a' >>> assert os.path.isdir(os.path.abspath(d)) Traceback (most recent call last): File "<input>", line 1, in <module> AssertionError >>> d = u'ελληνικα' >>> os.path.abspath(d) u'C:\\Dropbox\\eclipse_workspaces\\python\\wrye-bash\\\u03b5\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03b1' >>> assert os.path.isdir(os.path.abspath(d)) >>> 

我终于同意了:

 sys_fs_enc = sys.getfilesystemencoding() or 'mbcs' @staticmethod def tempDir(prefix=None): try: # workaround for http://bugs.python.org/issue1681974 see there return tempfile.mkdtemp(prefix=prefix) except UnicodeDecodeError: try: traceback.print_exc() print 'Trying to pass temp dir in...' tempdir = unicode(tempfile.gettempdir(), sys_fs_enc) return tempfile.mkdtemp(prefix=prefix, dir=tempdir) except UnicodeDecodeError: try: traceback.print_exc() print 'Trying to encode temp dir prefix...' return tempfile.mkdtemp( prefix=prefix.encode(sys_fs_enc)).decode(sys_fs_enc) except: traceback.print_exc() print 'Failed to create tmp dir, Bash will not function ' \ 'correctly.' 

显然 ,第一次尝试抓住就足够了,但是我留下了回溯,所以我可以得到更多的输入;)