自定义distutils命令

时间:2009-11-10 20:08:03

标签: python deployment distutils

我有一个名为“example”的库,我将其安装到我的全局site-packages目录中。但是,我希望能够安装两个版本,一个用于生产,一个用于测试(我有一个Web应用程序和其他以这种方式版本化的东西)。

有没有办法指定,比如“python setup.py stage”,它不仅会将不同的蛋安装到site-packages中,还会将模块从“example”重命名为“example_stage”或类似的东西?

如果distutils无法做到这一点,还有其他工具吗?

4 个答案:

答案 0 :(得分:51)

通过在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()方法一起使用的任何变量,该方法在初始化后调用以设置子类的自定义命名空间。
  • run()之前调用 finalize_options()方法。
  • 命令本身的内容将出现在 run()中,因此请务必在此之前进行任何其他准备工作。

使用的最佳示例只是查看 PYTHON_DIR / distutils / command 中的一个默认命令的源代码,例如 install.py 或< EM> build.py

答案 1 :(得分:13)

当然,您可以使用新命令扩展distutils。在distutil配置文件中,添加:

 [global]
 command-packages=foo.bar

这可以位于distutils.cfg包本身的distutils,主目录中的..pydistutils.cfg(Windows上没有前导点)或当前目录中的setup.cfg

然后在Python的site-packages目录中需要一个foo.bar包。

然后在该包中添加实现新的所需命令的类,例如stage,子类化distutils.cmd - 文档很弱,但是因为所有现有的distutils命令都有很多例子也是这样构建的。

答案 2 :(得分:4)

如果您想使用多个版本,则virtualenv virtualenvwrapper可以提供帮助。

答案 3 :(得分:3)

如果您想要一种方法来处理distutils,请参阅Alex's answer,但我发现Paver更适合这类事情。它使得自定义命令或覆盖现有命令变得容易得多。如果你已经习惯了distutils或setuptools,那么过渡并不是非常困难。