¿Es posible acceder a ipython desde el código?

81

Para mis necesidades de depuración, pdbes bastante bueno. Sin embargo, sería mucho más genial (y útil) si pudiera entrar ipython. ¿Es esto posible?

Geo
fuente

Respuestas:

112

Hay un ipdbproyecto que integra iPython en el pdb estándar, por lo que puede hacer lo siguiente:

import ipdb; ipdb.set_trace()

Es instalable a través del habitual pip install ipdb.

ipdbes bastante corto, por lo que en lugar de easy_installing también puede crear un archivo en ipdb.pyalgún lugar de su ruta de Python y pegar lo siguiente en el archivo:

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)
Daniel Roseman
fuente
Funciona asombrosamente bien con Django. Bueno, excepto por el hecho de que no puedo ver el texto que estoy escribiendo, pero probablemente se pueda arreglar fácilmente (ya que ipdb solo tiene seis líneas).
Xiong Chiamiov
4
En realidad, el problema es que Django bifurca un subproceso separado para el servidor de ejecución, y cada vez que realiza una edición de código, reaparece el subproceso. Esto normalmente funciona bien, pero si estás sentado en pdb cuando se mata el hilo, la terminal se vuelve loca. Puede solucionar esto saliendo de runserver, ejecutando 'stty sane' y luego iniciando runserver nuevamente.
Jeremy Dunck
1
@ Daniel-roseman Hola, me sale ModuleNotFoundError: No module named 'IPython.Debugger', ModuleNotFoundError: No module named 'IPython.Shell'yImportError: cannot import name 'ipapi'
SebMa
1
@memoselyk Hola, me sale ModuleNotFoundError: No module named 'IPython.Debugger', ModuleNotFoundError: No module named 'IPython.Shell'yImportError: cannot import name 'ipapi'
SebMa
Hay una forma de hacer que la breakpoint()función entre en ipdb.
gerrit
53

En IPython 0.11, puede incrustar IPython directamente en su código de esta manera

Su programa podría verse así

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

Esto es lo que sucede cuando lo ejecuta (elegí arbitrariamente ejecutarlo dentro de una sesión ipython existente. Anidar sesiones ipython como esta en mi experiencia puede hacer que se bloquee).

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
Alex Gaudio
fuente
Esta caída en una sesión de IPython es muy buena. Muchas gracias!
joon
1
Lo coloqué tontamente dentro de un bucle (casi infinito). ¿Cómo podré salir?
gerrit
2
@gerrit, presione Ctrl + d si todavía está allí.
confused00
2
@ confusion00 Eso habría sido tremendamente infinito, 6 meses después ;-)
gerrit
1
@gerrit, si está atascado en un bucle de inserción : def f() : pass ; IPython.embed = fpara que la embed()llamada sea un error, entonces Ctrl + D
MatrixManAtYrService
12

Si está usando una versión más moderna de IPython (> 0.10.2) puede usar algo como

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

Pero probablemente sea mejor usar ipdb

Chrisdev
fuente
11

El equivalente de

import pdb; pdb.set_trace()

con IPython es algo como:

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

Es un poco detallado, pero es bueno saberlo si no tiene ipdb instalado. La make_sessionllamada es necesaria una vez para configurar el esquema de color, etc., y las set_tracellamadas se pueden realizar en cualquier lugar donde necesite interrumpir.

ars
fuente
8

Normalmente, cuando uso ipython, enciendo la depuración automática con el comando "pdb" dentro de él.

Luego ejecuto mi script con el comando "ejecutar myscript.py" en el directorio donde se encuentra mi script.

Si obtengo una excepción, ipython detiene el programa dentro del depurador. Consulte el comando de ayuda para los comandos mágicos de ipython (% magic)

Jay Atkinson
fuente
entonces no hay forma de escribir algo como ipython.set_trace ()? :)
Geo
8

Me gusta simplemente pegar esta línea en mis scripts donde quiero establecer un punto de interrupción:

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

La versión más nueva podría usar:

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

Parece que los módulos se han barajado un poco recientemente. En IPython 0.13.1 lo siguiente funciona para mí

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

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

Aunque, por desgracia, todo es bastante inútil en qtconsole .

beardc
fuente
5

Las versiones más recientes de IPython proporcionan un mecanismo sencillo para incrustar y anidar sesiones de IPython en cualquier programa de Python. Puede seguir la siguiente receta para incrustar sesiones de 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)

Luego utilícelo ipshell()siempre que desee colocarlo en un shell de IPython. Esto le permitirá incrustar (e incluso anidar) intérpretes de IPython en su código.

Amelio Vázquez-Reina
fuente
3

De los documentos de IPython :

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

lanzará un shell de IPython mediante programación. Obviamente, los valores en el namespacedict son solo valores ficticios; podría tener más sentido usarlos locals()en la práctica.

Tenga en cuenta que tiene que codificar esto en; no va a funcionar como lo pdbhace. Si eso es lo que quiere, la respuesta de DoxaLogos probablemente se parezca más a lo que está buscando.

David Z
fuente
3

La forma más rápida y sencilla:

from IPython.Debugger import Tracer
debug = Tracer()

Entonces solo escribe

debug()

donde quiera comenzar a depurar su programa.

Viktiglemma
fuente
1
ImportError: No module named 'IPython.Debugger'en Python 3.4 / IPython 3
ostrokach
2

Tuve que buscar en Google esto un par de veces en los últimos días, así que agregué una respuesta ... a veces es bueno poder ejecutar un script normalmente y solo ingresar a ipython / ipdb en los errores, sin tener que poner ipdb.set_trace()puntos de interrupción en el código

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

(primero pip install ipythony pip install ipdbpor supuesto)

Anentrópico
fuente
1
¡Gracias! Un poco más simple:ipython --pdb -- ./path/to/my/script --with-args here
alisianoi
0

Esto es bastante simple:

ipython some_script.py --pdb

Necesita la instalación de iPython, generalmente esto funciona: pip install ipython

Yo uso ipython3 en lugar de ipython, así que sé que es una versión reciente de Python.

Esto es fácil de recordar porque solo usa iPython en lugar de python y agrega --pdb al final.

Luke Stanley
fuente