Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何从需要依赖性的设置中重写setuptools命令? 背景:_Python_Overriding_Setuptools - Fatal编程技术网

Python 如何从需要依赖性的设置中重写setuptools命令? 背景:

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中构建时将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):
        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编译器应该是一个可以在其他包中使用的包。当然,在我的第一次测试中,我把所有东西都放在了同一个包中。