如何通过代码获取自身pyproject.toml中的依赖列表?
获取pyproject.toml中符合当前Python版本的依赖列表
可以通过两种场景实现需求:开发阶段直接解析配置文件,或针对已安装的包读取元数据。
场景1:开发阶段解析pyproject.toml
直接读取并解析pyproject.toml,手动评估每个依赖的环境条件,筛选出符合当前Python版本的依赖名称。
实现代码
import sys from typing import List # 兼容Python版本:3.11+用内置tomllib,低版本用tomli try: import tomllib except ImportError: import tomli as tomllib def get_dev_dependencies() -> List[str]: # 读取pyproject.toml文件(注意路径,确保文件在当前工作目录) with open("pyproject.toml", "rb") as f: pyproject_data = tomllib.load(f) raw_deps = pyproject_data["project"]["dependencies"] valid_deps = [] for dep in raw_deps: # 拆分依赖名称与环境条件 if ";" in dep: dep_part, condition = dep.split(";", 1) dep_name = dep_part.split("=")[0].split(">")[0].split("<")[0].strip() # 构造PEP 508环境标记变量,用于评估条件 env_vars = { "python_version": f"{sys.version_info.major}.{sys.version_info.minor}", "python_full_version": sys.version.split()[0], "os_name": sys.platform } # 评估条件是否满足当前环境 try: if eval(condition.strip(), {}, env_vars): valid_deps.append(dep_name) except Exception: # 条件评估失败时跳过该依赖 continue else: # 无环境条件的依赖直接加入列表 dep_name = dep.split("=")[0].split(">")[0].split("<")[0].strip() valid_deps.append(dep_name) return valid_deps # 测试调用 if __name__ == "__main__": print(get_dev_dependencies())
说明
- 需要在Python<3.11环境下提前安装
tomli包(可加入开发依赖)。 - 严格按照PEP 508规范解析环境条件,确保筛选结果准确。
场景2:已安装的包读取元数据
包安装后,pyproject.toml不会被包含在安装目录中,此时可以通过Python的元数据API获取已处理好的依赖列表(已自动过滤不满足当前环境的依赖)。
实现代码
import sys from typing import List # 兼容Python版本:3.8+用内置importlib.metadata,低版本用importlib_metadata try: import importlib.metadata as pkg_metadata except ImportError: import importlib_metadata as pkg_metadata def get_installed_deps(package_name: str) -> List[str]: # 获取已安装包的依赖列表(已自动过滤环境条件) reqs = pkg_metadata.requires(package_name) if not reqs: return [] # 提取纯依赖名称,去除版本约束 return [req.split("=")[0].split(">")[0].split("<")[0].strip() for req in reqs] # 测试调用(替换为你的包名,比如示例中的"foobar") if __name__ == "__main__": print(get_installed_deps("foobar"))
说明
pkg_metadata.requires()会返回当前环境下该包实际需要的依赖,无需手动处理条件判断。- Python<3.8需要提前安装
importlib_metadata包。
内容的提问来源于stack exchange,提问作者Nico Schlömer
相关产品推荐
相关产品推荐

