Search code examples
pythonobjectexecpython-importlib

Error using python exec to call a function with object argument


I am trying to call a function that takes an object as an argument. The code looks somethin like this

exec(f"{object.attr1}.{object.attr2}({interface_obj})")

When I run this, I run into a

SyntaxError: invalid syntax

The syntax error is pointed right at the beginning of interface_obj But python does not say what exactly the issue is. Has anyone encountered this?

I had an issue with a dictionary converted to a class and circumvented by just passing the dictionary itself. However for the interface_obj I cannot do the same.

EDIT:

Here is some context - I am developing an automation platform that can run multiple tests. Each test is essentially an independent .py file.

for e.g.

main.py
.\Main_dependency
      |__ test_calling_script.py
.\Test
      |__ test1.py
      |__ test2.py
      :
      |__ testN.py

My idea is to have a single point of test import in the test_calling_script.py and run the respective test based on input. Hence using exec to have a single line code to call the corresponding test.

 test1.test_func(<__main__.TEST object at 0x000002962BF83FD0>)
                 ^
SyntaxError: invalid syntax

Thanks for the comments folks! I was able to use a combination of answers from @juanpa.arrivillaga and @cookieobjects to achieve what I was trying.

Updated Snippet

Usage
from importlib import import_module
variable = getattr(import_module(<package_name>.<test_file_name>, function)
variable(argument) 

Code
from importlib import import_module
test_module = getattr(import_module(f'Test.{object.attr1}'), {object.attr2})
test_module(interface_obj)

Found another question with similar use case


Solution

  • Using exec() for external scripts is bad practice due to having few checks as to whether or not your script is valid, and due to the limited nature of error handling for such highly dynamic and broad-spectrum functionality. It is more difficult to diagnose without a little infrastructure describing what is actually going on.

    For the problem of needing a way to dynamically import and run python scripts from an external folder, you can use importlib.

    import importlib
    
    def import_test(file_name):
        return importlib.import_module(file_name)
    
    testing_module = import_test('testing_module')
    results = testing_module.test_function(interface_obj)
    

    Your "loader" function would be import_test, and would be "test_calling_script" in your folder structure.