This is a specialized version of: How to replace existing Python class methods of (or otherwise extend) RepoSurgeon by means of 'exec' and 'eval'?
How can one add a new function to RepoSurgeon using the exec
facility (ie without editing the upstream code) to add a new function, augmenting existing functionality.
Problem: if you are using RepoSurgeon and you call a function from your script or on the command line and the function throws an exception, this will throw off nested function calls.
Example: you want to find all fossils on a branch by branch name in a single function. The following compound command will do the job for a branch named BRANCH
:
@dsc(@min(/BRANCH/)) list
This works fine if BRANCH
exists. But what if it doesn't? In such a case RepoSurgeon will get quite angry with us and throw an exception:
@dsc(@min(/NO_SUCH_BRANCH/)) list
[...]
ValueError: min() arg is an empty sequence
The problem is that this means that your whole lift script will get derailed.
What to do?
Perhaps one of the easiest solutions is to write your own function and bundle the call sequence of @dsc(@min(...))
while guarding against exceptions.
Assuming you have a lift script, embed the following here-doc as argument to exec
into it:
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
This implants the local function brpdsc_handler
as class member of the same name of class RepoSurgeon
and makes a function @brpdsc
immediately available to scripts or the command prompt.
The factory function exists to carry over the name for Recoverable
which is an exception class defined in the reposurgeon
script but not available to our code anymore after the exec
has finished. Other symbols can be carried over the same way.
Now all that can happen is that we receive:
reposurgeon: function @brpdsc() called with selection that resolves to empty set
from RepoSurgeon after attempting to run @brpdsc/NO_SUCH_BRANCH/) list
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.