debug ipython flask pytest

Salut les pythonistas!

Je suis un grand adepte de ipython, pour la mise au point de code. J’apprécie aussi les avatars plus récents de l’équipe, notebooks & co, mais l’objectif n’est pas le même.
Je suis aussi un grand adepte de pytest.
Là je suis sur un projet avec du Flask, du Rest, du pytest. Et je n’arrive absolument pas à faire cohabiter ipython avec Flask et pytest.

Soyons plus précis: mon scénario typique d’utiisation de ipython, c’est la “reproduction” de bogues, impossibles à déboguer en prod.

  • j’ouvre un ipython.
  • je reproduis les conditions conduisant au bug.
  • commande pdb.
  • invocation de mon script, ou de mon programme.
  • quand l’exception se (re) produit, je me retrouve sous pdb, au niveau du code ayant levé l’exception.
  • je peux naviguer dans la trame, up and down, voir les valeurs des variables, faire des appels: le plus souvent quelques minutes suffisent à comprendre le problème, et quelques secondes à le réparer.

Sous Flask et pytest, les exceptions sont systèmatiquement catchées, loggées, même si j’arrive à invoquer depuis ipython, pas moyen de “prendre pied” dans la vue ayant causé l’exception.
Il y a bien une extension “pytest-interactive”, qui semblait fournir la solution, mais un gros bug d’incompatibilité entre packages vient gacher la fête.

J’ai pensé que le problème était peut être que flask était invoqué dans un autre process, mais j’ai monté une manip pour détecter ça, et ça n’est pas le cas.

Si quelqu’un avait une idée, je suis prêt à lui cirer les godasses (en remote, ça brille plus!) pendant un mois!

Salut, je ne vais pas te proposer une solution pour résoudre ton problème avec pytest.

Mais je suis surpris de la démarche. Perso, j’utilise pytest comme tests automatiques.

Pdb & co. c’est plus en mode “dev” avec le serveur flask qui tourne.

Autre solution, ajouter des asserts dans tes tests pour vérifier les valeurs. Ou du log de debug que tu vas récupérer si ton test échoue.

Les assert dans les tests, c’est la base de pytest. Mais quand quelque chose va de traviolle, une exception pète, et ton assert te dit que tu as reçu un 500 au lieu d’un 200. Sympa, pytest t’imprime aussi le traceback. C’est souvent suffisant, mais quand c’est un peu tricky, voyager dans le traceback live est précieux. Bon, c’est possible aussi en mode debug, depuis un navigateur, mais c’est du coup tout un autre contexte à mettre en place, tu n’as pas les mêmes fixtures, t’as même pas de fixtures du tout…
Faire du log? Oui, mais ça alourdit le code, et ça n’est pas live.

La solution vers laquelle je m’oriente, c’est de bien séparer dans le code:

  • les views, qui vont être testées dans le cadre flask/pytest.
  • l’algorithmique plus pointue, testée unitairement hors du cadre flask.

Je soupçonne que tu as un catchallmidleware côté Flask qui t’embête. En local je le désactive pour pouvoir profiter de tout l’écosystème ipython par contre pour déboguer live en prod je poserais plutôt manuellement des breackpoints… Ou alors effectivement introduire le breackpoints au niveau de la page d’error handler/500 pour pouvoir remonter au coupable.

Oui! oui!, Ca ressemble bien à ca! Je vais creuser en ce sens, et vous faire un retour.
“ntroduire le breackpoints au niveau de la page d’error handler/500” Une autre bonne idée… Sauf que en l’état je sais pas ou c’est. Mais j’ai le traceback, je peux poser provisoirement un breakpoint avant le point qui fait péter l’exception.

En effet si tu arrive a enlever un “catchallmiddleware” tu peux peut être lancer ton serveur avec le module pdb (python -m pdb -m flask run ?) pour profiter du post-mortem?

catchallmiddleware, quand je google, c’est plutot un terme ruby, et j’ai pas trouvé l’équivalent dans flask. Je continue à creuser, mais j’ai d’autres priorités…

En cherchant on trouve des discussions qui parlent de pytest --pdb et de flask si ça peut te donner des pistes : pytest --pdb is no longer working with Flask_testing · Issue #1932 · pytest-dev/pytest · GitHub

N’utilisant pas du tout flask je ne peux pas t’en dire beaucoup plus, @seluj78 peut être ?

Hello,

En effet j’utilise Flask, mais je ne suis jamais tombé sur ton cas. Personellement, j’utilise Pycharm qui a son deboggeur intégré qui gère tout pour moi et dont l’intégration Flask me permets de debugger correctement parmis les threads etc… As-tu essayé ?

J’ai des réticiences envers pycharm. Envers tous les IDE, à vrai dire. Je suis un incorrigible emacsien, pas la techno la plus sexy pour le débutant!
Pycharm, j’ai prévu de m’y mettre, mais comme “roue de secours”. Pour le debug multithread entre autres.

Je pense avoir résolu mon pb, je vais faire un post général (je veux dire: pas niché dans une réponse) dès que j’ai un peu digéré tout ça. Les solus: ipdb, breakpoint, pdb++ (aka pdbpp)
En fait, j’étais sous python 2 jusqu’en 2017, Quand j’ai basculé python3 je me suis lu toutes les whats-new de 3.0 à 3.7, mais j’ai raté des choses.
Merci à tous en tout cas, j’avais fait ce post comme une bouteille à la mer, vos réponses m’ont fait reprendre les recherches.

Sinon répondre dans ce thread avec la solution et cocher solution pour le faire apparaitre en tête de thread comm ceci : problème d'affichage widgets dans ipywidgets

@pierre.imbaud tu peux aussi faire une mini-demo de qq minutes de tes solutions à la prochaine

C’est vendu! Mais j’ai besoin d’un peu de temps pour récapituler

Très bonne idée! Mais du coup, plonger cet exposé dans une récap de la problématique de la mise au point python, et des bonnes … et moins bonnes solus (print, log): 15 à 25 mn.

Si tu veux 15/20mn prends 15/22mn :slight_smile: