web-dev-qa-db-fra.com

Est-il possible d'entrer dans ipython à partir de code?

Pour mes besoins de débogage, pdb est plutôt bon. Cependant, il serait beaucoup plus cool (et utile) si je pouvais entrer dans ipython. Cette chose est-elle possible?

77
Geo

Il existe un projet ipdb qui intègre iPython dans la pdb standard. Vous pouvez donc effectuer les opérations suivantes:

import ipdb; ipdb.set_trace()

Il est installable via le pip install ipdb habituel.

ipdb est assez court, donc au lieu de easy_installing, vous pouvez également créer un fichier ipdb.py quelque part sur votre chemin Python et coller ce qui suit dans le fichier:

import sys
from IPython.Debugger import Pdb
from IPython.Shell import IPShell
from IPython import ipapi

Shell = IPShell(argv=[''])

def set_trace():
    ip = ipapi.get()
    def_colors = ip.options.colors
    Pdb(def_colors).set_trace(sys._getframe().f_back)
108
Daniel Roseman

Dans IPython 0.11, vous pouvez intégrer IPython directement dans votre code comme ceci

Votre programme pourrait ressembler à ceci

In [5]: cat > tmpf.py
a = 1

from IPython import embed
embed() # drop into an IPython session.
        # Any variables you define or modify here
        # will not affect program execution

c = 2

^D

C'est ce qui se produit lorsque vous l'exécutez (j'ai choisi arbitrairement de l'exécuter au sein d'une session ipython existante. L'imbrication de sessions ipython comme celle-ci dans mon expérience peut entraîner son blocage).

In [6]:

In [6]: run tmpf.py
Python 2.7.2 (default, Aug 25 2011, 00:06:33)
Type "copyright", "credits" or "license" for more information.

IPython 0.11 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: who
a       embed

In [2]: a
Out[2]: 1

In [3]:
Do you really want to exit ([y]/n)? y


In [7]: who
a       c       embed
50
Alex Gaudio

Si vous utilisez une version plus moderne d’IPython (> 0.10.2), vous pouvez utiliser quelque chose comme:

from IPython.core.debugger import Pdb
Pdb().set_trace()

Mais il vaut probablement mieux utiliser simplement ipdb 

11
chrisdev

L'équivalent de 

import pdb; pdb.set_trace()

avec IPython est quelque chose comme:

from IPython.ipapi import make_session; make_session()
from IPython.Debugger import Pdb; Pdb().set_trace()

C'est un peu bavard, mais bon à savoir si vous n'avez pas installé ipdb. L’appel make_session est requis une fois pour configurer le jeu de couleurs, etc. Les appels set_trace peuvent être placés partout où vous avez besoin d’une pause.

11
ars

Normalement, lorsque j'utilise ipython, j'active le débogage automatique avec la commande "pdb" qu'il contient.

J'exécute ensuite mon script avec la commande "run myscript.py" dans le répertoire où se trouve mon script.

Si je reçois une exception, ipython arrête le programme dans le débogueur. Consultez la commande d'aide pour les commandes magiques ipython (% magic)

8
Jay Atkinson

J'aime simplement coller ce one-liner dans mes scripts où je veux définir un point d'arrêt:

__import__('IPython').Debugger.Pdb(color_scheme='Linux').set_trace()

La nouvelle version pourrait utiliser:

__import__('IPython').core.debugger.Pdb(color_scheme='Linux').set_trace()
8
xApple

On dirait que les modules ont été mélangés un peu récemment. Sur IPython 0.13.1 ce qui suit fonctionne pour moi

from IPython.core.debugger import Tracer; breakpoint = Tracer()

breakpoint() # <= wherever you want to set the breakpoint

Bien que, hélas, tout cela soit joli nul dans qtconsole .

6
beardc

Les versions plus récentes d'IPython fournissent un mécanisme simple pour incorporer et imbriquer des sessions IPython dans n'importe quel programme Python. Vous pouvez suivre la recette suivante pour intégrer des sessions IPython:

try:
    get_ipython
except NameError:
    banner=exit_msg=''
else:
    banner = '*** Nested interpreter ***'
    exit_msg = '*** Back in main IPython ***'

# First import the embed function
from IPython.frontend.terminal.embed import InteractiveShellEmbed
# Now create the IPython Shell instance. Put ipshell() anywhere in your code
# where you want it to open.
ipshell = InteractiveShellEmbed(banner1=banner, exit_msg=exit_msg)

Utilisez ensuite ipshell() chaque fois que vous souhaitez accéder à un shell IPython. Cela vous permettra d'incorporer (et même d'imbriquer) des interprètes IPython dans votre code.

5

À partir de la documentation IPython :

import IPython.ipapi
namespace = dict(
    kissa = 15,
    koira = 16)
IPython.ipapi.launch_new_instance(namespace)

lancera un shell IPython par programme. Évidemment, les valeurs dans namespace dict ne sont que des valeurs factices - il serait peut-être plus logique d’utiliser locals() dans la pratique.

Notez que vous devez coder cela en dur; ça ne marchera pas comme pdb. Si c'est ce que vous voulez, la réponse de DoxaLogos correspond probablement davantage à ce que vous recherchez.

3
David Z

Le moyen rapide et facile:

from IPython.Debugger import Tracer
debug = Tracer()

Ensuite, écrivez

debug()

où que vous vouliez commencer à déboguer votre programme.

3
Viktiglemma

Il fallait que je recherche quelques mots sur Google ces derniers jours, alors il est donc agréable de pouvoir exécuter un script normalement et de ne passer que par ipython/ipdb en cas d'erreur, sans avoir à insérer de points d'arrêt ipdb.set_trace() dans le code.

ipython --pdb -c "%run path/to/my/script.py --with-args here"

(premier pip install ipython et pip install ipdb bien sûr)

2
Anentropic

C'est assez simple:

ipython some_script.py --pdb

Il faut installer iPython, cela fonctionne généralement comme suit: pip install ipython

J'utilise ipython3 au lieu de ipython, donc je sais que c'est une version récente de Python.

Ceci est simple à retenir car vous utilisez simplement iPython au lieu de python et ajoutez -pdb à la fin.

0
Luke Stanley