setup.py的设计模式,以避免重复的元数据

时间:2015-01-29 11:12:43

标签: python easy-install

我编写了一些python脚本,并在顶部嵌入了一些元数据,即:

__version__ = '0.6.1'

有人贡献了一个setup.py,主要是从脚本中复制元数据,所以我们有:

setup(
    (...)
    version='0.4.0',

我不喜欢这种重复,原因应该在上面显而易见。更新元数据是由人完成的,并非所有人都知道/记住它需要在两个地方更新。错误必然会发生。不要忘记这样一个事实,即更新版本号也更容易。我试图通过从代码本身中删除它来对元数据进行重复数据删除,但是...它实际上是在脚本中引用的(它是一个脚本,它毕竟接受--version和--help)。在脚本中嵌入这样的元数据也被认为是“最佳实践”。

我当然可以做一些技巧让setup.py从脚本中读取元数据。实际上,这可能比写这个问题花费更少的时间 - 我更想知道什么被认为是“最佳实践”。在setup.py和库/脚本中复制此信息是否真的被视为“最佳实践”?是否存在一些现成的cookbook样板代码,用于从脚本/包本身读取元数据?如果设置方法可以单独执行此操作,那会不会有意义?

2 个答案:

答案 0 :(得分:1)

您可以导入您的包并从那里获取元数据。

这确实假设您的文件结构如下所示:

root/
    code.py
    setup.py

或者

root/
    code/
        __init__.py
    setup.py

code.py__init__.py都有元数据。

import os
import sys

__dir__ = path.abspath(path.dirname(__file__))  # The directory of setup.py, root/
sys.path.insert(0, __dir__)  # Will search __dir__ first for the package

try:
    import code
finally:
    sys.path.pop(0)

setup_args = dict(
    name='code',
    # ...
)

for metadata in ('version', 'author', 'email', 'license'):
    if hasattr(code, '__{}__'.format(metadata)):
        setup_args[metadata] = getattr(code, '__{}__'.format(metadata))

setup(**setup_args)

答案 1 :(得分:0)

经过一番研究,我会自己回答......

首先 - 显然没有任何惯例在脚本或库本身中嵌入元数据 - 我只能猜测将__author____license__等添加到我自己的发明中脚本。

ATOH,存在向脚本和库添加__version__的约定。 PEP 8描述了这应该在每次提交时自动设置为VCS修订号 - 尽管它通常设置为语义版本号。 PEP 396试图澄清这一点,但由于缺乏对方或时间而被推迟。

因此,当在__version__中拥有语义版本号并且还为项目提供setup.py时,需要在两个位置更新版本号,或者做一些技巧以使其自动化-updated在一个地方(或者可能让VCS将它们两个地方自动更新)。

至于我自己,我最终将脚本导入setup.py并从那里读取__version__ - https://github.com/tobixen/calendar-cli/commit/854948ddc057f0ce7cc047b3618e8d5f6a1a292c