为了能够在建立时在setuptools中将GNU gettext po文件转换为mo文件,我创建了setuptools.command.build_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
然后我只需要在cmdclass
的{{1}}参数中声明它:
setup
到目前为止,很好,当在setup(
...
cmdclass = {"build_py", mypgk.build_py},
)
脚本中安装并导入我的模块时,setuptools的构建阶段可以正确处理我的po文件。
目标是允许使用pip简单安装源代码发行版。事情看起来不错,因为pip可以处理任何依赖项,只要它们在setup.py
或install_requires
参数中声明即可。这就是鸡和鸡蛋的问题所在:运行setup_requires
时会安装依赖项,但是如果不首先安装setup.py
则无法运行依赖项。
我尝试使用魔术mypkg
在entry_points
build_py
脚本中声明mypkg
覆盖:
setup.py
但是它没有任何作用,尽管我可以这样声明一个有效的新...
entry_points = {
"distutils.commands": [
"build_py = mypkg:build_py",
],
}
命令:
build_mo
长话短说,entry_points = {
"distutils.commands": [
"build_mo = mypkg:build_py",
],
}
调用我的替代,而python setup.py build_mo
调用setuptools版本。
为什么用python setup.py build_py
声明覆盖build_py
命令的尝试无效,怎么办?
答案 0 :(得分:0)
我接近解决方案。经过setuptools
文档和资料的进一步研究后,我终于意识到它已经使用entry_points
机制来用自己的命令覆盖distutils
命令。
这意味着当您尝试覆盖setuptools
命令时,实际上您建议对同一命令进行第二次覆盖。由于setuptools
的处理方式,仅使用找到的第一个替代,而根据我的测试,setuptools
就是第一个替代。
我现在可以说,因此,只能以这种方式处理distutils
中未被覆盖的来自setuptools
的命令。好消息是build
没有被覆盖,在正常使用中,总是从build_py
调用build
。
由于build
不会覆盖setuptools
命令,因此很容易用entry_point
替换它。然后,自定义build
命令类可以更新cmdclass
目录以声明自定义build_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)
在我的测试中,只需简单地使setuptools
使用自定义build_py
类即可
setup(
...
setup_requires = ["mypkg"],
)