是否有一种标准的方法将版本字符串与Python包相关联,以便我可以执行以下操作?

import foo
print(foo.version)

我认为有一些方法可以在没有任何额外硬编码的情况下检索数据,因为minor/major字符串已经在setup.py中指定了。我发现的替代解决方案是在我的foo/__init__.py中导入__version__,然后由setup.py生成__version__.py。


当前回答

《绿箭侠》以一种有趣的方式处理它。

现在(2e5031b起)

在箭头/ __init__ . py:

__version__ = 'x.y.z'

在setup . py:

from arrow import __version__

setup(
    name='arrow',
    version=__version__,
    # [...]
)

之前

在箭头/ __init__ . py:

__version__ = 'x.y.z'
VERSION = __version__

在setup . py:

def grep(attrname):
    pattern = r"{0}\W*=\W*'([^']+)'".format(attrname)
    strval, = re.findall(pattern, file_text)
    return strval

file_text = read(fpath('arrow/__init__.py'))

setup(
    name='arrow',
    version=grep('__version__'),
    # [...]
)

其他回答

根据延迟的[STOP PRESS: rejected] PEP 396(模块版本号),有一种建议的方法来做到这一点。它描述了模块遵循的基本原理(当然是可选的)标准。下面是一个片段:

当模块(或包)包含版本号时,该版本应该在__version__属性中可用。

对于位于命名空间包中的模块,模块应该包含__version__属性。命名空间包本身不应该包含自己的__version__属性。

__version__属性的值应该是一个字符串。

只使用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版本的包,没有它它将无法工作。

如果您使用CVS(或RCS)并想要快速解决方案,您可以使用:

__version__ = "$Revision: 1.1 $"[11:-2]
__version_info__ = tuple([int(s) for s in __version__.split(".")])

(当然,修订号会被CVS代替)

这为您提供了一个打印友好的版本和版本信息,您可以使用它来检查您正在导入的模块至少具有预期的版本:

import my_module
assert my_module.__version_info__ >= (1, 1)

带有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]

同样值得注意的是,__version__是一个半std。在python中,__version_info__也是一个元组,在简单的情况下,你可以这样做:

__version__ = '1.2.3'
__version_info__ = tuple([ int(num) for num in __version__.split('.')])

...你可以从文件或其他地方获取__version__字符串。