如何向RepoSurgeon添加新功能(就像dsc或amp或min)

时间:2014-08-21 11:52:33

标签: python-2.7 reposurgeon

这是How to replace existing Python class methods of (or otherwise extend) RepoSurgeon by means of 'exec' and 'eval'?

的专业版

如何使用exec工具向RepoSurgeon添加新功能(即不编辑上游代码)以添加新功能,增强现有功能。

问题:如果您正在使用RepoSurgeon,并且从脚本或命令行调用函数,并且函数抛出异常,则会抛出嵌套函数调用。

示例:您希望在单个函数中按分支名称查找分支上的所有化石。以下复合命令将为名为BRANCH的分支执行作业:

@dsc(@min(/BRANCH/)) list

如果存在BRANCH,这样可以正常工作。但如果不是呢?在这种情况下,RepoSurgeon将对我们非常生气并抛出异常:

@dsc(@min(/NO_SUCH_BRANCH/)) list
[...]
ValueError: min() arg is an empty sequence

问题在于这意味着您的整个电梯脚本会脱轨。

怎么办?

1 个答案:

答案 0 :(得分:1)

也许最简单的解决方案之一就是编写自己的函数并捆绑@dsc(@min(...))的调用序列,同时防范异常。

假设您有一个提升脚本,请将以下here-doc作为exec的参数嵌入其中:

exec <<EOF
    if self:
        def brpdsc_factory(recov):
            Recoverable = recov
            def brpdsc_handler(self, subarg):
                if not subarg:
                    raise Recoverable("function @brpdsc() called with selection that resolves to empty set")
                minset =      set([])
                descendants = set([])
                try:
                    minset = self.min_handler(subarg)
                except ValueError as e:
                    raise Recoverable("invalid value passed to function @min()")
                try:
                    descendants = self.dsc_handler(minset)
                except:
                    raise Recoverable("the implicit call to @dsc() failed")
                return descendants
            return brpdsc_handler
        brpdsc_handler = brpdsc_factory(Recoverable)
        setattr(self, 'brpdsc_handler', brpdsc_handler.__get__(self, self.__class__))
EOF

这将本地函数brpdsc_handler植入为同名class RepoSurgeon的类成员,并使函数@brpdsc立即可用于脚本或命令提示符。

工厂函数用于继承Recoverable的名称,reposurgeonexec脚本中定义的异常类,但在reposurgeon: function @brpdsc() called with selection that resolves to empty set 完成后我们的代码不再可用。其他符号可以通过相同的方式传播。

现在所有可能发生的事情是我们收到:

@brpdsc/NO_SUCH_BRANCH/) list
尝试运行{{1}}后,来自RepoSurgeon的