考虑最简单的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)
这样做是否安全;有更好的选择吗?
答案 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
也没问题。