setup.cfg Python 个项目的单一采购包版本
single-sourcing package version for setup.cfg Python projects
对于具有 setup.py
的传统 Python 项目,有多种方法可以确保版本字符串不必在整个代码库中重复。有关建议列表,请参阅 PyPA's guide on "Single-sourcing the package version"。
许多人正试图从 setup.py
转移到 setup.cfg
(可能是在 PEP517 和 PEP518[=28 的影响下=]; setup.py
主要是声明式使用,当 setup.py
中有逻辑时,情况可能更糟。)这意味着大多数建议将不再有效,因为 setup.cfg
不能包含 "code".
如何为使用 setup.cfg
的 Python 个项目单一来源包版本?
有几种方法可以做到这一点(有关这些示例中使用的项目结构,请参见下文):
1.
setup.cfg
[metadata]
version = 1.2.3.dev4
src/my_top_level_package/__init__.py
import importlib.metadata
__version__ = importlib.metadata.version('MyProject')
2.
setup.cfg
[metadata]
version = file: VERSION.txt
VERSION.txt
1.2.3.dev4
src/my_top_level_package/__init__.py
import importlib.metadata
__version__ = importlib.metadata.version('MyProject')
3.
setup.cfg
[metadata]
version = attr: my_top_level_package.__version__
src/my_top_level_package/__init__.py
__version__ = '1.2.3.dev4'
还有更多...
可能还有其他方法可以做到这一点,方法是使用不同的组合。
参考资料:
- https://setuptools.readthedocs.io/en/latest/userguide/declarative_config.html
- https://docs.python.org/3/library/importlib.metadata.html
前面示例中假定的结构如下...
MyProject
├── setup.cfg
├── setup.py
└── src
└── my_top_level_package
└── __init__.py
setup.py
#!/usr/bin/env python3
import setuptools
if __name__ == '__main__':
setuptools.setup(
# see 'setup.cfg'
)
setup.cfg
[metadata]
name = MyProject
# See above for the value of 'version = ...'
[options]
package_dir =
= src
packages = find:
[options.packages.find]
where = src
src/my_top_level_package/__init__.py
__version__ = '1.2.3.dev4'
$ 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
对于具有 setup.py
的传统 Python 项目,有多种方法可以确保版本字符串不必在整个代码库中重复。有关建议列表,请参阅 PyPA's guide on "Single-sourcing the package version"。
许多人正试图从 setup.py
转移到 setup.cfg
(可能是在 PEP517 和 PEP518[=28 的影响下=]; setup.py
主要是声明式使用,当 setup.py
中有逻辑时,情况可能更糟。)这意味着大多数建议将不再有效,因为 setup.cfg
不能包含 "code".
如何为使用 setup.cfg
的 Python 个项目单一来源包版本?
有几种方法可以做到这一点(有关这些示例中使用的项目结构,请参见下文):
1.
setup.cfg
[metadata]
version = 1.2.3.dev4
src/my_top_level_package/__init__.py
import importlib.metadata
__version__ = importlib.metadata.version('MyProject')
2.
setup.cfg
[metadata]
version = file: VERSION.txt
VERSION.txt
1.2.3.dev4
src/my_top_level_package/__init__.py
import importlib.metadata
__version__ = importlib.metadata.version('MyProject')
3.
setup.cfg
[metadata]
version = attr: my_top_level_package.__version__
src/my_top_level_package/__init__.py
__version__ = '1.2.3.dev4'
还有更多...
可能还有其他方法可以做到这一点,方法是使用不同的组合。
参考资料:
- https://setuptools.readthedocs.io/en/latest/userguide/declarative_config.html
- https://docs.python.org/3/library/importlib.metadata.html
前面示例中假定的结构如下...
MyProject
├── setup.cfg
├── setup.py
└── src
└── my_top_level_package
└── __init__.py
setup.py
#!/usr/bin/env python3
import setuptools
if __name__ == '__main__':
setuptools.setup(
# see 'setup.cfg'
)
setup.cfg
[metadata]
name = MyProject
# See above for the value of 'version = ...'
[options]
package_dir =
= src
packages = find:
[options.packages.find]
where = src
src/my_top_level_package/__init__.py
__version__ = '1.2.3.dev4'
$ 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