Comment exécuter des instructions multilignes dans le propre débogueur de Python (PDB)

157

Je lance donc un script Python dans lequel j'appelle le débogueur de Python, PDB en écrivant:

import ipdb; ipdb.set_trace()

(La version iPython de PDB, bien que pour le sujet je ne pense pas que cela fasse une différence; je l'utilise uniquement pour la sortie colorée).

Maintenant, quand j'arrive au débogueur, je veux exécuter une instruction multiligne telle qu'une clause if ou une boucle for mais dès que je tape

if condition:

et appuyez sur la touche retour, j'obtiens le message d'erreur *** SyntaxError: invalid syntax (<stdin>, line 1)

Comment peut-on exécuter des instructions multilignes dans PDB? Si ce n'est pas possible, existe-t-il un moyen de contourner ce problème pour continuer à exécuter une clause if ou une boucle for?

Mike
la source

Réponses:

265

Vous pouvez le faire dans pdb pour lancer une session Python interactive temporaire avec toutes les variables locales disponibles:

(pdb) !import code; code.interact(local=vars())
Python 2.6.5 (r265:79063, Apr 16 2010, 13:57:41) 
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> 

Lorsque vous avez terminé, utilisez Ctrl-D pour revenir à l'invite pdb normale.

N'appuyez pas simplement sur Ctrl-C, cela mettra fin à toute la session pdb.

Marius Gedminas
la source
46
Il semble que la même chose puisse être obtenue en utilisant la interactcommande pdb ( comme je l'ai appris de ce message de suivi de bogues ).
gerrit
3
Pourquoi !la importdéclaration est-elle nécessaire ?
Indradhanush Gupta
19
Ce n'est probablement pas nécessaire, mais j'ai l'habitude de préfixer toutes les instructions Python dans pdb avec !, pour éviter les accidents. Par exemple, c = 42dans pdb continuerait l' exécution au lieu de l'assigner à une variable c.
Marius Gedminas
8
@MariusGedminas la chose la plus frustrante avec PDB! Ce serait bien si leurs commandes devaient être préfixées ...
Ian Clark
Remarque: Ctrl-D semble également être la bonne façon de quitter interact, mais cela ne fonctionne pas bien avec Spyder pour moi.
Josiah Yoder
70

En python3 ipdb(et pdb) ont une commande appelée interact . Il peut être utilisé pour:

Démarrez un interpréteur interactif (à l'aide du module de code ) dont l'espace de noms global contient tous les noms (globaux et locaux) trouvés dans la portée actuelle.

Pour l'utiliser, entrez simplement interactà l'invite pdb. Entre autres choses, il est utile pour appliquer du code s'étendant sur plusieurs lignes, et aussi pour éviter le déclenchement accidentel d'autres commandes pdb.

vaer-k
la source
2
Cela me donne "NameError: le nom 'interagir' n'est pas défini" en faisant cela.
Jason
1
@jason version 3.2 ou supérieure
vaer-k
2
Cela explique. J'étais en python 2.7.
Jason
Attention, cela a effectivement jeté une erreur qui pourrait interagir n'est pas définie et a quitté le processus
Camron_Godbout
1
Je pense que suggérer d'éviter interactest une suggestion trop forte. 90%, c'est tout ce dont j'ai besoin, et c'est beaucoup plus facile à taper quefrom IPython import embed; embed()
vaer-k
43

Ma recommandation est d'utiliser l'intégration IPython.

ipdb> from IPython import embed; embed()
fx-kirin
la source
2
Si vous avez une valeur d'erreur définie dans la compréhension de la liste, essayez d'utiliser depuis IPython import embed; embed(user_ns=locals()).
fx-kirin
1
cela fonctionne beaucoup mieux pour moi que la réponse acceptée. Par exemple - cela permet une édition correcte de multiligne - comme remonter quelques lignes et réparer quelque chose, pour que vous n'ayez pas à réécrire à nouveau votre expression multiligne entière ... Je passe les sections locales comme @ fx-kirin suggéré.
ZeDuS
33

Dans l'interpréteur ou le débogueur Python (2.7.1) (import pdb), vous pouvez exécuter une instruction multiligne avec la syntaxe suivante.

for i in range(5): print("Hello"); print("World"); print(i)

Remarque: lorsque je suis dans l'interpréteur, je dois appuyer deux fois sur retour avant que le code ne s'exécute. Dans le débogueur, cependant, je n'ai qu'à appuyer une fois sur retour.

Garrett Hyde
la source
5
Il ne permet pas d'exécuter quelque chose de plus profond qu'un niveau.
Antony Hatchkins
7

Il existe un cas particulier si vous souhaitez que quelques commandes soient exécutées lorsque vous atteignez un point d'arrêt. Ensuite, il y a la commande du débogueur commands. Il vous permet de saisir plusieurs lignes de commandes puis de terminer toute la séquence avec le endmot clé. Plus avec (pdb) help commands.

ThomasH
la source
2

Je ne sais pas si vous pouvez le faire, ce serait une fonctionnalité intéressante pour ipdb. Vous pouvez bien sûr utiliser les compréhensions de liste et exécuter des expressions multilignes simples comme:

if y == 3: print y; print y; print y;

Vous pouvez également écrire certaines fonctions à l'avance pour faire tout ce dont vous avez besoin et qui prend normalement plusieurs lignes.

Zeekay
la source