# Checking Suspicious Functions

Sun Feb 27 06:20:52 EST 2000

```After Tim and mine discusion, I thought writing code for a change would be
nice. Here's a rough draft of my "checking whether a function can return a
value from one place and return None from another" code:

--- suspect.py
import dis # for HAVE_ARGUMENT, and opname

# currently we're to dumb to understand this is valid:
# if x:
#	return 1
# else:
#	return 0

for i in range(len(dis.opname)):
if dis.opname[i]=='RETURN_VALUE':
return_value = i

none_place = 0 # None is always the first suspect

def basic_dis(code):
ret = []
n = len(code)
i = 0
while i < n:
b = ord(code[i])
if b < dis.HAVE_ARGUMENT:
ret.append((b,))
else:
argument = ord(code[i+1])+256*ord(code[i+2])
ret.append((b, argument))
i = i+2
i = i+1
return ret

def get_suspects(ops):
suspects = []
for i in range(len(ops)):
# if Python's compiler has a bug, this will output nonsense
if ops[i] == (return_value,):
suspects.append((i, ops[i-1]))
# if there are two returns at the end, the last one if Python's
# fault: it should be smart enough to optimize it away:
if len(suspects)>=2 and suspects[-1]==suspects[-2]+2:
del suspects[-1]
return map(lambda x: x, suspects)

def check_suspects(suspects):
if not suspects:
return 1
first, rest = suspects, suspects[1:]
for el in rest:
return 0
return 1
else:
for el in rest:
return 0
return 1

code = func.func_code.co_code
ops = basic_dis(code)
suspects = get_suspects(ops)
if check_suspects(suspects):
return 0
return 1

if __name__=='__main__':
def foo():
pass

def bar():
return 1

def baz():
if a:
return 1

def qux():
return 1
return

for f in (foo, bar, baz, qux):
print f.func_name, "is shaky"
else:
print f.func_name, "seems alright"
--- cut here -----
--