¿Cómo puedo depurar las expresiones e instrucciones escritas manualmente en pdb?

En pdb (o ipdb) podemos ejecutar sentencias y evaluar expresiones con ! o p comandos :

expresión p
Evalúa la expresión en el contexto actual e imprime su valor.

[!]statement

Ejecute la instrucción (una línea) en el contexto del marco de stack actual. El signo de exclamación se puede omitir a menos que la primera palabra de la statement se parezca a un comando del depurador. Para establecer una variable global, puede prefijar el comando de asignación con un comando global en la misma línea

Entonces, por ejemplo, puedo escribir p reddit.get_subreddits() mientras se realiza la depuración en ipdb y el código se ejecutará en el contexto actual y veré el valor de retorno.

¿Hay alguna manera de depurar la ejecución de tales expresiones “escritas manualmente”?

Básicamente, me gustaría hacer es s reddit.get_subreddits() , pero eso solo ejecuta el comando step e ignora la expresión.

EDITAR: Un ejemplo trivial.

Tome esta función simple:

 import random def get_value_for_weekday(weekday_index=None): values = [10, 20, 20, 10, 30, 30, 30] if not weekday_index: # If no weekday provided, return the average of all weekdays return sum(values) / 7 return averages[weekday_index] if __name__ == '__main__': while True: import ipdb; ipdb.set_trace() # enter ipbd for debug get_value_for_weekday(random.randint(0, 7)) 

Lo que está mal debido a que if not weekday_index (debe verificar que el día de la weekday_index is not None ).

Supongamos que me doy cuenta de que obtengo 10 mitad de las veces que esperaba. Así que agregué un import ipdb; ipdb.set_trace() import ipdb; ipdb.set_trace() antes de la llamada a la función para intentar depurar el código.

Así que estoy en la consola ipdb y de repente se me ocurre la idea de que tal vez el problema sea cuando paso 0 como día de la semana. Puedo probar mi hipótesis directamente en ipdb:

 ipdb> p get_value_for_weekday(0) 22 

Ok, entonces me doy cuenta de que hay algo mal cuando el número de weekday_index=0 .
Lo que me gustaría hacer ahora es depurar paso a paso la llamada a get_value_for_weekday(0) , para que pueda ver que entro en el bloque if.

Obviamente, podría salir de ipdb, detener el script, cambiar el código para pasar siempre 0, relanzar el script y cuando ingrese ipdb, depurar la llamada con el comando ipdb step ( s ).
Pero, ¿no sería más fácil si pudiera hacer s get_value_for_weekday(0) la misma manera que pude hacer p get_value_for_weekday(0) ?

¿Hay alguna manera de hacer algo como esto?

Creo que está buscando el comando (d)ebug que, por alguna razón, no se especifica en los comandos del depurador . Solo para futuras referencias, pdb tiene un buen conjunto de comandos especificados (que puede ver escribiendo la help en el indicador interactivo). En el comando de debug :

 (Pdb) help debug debug code Enter a recursive debugger that steps through the code argument (which is an arbitrary expression or statement to be executed in the current environment). 

Lo que parece hacer lo que buscas. Usando su script de ejemplo desde el terminal:

 python -m pdb pdbscript.py 

Después de emitir dos n comandos para que la función se analice (creo que así es como funciona pdb ). Puede emitir un debug get_value_for_weekday(0) para debug get_value_for_weekday(0) recursivamente en la función:

 (Pdb) debug get_value_for_weekday(0) ENTERING RECURSIVE DEBUGGER > (1)() ((Pdb)) s --Call-- > /home/jim/Desktop/pdbscript.py(3)get_value_for_weekday() -> def get_value_for_weekday(weekday_index=None): ((Pdb)) n > /home/jim/Desktop/pdbscript.py(4)get_value_for_weekday() -> values = [10, 20, 20, 10, 30, 30, 30] ((Pdb)) n > /home/jim/Desktop/pdbscript.py(5)get_value_for_weekday() -> if not weekday_index: ((Pdb)) p weekday_index 0 ((Pdb)) n > /home/jim/Desktop/pdbscript.py(7)get_value_for_weekday() -> return sum(values) / 7 

Tenga en cuenta, me siento muy esquemático acerca de esta forma de meta-depuración, pero parece ser lo que está buscando.

Con respecto a su ejemplo, no necesita salir de pdb y cambiar el código. Puede ingresar a la función (con ‘s’) y establecer en día semana_index = 0.

Una solución a su problema original es usar el comando de salto del depurador de la siguiente manera:

  1. salta antes de la llamada a la función usando ‘j # line-number’
  2. paso en la función con ‘s’
  3. establecer los parámetros de entrada y continuar la depuración.

Esto funcionó cuando lo probé, pero el depurador se quejó cuando intenté hacer el paso 3 antes del paso 2 por alguna razón.