是否有一种标准的方法将版本字符串与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。
当前回答
带有bump2版本的策略路由
这个解决方案来自本文
用例- python GUI包通过PyInstaller分发。需要显示版本信息。
这里是项目包的结构
packagex
├── packagex
│ ├── __init__.py
│ ├── main.py
│ └── _version.py
├── packagex.spec
├── LICENSE
├── README.md
├── .bumpversion.cfg
├── requirements.txt
├── setup.cfg
└── setup.py
setup.py在哪里
# setup.py
import os
import setuptools
about = {}
with open("packagex/_version.py") as f:
exec(f.read(), about)
os.environ["PBR_VERSION"] = about["__version__"]
setuptools.setup(
setup_requires=["pbr"],
pbr=True,
version=about["__version__"],
)
Packagex /_version.py包含just
__version__ = "0.0.1"
和packagex / __init__ . py
from ._version import __version__
对于.bumpversion.cfg
[bumpversion]
current_version = 0.0.1
commit = False
tag = False
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(\-(?P<release>[a-z]+)(?P<build>\d+))?
serialize =
{major}.{minor}.{patch}-{release}{build}
{major}.{minor}.{patch}
[bumpversion:part:release]
optional_value = prod
first_value = dev
values =
dev
prod
[bumpversion:file:packagex/_version.py]
其他回答
我在包目录中使用了一个JSON文件。这符合Zooko的要求。
内部pkg_dir / pkg_info.json:
{"version": "0.1.0"}
在setup . py:
from distutils.core import setup
import json
with open('pkg_dir/pkg_info.json') as fp:
_info = json.load(fp)
setup(
version=_info['version'],
...
)
内部pkg_dir / __init__ . py:
import json
from os.path import dirname
with open(dirname(__file__) + '/pkg_info.json') as fp:
_info = json.load(fp)
__version__ = _info['version']
我还在pkg_info中放入了其他信息。Json,比如author。我 我喜欢使用JSON,因为我可以自动管理元数据。
无论如何,如果你使用NumPy distutils, NumPy .distutils.misc_util。Configuration有一个make_svn_version_py()方法,它将版本号嵌入到包中。变量version中的__svn_version__。
自从第一次提出这个问题以来,已经完成了许多关于统一版本和支持约定的工作。可接受的选项现在在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将直接报告版本。
根据延迟的[STOP PRESS: rejected] PEP 396(模块版本号),有一种建议的方法来做到这一点。它描述了模块遵循的基本原理(当然是可选的)标准。下面是一个片段:
当模块(或包)包含版本号时,该版本应该在__version__属性中可用。
对于位于命名空间包中的模块,模块应该包含__version__属性。命名空间包本身不应该包含自己的__version__属性。
__version__属性的值应该是一个字符串。
我在这里描述了一种标准的现代方法,它依赖于setuptools_scm。 在过去的几年中,这种模式已经成功地应用于许多已发布的包,因此我强烈推荐它。
注意,您不需要getversion包来实现这个模式。getversion文档恰好包含这个技巧。