Python2.7下pip安装命名空间包转为builtin致uWSGI导入异常排查
解决Python2.7下pip安装namespace包导致uWSGI导入失败的问题
我之前也踩过这个Python2.7的坑,pip和python setup.py install处理namespace packages的逻辑确实存在差异,尤其是nspkg.pth文件的生成逻辑会直接影响uWSGI的导入行为。下面是具体的排查和解决步骤:
问题根源
当用pip安装带有namespace_packages=['jmb']的包时,pip调用setuptools生成的jmb.nspkg.pth文件,可能会错误地将jmb命名空间标记为builtin模块;而直接用python setup.py install生成的pth文件是标准的namespace声明。uWSGI的Python导入机制对builtin模块优先级极高,这就导致它会忽略你实际安装的jmb.vega包,最终触发导入失败。
具体解决方法
1. 修正setup.py和namespace包的__init__.py
确保你的namespace包结构和setup配置完全符合setuptools的要求:
- 在
jmb目录下创建__init__.py,内容必须为:__import__('pkg_resources').declare_namespace(__name__) - 更新setup.py,明确使用
find_packages()识别子包:from setuptools import setup, find_packages setup( name='jmb.vega', namespace_packages=['jmb'], version='0.1', packages=find_packages(), # 其他必要配置(如author、description等) )
2. 用pip安装时禁用二进制包
pip默认优先使用wheel二进制包,而wheel打包过程中容易错误处理namespace的pth文件。改用源码安装可以规避这个问题:
pip install --no-binary :all: path/to/your/jmb.vega/package
3. 检查并修复nspkg.pth文件
安装完成后,前往Python的site-packages目录找到jmb.nspkg.pth,对比两种安装方式的内容:
- 正确的pth内容应该类似:
import sys,types,os; sys.modules.setdefault('jmb', types.ModuleType('jmb')); __import__('pkg_resources').declare_namespace('jmb') - 如果pip生成的pth里存在将
jmb加入sys.builtin_module_names的逻辑,手动替换成上面的正确内容,然后重启uWSGI。
4. 调整uWSGI配置确保site-packages加载
在uWSGI的配置文件中,明确指定PYTHONPATH包含你的包安装目录,或者确保uWSGI没有忽略site-packages的pth文件:
[uwsgi] pythonpath = /path/to/your/python/site-packages # 其他配置...
验证步骤
安装完成后,先在普通Python环境中测试导入:
import jmb.vega print(jmb.vega.__file__)
如果能正常打印包的路径,再启动uWSGI测试,确认导入问题解决。
内容的提问来源于stack exchange,提问作者Alessandro Dentella
相关产品推荐
相关产品推荐

