3

Starting from a script foo.py find all functions that are in use in local source code (i.e not built-in or third party packages), recursively.

EDIT: I do not want to find recursive functions. I want to find all functions that are in use!

e.g. foo.py

import bar

def not_used():
    pass

bar.do_stuff(x,y)

bar.py

import math

def more_stuff(x,y):
    result = math.abs(-x+-y)
    return result

def do_stuff(x,y):
    more_stuff(x,y)

Should return do_stuff & more_stuff

Should ignore not_used & abs

Many thanks

EDIT: Code so far

import dis

py_file = 'foo.py'

with open(py_file) as file:
    source_code = file.read()

compiled = compile(source_code, py_file, "exec")

funcs = []
byte_code = dis.Bytecode(compiled)
instructions = list(reversed([x for x in byte_code]))

for (ix, instruction) in enumerate(instructions):
    if instruction.opname == "CALL_FUNCTION":
        load_func_instr = instructions[ix + instruction.arg + 1]
        funcs.append(load_func_instr.argval)

results = [f'{ix}: {funcname}'for (ix, funcname) in enumerate(reversed(funcs), 1)]
Anonymous
  • 1,015
  • 1
  • 10
  • 14
  • Please define "in use", because it seems to me that `math.abs` should be considered "in use" here. – Leporello Jun 06 '19 at 09:10
  • @Leporello good point, updated. thanks. – Anonymous Jun 06 '19 at 09:13
  • @Anonymous this is quite old, but if you still got the code it would be cool, if you could share your solution to avoid "reinventing the wheel" as you fittingly pointed in a comment below. – LC117 Mar 24 '23 at 11:52

1 Answers1

0

You can use Python's ast (abstract syntax tree) module

A short example:

import ast

code = """
import math

def more_stuff(x,y):
    result = math.abs(-x+-y)
    return result

def do_stuff(x,y):
    more_stuff(x,y)
"""

tree = ast.parse(code)

funcs = [x for x in ast.walk(tree) if isinstance(x, ast.FunctionDef)]

print(', '.join(f.name for f in funcs))

prints:

more_stuff, do_stuff

now you can add the tests, you like. For example the SO question
How to find/detect if a build-in function is used in Python AST?
discusses how to detect if a function is being used.

Snow bunting
  • 1,120
  • 8
  • 28
  • Thanks @snow-bunting not really what I'm after, as it would pick-up all the unused functions and it doesn't resolve files that are referenced in imports. But I think a combination of the two approaches could probably work. I was going to write something, but I thought that somebody must've done this before and I hate reinventing the wheel - hence asking on here. – Anonymous Jun 06 '19 at 09:22