BeastCoder
BeastCoder

Reputation: 2731

Catch the traceback from the imported module only

I have a package which can execute other modules and perform some methods on them. One of the things I need to have is the full trackback from the modules execution, should it run into an error. Currently I'm executing the module and getting the traceback like so:

try:
    module = importlib.import_module(os.path.splitext(args.file)[0])
except Exception as e:
    traceback.print_tb(e.__traceback__)

As an example, if I have this module:

# example.py
print({}[1])

The trackback if I get when I run the code alone is like this:

Traceback (most recent call last):
  File "example.py", line 2, in <module>
    print(my_dict[1])
KeyError: 1

That's the expected output, but my code gives additional unwanted information:

  File "/home/username/Desktop/Coding/Python/packagename/packagename/__main__.py", line 15, in <module>
    module = importlib.import_module(os.path.splitext(args.file)[0])
  File "/usr/lib/python3.8/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 783, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/home/username/Desktop/Coding/Python/packagename/example.py", line 2, in <module>
    print(my_dict[1])

How can I get only the expected output, instead of that full traceback?


EDIT

So, I've found another solution, but I have to execute it twice:

try:
    subprocess.call(f"python3 {args.file}", shell=True)
    importlib.import_module(os.path.splitext(args.file)[0])
except Exception as e:
    # Function that does something with e
    foo(e)

This isn't very nice code, so I was wondering how I could make it better? Thanks!

Upvotes: 2

Views: 597

Answers (1)

recursive_tree
recursive_tree

Reputation: 109

The traceback always goes up to where you catch it, so if you want to exclude the steps done during importing else, you need to catch it earlier. Can you catch it in the script you import? Then you could for example raise another exception with the original exception as argument to move the original exception a level down.

#the imported file
try:
    print({}[1])
except Exception as e:
    raise Exception(e)

#the importing file
try:
    module = importlib.import_module(os.path.splitext(args.file)[0])
except Exception as e:
    traceback.print_tb(e.args[0].__traceback__)

Upvotes: 1

Related Questions