Как добавить новую функцию в RepoSurgeon (точно так же, как dsc или amp или min)
Это специализированная версия: Как заменить существующие методы класса Python (или иным образом расширить) RepoSurgeon с помощью "exec" и "eval"?
Как добавить новую функцию в RepoSurgeon, используя exec
возможность (т.е. без редактирования вышестоящего кода) добавить новую функцию, дополняя существующую функциональность.
Проблема: если вы используете RepoSurgeon и вызываете функцию из своего скрипта или из командной строки, и функция выдает исключение, это отбросит вызовы вложенных функций.
Пример: вы хотите найти все окаменелости на ветке по имени ветки в одной функции. Следующая составная команда выполнит работу для ветви с именем BRANCH
:
@dsc(@min(/BRANCH/)) list
Это работает нормально, если BRANCH
существует. Но что, если это не так? В таком случае RepoSurgeon рассердится на нас и выдаст исключение:
@dsc(@min(/NO_SUCH_BRANCH/)) list
[...]
ValueError: min() arg is an empty sequence
Проблема в том, что это означает, что весь ваш скрипт лифта будет сорван.
Что делать?
1 ответ
Возможно, одно из самых простых решений - написать собственную функцию и связать последовательность вызовов @dsc(@min(...))
при защите от исключений.
Предполагая, что у вас есть скрипт лифта, вставьте следующий документ здесь в качестве аргумента 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
,