如何修复Python 2.7环境下Docker构建时的setup.py egg_info错误
问题
接手一套Docker容器化部署环境,原维护人员已离职。构建镜像时,requirements.txt中指定的包安装失败。
原requirements.txt内容
setuptools==40.6.3 pip==1.5.4 paramiko==2.4.2 scp==0.13.0 timeout_decorator==0.4.1 requests==2.21.0 pylint==1.9.4 jsonschema==2.6.0 six==1.11.0 dnslib==0.9.10 SQLAlchemy==1.3.5 psycopg2==2.8.3 future==0.17.1 tenacity
安装错误日志
Collecting lazy-object-proxy (from astroid<2.0,>=1.6->pylint==1.9.4->-r requirements.txt (line 7)) Downloading https://files.pythonhosted.org/packages/6f/3e/7c80e8536b9d5eb66e784fff4c359adf9e55b37460fd6928192256ba71f2/lazy-object-proxy-1.7.0.tar.gz (42kB) Complete output from command python setup.py egg_info: Traceback (most recent call last): File "<string>", line 1, in <module> File "/tmp/pip-build-JMyxNe/lazy-object-proxy/setup.py", line 146, in <module> distclass=BinaryDistribution, File "/usr/lib/python2.7/dist-packages/setuptools/__init__.py", line 128, in setup _install_setup_requires(attrs) File "/usr/lib/python2.7/dist-packages/setuptools/__init__.py", line 123, in _install_setup_requires dist.fetch_build_eggs(dist.setup_requires) File "/usr/lib/python2.7/dist-packages/setuptools/dist.py", line 513, in fetch_build_eggs replace_conflicting=True, File "/usr/lib/python2.7/dist-packages/pkg_resources/__init__.py", line 774, in resolve replace_conflicting=replace_conflicting File "/usr/lib/python2.7/dist-packages/pkg_resources/__init__.py", line 1057, in best_match return self.obtain(req, installer) File "/usr/lib/python2.7/dist-packages/pkg_resources/__init__.py", line 1069, in obtain return installer(requirement) File "/usr/lib/python2.7/dist-packages/setuptools/dist.py", line 580, in fetch_build_egg return cmd.easy_install(req) File "/usr/lib/python2.7/dist-packages/setuptools/command/easy_install.py", line 698, in easy_install return self.install_item(spec, dist.location, tmpdir, deps) File "/usr/lib/python2.7/dist-packages/setuptools/command/easy_install.py", line 724, in install_item dists = self.install_eggs(spec, download, tmpdir) File "/usr/lib/python2.7/dist-packages/setuptools/command/easy_install.py", line 909, in install_eggs return self.build_and_install(setup_script, setup_base) File "/usr/lib/python2.7/dist-packages/setuptools/command/easy_install.py", line 1177, in build_and_install self.run_setup(setup_script, setup_base, args) File "/usr/lib/python2.7/dist-packages/setuptools/command/easy_install.py", line 1163, in run_setup run_setup(setup_script, args) File "/usr/lib/python2.7/dist-packages/setuptools/sandbox.py", line 253, in run_setup raise File "/usr/lib/python2.7/contextlib.py", line 35, in __exit__ self.gen.throw(type, value, traceback) File "/usr/lib/python2.7/dist-packages/setuptools/sandbox.py", line 195, in setup_context yield File "/usr/lib/python2.7/contextlib.py", line 35, in __exit__ self.gen.throw(type, value, traceback) File "/usr/lib/python2.7/dist-packages/setuptools/sandbox.py", line 166, in save_modules saved_exc.resume() File "/usr/lib/python2.7/dist-packages/setuptools/sandbox.py", line 141, in resume six.reraise(type, exc, self._tb) File "/usr/lib/python2.7/dist-packages/setuptools/sandbox.py", line 154, in save_modules yield saved File "/usr/lib/python2.7/dist-packages/setuptools/sandbox.py", line 195, in setup_context yield File "/usr/lib/python2.7/dist-packages/setuptools/sandbox.py", line 250, in run_setup _execfile(setup_script, ns) File "/usr/lib/python2.7/dist-packages/setuptools/sandbox.py", line 44, in _execfile code = compile(script, filename, 'exec') File "/tmp/easy_install-bKS9kl/setuptools_scm-7.0.5/setup.py", line 20 def scm_version() -> str: ^ SyntaxError: invalid syntax ---------------------------------------- Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-JMyxNe/lazy-object-proxy/
已知当前使用Python 2.7(暂无法升级到Python 3+),原本这些包版本适配Python 2.7且之前运行正常,删除镜像后出现该问题,求修复方案。
解决方案
问题根源是:lazy-object-proxy默认拉取了不兼容Python 2.7的新版本,且依赖的setuptools_scm 7.x版本使用了Python 3的类型注解语法,导致Python 2.7解析报错。同时原requirements.txt中tenacity未指定版本,也可能拉取到不兼容版本。
按以下步骤修复:
1. 锁定所有依赖的兼容版本
修改requirements.txt,明确指定Python 2.7兼容的依赖版本,包括间接依赖:
setuptools==40.6.3 pip==1.5.4 paramiko==2.4.2 scp==0.13.0 timeout_decorator==0.4.1 requests==2.21.0 pylint==1.9.4 jsonschema==2.6.0 six==1.11.0 dnslib==0.9.10 SQLAlchemy==1.3.5 psycopg2==2.8.3 future==0.17.1 # 指定tenacity兼容Python2.7的最高版本 tenacity==5.1.5 # 锁定lazy-object-proxy的Python2.7兼容版本 lazy-object-proxy==1.4.3 # 锁定astroid版本(pylint的依赖,确保兼容) astroid==1.6.6 # 锁定setuptools_scm的Python2.7兼容版本 setuptools_scm==1.19.0
2. 调整Docker构建时的pip安装命令
在Dockerfile中,使用pip install时添加--no-cache-dir避免缓存旧的错误包,同时确保先安装指定的setuptools和pip,再安装其他依赖:
# 假设基础镜像是Python2.7 FROM python:2.7-slim WORKDIR /app COPY requirements.txt . # 先安装指定版本的setuptools和pip RUN pip install --no-cache-dir setuptools==40.6.3 pip==1.5.4 # 再安装所有依赖 RUN pip install --no-cache-dir -r requirements.txt # 其他构建步骤...
3. 验证依赖兼容性
如果仍有报错,可通过以下方式排查:
- 确认每个包的版本是否明确支持Python 2.7
- 使用
pip install <package>==<version>单独测试安装,定位具体问题包 - 针对旧版pip,添加
--use-deprecated=legacy-resolver参数优化依赖解析:pip install --use-deprecated=legacy-resolver --no-cache-dir -r requirements.txt
内容的提问来源于stack exchange,提问作者Akshay Jagtap
相关产品推荐
相关产品推荐

