Как автоматизировать команды pdb? - PullRequest
0 голосов
/ 02 июня 2018

Я вызываю pdb для некоторой функции func, т. Е.

def fun():
    a = 10
    c = fun2(a)
    d = 40
    return c+d
def fun2(a):
    xyz ='str'
    return a+10

Теперь я запускаю pdb, используя pdb.runcall(func,a,b). Теперь откроется консоль pdb для отладки, теперь предположим, что я нажимаю 2 раза s (шаг) и q до quit в консоли pdb, но проблема в том, что я не хочу делать это вручную, я хочу сделать какой-нибудь скрипт, который делает что-то вроде этого (автоматическая команда скажи pdb первые двеs тогда третье - это q), я спрашиваю, потому что есть много функций, которым нужно как минимум два раза c (продолжить) до полного исключения функции, чтобы она могла выдавать / возвращать некоторые допустимые выходные данные (например, скажем, генераторы)

Любая помощь будет для меня серьезной помощью.

1 Ответ

0 голосов
/ 02 июня 2018

Обновите после лучшего понимания вопроса:

В общем, я не думаю, что это идеальный способ тестирования кода;разработка кода для тестируемости (например, с использованием TDD) часто приводит к функциям, которые легче тестировать (например, с использованием ложных / фиктивных объектов, внедрения зависимостей и т. д.), и я рекомендую вам рассмотреть возможность рефакторинга кода, если это возможно.Другая проблема с этим подходом заключается в том, что тесты могут быть очень тесно связаны с кодом.Тем не менее, я предполагаю, что вы знаете, что делаете, и что вышеописанное не подходит по любой причине.

Создание сценариев pdb

Если вы хотите создавать сценарии pdb из кода,на самом деле это возможно путем создания собственного класса pdb.Pdb и передачи stdin и, на момент написания, аргумента stdout (я не уверен, что оба должны быть обязательны - я подал https://bugs.python.org/issue33749).

Пример (я только что добавил дополнительный входной аргумент в fun):

def fun(i):
    a = 10 + i
    c = fun2(a)
    d = 40
    return c+d
def fun2(a):
    xyz ='str'
    return a+10

import pdb
import io
output = io.StringIO()
# this contains the pdb commands we want to execute:
pdb_script = io.StringIO("p i;; i = 100;; n;; p a;; c;;")
mypdb = pdb.Pdb(stdin=pdb_script, stdout=output)

Обычный результат (без сценариев):

In [40]: pdb.runcall(fun, 1)
    ...:
> <ipython-input-1-28966c4f6e38>(2)fun()
-> a = 10 + i
(Pdb)
(Pdb) c
Out[40]: 61

Сценарий pdb:

In [44]: mypdb = pdb.Pdb(stdin=pdb_script, stdout=output)

In [45]: mypdb.runcall(fun, 1)
Out[45]: 160

In [50]: print(output.getvalue())
> <ipython-input-1-28966c4f6e38>(2)fun()
-> a = 10 + i
(Pdb) 1
> <ipython-input-1-28966c4f6e38>(3)fun()
-> c = fun2(a)
110

Может оказаться полезным использовать pdb_script.seek(0) для сброса сценария.

Оригинальный ответ - с использованием условных точек останова

Звучит так, как будто вы действительно хотите попасть только вотладчик, когда ваш код находится в определенном состоянии. Это можно сделать с помощью условных точек останова (см. pdb docs ). Например, допустим, вы хотите разбить fun2, если a > 10:

   ...:

In [2]: import pdb

In [3]: pdb.runcall(fun, 1)
> <ipython-input-1-28966c4f6e38>(2)fun()
-> a = 10 + i
(Pdb) break fun2, a > 10
Breakpoint 1 at <ipython-input-1-28966c4f6e38>:6
(Pdb) c
> <ipython-input-1-28966c4f6e38>(7)fun2()
-> xyz ='str'
(Pdb) c
Out[3]: 61

In [4]: pdb.runcall(fun, -1)
> <ipython-input-1-28966c4f6e38>(2)fun()
-> a = 10 + i
(Pdb) c
Out[4]: 59

Обратите внимание, что в первом случае вы нажалиReakpoint, во втором вы не сделали.

Оригинальный ответ - использование точек останова и выполнение команд при нажатии

Вы также можете попробовать установить точку останова и использовать команды средство.

...