python - 在 python mkdtemp 中处理 unicode 用户名

标签 python windows python-2.7 unicode python-unicode

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

mkdtemp fails on Windows if Windows user name has any non-ASCII characters, like ä or ö, in it. mkdtemp throws an encoding error. This seems to be because the default temp dir in Windows is "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)

我有 2 个问题:

  1. 为什么这应该有效?
  2. 这有多充分的证据?从类似的问题(参见这个答案: Python Popen failing to use proper encoding in 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 encoding: None; output encoding: None; locale: ('ja_JP', 'cp932')

所以也许我应该选择 locale.getpreferredencoding() (例如 subprocess.Popen with a unicode path )

Edit2:在评论中建议我将前缀编码为mbcs - 不幸的是,这不是一个选项,因为代码库期望unicode无处不在,并且迟早会崩溃。发布的代码是一个简化的片段。

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

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

是否还有任何非 ascii 用户需要测试。

同时 - 下面的复制器不适合我:

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'

以及变体...

edit4 - 目录以绝对意义存在:

>>> 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.'

Apparently第一次 try catch 就足够了,但我留下了回溯,这样我就可以获得更多输入;)

关于python - 在 python mkdtemp 中处理 unicode 用户名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28101187/

相关文章:

python filelock模块删除文件

python - 在对另一列进行分组后,查找列值的最大出现次数

c++ - 获取文件的完整路径给定其 "Reference Number"

c++ - 免费数值库、C++、Windows

python - 整数除法在 CPython 2.7 和 Spyder 中给出不同的结果

python - 如何将值从一个列表转移到另一个列表?

python - 根据重复模式捕获整个重复字符串

python - 修改嵌套列表

python - 用于 u""文字的编码

windows - 您如何测试窗口(按标题)是否已从命令提示符打开?