在setup.cfg和setup.py中引用现有的distutils选项

18

我正在使用Python 2.7和Distutils来分发和安装我的自己创建的包。我的setup.cfg文件看起来像这样:

[install]
prefix=/usr/local/MODULENAME
record=installation.txt

我有两个问题:

  1. 在定义其他setup.cfg选项时,是否可以引用在setup.cfg中设置的变量(也使用命令行选项)?例如:

    install-scripts=PREFIX/my-scripts
    

    我希望PREFIX成为在setup.cfg内或使用--prefix命令行参数定义的前缀,类似于使用ConfigParser时的变量插值。

  2. 是否可以在我的setup.py中引用在setup.cfg中设置的变量,而不需要手动使用ConfigParser解析配置文件?


1
出于好奇,为什么您不想在问题2)中依赖于ConfigParser?如果依赖Python标准库是一个问题,那么可以使用一个简单的、单一目的的解析器,在您自己的模块中编写来解析配置文件。 - NuclearPeon
如果用户通过CLI提供(重新定义)前缀,则ConfigParser将无用。 - zaufi
所以请纠正我如果我错了,但您想要一种调用 setup.py 的方法,使其 1: 读取 setup.cfg 文件并获取其所有值,2:setup.cfg 中的值与 setup.py 的命令行参数关联起来,而不使用 ConfigParser,并且 3: 运行安装过程。在尝试解决这个问题之前,我只是想确认您的意图。 - NuclearPeon
1
@NuclearPeon,不是这样的...我只想能够从setup.py中访问真正的前缀(通过CLI或从setup.cfg指定,我不在乎)。我坚信它确切地知道用户想要安装我的软件包的位置,所以问题是_如何访问和使用真正的前缀_。对于构建系统(如CMake或autotools)或打包工具(如RPM/DEB规范),您可以随时轻松访问它。为什么setup.py没有类似的东西(或者至少很难/不明显)? - zaufi
你能不能在你的setup.py中解析setup.cfg呢?毕竟,它只是一个带有部分的简单键/值配置文件。真正的问题是,一旦你有了一个嵌套的选项字典,你想做什么呢? - James Mills
显示剩余6条评论
1个回答

12

关于在setup.cfg文件中引用变量

您可以在setup.cfg文件中引用其他变量/选项。语法是$variable,例如:

[install]
prefix = /my/prefix
install-scripts = $base/scripts
请注意,我使用了$base,因为该变量受到您在setup.cfg中提供的前缀设置和使用setup.py install --prefix命令行选项影响。在这种情况下,除非用户使用命令行指定另一个前缀,否则您的脚本将安装到/my/prefix/scripts
同样可以在setup.cfg中使用$prefix,但似乎不受自定义配置的影响。
访问setup()之后setup.py中变量的值
还可以读取setup.py中所有变量/选项的值。函数setup返回类Distribution的实例。该类按命令(例如install)分组保存所有变量的值,并且您可以使用get_option_dict方法获取它们。例如:
#!/usr/bin/env python

from distutils.core import setup

d = setup(
          # Here come your setup arguments
         )
print(d.get_option_dict('install'))

将打印:

{'prefix': ('setup.cfg', '/my/prefix'), 
 'install_scripts': ('setup.cfg', '$base/scripts')}

在 setup.py 的 setup() 之前访问变量的值

在运行 setup() 之前,也可以获得类Distribution的实例。为此,我们可以复制 setup() 内部正在执行的操作,并自己构建该类的一个实例。然后,可以基于某些安装选项的值来决定设置参数的值。我们看一个例子:

from distutils.core import setup
from distutils.dist import Distribution

# Get our own instance of Distribution
dist = Distribution()
dist.parse_config_files()
dist.parse_command_line()

# Get prefix from either config file or command line
prefix = dist.get_option_dict('install')['prefix'][1]
print("Prefix is: " + prefix)

# Use the prefix to decide on the data path for data.txt
setup(data_files=[('/first/path/to/data' if prefix == '/some/prefix'
                                         else '/second/path/to/data',
                   ['data.txt'])])

谢谢你的回答。但问题是:我需要在对setup()的调用中引用一个前缀... 例如:setup(..., data_files = [('/etc/mypkg' if prefix == '/usr' else prefix + '/etc/mypkg', ['config/mypkg.conf.sample'])], ...) ... )` - zaufi
我也添加了一个解决方案。请查看我的编辑。 - Andrzej Pronobis
太好了!正是我想要找的!非常感谢! - zaufi
@AndrzejPronobis 我可以在我的 setup.cfg 文件中引用环境变量吗? - red888

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接