distutils:如何将用户定义的参数传递给setup.py?

2024-06-16 12:08:36 发布

您现在位置:Python中文网/ 问答频道 /正文

请提示我如何将用户定义的参数从命令行和setup.cfg配置文件传递到distutils的setup.py脚本。我想编写一个setup.py脚本,它接受我的包特定参数。例如:

python setup.py install -foo myfoo

谢谢,
Mher公司


Tags: install命令行用户py脚本参数定义foo
3条回答

由于Setuptools/Distuils被可怕地记录在案,我自己也很难找到答案。但最终我偶然发现了this示例。同样,this类似的问题也是有帮助的。基本上,带有选项的自定义命令如下所示:

from distutils.core import setup, Command

class InstallCommand(Command):
    description = "Installs the foo."
    user_options = [
        ('foo=', None, 'Specify the foo to bar.'),
    ]
    def initialize_options(self):
        self.foo = None
    def finalize_options(self):
        assert self.foo in (None, 'myFoo', 'myFoo2'), 'Invalid foo!'
    def run(self):
        install_all_the_things()

setup(
    ...,
    cmdclass={
        'install': InstallCommand,
    }
)

这里有一个非常简单的解决方案,您只需过滤掉sys.argv,并在调用distutilssetup(..)之前自己处理它。 像这样的:

if "--foo" in sys.argv:
    do_foo_stuff()
    sys.argv.remove("--foo")
...
setup(..)

关于如何使用distutils实现这一点的文档非常糟糕,最终我遇到了这个:the hitchhikers guide to packaging,它使用sdist及其user_options。 我发现extending distutils引用没有特别的帮助。

虽然这看起来像是用distutils来做的“正确”的方法(至少我能找到的唯一一个是含糊不清的文档)。我在另一个答案中提到的--with--without开关上找不到任何东西。

这个distutils解决方案的问题是,它对我所寻找的东西来说太复杂了(对你来说也是如此)。 对我来说,添加几十行和子类化sdist是错误的。

是的,现在是2015年,在setuptoolsdistutils中添加命令和选项的文档仍然大部分丢失。

几个小时后,我找到了以下代码,用于向setup.py命令的install添加自定义选项:

from setuptools.command.install import install


class InstallCommand(install):
    user_options = install.user_options + [
        ('custom_option=', None, 'Path to something')
    ]

    def initialize_options(self):
        install.initialize_options(self)
        self.custom_option = None

    def finalize_options(self):
        #print('The custom option for install is ', self.custom_option)
        install.finalize_options(self)

    def run(self):
        global my_custom_option
        my_custom_option = self.custom_option
        install.run(self)  # OR: install.do_egg_install(self)

值得一提的是,install.run()检查它是否被称为“本机”或已被修补:

if not self._called_from_setup(inspect.currentframe()):
    orig.install.run(self)
else:
    self.do_egg_install()

此时,您可以使用setup注册命令:

setup(
    cmdclass={
        'install': InstallCommand,
    },
    :

相关问题 更多 >