【问题标题】:Pip install raises UnicodeDecodeError on Windows. Fix?Pip install 在 Windows 上引发 UnicodeDecodeError。使固定?
【发布时间】: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.batset获取环境。当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.Popenuniversal_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


【解决方案1】:

您可以尝试以下方法,看看它是否有效。用您的实际路径替换 python 的路径。
我无法在我的 Windows 笔记本电脑上进行模拟。

import sys
import subprocess

reload(sys)  # Reload may do the trick!
sys.setdefaultencoding('UTF8')


theproc =subprocess.call(['C:\\Python27\\Scripts\\pip.exe', 'install', 'mysql-python'])
theproc.communicate()

【讨论】:

  • 我用谷歌搜索了一下,除了提出另一个可能破坏依赖于标准 ascii 编码的代码的问题外,python 3 中删除了 sys.setdefaultencoding hack。
  • 你可以在最后一行再次使用reload(sys)。这将在执行下一组代码之前重新加载默认系统参数,因此有望防止任何破坏。我们正在尝试将其仅用于pip install 部分。
  • 代码取决于 ascii,我的意思是整个安装过程(无论那里发生什么)。这种方法仍然不适用于 python3.x,sys.setdefaultencoding 将保持删除状态,即使在调用 imp.reload 时也是如此。
猜你喜欢
  • 1970-01-01
  • 2014-09-22
  • 1970-01-01
  • 2017-03-20
  • 1970-01-01
  • 2014-08-11
  • 1970-01-01
  • 2016-04-29
  • 1970-01-01
相关资源
最近更新 更多