HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Checking if blocks are catch extendable

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
extendableblocksarecheckingcatch

Problem

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] | sofa

Solution

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.)

Code Snippets

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
…
        if success:
            continue

        if catchtype == newcatchtype:
            break

        catchtype = newcatchtype
        ct_changed = True

Context

StackExchange Code Review Q#14556, answer score: 6

Revisions (0)

No revisions yet.