自定义 distutils 命令

发布于 2024-08-10 22:47:00 字数 253 浏览 5 评论 0原文

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

有没有一种方法可以指定“python setup.py stage”,它不仅可以将不同的egg安装到站点包中,而且还可以将模块从“example”重命名为“example_stage”或类似的名称?

如果 distutils 不能做到这一点,还有其他工具可以吗?

I have a library called "example" that I'm installing into my global site-packages directory. However, I'd like to be able to install two versions, one for production and one for testing (I have a web application and other things that are versioned this way).

Is there a way to specify, say "python setup.py stage" that will not only install a different egg into site-packages, but also rename the module from "example" to "example_stage" or something similar?

If distutils cannot do this, is there any other tool that can?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

白龙吟 2024-08-17 22:47:00

通过在 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

This can easily be done with distutils by subclassing distutils.core.Command inside of setup.py.

For example:

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')  

To enable the command you must reference it in setup():

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

Note that you can override built-in commands this way too, such as what I did with 'clean'. (I didn't like how the built-in version left behind the 'dist' and 'build' directories.)

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

There are a number of conventions that are used:

  • You specify any command-line arguments with user_options.
  • You declare any variables you would use with the initialize_options() method, which is called after initialization to setup your custom namespace for the subclass.
  • The finalize_options() method is called right before run().
  • The guts of the command itself will occur in run() so be sure to do any other prep work before that.

The best example to use is just to look at the source code for one of the default commands found at PYTHON_DIR/distutils/command such as install.py or build.py.

苏辞 2024-08-17 22:47:00

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

 [global]
 command-packages=foo.bar

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

然后,您的 Python 站点包目录中需要有一个 foo.bar 包。

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

Sure, you can extend distutils with new commands. In your distutil configuration file, add:

 [global]
 command-packages=foo.bar

this can be in distutils.cfg in the distutils package itself, ..pydistutils.cfg in your home directory (no leading dot on Windows), or setup.cfg in the current directory.

Then you need a foo.bar package in your Python's site-packages directory.

Then in that package you add the classes implementing your new desired commands, such as stage, subclassing distutils.cmd -- the docs are weak, but there are plenty of examples since all the existing distutils commands are also built that way.

巴黎夜雨 2024-08-17 22:47:00

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

If you'd like to use multiple version then virtualenv with virtualenvwrapper can help.

独夜无伴 2024-08-17 22:47:00

如果您想要一种使用 distutils 执行此操作的方法,请参阅 Alex 的答案,但我发现 < a href="http://www.blueskyonmars.com/projects/paver/" rel="nofollow noreferrer">Paver 更适合这种事情。它使创建自定义命令或覆盖现有命令变得更加容易。另外,如果您习惯使用 distutils 或 setuptools,那么转换并不是非常困难。

See Alex's answer if you want a way to do this with distutils, but I find Paver to be better for this kind of thing. It makes it a lot easier to make custom commands or override existing ones. Plus the transition isn't terribly difficult if you're used to distutils or setuptools.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文