The following code implements a loop-check for objects in roundup (not just issues) that refer to the same type of object via a link or multilink property. The code is intended to be called by an auditor. The first parameter is a gettext method for localisation of the error message in Reject. The other paramerts are cl: roundup class, id: id of the current item (can be None for a new item), prop: the name of the link or multilink property of the class for which no loop should occur, and attr: the contents of the prop attribute of the current item. The parameter ids is only used for recursive calls of the function:
from roundup.hyperdb import String, Link, Multilink def check_loop (_, cl, id, prop, attr, ids = []) : is_multi = isinstance (cl.properties [prop], Multilink) assert (is_multi or isinstance (cl.properties [prop], Link)) label = cl.labelprop () if id : ids.append (id) if attr : if not is_multi : attr = [attr] for a in attr : if a in ids : raise Reject, _ ("%s loop: %s") % \ (_ (prop), ','.join ([cl.get (i, label) for i in ids])) check_loop (_, cl, a, prop, cl.get (a, prop), ids) ids.pop () # end def check_loop
Usage example: Say, we have a supervisor attribute in the user class. Now we want to check that there is no supervisor-loop (one person being supervised by him or herself recursively). We'd call the following in an auditor for the user class:
if 'supervisor' in new_values : check_loop (_, cl, nodeid, 'supervisor', new_values ['supervisor'])