It is very difficult to determine which functions and methods to call without executing the code, even if the code does not do any fancy things. Ordinary function calls are pretty easy to spot, but method calls are really complex. A simple example:
class A(object): def f(self): pass class B(A): def f(self): pass a = [] a.append(A()) a.append(B()) a[1].f()
Nothing special happens here, but any script that tries to determine whether Af() or Bf() will be called will have a rather difficult time without executing this code.
While the above code does nothing useful, it certainly uses templates that are displayed in real code, namely the placement of instances in containers. Real code usually does even more complex things โ pickling and scattering, hierarchical data structures, conventions.
As stated above, just detecting simple form call functions
function(...)
or
module.function(...)
will be pretty easy. You can use the ast module to analyze your source files. You will need to record all the imports and the names used to import other modules. You will also need to track the definitions of top-level functions and the calls inside these functions. This will give you a dependency graph, and you can use NetworkX to discover the connected components of this graph.
Although this may seem rather complicated, it can perhaps be done with less than 100 lines of code. Unfortunately, almost all major Python projects use classes and methods, so this will help little.
Sven Marnach Mar 02 2018-12-12T00: 00Z
source share