是否有一种标准的方法将版本字符串与Python包相关联,以便我可以执行以下操作?
import foo
print(foo.version)
我认为有一些方法可以在没有任何额外硬编码的情况下检索数据,因为minor/major字符串已经在setup.py中指定了。我发现的替代解决方案是在我的foo/__init__.py中导入__version__,然后由setup.py生成__version__.py。
是否有一种标准的方法将版本字符串与Python包相关联,以便我可以执行以下操作?
import foo
print(foo.version)
我认为有一些方法可以在没有任何额外硬编码的情况下检索数据,因为minor/major字符串已经在setup.py中指定了。我发现的替代解决方案是在我的foo/__init__.py中导入__version__,然后由setup.py生成__version__.py。
当前回答
经过几个小时的努力,我找到了最简单可靠的解决方案,以下是其中的几个部分:
在你的包"/mypackage"文件夹中创建一个version.py文件:
# Store the version here so:
# 1) we don't load dependencies by storing it in __init__.py
# 2) we can import it in setup.py for the same reason
# 3) we can import it into your module module
__version__ = '1.2.7'
在setup . py:
exec(open('mypackage/version.py').read())
setup(
name='mypackage',
version=__version__,
在主文件夹init.py中:
from .version import __version__
exec()函数在任何导入之外运行脚本,因为在导入模块之前运行setup.py。您仍然只需要在一个地方的一个文件中管理版本号,但不幸的是,它不在setup.py中。(这是缺点,但没有导入错误是优点)
其他回答
只使用VERSION .py文件,文件中有__version__ = <VERSION>参数。在setup.py文件中导入__version__参数,并将其值放在setup.py文件中,如下所示: version = __version__ 另一种方法是只使用version=<CURRENT_VERSION>的setup.py文件- CURRENT_VERSION是硬编码的。
因为我们不希望每次创建一个新标记(准备发布一个新的包版本)时都手动更改文件中的版本,所以我们可以使用以下..
我强烈推荐凸版包。多年来我一直在用它来撞一个版本。
首先在setup.py文件中添加version=< version >,如果你还没有的话。
你应该在每次碰到一个版本时使用这样一个简短的脚本:
bumpversion (patch|minor|major) - choose only one option
git push
git push --tags
然后为每个repo添加一个名为.bumpversion.cfg的文件:
[bumpversion]
current_version = <CURRENT_TAG>
commit = True
tag = True
tag_name = {new_version}
[bumpversion:file:<RELATIVE_PATH_TO_SETUP_FILE>]
注意:
你可以像在其他文章中建议的那样,在version.py文件下使用__version__参数,并像这样更新bumpversion文件: [bumpversion:文件:< RELATIVE_PATH_TO_VERSION_FILE >) 你必须git提交或git重置你的回购中的所有东西,否则你会得到一个肮脏的回购错误。 确保你的虚拟环境包含了bump版本的包,没有它它将无法工作。
同样值得注意的是,__version__是一个半std。在python中,__version_info__也是一个元组,在简单的情况下,你可以这样做:
__version__ = '1.2.3'
__version_info__ = tuple([ int(num) for num in __version__.split('.')])
...你可以从文件或其他地方获取__version__字符串。
我还看到了另一种风格:
>>> django.VERSION
(1, 1, 0, 'final', 0)
我在这里描述了一种标准的现代方法,它依赖于setuptools_scm。 在过去的几年中,这种模式已经成功地应用于许多已发布的包,因此我强烈推荐它。
注意,您不需要getversion包来实现这个模式。getversion文档恰好包含这个技巧。
自从第一次提出这个问题以来,已经完成了许多关于统一版本和支持约定的工作。可接受的选项现在在Python打包用户指南中详细介绍。同样值得注意的是,版本号方案在Python PEP 440中是相对严格的,因此如果您的包将被发布到Cheese Shop,那么保持正常是至关重要的。
以下是版本控制选项的简短分类:
Read the file in setup.py (setuptools) and get the version. Use an external build tool (to update both __init__.py as well as source control), e.g. bump2version, changes or zest.releaser. Set the value to a __version__ global variable in a specific module. Place the value in a simple VERSION text file for both setup.py and code to read. Set the value via a setup.py release, and use importlib.metadata to pick it up at runtime. (Warning, there are pre-3.8 and post-3.8 versions.) Set the value to __version__ in sample/__init__.py and import sample in setup.py. Use setuptools_scm to extract versioning from source control so that it's the canonical reference, not code.
注意(7)可能是最现代的方法(构建元数据独立于代码,由自动化发布)。还要注意,如果setup用于包发布,那么简单的python3 setup.py——version将直接报告版本。