导入Python自定义包时如何获取对应版本的git hash
Python包非仓库环境下获取构建时Git Hash的实现方案
核心思路
不要将Git Hash拼入版本号违反PEP 440规范,而是在构建包的阶段,将当前仓库的Git Hash写入包内的自动生成文件,安装后直接读取该文件的固定值即可,全程不需要依赖Git环境。
实现步骤
1. 调整项目结构
新增自动生成的版本存储文件,示例结构如下:
项目根目录/ ├── mypackage/ # 你的Python包目录 │ ├── __init__.py │ └── _version.py # 自动生成,不需要提交到Git仓库 ├── setup.py └── .gitignore
2. 配置setup.py构建逻辑
在setup.py中新增Git Hash获取、自动写入_version.py的逻辑,版本号使用符合PEP 440规范的正式版本:
import os from setuptools import setup from subprocess import check_output, CalledProcessError def get_git_hash(): """构建阶段获取当前Git commit哈希值""" try: # 获取短哈希,要全哈希可以去掉--short参数 return check_output(["git", "rev-parse", "--short", "HEAD"], text=True).strip() except (CalledProcessError, OSError): return "unknown" # 配置基础信息 GIT_HASH = get_git_hash() FORMAL_VERSION = "1.0.0" # 符合PEP 440规范的版本号,可按需修改 # 写入版本信息到包内文件 version_file = os.path.join("mypackage", "_version.py") with open(version_file, "w", encoding="utf-8") as f: f.write(f'__version__ = "{FORMAL_VERSION}"\n') f.write(f'__git_hash__ = "{GIT_HASH}"\n') # 原有setup配置 setup( name="mypackage", version=FORMAL_VERSION, packages=["mypackage"], # 其他原有配置:author、description、install_requires等保持不变 )
3. 配置包导出属性
在mypackage/__init__.py中导入自动生成的版本属性,对外暴露:
from ._version import __version__, __git_hash__ __all__ = ["__version__", "__git_hash__"]
4. 配置.gitignore
将自动生成的_version.py加入忽略列表,避免提交到仓库:
# 加到.gitignore最后一行 mypackage/_version.py
使用方法
任意环境安装构建好的包后,直接调用对应属性即可:
import mypackage print(mypackage.__version__) # 输出正式版本号,如1.0.0 print(mypackage.__git_hash__) # 输出构建时的Git哈希,如a1b2c3d
注意事项
- 构建wheel包时必须在Git仓库环境下执行
python -m build或pip wheel .,生成的wheel包内已内置Git Hash,后续在任意环境安装该wheel都可以正常读取 - 直接通过Git地址安装包(
pip install git+<仓库地址>)时,pip会自动完成构建流程,也可以正常获取Git Hash - 不需要依赖gitpython等第三方包,也不需要使用legacy安装方式,完全兼容wheel构建和PEP 440规范
内容的提问来源于stack exchange,提问作者pyCthon
相关产品推荐
相关产品推荐

