Comment modifier un objet de trace Python lors de la génération d'une exception?

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

  •  05-07-2019
  •  | 
  •  

Question

Je travaille sur une bibliothèque Python utilisée par des développeurs tiers pour écrire des extensions pour notre application principale.

J'aimerais savoir s'il est possible de modifier le suivi lors de la génération d'exceptions. Le dernier cadre de pile est donc l'appel de la fonction de bibliothèque dans le code du développeur, plutôt que la ligne de la bibliothèque qui a généré l'exception. Il y a aussi quelques images au bas de la pile contenant des références aux fonctions utilisées lors du premier chargement du code que j'aimerais idéalement supprimer aussi.

Merci d'avance pour vos conseils!

Était-ce utile?

La solution

Pourquoi ne pas changer le suivi? Les deux choses que vous demandez peuvent être réalisées plus facilement d’une manière différente.

  1. Si l'exception de la bibliothèque est interceptée dans le code du développeur et qu'une nouvelle exception est générée, le compte rendu d'origine sera bien sûr jeté. C’est ainsi que les exceptions sont généralement gérées ... si vous autorisez simplement la levée de l’exception originale mais que vous lui demandez de supprimer tous les paramètres "supérieur" trames, l’exception réelle n’aura pas de sens puisque la dernière ligne de la trace ne serait pas elle-même capable de lever l’exception.
  2. Pour supprimer les dernières images, vous pouvez demander que vos tracés en arrière soient raccourcis ... des éléments tels que traceback.print_exception () prennent une "limite". paramètre que vous pouvez utiliser pour ignorer les dernières entrées.

Cela dit, il devrait être tout à fait possible de remplacer les retraits si vous en avez vraiment besoin ... mais où le feriez-vous? Si vous utilisez du code d’emballage au plus haut niveau, vous pouvez simplement saisir l’arrière-plan, prendre une partie pour supprimer les parties non souhaitées, puis utiliser des fonctions dans la section "traceback". module pour formater / imprimer à votre guise.

Autres conseils

Vous pouvez facilement supprimer le haut de la trace en soulevant avec l'élément tb_next de la trace:

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

tb_next est un attribut read_only, donc je ne connais pas de moyen de supprimer des éléments du bas. Vous pourrez peut-être utiliser le mécanisme de propriétés pour autoriser l'accès à la propriété, mais je ne sais pas comment faire.

Regardez ce que jinja2 fait ici:

https://github/ /5b498453b5898257b2287f14ef6c363799f1405a/jinja2/debug.py

C'est moche, mais il semble faire ce que vous avez besoin de faire. Je ne copierai pas l'exemple ici parce que c'est long.

Vous pouvez également être intéressé par PEP-3134 , qui est implémenté en python 3 et vous permet d’ajouter une exception / traceback à une exception en amont.

Ce n'est pas tout à fait la même chose que de modifier le traçage, mais ce serait probablement le moyen idéal pour transmettre la "version courte". aux utilisateurs de la bibliothèque tout en conservant la " version longue " disponible.

Ce code pourrait vous intéresser.

Il prend une trace et supprime le premier fichier, qui ne devrait pas être affiché. Ensuite, il simule le comportement Python:

Traceback (most recent call last):

ne sera affiché que si la trace contient plus d'un fichier. Cela ressemble exactement à ce que mon cadre supplémentaire n'était pas là.

Ici mon code, en supposant qu'il y ait une chaîne texte :

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)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top