自定义Distutils命令

28

我有一个名为"example"的库,我正在将它安装到全局站点软件包目录中。然而,我想要能够安装两个版本,一个用于生产环境,另一个用于测试(我有一个网络应用程序和其他按照这种方式进行版本控制的东西)。

是否有一种方法可以指定例如 "python setup.py stage",不仅可以将不同的egg安装到site-packages中,还可以将模块从"example"重命名为"example_stage"或类似的名称?

如果distutils无法实现此功能,是否有其他工具可以实现?

4个回答

56

通过在setup.py中子类化distutils.core.Command,可以很容易地使用distutils实现这一点。

例如:

from distutils.core import setup, Command
import os, sys

class CleanCommand(Command):
    description = "custom clean command that forcefully removes dist/build directories"
    user_options = []
    def initialize_options(self):
        self.cwd = None
    def finalize_options(self):
        self.cwd = os.getcwd()
    def run(self):
        assert os.getcwd() == self.cwd, 'Must be in package root: %s' % self.cwd
        os.system('rm -rf ./build ./dist')  

要启用命令,必须在setup()中引用它:

setup(
     # stuff omitted for conciseness.
     cmdclass={
        'clean': CleanCommand
}

请注意,您也可以以此方式覆盖内置命令,就像我在'clean'上所做的那样。(我不喜欢内置版本留下'dist'和'build'目录。)

% python setup.py --help-commands | grep clean
  clean            custom clean command that forcefully removes dist/build dirs.

有一些约定惯例:

  • 您可以使用 user_options 指定任何命令行参数。
  • 您需要在 initialize_options() 方法中声明将要使用的任何变量,该方法在初始化后调用以为子类设置自定义名称空间。
  • finalize_options() 方法在 run() 之前被调用。
  • 命令本身的核心部分将在 run() 中发生,因此请确保在那之前完成任何其他准备工作。

最好的示例是查看默认命令之一的源代码,例如 PYTHON_DIR/distutils/command 中的 install.pybuild.py


使用源代码,Luke。 - Richard Gomes
1
请查看文档(https://docs.python.org/2/distutils/apiref.html#creating-a-new-distutils-command)。 - anatoly techtonik

14

当然,您可以通过添加以下内容到distutil配置文件来扩展新命令:

 [global]
 command-packages=foo.bar

这可以在distutils包中的distutils.cfg,在您的主目录中的..pydistutils.cfg(Windows上没有前导点),或当前目录中的setup.cfg中进行设置。
然后,您需要在Python的site-packages目录中添加一个foo.bar包。
然后,在该包中添加实现您的新命令的类,例如stage,继承distutils.cmd - 文档比较薄弱,但由于所有现有的distutils命令也是这样构建的,因此有很多示例。

5
这回答了所提出的问题,但virtualenv是解决这个问题的更好方法。 - Carl Meyer

5
如果您想使用多个版本,则可以使用virtualenv和virtualenvwrapper。它们可以帮助您实现这一目的。请访问以下链接了解更多信息:virtualenvvirtualenvwrapper

2
如果你想使用distutils实现这一点,可以参考Alex的回答,但我认为Paver更适合这种情况。它使得创建自定义命令或覆盖现有命令变得更加容易。此外,如果你已经习惯了distutils或setuptools,转换也不会太困难。

1
Paver提供了许多有趣的便捷功能和快捷方式。另一方面,它在distutils之上添加了另一种范例(和架构)。我更喜欢一个简单的setup.py文件,它是自包含的,并且可以完成所有需要完成的工作。 - Richard Gomes

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