0

这是一个专门的版本:如何通过“exec”和“eval”来替换(或扩展)RepoSurgeon 的现有 Python 类方法?

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

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

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

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

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

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

问题是这意味着您的整个提升脚本将脱轨。

该怎么办?

4

1 回答 1

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中定义的异常类的名称,reposurgeon但在完成后不再可用于我们的代码exec。其他符号可以以相同的方式进行。

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

reposurgeon: function @brpdsc() called with selection that resolves to empty set

从 RepoSurgeon 尝试运行后@brpdsc/NO_SUCH_BRANCH/) list

于 2014-08-21T13:36:29.873 回答