是否有一种标准的方法将版本字符串与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。
当前回答
我在包目录中使用了一个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,因为我可以自动管理元数据。
其他回答
在python包中嵌入版本字符串似乎没有标准的方法。我见过的大多数包都使用您的解决方案的一些变体,即eitner
将版本嵌入到setup.py中,并让setup.py生成一个只包含版本信息的模块(例如version.py),该模块由你的包导入,或者 相反:把版本信息放在你的包中,然后在setup.py中导入它来设置版本
在与__init__.py相同的文件夹中创建一个名为_version.txt的文件,并将version写成一行:
0.8.2
从__init__.py中的_version.txt文件中读取以下信息:
import os
def get_version():
with open(os.path.join(os.path.abspath(os.path.dirname(__file__)), "_version.txt")) as f:
return f.read().strip()
__version__ = get_version()
使用setuptools和pyproject.toml
Setuptools现在提供了一种动态获取pyproject.toml版本的方法
重现这里的示例,您可以在pyproject.toml中创建如下内容
# ...
[project]
name = "my_package"
dynamic = ["version"]
# ...
[tool.setuptools.dynamic]
version = {attr = "my_package.__version__"}
同样值得注意的是,__version__是一个半std。在python中,__version_info__也是一个元组,在简单的情况下,你可以这样做:
__version__ = '1.2.3'
__version_info__ = tuple([ int(num) for num in __version__.split('.')])
...你可以从文件或其他地方获取__version__字符串。
《绿箭侠》以一种有趣的方式处理它。
现在(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__'),
# [...]
)