【发布时间】:2016-03-01 22:54:44
【问题描述】:
当尝试在我的 Windows 10 机器上安装 mysql-python 时,我收到以下错误:
File "<string>", line 1, in <module>
File "C:\Users\LUCAFL~1\AppData\Local\Temp\pip-build-3u7aih0l\mysql-python\setup.py", line 21, in <module>
setuptools.setup(**metadata)
File "c:\program files (x86)\python35-32\lib\distutils\core.py", line 148, in setup
dist.run_commands()
...
File "c:\program files (x86)\python35-32\lib\subprocess.py", line 1055, in communicate
stdout = self.stdout.read()
File "c:\program files (x86)\python35-32\lib\encodings\cp1252.py", line 23, in decode
return codecs.charmap_decode(input,self.errors,decoding_table)[0]
UnicodeDecodeError: 'charmap' codec can't decode byte 0x81 in position 1716: character maps to <undefined>
我尝试安装其他软件包并且几乎每个软件包都收到相同的错误(一个例外是 pymysql)。所有这些包都很大并且有依赖关系。我猜那些大的会在我的用户目录 APPDATA 文件夹中创建临时数据。如您所见, ü 未正确解码(ü 为字节 0x81)。产生错误的总是德语变音符号(主要是 ü,因为它是我的用户文件夹名称的一部分)。
我在过去的 2 个小时里搜索了很多人,发现很多人都有同样的问题,但大多数人是在打开 github 票证或讨论 Ubuntu/Fedora/OSX 等问题。我读过几次,标准windows下的编码是cp-1252,这会导致问题。我可以使用控制台强制 Windows 使用 utf-8 进行此会话,然后运行 pip 吗?
请不要建议我重命名我的用户文件夹。在 Windows 10 下不容易完成,我不想仅仅因为 python 就重新安装 Windows。
我的设置:Windows 10、Python 3.5.1、pip 8.0.3
【问题讨论】:
-
distutils._msvccompiler._get_vc_env使用子进程模块调用vcvarsall.bat和set获取环境。当stdout是管道时,cmd.exe 内置命令(例如set)默认使用当前控制台代码页,在您的情况下是 OEM 代码页 850。但是使用universal_newlines=True子进程使用 ANSI 解码输出代码页,在您的情况下为 1252。作为快速修复,首先运行chcp.com 1252以更改控制台代码页。 -
这里distutils的最佳选择是直接调用
subprocess.Popen运行cmd.exe /U /c,这使得内置的set命令输出UTF-16LE文本。然后从stdout = io.TextIOWrapper(proc.stdout, encoding='utf-16le')读取输出。通过这种方式,您可以获得准确的 Unicode 环境,而不是通过 ANSI 或 OEM 代码页转换来破坏它。 -
这似乎解决了解码问题。我仍然有点困惑,为什么更改代码页可以解决问题。我还以为是 UnicodeDecodeError?
-
subprocess.Popen的universal_newlines选项使用io.TextIOWrapper包装子进程stdout流,该io.TextIOWrapper使用平台的首选编码(即Windows 上的ANSI 代码页)对流进行解码。但是 cmd.exe 正在使用控制台代码页对set命令的输出进行编码,该代码页默认为 OEM 代码页 850。在代码页 850 中,“ü”是b'\x81',它不是由代码页 1252 映射的——因此解码错误。 -
将环境转换为代码页 850 或 1252 真的很可怕。环境是 Unicode,文件系统是 Unicode,因此来自环境变量的相关路径,尤其是涉及用户名时,可能无法在 OEM 或 ANSI 代码页中编码。在您的情况下,ANSI 有效,但我在错误报告方面看到了不止几个案例,其中需要从头到尾严格使用 Unicode。现在是 2016 年,我们仍然被 80 年代和 90 年代早期 Unicode 时代之前的代码页所困扰。真可惜。
标签: python windows python-3.x pip