介绍
Python为了提供给开发者较为便捷的调试环境,允许开发者在不对包进行封装(即使用python setup.py
或python -m build
)的前提下,使用pip install --editable .
对开发中的软件包进行可编辑的安装(editable installs),这也被称为development mode。详情请参阅https://setuptools.pypa.io/en/latest/userguide/development_mode.html
表现
我在使用pip install --editable .
命令后,计算机上的Python环境发生了致命的崩溃。每次启动任何依赖于Python的程序时,均会报错如下:
Fatal Python error: init_import_size: Failed to import the site module
Python runtime state: initialized
Traceback (most recent call last):
File "C:ProgramDataAnaconda3libsite.py", line 580, in
main()
File "C:ProgramDataAnaconda3libsite.py", line 567, in main
known_paths = addsitepackages(known_paths)
File "C:ProgramDataAnaconda3libsite.py", line 350, in addsitepackages
addsitedir(sitedir, known_paths)
File "C:ProgramDataAnaconda3libsite.py", line 208, in addsitedir
addpackage(sitedir, name, known_paths)
File "C:ProgramDataAnaconda3libsite.py", line 164, in addpackage
for n, line in enumerate(f):
UnicodeDecodeError: 'gbk' codec can't decode byte 0xa4 in position 44: illegal multibyte sequence
这一报错涉及到了所有需要使用Python解释器的程序,包括pip
、conda
等,使得想要反悔操作也不可行(比如用pip uninstall
)。所有在StackOverflow
上查阅的方法均不可行。
原因
通过查阅site.py
源代码和Development Mode的文档,找到问题所在:我所安装的包的路径中包含中文字符,而pip install --editable
指令会在site-packages
路径下生成一个__editable__.*.pth
文件。
打开该文件,可以发现文件中记录着安装的包的绝对路径。而我的路径是包含中文字符的。并且,该文件采用了UTF-8编码——这个文件是pip自动生成的,编码格式并不由我决定。
而所谓的editable install,就是指将包的绝对路径以.pth
文件的形式添加到site-packages
下,而site.py
则会在每一次Python解释器启动时,自动地、优先地导入这些.pth
文件所描述的路径至sys.path
列表中。只有当这些路径全部成功导入后,正式的Python代码才会运行。问题正是出现在site.py
的第160行,io.TextIOWrapper()
中。
由于site.py
没能显式地指定encoding
的类型,TextIOWrapper
的构造函数默认会调用locale.getpreferredencoding(False)
方法。由于Win32API自身的问题,在某些计算机中不可避免地会得到'cp936'
的返回值,而'cp936'
就是GBK编码的含义。使用GBK来解码UTF8编码的.pth
文件,自然会遇到乱码报错问题。
这一返回值是Win32API的固有属性,无法针对这一值进行配置。
解决方案
通过上面的分析,可以想到如下两种解决方案:
1. 避免使用中文路径,这一方法治标不治本;
2. 修改site.py
第160行,使其成为
Python使用development mode后报Fatal Python error成因及解决方案 由 赵匡是 采用 知识共享 署名 4.0 国际 许可协议进行许可。
本许可协议授权之外的使用权限可以从 关于知识产权 处获得。
真不错