TI/Zadanie z tracebackami

Z Brain-wiki

Zadanie 1

"Tracebacki" w Pythonie mają następującą postać:

Traceback (most recent call last):
  File "<nazwa-pliku>", line <n>, in <nazwa-funkcji-lub-<module>>
     <linijka-kodu>
  File "<nazwa-pliku>", line <n>, in <nazwa-funkcji-lub-<module>>
     <linijka-kodu>
  ...
<klasa-wyjatku>: <opis>

(Parę przykładów jest poniżej.)

Prosze napisać funkcję do parsowania tracebacków z napisu:
parse(s) która zwraca trzy rzeczy:

  • typ wyjątku (w postaci nazwy klasy)
  • opis wyjątku (w postaci napisu)
  • sekwencję linijek nastepującej postaci
    (<nazwa-pliku>, <n>, <nazwa-funkcji-lub-<module>>, <linijka-kodu>)

W zwracanej sekwencji <nazwa-pliku> i <linijka-kodu> niech będą napisami. Numer <n> niech będzie liczbą. <nazwa-funkcji-lub-<module>> jest najbardziej kłopotliwa, bo może to być albo nazwa funkcji, albo stały napis <module>, oznaczający że fragment kodu był na poziomie modułu, a nie w żadnej funkcji. W przypadku gdy <nazwa-funkcji-lub-<module>> jest funkcją, zwracana sekwencja powinna zawierać nazwę funkcji jako napis, natomiast wpp. None.


Zadanie 2

Wykorzystując funkcję parse z poprzedniego zadania, prosżę napisać funkcję

 parse_file(file)

która otworzy plik file i wczyta z niego "traceback". Jeśli file jest napisem, to funkcja powinna sama otworzyć plik traktując file jako nazwę pliku.

"Traceback" w pliku można znaleźć szukając linijki zaczynającej się od "Traceback (most recent". Z koleji wiemy, że "traceback" nie jest skończony, dopóki mamy linijki zaczynające się od spacji. Pierwsza linija nie zaczynająca się od spacji powinna być linijką z typem i opisem wyjątku. (Mimo, że nie brzmi to specjalnie niezawodnie, moduł doctest w standardowej bibliotece Pythona działa w dokładnie taki sposób.)

Zadanie 3

Wykorzystując funkcję parse_file z poprzedniego zadania, proszę napisać program

 parser.py

który wypisze wyjątki występujące w plikach podanych jako argumenty programu. Wyjatki powinny być wypisane w zwięzłej formie:

<typ-wyjątku>
  <nazwa-pliku>:<n>:<nazwa-funkcji>: <linijka-kodu>
  <nazwa-pliku>:<n>:<nazwa-funkcji>: <linijka-kodu>
  ...
<opis-wyjątku>

Przykład

Dla następującego pliku plik-1:

Traceback (most recent call last):
  File "examples.py", line 10, in f
    def f(): g()
  File "examples.py", line 11, in g
    def g(): h()
  File "examples.py", line 12, in h
    def h(): 1/0
ZeroDivisionError: integer division or modulo by zero

wywołanie

 parser.py plik-1

powinno dać

ZeroDivisionError
  examples.py:10:f: def f(): g()
  examples.py:11:g: def g(): h()
  examples.py:12:h: def h(): 1/0
integer division or modulo by zero

Tracebacki

Traceback (most recent call last):
  File "examples.py", line 6, in trace
    func()
  File "examples.py", line 10, in f
    def f(): g()
  File "examples.py", line 11, in g
    def g(): h()
  File "examples.py", line 12, in h
    def h(): 1/0
ZeroDivisionError: integer division or modulo by zero
Traceback (most recent call last):
  File "examples.py", line 6, in trace
    func()
  File "examples.py", line 17, in f
    g()
  File "examples.py", line 19, in g
    h()
  File "examples.py", line 21, in h
    1/0
ZeroDivisionError: integer division or modulo by zero
Traceback (most recent call last):
  File "examples.py", line 6, in trace
    func()
  File "examples.py", line 26, in m
    import module
  File "/home/zbyszek/python/neuroinformatyka/tracebacks/module.py", line 1, in <module>
    {}['x']
KeyError: 'x'
Traceback (most recent call last):
  File "examples.py", line 30, in <module>
    1/0
ZeroDivisionError: integer division or modulo by zero