单一采购包版本¶
有许多技术可以维护项目版本号的单一真实性来源:
在中读取文件
setup.py
并使用regex解析该版本。示例(来自 pip setup.py ):here = os.path.abspath(os.path.dirname(__file__)) def read(*parts): with codecs.open(os.path.join(here, *parts), 'r') as fp: return fp.read() def find_version(*file_paths): version_file = read(*file_paths) version_match = re.search(r"^__version__ = ['\"]([^'\"]*)['\"]", version_file, re.M) if version_match: return version_match.group(1) raise RuntimeError("Unable to find version string.") setup( ... version=find_version("package", "__init__.py") ... )
注解
这种方法的缺点是必须处理正则表达式的复杂性。
使用一个外部构建工具来管理两个位置的更新,或者提供两个位置都可以使用的API。
您可以使用的工具很少,没有特定的顺序,也不一定完整: bump2version , changes , zest.releaser .
将值设置为
__version__
项目中专用模块中的全局变量(例如version.py
,然后有setup.py
阅读和exec
将值转换为变量。version = {} with open("...sample/version.py") as fp: exec(fp.read(), version) # later on we use: version['__version__']
使用此技术的示例: warehouse .
将值放在一个简单的
VERSION
文本文件和setup.py
项目代码读取它。with open(os.path.join(mypackage_root_dir, 'VERSION')) as version_file: version = version_file.read().strip()
这种技术的一个优点是它不特定于Python。任何工具都可以读取版本。
警告
通过这种方法,您必须确保
VERSION
文件包含在所有源和二进制分发中(例如,添加include VERSION
对你MANIFEST.in
)将值设置为
setup.py
并让项目代码使用pkg_resources
应用程序编程接口。import pkg_resources assert pkg_resources.get_distribution('pip').version == '1.2.0'
请注意
pkg_resources
API只知道安装元数据中的内容,而不一定是当前导入的代码。使用此技术的示例: setuptools .
将值设置为
__version__
在里面sample/__init__.py
和导入sample
在里面setup.py
.import sample setup( ... version=sample.__version__ ... )
警告
尽管这种技术很常见,但要注意,如果
sample/__init__.py
从导入包install_requires
依赖项,当setup.py
运行。将版本号保留在版本控制系统(Git、Mercurial等)的标记中而不是代码中,并使用自动从中提取版本号 setuptools_scm .