You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何读取Python包requires.txt中的依赖并评估条件表达式?

处理Python 2.7下带条件的cryptography依赖(用于RPM元数据)

针对你用python setup.py bdist_rpm构建cryptography-2.2.2时遇到的带条件表达式的依赖问题,我给你两种实用的解决方法,帮你读取并评估这些依赖,最终整理出适合添加到RPM元数据的内容:

方法一:用setuptools自带工具解析(推荐)

Python2.7的setuptools(只要版本≥36.0)自带了解析PEP 508格式条件依赖的能力,能自动根据当前环境过滤出有效的依赖。

  1. 先确保你的setuptools版本达标:
    pip install setuptools>=36.0
    
  2. 写个简单的Python脚本解析requires.txt:
    from pkg_resources import parse_requirements
    
    def get_valid_deps(requires_file_path):
        valid_dependencies = []
        with open(requires_file_path, 'r') as f:
            # 逐个解析依赖项
            for req in parse_requirements(f.read()):
                # 检查当前环境是否满足依赖的条件标记
                if req.marker is None or req.marker.evaluate():
                    valid_dependencies.append(str(req.req))
        return valid_dependencies
    
    # 替换成你的requires.txt实际路径
    final_deps = get_valid_deps('/src/cryptography.egg-info/requires.txt')
    # 输出结果,方便后续导入RPM元数据
    print("\n".join(final_deps))
    
  3. 运行这个脚本,就能直接得到当前Python2.7环境下需要的所有依赖,之后你可以把这些内容添加到RPM的Requires字段里。

方法二:手动解析并评估条件(无额外依赖)

如果你不想升级setuptools,也可以手动解析文件内容,不过要注意只有在你完全信任requires.txt内容的情况下才用这种方法(因为用到了eval)。

  1. 用下面的脚本处理:
    import sys
    import platform
    import os
    
    def check_marker_condition(marker_str):
        # 准备PEP 508标记用到的环境变量
        env_vars = {
            'platform_python_implementation': platform.python_implementation(),
            'python_version': '.'.join(map(str, sys.version_info[:2])),
            'sys_platform': sys.platform,
            'os_name': os.name
        }
        # 把标记语法转成Python可执行的表达式
        eval_expr = marker_str.replace('!=', '!=') \
                              .replace('==', '==') \
                              .replace('>=', '>=') \
                              .replace('<', '<')
        return eval(eval_expr, {}, env_vars)
    
    def extract_valid_deps(requires_file_path):
        valid_deps = []
        with open(requires_file_path, 'r') as f:
            for line in f:
                line = line.strip()
                # 跳过空行和注释
                if not line or line.startswith('#'):
                    continue
                # 分离依赖和条件部分
                if '[' in line and ']' in line:
                    dep_content, marker_content = line.split('[', 1)
                    marker_content = marker_content.rstrip(']')
                    # 评估条件,满足就保留这个依赖
                    if check_marker_condition(marker_content):
                        valid_deps.append(dep_content.strip())
                else:
                    # 没有条件的直接保留
                    valid_deps.append(line.strip())
        return valid_deps
    
    # 替换为你的文件路径
    final_deps = extract_valid_deps('/src/cryptography.egg-info/requires.txt')
    print("\n".join(final_deps))
    

整合到RPM构建流程

拿到解析后的依赖列表后,你可以把它整合到RPM构建里:

  • 比如在RPM spec文件中,先运行脚本生成依赖列表,再传给bdist_rpm:
    %prep
    # 运行脚本生成有效依赖文件
    %{__python} your_script.py > resolved_deps.txt
    
    %build
    # 把依赖用逗号分隔传给bdist_rpm的--requires参数
    python setup.py bdist_rpm --requires="$(cat resolved_deps.txt | tr '\n' ',')"
    
  • 或者直接修改setup.py,在setup()函数里动态设置install_requires为解析后的依赖列表,这样bdist_rpm会自动把这些依赖写入RPM元数据。

内容的提问来源于stack exchange,提问作者Eddy Pronk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:18:28