从 git 标签获取版本(通过 pbr)
Get version from git tags (through pbr)
我用pbr来打包。它从 git 标签中获取版本并将其应用于 setup.py
现在我也想在包内提供可用的版本。例如具有 __version__
属性。我可以为此使用 pbr
库吗?
还有另一个库:versioneer 也从 git 标签中提取版本,但这会增加一个额外的要求。我更愿意从 pbr
获得此功能
如果您同意 pbr
作为包的运行时依赖项,那么您可以使用 pbr.version
:
中的 VersionInfo
class
from pbr.version import VersionInfo
package_name='my_package'
info = VersionInfo(package_name)
print(info.version_string())
(另见 How to load package version into __version__ variable if you are using pbr?)
考虑 setuptools_scm,它在可用时从 git 或 hg 标签中提取版本,或者生成适当的开发版本(例如,hgvs-1.2.5.dev6+hb5d989061852.d20181124
)。该版本与硬编码版本一样被写入包元数据中。不需要非标准运行时支持。
虽然我在很多项目中使用了setuptools_scm,但我没有使用过PBR。我很好奇并制作了这个简单的演示:
snafu$ head setup.py setup.cfg pbrversiontest/*.py
==> setup.py <==
from setuptools import setup
setup(
setup_requires=[
"pbr",
"setuptools_scm"
],
pbr=True,
use_scm_version=True,
)
==> setup.cfg <==
[metadata]
name = pbrversiontest
summary = test whether we can use pbr and setuptools_scm
[files]
packages =
pbrversiontest
==> pbrversiontest/__init__.py <==
# This is straight from setuptools_scm README
from pkg_resources import get_distribution, DistributionNotFound
try:
__version__ = get_distribution(__name__).version
except DistributionNotFound:
# package is not installed
pass
==> pbrversiontest/__main__.py <==
# this isn't required -- only for the demo
import pbrversiontest
print("version is " + pbrversiontest.__version__)
在开发目录中,你可能有这样一个会话:
snafu$ python3.6 -mvenv venv/3.6
snafu$ source venv/3.6/bin/activate
(3.6) snafu$ git tag 0.1.2
(3.6) snafu$ pip install -e .
(3.6) snafu$ python -m pbrversiontest
version is 0.1.2
(3.6) snafu$ pip install wheel
(3.6) snafu$ python setup.py bdist_wheel
...
creating 'dist/pbrversiontest-0.1.2-py3-none-any.whl' and adding 'build/bdist.linux-x86_64/wheel' to it
...
(3.6) snafu$ unzip -l dist/pbrversiontest-0.1.2-py3-none-any.whl
Archive: dist/pbrversiontest-0.1.2-py3-none-any.whl
Length Date Time Name
--------- ---------- ----- ----
192 2018-11-25 05:26 pbrversiontest/__init__.py
73 2018-11-25 05:46 pbrversiontest/__main__.py
33 2018-11-25 06:06 pbrversiontest-0.1.2.dist-info/AUTHORS
217 2018-11-25 06:06 pbrversiontest-0.1.2.dist-info/METADATA
92 2018-11-25 06:06 pbrversiontest-0.1.2.dist-info/WHEEL
47 2018-11-25 06:06 pbrversiontest-0.1.2.dist-info/pbr.json
15 2018-11-25 06:06 pbrversiontest-0.1.2.dist-info/top_level.txt
675 2018-11-25 06:06 pbrversiontest-0.1.2.dist-info/RECORD
--------- -------
1344 8 files
正确设置 setuptools
和 pbr
后,可以通过以下几种方法进行设置:
import pkg_resources # part of setuptools
# I don't like this one because the version method is hidden
v1 = pkg_resources.require("my_package_name")[0].version
print('v1 {}'.format(v1))
# This is my favorite - the output without .version is just a longer string with
# both the package name, a space, and the version string
v2 = pkg_resources.get_distribution('my_package_name').version
print('v2 {}'.format(v2))
from pbr.version import VersionInfo
# This one seems to be slower, and with pyinstaller makes the exe a lot bigger
v3 = VersionInfo('my_package_name').release_string()
print('v3 {}'.format(v3))
# Update, new option as of Python 3.8 (credit: sinoroc)
# In Python 3.8, importlib.metadata is part of the stdlib,
# which removes run-time dependencies on `pbr` or `setuptools`
import importlib.metadata
__version__ = importlib.metadata.version('my_package_name')
如果你想在命令行中使用它,你可以这样做:
py setup.py --version
甚至 运行 脚本中的 setup.py 脚本,如果软件包将始终安装在本地:
from subprocess import Popen, PIPE
(output, err) = Popen('py setup.py --version'.split(' '),
stdout=PIPE, stderr=PIPE, text=True).communicate()
if err: print('ERROR: "{}"'.format(err))
else: print('setup.py --version = {}'.format(output))
注意:有关使用子进程启动和读取 stdout 等的更多详细信息,请参阅 this answer,尤其是在 Python 的旧版本(之前到 3.7).
然后您可以像这样将 __version__
添加到您的包裹 __init__.py
中:
__all__ = (
'__version__',
'my_package_name'
)
# Or substitute a different method and assign the result to __version__
import pkg_resources # part of setuptools
__version__ = pkg_resources.get_distribution("my_package_name").version
其他一些可能有助于设置的问答以及有关如何更新版本和其他信息的详细信息,特别是如果从您的 Git 存储库(来自标签、作者和 ChangeLog 信息的版本)获取信息:
我用pbr来打包。它从 git 标签中获取版本并将其应用于 setup.py
现在我也想在包内提供可用的版本。例如具有 __version__
属性。我可以为此使用 pbr
库吗?
还有另一个库:versioneer 也从 git 标签中提取版本,但这会增加一个额外的要求。我更愿意从 pbr
如果您同意 pbr
作为包的运行时依赖项,那么您可以使用 pbr.version
:
VersionInfo
class
from pbr.version import VersionInfo
package_name='my_package'
info = VersionInfo(package_name)
print(info.version_string())
(另见 How to load package version into __version__ variable if you are using pbr?)
考虑 setuptools_scm,它在可用时从 git 或 hg 标签中提取版本,或者生成适当的开发版本(例如,hgvs-1.2.5.dev6+hb5d989061852.d20181124
)。该版本与硬编码版本一样被写入包元数据中。不需要非标准运行时支持。
虽然我在很多项目中使用了setuptools_scm,但我没有使用过PBR。我很好奇并制作了这个简单的演示:
snafu$ head setup.py setup.cfg pbrversiontest/*.py
==> setup.py <==
from setuptools import setup
setup(
setup_requires=[
"pbr",
"setuptools_scm"
],
pbr=True,
use_scm_version=True,
)
==> setup.cfg <==
[metadata]
name = pbrversiontest
summary = test whether we can use pbr and setuptools_scm
[files]
packages =
pbrversiontest
==> pbrversiontest/__init__.py <==
# This is straight from setuptools_scm README
from pkg_resources import get_distribution, DistributionNotFound
try:
__version__ = get_distribution(__name__).version
except DistributionNotFound:
# package is not installed
pass
==> pbrversiontest/__main__.py <==
# this isn't required -- only for the demo
import pbrversiontest
print("version is " + pbrversiontest.__version__)
在开发目录中,你可能有这样一个会话:
snafu$ python3.6 -mvenv venv/3.6
snafu$ source venv/3.6/bin/activate
(3.6) snafu$ git tag 0.1.2
(3.6) snafu$ pip install -e .
(3.6) snafu$ python -m pbrversiontest
version is 0.1.2
(3.6) snafu$ pip install wheel
(3.6) snafu$ python setup.py bdist_wheel
...
creating 'dist/pbrversiontest-0.1.2-py3-none-any.whl' and adding 'build/bdist.linux-x86_64/wheel' to it
...
(3.6) snafu$ unzip -l dist/pbrversiontest-0.1.2-py3-none-any.whl
Archive: dist/pbrversiontest-0.1.2-py3-none-any.whl
Length Date Time Name
--------- ---------- ----- ----
192 2018-11-25 05:26 pbrversiontest/__init__.py
73 2018-11-25 05:46 pbrversiontest/__main__.py
33 2018-11-25 06:06 pbrversiontest-0.1.2.dist-info/AUTHORS
217 2018-11-25 06:06 pbrversiontest-0.1.2.dist-info/METADATA
92 2018-11-25 06:06 pbrversiontest-0.1.2.dist-info/WHEEL
47 2018-11-25 06:06 pbrversiontest-0.1.2.dist-info/pbr.json
15 2018-11-25 06:06 pbrversiontest-0.1.2.dist-info/top_level.txt
675 2018-11-25 06:06 pbrversiontest-0.1.2.dist-info/RECORD
--------- -------
1344 8 files
正确设置 setuptools
和 pbr
后,可以通过以下几种方法进行设置:
import pkg_resources # part of setuptools
# I don't like this one because the version method is hidden
v1 = pkg_resources.require("my_package_name")[0].version
print('v1 {}'.format(v1))
# This is my favorite - the output without .version is just a longer string with
# both the package name, a space, and the version string
v2 = pkg_resources.get_distribution('my_package_name').version
print('v2 {}'.format(v2))
from pbr.version import VersionInfo
# This one seems to be slower, and with pyinstaller makes the exe a lot bigger
v3 = VersionInfo('my_package_name').release_string()
print('v3 {}'.format(v3))
# Update, new option as of Python 3.8 (credit: sinoroc)
# In Python 3.8, importlib.metadata is part of the stdlib,
# which removes run-time dependencies on `pbr` or `setuptools`
import importlib.metadata
__version__ = importlib.metadata.version('my_package_name')
如果你想在命令行中使用它,你可以这样做:
py setup.py --version
甚至 运行 脚本中的 setup.py 脚本,如果软件包将始终安装在本地:
from subprocess import Popen, PIPE
(output, err) = Popen('py setup.py --version'.split(' '),
stdout=PIPE, stderr=PIPE, text=True).communicate()
if err: print('ERROR: "{}"'.format(err))
else: print('setup.py --version = {}'.format(output))
注意:有关使用子进程启动和读取 stdout 等的更多详细信息,请参阅 this answer,尤其是在 Python 的旧版本(之前到 3.7).
然后您可以像这样将 __version__
添加到您的包裹 __init__.py
中:
__all__ = (
'__version__',
'my_package_name'
)
# Or substitute a different method and assign the result to __version__
import pkg_resources # part of setuptools
__version__ = pkg_resources.get_distribution("my_package_name").version
其他一些可能有助于设置的问答以及有关如何更新版本和其他信息的详细信息,特别是如果从您的 Git 存储库(来自标签、作者和 ChangeLog 信息的版本)获取信息: