distutils`Command`应该如何返回非零退出代码?

时间:2016-06-05 16:12:46

标签: python python-3.x

考虑最简单的python setup.py cmd

from distutils.core import Command, setup


class Foo(Command):
    user_options = []

    def initialize_options(self):
        pass

    def finalize_options(self):
        pass

    def run(self):
        pass

setup(
    cmdclass={'cmd': Foo}
)

它确实没有。

但是假设在我们什么也不做的时候出现问题,该命令应该如何向用户返回非零退出代码?

似乎忽略了返回值; the documentation只说:

  

所有终端输出和文件系统交互都应该通过run()来完成。

似乎没有特别有帮助。

也许我们应该推断exit

class Foo(Command):
    # ...
    def run(self):
        exit(1)

当然这是有效的。

但我不清楚这是正确的做法:如果命令是作为较长进程的一部分运行,或者它是否覆盖了内置命令,大概没有什么可以执行的。

我们可以直接提出相关的例外,假设它可能更有可能得到妥善处理,但是当我们退出时会出现令人讨厌的追溯 - 如果我们自己已经记录了更好的东西呢?

class Foo(Command):
    # ...
    def run(self):
        print('Oh noes!', file=sys.stderr)
        exit(1)

这样做是否安全;有更好的选择吗?

1 个答案:

答案 0 :(得分:0)

虽然exit将无效地工作,但是使用期望停止执行的错误消息引发任何distutils.errors是内部处理问题的困难。例如,如果希望阻止setuptools提供的可编辑(开发)安装方法,仅使用distutils API,则可以实现此目的。{/ p>

DistutilsError

使用develop选项运行它可能会导致:

from setuptools.command.develop import develop 
from distutils.errors import DistutilsError

class fail_develop(develop):

    def run(self):
        raise DistutilsError('develop installation mode unsupported')

setup(
    ...
    cmdclass={'develop': fail_develop},
)

执行将停止,因为它被捕获并且将引发running develop error: develop installation mode unsupported (现在,如果某种程度上整个过程被一些其他Python库包装,这些库捕获包括SystemExit在内的所有异常或某些其他进程可能会产生非零退出代码,回溯或其他意外输出)。虽然从表面上看这与直接提出SystemExit(或调用SystemExit)并没有太大区别,但是有一些前缀可以为sys.exit之类的错误生成,而这些错误可能会在自定义中引发DistutilsSetupError课程。所以尽管如此,调用Distribution也没问题。