Python3环境下pipreqs扫描Python2代码报SyntaxError及依赖安装问题
问题与解决方案
问题背景
- 需基于不可修改的Python2代码生成
requirements.txt,当前运行在Python3.6虚拟环境,目标是安装依赖后通过测试 - 尝试
pip freeze和pipreqs生成依赖文件均失败,后续用--ignore生成文件但安装时出现版本不兼容问题
问题1:pipreqs扫描Python2代码触发SyntaxError
报错详情:
INFO: Not scanning for jupyter notebooks. ERROR: Failed on file: ./tests/data/python2.py Traceback (most recent call last): File "<frozen runpy>", line 198, in _run_module_as_main File "<frozen runpy>", line 88, in _run_code File "/Users/plus1/Desktop/black/venv/lib/python3.12/site-packages/pipreqs/pipreqs.py", line 615, in <module> main() # pragma: no cover ^^^^^^ File "/Users/plus1/Desktop/black/venv/lib/python3.12/site-packages/pipreqs/pipreqs.py", line 609, in main init(args) File "/Users/plus1/Desktop/black/venv/lib/python3.12/site-packages/pipreqs/pipreqs.py", line 533, in init candidates = get_all_imports( ^^^^^^^^^^^^^^^^ File "/Users/plus1/Desktop/black/venv/lib/python3.12/site-packages/pipreqs/pipreqs.py", line 153, in get_all_imports raise exc File "/Users/plus1/Desktop/black/venv/lib/python3.12/site-packages/pipreqs/pipreqs.py", line 139, in get_all_imports tree = ast.parse(contents) ^^^^^^^^^^^^^^^^^^^ File "/opt/homebrew/Cellar/python@3.12/3.12.2_1/Frameworks/Python.framework/Versions/3.12/lib/python3.12/ast.py", line 52, in parse return compile(source, filename, mode, flags, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "<unknown>", line 7 print >> sys.stderr , "Look, a repr:", `sys` ^ SyntaxError: invalid syntax
触发报错的Python2代码:
#!/usr/bin/env python2 import sys print >> sys.stderr , "Warning:" , print >> sys.stderr , "this is a blast from the past." print >> sys.stderr , "Look, a repr:", `sys` def function((_globals, _locals)): exec ur"print 'hi from exec!'" in _globals, _locals
原因:pipreqs在Python3环境中用Python3的ast.parse解析代码,而该代码包含Python2独有的语法(print >>语句、反引号repr语法、函数参数元组解包、ur""字符串),导致语法解析失败。
问题2:生成requirements.txt后安装失败
- 部分包版本不存在(高于PyPI上的可用版本)
- 安装
lxml==5.3.2时触发错误:pip._vendor.pytoml.core.TomlError: /private/var/folders/97/dkw6z2ts52q6bdx9939nslvm0000gn/T/pip-install-xl8nb688/lxml/pyproject.toml(46, 1): msg
原因:
- pipreqs可能生成了不兼容Python3.6的高版本包(比如lxml5.x系列要求Python3.7+,不支持3.6)
- 高版本包的
pyproject.toml语法或结构与旧版本pip(Python3.6配套的pip版本较低)不兼容
解决方案
解决pipreqs解析Python2代码的问题
选以下任意一种方法:
- 在Python2环境生成requirements.txt
- 搭建Python2.7虚拟环境,安装
pipreqs(pip install pipreqs),然后运行pipreqs .生成依赖文件,再复制到Python3.6环境使用
- 搭建Python2.7虚拟环境,安装
- 用支持Python2语法的依赖扫描工具
- 安装
pigar(支持Python2和3的依赖扫描):pip install pigar,运行pigar -r .生成requirements.txt
- 安装
- 手动提取依赖+语法兼容处理
- 直接从Python2代码中提取
import语句(示例中仅依赖sys,属于标准库,无第三方依赖),如果有其他第三方库,手动写入requirements.txt
- 直接从Python2代码中提取
- 用2to3转换代码后再扫描
- 先用
2to3转换Python2代码为Python3兼容版本:2to3 ./tests/data/python2.py -o ./tests/data/python3_compatible.py,再用pipreqs扫描转换后的文件
- 先用
解决依赖安装失败的问题
- 指定兼容Python3.6的包版本
- 对于
lxml,查找支持Python3.6的最高版本(比如4.9.3),修改requirements.txt为lxml==4.9.3 - 其他包同理,可通过PyPI官网搜索包名,查看其版本兼容性说明
- 对于
- 让pip自动选择兼容版本
- 运行
pip install -r requirements.txt --no-deps --upgrade,或者直接去掉requirements.txt中的版本号,让pip自动安装当前Python版本支持的最新兼容版本
- 运行
- 升级pip版本(Python3.6环境)
- 先升级pip到Python3.6支持的最高版本:
pip install pip==21.3.1(21.3.1是支持Python3.6的最后一个pip版本),再尝试安装依赖,可解决旧pip对pyproject.toml的兼容问题
- 先升级pip到Python3.6支持的最高版本:
内容的提问来源于stack exchange,提问作者J X
相关产品推荐
相关产品推荐

