重写cmdclass时忽略python setuptools install_requires

重写cmdclass时忽略python setuptools install_requires,python,setuptools,distutils,install-requires,Python,Setuptools,Distutils,Install Requires,我有一个setup.py,看起来像这样: from setuptools import setup from subprocess import call from setuptools.command.install import install class MyInstall(install): def run(self): call(["pip install -r requirements.txt --no-clean"], shell=True)

我有一个
setup.py
,看起来像这样:

from setuptools import setup
from subprocess import call
from setuptools.command.install import install

class MyInstall(install):
    def run(self):
        call(["pip install -r requirements.txt --no-clean"], shell=True)
        install.run(self)

setup(
    author='Attila Zseder',
    version='0.1',
    name='entity_extractor',
    packages=['...'],
    install_requires=['DAWG', 'mrjob', 'cchardet'],
    package_dir={'': 'modules'},
    scripts=['...'],
    cmdclass={'install': MyInstall},
)
我需要
MyInstall
,因为我想从github安装一些库,而且我不想使用
dependency\u links
选项,因为它是不受鼓励的(例如),所以我可以使用requirements.txt来实现

当我用
pip
安装这个软件包时,一切都很正常,但出于某些原因,我必须用纯
python setup.py安装解决这个问题。但事实并非如此

当用我自己的类重写
setup()
中的
cmdclass
时,
install\u requires
似乎被忽略。我一评论这一行,这些软件包就已经安装好了

我知道install_requires在distutils中不受支持(如果我记得很清楚的话),但在setuptools中是受支持的。然后
cmdclass
将不会对
install\u requires
产生任何影响

我在谷歌上搜索了几个小时,在stackoverflow上找到了很多相关的答案,但不是针对这个问题


将每个需要的包放到requirements.txt中,一切正常,但我想了解为什么会发生这种情况。谢谢

同样的问题刚刚发生在我身上。似乎有什么东西触发了setuptools对
distutils
执行“旧式安装”,而这实际上不支持
install\u requires

您可以调用install.run(self),它在setuptools/setuptools/command/install.py的第51-74行中调用run(self)

我不确定这种行为是否有意,但是

install.run(self)

应该能解决你的问题。至少它对我有效,但我也希望得到更详细的答案。谢谢

根据一种更正确的方法,这可能是重写
bdist_egg
命令

你可以试试:

from setuptools.command.bdist_egg import bdist_egg as _bdist_egg

class bdist_egg(_bdist_egg):
    def run(self):
        call(["pip install -r requirements.txt --no-clean"], shell=True)
        _bdist_egg.run(self)

...

setup(...
    cmdclass={'bdist_egg': bdist_egg},  # override bdist_egg
)

它对我很有用,
install\u require
不再被忽略。尽管如此,我仍然不明白为什么大多数人似乎覆盖了
cmdclass安装,并且没有抱怨
install\u require
被忽略。

我知道这是一个老问题,但我遇到了类似的问题。我找到的解决方案为我解决了这个问题,它非常微妙:您在
cmd\u class
中设置的
install
类必须实际命名为
install
。有关相关问题,请参阅

请注意,我使用派生类的类名install,因为python setup.py--help命令将使用这个类名

您还应该在post安装中使用
self.execute(\u func\u name,(),msg=“msg”)
,而不是直接调用该函数

因此,实现这样的功能应该可以避免上面由KEgg实现的
do_egg\u install
解决方案

from setuptools.command.install import install as _install
...
def _post_install():
    #code here
class install(_install):
    def run(self):
        _install.run(self)
        self.execute(_post_install, (), msg="message here")

它确实解决了我的问题,谢谢!是的,我也希望能详细回答原因。对于任何想知道的人来说,有趣的观察结果是:
setuptools
commands子类,这是一个老式的Python
class
。由于这个原因,
super
不能使用,父类必须直接引用。这不应该是
install.do\u egg\u install(self)
?我希望我能多次对这个答案进行投票。另外,当使用python3时,调用
super().do_egg\u install()
使用此解决方案时,我收到了
错误:从PyPi安装包时生成控制盘失败
消息。我的结论是生产模块不应依赖于
cmdclass
。它的文档太差,并且有太多意外失败的边缘情况。可能他们只使用了
pip安装
,而从不使用
python setup.py安装
,或者当使用后者时,他们在已经填充了依赖项的
virtualenv
中这样做。你确定吗?我无法复制,这也不能解决setuptools运行时的帧检查问题。老实说,我不确定<代码>设置工具
的文档记录非常少,并且经常表现为零星行为。我能够通过可复制的安装后命令为我的PyPI包获得所需的行为,可能是以我不理解的方式。您可以下载、解压缩,然后自己检查setup.py:
from setuptools.command.bdist_egg import bdist_egg as _bdist_egg

class bdist_egg(_bdist_egg):
    def run(self):
        call(["pip install -r requirements.txt --no-clean"], shell=True)
        _bdist_egg.run(self)

...

setup(...
    cmdclass={'bdist_egg': bdist_egg},  # override bdist_egg
)
from setuptools.command.install import install as _install
...
def _post_install():
    #code here
class install(_install):
    def run(self):
        _install.run(self)
        self.execute(_post_install, (), msg="message here")