Python 如何从需要依赖性的设置中重写setuptools命令? 背景:
为了能够在setuptools中构建时将GNU gettext po文件转换为mo文件,我创建了Python 如何从需要依赖性的设置中重写setuptools命令? 背景:,python,overriding,setuptools,Python,Overriding,Setuptools,为了能够在setuptools中构建时将GNU gettext po文件转换为mo文件,我创建了setuptools.command.build\u py的子类,在调用其基类之前(通过pymsgfmt的副本)对其进行编译: from setuptools.command.build_py import build_py as _build_py class build_py(_build_py): parent = _build_py def run(self):
setuptools.command.build\u py
的子类,在调用其基类之前(通过pymsgfmt的副本)对其进行编译:
from setuptools.command.build_py import build_py as _build_py
class build_py(_build_py):
parent = _build_py
def run(self):
self.compile_po_files() # internal implementation
self.parent.run(self)
def get_outputs(self): # overriden to produce a correct list of installed files
build_mo = self.get_finalized_command("build_mo")
return _build_py.get_outputs(self) + self.outputs
然后我只需在setup
的cmdclass
参数中声明它:
setup(
...
cmdclass = {"build_py", mypgk.build_py},
)
到目前为止,很好,当我的模块安装并导入到setup.py
脚本中时,setuptools的构建阶段会正确处理我的po文件
问题:
目标是允许使用pip简单地安装源发行版。事情看起来不错,因为只要在install\u requires
或setup\u requires
参数中声明依赖项,pip就会处理这些依赖项。这就是鸡和蛋的问题所在:依赖性是在运行setup.py
时安装的,但是如果不首先安装mypkg
,它就无法运行
当前研究:
我已尝试使用魔法入口点
在mypkg
setup.py
脚本中声明build\u py
覆盖:
...
entry_points = {
"distutils.commands": [
"build_py = mypkg:build_py",
],
}
但是它没有效果,我可以这样声明一个新的build\u mo
命令:
entry_points = {
"distutils.commands": [
"build_mo = mypkg:build_py",
],
}
长话短说,python setup.py build\u-mo
调用我的覆盖,而python setup.py build\u-py
调用setuptools version
问题:
为什么我试图用入口点
声明覆盖build\u py
命令无效,我该如何做?解释问题
我已经接近解决方案了。在对setuptools
docs和sources进行了更多的研究之后,我终于意识到它已经使用了entry\u points
机制来覆盖distutils
命令
这意味着,当您尝试覆盖setuptools
命令时,实际上您建议对同一命令进行第二次覆盖。由于setuptools
处理它的方式,只使用找到的第一个覆盖,从我的测试来看,setuptools
one就是第一个
因此,我现在可以说,只有distutils
中未在setuptools
中重写的命令才能以这种方式处理。好消息是,build
不会被覆盖,在正常使用中,build\u py
总是从build
调用
可能的解决办法:
由于build
命令不会被setuptools
覆盖,因此很容易将其替换为入口点。然后,自定义build
命令类可以更新cmdclass
目录来声明自定义build\u py
类,因为基本build
会加载它。代码可以是:
from distutils.command.build import build as _build
class build(_build):
parent = _build
def run(self):
self.distribution.cmdclass["build_py"] = build_py
self.parent.run(self)
在我的测试中,只需使用一个简单的
setup(
...
setup_requires = ["mypkg"],
)
我使用build_py
步骤,而不是build_ext
,因为我希望能够生成平台和版本独立的控制盘。这是有意义的,因为GNU gettext mo文件可以在任何平台上使用,无论其endianness如何。从您提供的代码来看,不清楚为什么您必须将自定义命令放在单独的包中,而不是将其保留在安装脚本中。正如您已经发现的,真正的问题是您需要引导包以构建或安装它。引导是一个脆弱的解决方案-你不能在安装脚本中隔离构建代码吗?@hoefling:因为po-to-mo编译器应该是一个可以在其他包中使用的包。当然,在我的第一次测试中,我把所有东西都放在了同一个包中。