Python3: Don't show full directory path in error message

Is there a way to show only important directory paths when running a python program?

I am currently getting the following:

python3 foo.py Traceback (most recent call last): File "foo.py", line 60, in <module> foo = Foo() File "foo.py", line 22, in __init__ self._run() File "/media/MyDocuments/xxxxxxx/yyyyyyyyy/python_code/foo.py", line 18, in check_input bar = obj.get_action() AttributeError: 'obj' object has no attribute 'get_action' 

As I know in which directory my code is located, the full directory makes the error message less readable. Can I tell python to show me the result more than this?

 python3 foo.py Traceback (most recent call last): File "foo.py", line 60, in <module> foo = Foo() File "foo.py", line 22, in __init__ self._run() File ".../foo.py", line 18, in check_input bar = obj.get_action() AttributeError: 'obj' object has no attribute 'get_action' 

Answer

Using the code from unutbu , I added some lines for the colors, if someone is looking for a slight improvement on the interpreter output, just use this as a module and import it:

 import sys import traceback import os import re RED = '\033[91m' GREEN = '\033[92m' YELLOW = '\033[93m' LIGHT_PURPLE = '\033[94m' PURPLE = '\033[95m' CYAN = '\033[96m' END = '\033[0m' def my_excepthook(type, value, tb): lines = traceback.format_list(traceback.extract_tb(tb)) def shorten(match): return 'File "{}"'.format(os.path.basename(match.group(1))) lines = [re.sub(r'File "([^"]+)"', shorten, line) for line in lines] _print_color(lines) # print(''.join(lines)) print(RED + '{}: {}'.format(type.__name__, value) + END) sys.excepthook = my_excepthook def _print_color(lines): for l in lines: for i in range(len(l)-1): if l[i:i+5]=="line ": i +=5 # Find the length of the number numLen = 0 while l[i+numLen].isdigit(): numLen +=1 # Find the length of the function funLen = 0 while not l[i+numLen+4 + funLen]=="\n": funLen+=1 l = ''.join([l[:i], YELLOW+"{}".format(l[i:i+numLen])+END, l[i+numLen:i+numLen+5], LIGHT_PURPLE+"{}".format(l[i+numLen+5:i+numLen+5+funLen])+END, CYAN+"{}".format(l[i+numLen+5+funLen:])+END]) print(l,end="") break print("") 
+5
source share
3 answers

You can assign a custom sys.excepthook function to handle all uncaught exceptions :

 sys.excepthook = my_excepthook 

Then you can use

 def my_excepthook(type, value, tb): lines = traceback.format_list(traceback.extract_tb(tb)) # process/modify lines print(''.join(lines)) 

to get a trace error message as a sequence of lines, and then modify and print as you like.


For example, if you want to shorten all paths to a file to its base name only, you can use:

 import sys import traceback import os import re def my_excepthook(type, value, tb): lines = traceback.format_list(traceback.extract_tb(tb)) def shorten(match): return 'File "{}"'.format(os.path.basename(match.group(1))) lines = [re.sub(r'File "([^"]+)"', shorten, line, 1) for line in lines] print(''.join(lines)) print('{}: {}'.format(type.__name__, value)) sys.excepthook = my_excepthook # comment this out to see the difference class Foo(): def run(self): 1/0 foo = Foo() foo.run() 

what gives

  File "script.py", line 24, in <module> foo.run() File "script.py", line 21, in run 1/0 ZeroDivisionError: division by zero 

instead

 Traceback (most recent call last): File "/home/unutbu/pybin/script.py", line 24, in <module> foo.run() File "/home/unutbu/pybin/script.py", line 21, in run 1/0 ZeroDivisionError: division by zero 
+4
source

I think the best way to write my own mistakes is to use try and except.

 try: doSomething() # You code goes here. except Exception: # Whatever you want to be shown, full path, anything. pass 
0
source

You may have a try except block around your main routine or at the very highest level if you don't have a main routine. In the except block, you can analyze the exception trace to remove the directory name and other important information using the traceback module.

 import traceback import sys if __name__ == '__main__': try: #SomeOperation #More operation except: errorMsg = traceback.format_exc() #Format error message according to your preference print(errorMsgTransformed) sys.exit(1) 
0
source

All Articles