программно найти все функции, которые используются, рекурсивно - PullRequest
2 голосов
/ 06 июня 2019

Начиная со скрипта foo.py, рекурсивно найдите все функции, которые используются в локальном исходном коде (т.е. не в встроенных или сторонних пакетах).

РЕДАКТИРОВАТЬ: я не хочу, чтобы найти рекурсивные функции. Я хочу найти все используемые функции!

например. 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)

Должен вернуть do_stuff & more_stuff

Следует игнорировать not_used & abs

Большое спасибо

РЕДАКТИРОВАТЬ: код до сих пор

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

1 Ответ

0 голосов
/ 06 июня 2019

Вы можете использовать Python ast (абстрактное синтаксическое дерево) module

Краткий пример:

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

печатает:

more_stuff, do_stuff

Теперь вы можете добавлять тесты, вам нравится.Например, вопрос SO
Как найти / определить, используется ли встроенная функция в Python AST?
обсуждает, как определить, используется ли функция.

...