setup.cfg Python 项目的单一来源包版本

Nic*_*mer 5 python setup.py

对于带有 的传统 Python 项目setup.py,有多种方法可以确保版本字符串不必在整个代码库中重复。有关建议列表,请参阅PyPA 的“单一采购包版本”指南。

许多人试图从setup.pyto移开setup.cfg(可能是在PEP517PEP518的影响下;setup.py无论如何主要以声明方式使用,并且当 中存在逻辑时setup.py,情况可能更糟。)这意味着大多数建议将不再起作用因为setup.cfg不能包含“代码”。

如何为使用 的 Python 项目提供单一来源的包版本setup.cfg

sin*_*roc 10

有几种方法可以做到这一点(有关这些示例中使用的项目结构,请参见下文):

1.

setup.cfg

[metadata]
version = 1.2.3.dev4
Run Code Online (Sandbox Code Playgroud)

src/my_top_level_package/__init__.py

import importlib.metadata
__version__ = importlib.metadata.version('MyProject')
Run Code Online (Sandbox Code Playgroud)

2.

setup.cfg

[metadata]
version = file: VERSION.txt
Run Code Online (Sandbox Code Playgroud)

VERSION.txt

1.2.3.dev4
Run Code Online (Sandbox Code Playgroud)

src/my_top_level_package/__init__.py

import importlib.metadata
__version__ = importlib.metadata.version('MyProject')
Run Code Online (Sandbox Code Playgroud)

3.

setup.cfg

[metadata]
version = attr: my_top_level_package.__version__
Run Code Online (Sandbox Code Playgroud)

src/my_top_level_package/__init__.py

__version__ = '1.2.3.dev4'
Run Code Online (Sandbox Code Playgroud)

和更多...

通过玩不同的组合,可能还有其他方法可以做到这一点。


参考资料


前面例子中假设的结构如下...

MyProject
??? setup.cfg
??? setup.py
??? src
    ??? my_top_level_package
        ??? __init__.py
Run Code Online (Sandbox Code Playgroud)

setup.py

#!/usr/bin/env python3

import setuptools

if __name__ == '__main__':
    setuptools.setup(
        # see 'setup.cfg'
    )
Run Code Online (Sandbox Code Playgroud)

setup.cfg

[metadata]
name = MyProject
version = attr: my_top_level_package.__version__

[options]
package_dir =
    = src
packages = find:

[options.packages.find]
where = src
Run Code Online (Sandbox Code Playgroud)

src/my_top_level_package/__init__.py

__version__ = '1.2.3.dev4'
Run Code Online (Sandbox Code Playgroud)
$ cd path/to/MyProject
$ python3 setup.py --version
1.2.3.dev4
$ python3 -m pip install .
# ...
$ python3 -c 'import my_top_level_package; print(my_top_level_package.__version__)'
1.2.3.dev4
$ python3 -V
Python 3.6.9
$ python3 -m pip list
Package       Version   
------------- ----------
MyProject     1.2.3.dev4
pip           20.0.2    
pkg-resources 0.0.0     
setuptools    45.2.0    
wheel         0.34.2    
zipp          3.0.0
Run Code Online (Sandbox Code Playgroud)

  • `importlib.metadata` 变体的缺点是它总是提供_installed_ 包的版本,即使您使用 devel master 的签出。 (2认同)
  • 选项 (3.) 不起作用。该软件包不会使用“pip install .”在本地安装,并且看似不相关的“ModuleNotFoundError”。当在“[metadata]”中使用“version = 1.2.3”时,一切正常。可能是一个点错误,不确定。 (2认同)
  • @red888 这超出了这个问题的范围,但是是的。在 `setuptools.setup()` 函数调用的 `setup.py` 中,您可以编写类似 `version=os.getenv('MYPROJECT_VERSION')` 的内容。 (2认同)