14

Is there a library or a python magic that allows me to execute all functions in a file without explicitly calling them. Something very similar to what pytest is doing - running all functions that start with 'test_...' without ever registering them anywhere.

For example assume I have a file a.py:

def f1():
    print "f1"

def f2():
    print "f2"

and assume I have file - my main file - main.py:

if __name__ == '__main__':
    some_magic()

so when I call:

python main.py

The output would be:

f1
f2
Ezra
  • 1,401
  • 5
  • 15
  • 33
  • Seems like you might be interested in [metaprogramming](http://python-3-patterns-idioms-test.readthedocs.org/en/latest/Metaprogramming.html). I've never delved into it so I'd be the last person to tell you how to approach it. – Makoto Feb 21 '15 at 08:14
  • You can use introspection to find all the functions in the globals and locals dictionary, possibly by going back through the call stack to find the caller's globals/locals. Look at the `inspect` module in the standard library. – cdarke Feb 21 '15 at 08:25

3 Answers3

20

Here's a way:

def some_magic():
    import a
    for i in dir(a):
        item = getattr(a,i)
        if callable(item):
            item()

if __name__ == '__main__':
    some_magic()

dir(a) retrieves all the attributes of module a. If the attribute is a callable object, call it. This will call everything callable, so you may want to qualify it with and i.startswith('f').

Mark Tolonen
  • 166,664
  • 26
  • 169
  • 251
1

Here's another way:

#!/usr/local/bin/python3
import inspect
import sys


def f1():
    print("f1")


def f2():
    print("f2")


def some_magic(mod):
    all_functions = inspect.getmembers(mod, inspect.isfunction)
    for key, value in all_functions:
        if str(inspect.signature(value)) == "()":
            value()

if __name__ == '__main__':
    some_magic(sys.modules[__name__])

It will only call functions that don't have any parameters by using inspect.signature(function).

apricity
  • 1,300
  • 1
  • 14
  • 22
0

Have you tried callifile?

pip install callifile

and then, in your file:

from callifile.callifile import callifile as callifile
import sys

callifile(module=sys.modules[__name__], verbose=True)

Self-sufficient example:

In a file some_callify.py:

from callifile.callifile import callifile as callifile
import sys

def f_1():
    print "bla"

callifile(module=sys.modules[__name__], verbose=True)

Calling in terminal:

python some_callify.py

Gives me the terminal output:

Apply call_all_function_in_this_file on <module '__main__' from 'some_callify.py'>
See if should call callifile
See if should call f_1
Call f_1
bla
Zorglub29
  • 6,979
  • 6
  • 20
  • 37