Wie kann ich ein Python Zurückverfolgungs Objekt ändern, wenn eine Ausnahme erhöhen?

StackOverflow https://stackoverflow.com/questions/1603940

  •  05-07-2019
  •  | 
  •  

Frage

Ich arbeite an einer Python-Bibliothek mit dem Entwickler von Drittanbietern verwendet, um Erweiterungen für unsere Kernanwendung zu schreiben.

Ich würde gerne wissen, ob es möglich ist, die Rückverfolgung zu ändern, wenn Ausnahmen erhöht, so dass der letzte Stapelrahmen ist der Aufruf der Bibliotheksfunktion im Code des Entwicklers, anstatt die Zeile in der Bibliothek, die die Ausnahme ausgelöst. Es gibt auch ein paar Frames an der Unterseite des Stapels Verweis auf Funktionen enthält, wenn der Code zuerst geladen, dass ich im Idealfall löschen möchte.

Vielen Dank im Voraus für jede Beratung!

War es hilfreich?

Lösung

Was ist nicht das Zurückverfolgungs verändern? Die beiden Dinge, die Sie anfordern können sowohl leichter auf andere Weise durchgeführt werden.

  1. Wenn die Ausnahme von der Bibliothek in dem Code des Entwicklers gefangen wird und eine neue Ausnahme wird stattdessen erhöht, werden natürlich die ursprünglichen Zurückverfolgungs geworfen werden. Dies ist, wie Ausnahmen im Allgemeinen behandelt werden ..., wenn Sie nur die ursprüngliche Ausnahme angehoben werden lassen, aber sie munge es all „oberen“ Rahmen zu entfernen, wird die tatsächliche Ausnahme keinen Sinn in der Rückverfolgungs seit der letzten Zeile machen würde nicht selbst der Anhebung der Ausnahme der Lage sein.
  2. Um die letzten paar Frames Streifen, können Sie verlangen, dass Ihre Tracebacks verkürzt werden ... Dinge wie traceback.print_exception () nehmen eine „Grenze“ Parameter, die Sie nutzen könnten, die letzten Einträge überspringen.

Wie gesagt, sollte es durchaus möglich sein, die Tracebacks munge, wenn Sie wirklich brauchen, um ... aber wo würden Sie es tun? Wenn in einigen Wrapper-Code auf der obersten Ebene, dann könnte man einfach die Zurückverfolgungs greifen, nehmen Sie ein Stück, um die Teile zu entfernen Sie nicht wollen, und dann Funktionen im „Traceback“ Modul Format / Druck nach Wunsch.

Andere Tipps

Sie können die Spitze des Rückverfolgungs entfernen leicht mit durch mit dem tb_next Elemente der Zurückverfolgungs Anhebung:

except:
    ei = sys.exc_info()
    raise ei[0], ei[1], ei[2].tb_next

tb_next ist ein read_only Attribut, so weiß ich nicht, von einer Art und Weise Dinge aus dem Boden zu entfernen. Sie könnten mit den Eigenschaften Mechanismus zum Einschrauben der Lage sein, den Zugang zu dem Grundstück zu erlauben, aber ich weiß nicht, wie das zu tun.

Werfen Sie einen Blick an, was jinja2 tut sich hier:

https://github.com/mitsuhiko/jinja2/blob /5b498453b5898257b2287f14ef6c363799f1405a/jinja2/debug.py

Es ist hässlich, aber es scheint zu tun, was Sie brauchen getan. Ich werde das Beispiel hier nicht copy-paste, weil es lang ist.

Das könnte Sie auch interessieren: PEP-3134 , die ausgebildet ist, in python 3 und ermöglicht es Ihnen, eine Ausnahme / Rückverfolgung auf einer vorgeschalteten Ausnahme, tack.

Das ist nicht ganz dasselbe wie das Zurückverfolgungs ändern, aber es wäre wahrscheinlich der ideale Weg, um die „Kurzversion“ zu Bibliotheksbenutzer zu vermitteln, während immer noch die „lange Version“ zur Verfügung zu haben.

Dieser Code könnte für Sie von Interesse sein.

Es dauert eine Rückverfolgung und entfernt die erste Datei, die sollte nicht gezeigt. Dann simuliert es das Python-Verhalten:

Traceback (most recent call last):

wird nur angezeigt, wenn die Zurückverfolgungs mehr als eine Datei enthalten. Das sieht genau, als ob mein Extrarahmen nicht da war.

Hier ist mein Code, vorausgesetzt, es ist ein String text:

try:
    exec(text)
except:
    # we want to format the exception as if no frame was on top.
    exp, val, tb = sys.exc_info()
    listing = traceback.format_exception(exp, val, tb)
    # remove the entry for the first frame
    del listing[1]
    files = [line for line in listing if line.startswith("  File")]
    if len(files) == 1:
        # only one file, remove the header.
        del listing[0]
    print("".join(listing), file=sys.stderr)
    sys.exit(1)
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top