Checking if blocks are catch extendable Basically, I have a list, newtry of blocks, and I want to find a value of catchtype that makes them all return true for block.isCatchExtendable(newhandler, catchtype) or report an error if this can't be done. block.isCatchExtendable returns two values, success and a new type to try on failure.

My current code works, but the control flow is very convoluted, with numerous breaks and elses. I was wondering if anyone could think of a better way to arrange things. Also, these are all my own functions, so I am free to change the interfaces, etc.

while 1:
    ct_changed = False

    for block in newtry:
        success, newcatchtype = block.isCatchExtendable(newhandler, catchtype)
        if not success:
            if catchtype == newcatchtype: #no success and no other types to try, so just break and fail
                break
            catchtype, ct_changed = newcatchtype, True
    else:
        if ct_changed:
            continue
        else:
            break
    error('Unable to extend try block completely')


isCatchExtendible:

def isCatchExtendable(self, newhandler, catchtype):
    return self.catchset.extendible(newhandler, catchtype, self.currentHandlers)


This then calls:

#If not extendible with current catchtype, returns suggested type as second arg
def extendible(self, newhandler, catchtype, outerhs):
    if catchtype is None:
        temp = self.catchsets.get(newhandler)
        if temp is None:
            return True, None
        return False, temp.getSingleTType()[0]

    proposed = ExceptionSet.fromTops(self.env, catchtype)
    inner = [h for h in self.handlers if h != newhandler and h not in outerhs]
    outer = [h for h in self.handlers if h in outerhs]

    sofar = ExceptionSet.fromTops(self.env)
    for h in inner:
        sofar = sofar | self.catchsets[h]
    if (proposed - sofar) != self.catchsets[newhandler]:

        #Get a suggsted catch type to try instead
        suggested = (self.catchsets[newhandler] | sofar).getSingleTType()
        suggested = objtypes.commonSupertype(self.env, suggested, (catchtype, 0))
        assert(self.env.isSubClass(suggested[0], 'java/lang/Throwable'))
        return False, suggested[0]
    for h in outer:
        if not proposed.isdisjoint(self.catchsets[h]):
            return False, catchtype
    return True, catchtype
First off, a pet peeve of mine: while 1 makes no semantical sense. You want while True.

However, in your case you actually want while ct_changed:

ct_changed = True
while ct_changed:
    ct_changed = False
    for block in newtry:
        success, newcatchtype = block.isCatchExtendable(newhandler, catchtype)
        if not success:
            if catchtype == newcatchtype:
                break
            else:
                catchtype = newcatchtype
                ct_changed = True


Alternatively, you can flatten the nesting level by inverting the if not success conditional, and continuing:

        …
        if success:
            continue

        if catchtype == newcatchtype:
            break

        catchtype = newcatchtype
        ct_changed = True


(In fact, I’d probably go for this.)