"pdb" --- Python 偵錯器
***********************

**原始碼：**Lib/pdb.py

======================================================================

"pdb" 模組定義了一個 Python 程式的互動式原始碼偵錯器。它支援在原始碼列
層級 (source line level) 設定（條件式的）斷點 (breakpoint) 和單步執行
、檢視 stack frame（堆疊框）、列出原始碼、以及在任何 stack frame 情境
(context) 中為任意 Python 程式碼求值 (evaluation)。它還支援事後偵錯
(post-mortem debugging)，並可以在程式控制下呼叫。

偵錯器是可擴充的 —— 偵錯器實際被定義為 "Pdb" 類別。該類別目前沒有文件
，但可以很容易地透過閱讀原始碼來理解它。擴充套件介面使用了 "bdb" 和
"cmd" 模組。

也參考:

  "faulthandler" 模組
     用於在出現故障時、超時 (timeout) 後或於接收到使用者訊號時，顯式地
     轉儲 (dump) Python 回溯 (traceback)。

  "traceback" 模組
     用於提取、格式化和印出 Python 程式 stack trace（堆疊追蹤）的標準
     介面。

自一個執行中程式切入偵錯器的典型用法為插入：

   import pdb; pdb.set_trace()

或：

   breakpoint()

到你想切入偵錯器的位置，然後執行程式，就可以單步執行上述陳述式之後的程
式碼，並可以使用 "continue" 命令來離開偵錯器、繼續執行。

在 3.7 版的變更: 當使用預設值呼叫時，可以使用內建的 "breakpoint()" 來
取代 "import pdb; pdb.set_trace()"。

   def double(x):
      breakpoint()
      return x * 2
   val = 3
   print(f"{val} * 2 is {double(val)}")

偵錯器的提示字元是 "(Pdb)"，這表示你處於偵錯模式：

   > ...(2)double()
   -> breakpoint()
   (Pdb) p x
   3
   (Pdb) continue
   3 * 2 is 6

在 3.3 版的變更: 透過 "readline" 模組達成的 tab 補全可用於補全本模組的
命令和命令的引數，例如會提供當前的全域和區域名稱以作為 "p" 命令的引數
。

你還可以從命令列調用 "pdb" 來偵錯其他腳本。例如：

   python -m pdb myscript.py

當作為模組調用時，如果被偵錯的程序不正常地退出，pdb 將自動進入事後偵錯
。事後偵錯後（或程式正常退出後），pdb 將重新啟動程式。自動重新啟動會保
留 pdb 的狀態（例如斷點），並且在大多數情況下比在程式退出時退出偵錯器
更有用。

在 3.2 版的變更: 新增了 "-c" 選項來執行命令，就像能在 ".pdbrc" 檔案中
給定的那樣；請參閱偵錯器命令。

在 3.7 版的變更: 新增了 "-m" 選項以類似於 "python -m" 的方式來執行模組
。與腳本一樣，偵錯器將在模組的第一列之前暫停執行。

在偵錯器控制下執行陳述式的典型用法是：

   >>> import pdb
   >>> def f(x):
   ...     print(1 / x)
   >>> pdb.run("f(2)")
   > <string>(1)<module>()
   (Pdb) continue
   0.5
   >>>

檢查一個損壞程式的典型用法：

   >>> import pdb
   >>> def f(x):
   ...     print(1 / x)
   ...
   >>> f(0)
   Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
     File "<stdin>", line 2, in f
   ZeroDivisionError: division by zero
   >>> pdb.pm()
   > <stdin>(2)f()
   (Pdb) p x
   0
   (Pdb)

在 3.13 版的變更: **PEP 667** 的實作意味著透過 "pdb" 進行的名稱賦予
(name assignments) 會立即影響有效作用域，即使在*最佳化作用域*內運作也
是如此。

本模組定義了下列函式，每個函式進入偵錯器的方式略有不同：

pdb.run(statement, globals=None, locals=None)

   在偵錯器控制下執行 *statement*（以字串或程式碼物件形式給定）。偵錯
   提示字元會在執行任何程式碼前出現；你可以設定斷點並輸入 "continue"，
   或也可以使用 "step" 或 "next" 逐步執行陳述式（這些命令在下面都有說
   明）。可選引數 *globals* 和 *locals* 指定程式碼執行的環境；預設使用
   "__main__" 模組的字典。（請參閱內建函式 "exec()" 或 "eval()" 的說明
   。）

pdb.runeval(expression, globals=None, locals=None)

   在偵錯器控制下為 *expression* 求值（以字串或程式碼物件形式給定）。
   當 "runeval()" 回傳時，它回傳 *expression* 的值。除此之外，該函式與
   "run()" 類似。

pdb.runcall(function, *args, **kwds)

   使用給定的引數呼叫 *function*（只可以是函式或方法物件，不能是字串）
   。"runcall()" 回傳的是所呼叫函式的回傳值。偵錯器提示字元將在進入函
   式後立即出現。

pdb.set_trace(*, header=None, commands=None)

   Enter the debugger at the calling stack frame.  This is useful to
   hard-code a breakpoint at a given point in a program, even if the
   code is not otherwise being debugged (e.g. when an assertion
   fails).  If given, *header* is printed to the console just before
   debugging begins. The *commands* argument, if given, is a list of
   commands to execute when the debugger starts.

   在 3.7 版的變更: 僅限關鍵字引數 *header*。

   在 3.13 版的變更: "set_trace()" 將立即進入偵錯器，而不是在下一列要
   執行的程式碼中。

   在 3.14 版被加入: The *commands* argument.

pdb.post_mortem(traceback=None)

   進入所給定 *traceback* 物件的事後偵錯。如果沒有給定 *traceback*，預
   設使用當前正在處理的例外之一（使用預設情況時，必須要有正在處理的例
   外存在）。

pdb.pm()

   進入在 "sys.last_exc" 中發現的例外的事後偵錯。

"run*" 函式和 "set_trace()" 都是別名，用於實例化 (instantiate) "Pdb"
類別並呼叫同名方法。如果要使用更多功能，則必須自己執行以下操作：

class pdb.Pdb(completekey='tab', stdin=None, stdout=None, skip=None, nosigint=False, readrc=True, mode=None)

   "Pdb" 是偵錯器類別。

   *completekey*、*stdin* 與 *stdout* 引數會被傳到底層的 "cmd.Cmd" 類
   別；請於該文件閱讀相關敘述。

   如果給定 *skip* 引數，則它必須是一個給出 glob 樣式之模組名稱的疊代
   器。如果遇到匹配這些樣式的模組，偵錯器將不會進入來自該模組的 frame
   。 [1]

   預設情況下，當你發出 "continue" 命令時，Pdb 會為 SIGINT 訊號（即使
   用者在控制台上按下 "Ctrl-C" 時會發送的訊號）設定一個處理程式
   (handler)，這允許你透過按下 "Ctrl-C" 再次切入偵錯器。如果你希望 Pdb
   不影響到 SIGINT 處理程式，請將 *nosigint* 設定為 true。

   *readrc* 引數預設為 true，它控制 Pdb 是否從檔案系統載入 .pdbrc 檔案
   。

   The *mode* argument specifies how the debugger was invoked. It
   impacts the workings of some debugger commands. Valid values are
   "'inline'" (used by the breakpoint() builtin), "'cli'" (used by the
   command line invocation) or "None" (for backwards compatible
   behaviour, as before the *mode* argument was added).

   啟用追蹤 (tracing) 且帶有 *skip* 引數的呼叫示範：

      import pdb; pdb.Pdb(skip=['django.*']).set_trace()

   不帶引數地引發一個稽核事件 (auditing event) "pdb.Pdb"。

   在 3.1 版的變更: 新增了 *skip* 參數。

   在 3.2 版的變更: 新增了 *nosigint* 參數。以前 SIGINT 處理程式從未被
   Pdb 設定過。

   在 3.6 版的變更: *readrc* 引數。

   在 3.14 版被加入: Added the *mode* argument.

   run(statement, globals=None, locals=None)
   runeval(expression, globals=None, locals=None)
   runcall(function, *args, **kwds)
   set_trace()

      請見上面關於這些函式的文件說明。


偵錯器命令
==========

下方列出的是偵錯器能認得的命令。如下所示，大多數命令可以縮寫為一個或兩
個字母。如 "h(elp)" 表示可以輸入 "h" 或 "help" 來輸入幫助命令（但不能
輸入 "he" 或 "hel"，也不能是 "H" 或 "Help" 或 "HELP"）。命令的引數必須
用空格（空格符 (spaces) 或製表符 (tabs)）分隔。在命令語法中，可選引數
被括在方括號 ("[]") 中；使用時請勿輸入方括號。命令語法中的選擇項由豎線
("|") 分隔。

輸入一個空白列 (blank line) 將重複上次輸入的命令。例外：如果上一個命令
是 "list" 命令，則會列出接下來的 11 列。

偵錯器無法識別的命令將被認為是 Python 陳述式，並以正在偵錯的程式之情境
來執行。Python 陳述式也可以用驚嘆號 ("!") 作為前綴，這是檢視正在偵錯之
程式的強大方法，甚至可以修改變數或呼叫函式。當此類陳述式發生例外，將印
出例外名稱，但偵錯器的狀態不會改變。

在 3.13 版的變更: 現在可以正確辨識並執行前綴為 pdb 命令的運算式/陳述式
。

偵錯器有支援設定別名。別名可以有參數，使得偵錯器對被檢查的情境有一定程
度的適應性。

在一列中可以輸入多個以 ";;" 分隔的命令。（不能使用單個 ";"，因為它用於
分隔傳遞給 Python 剖析器一列中的多個命令。）切分命令沒運用什麼高深的方
式；輸入總是在第一處 ";;" 被切分開，即使它位於引號內的字串之中。對於具
有雙分號字串的一個變通解法，是使用隱式字串連接 "';'';'" 或 "";"";""。

要設定臨時全域變數，請使用*便利變數 (convenience variable)*。*便利變數
*是名稱以 "$" 開頭的變數。例如 "$foo = 1" 會設定一個全域變數 "$foo"，
你可以在偵錯器會話 (debugger session) 中使用它。當程式恢復執行時，*便
利變數*將被清除，因此與使用 "foo = 1" 等普通變數相比，它不太會去干擾你
的程式。

共有三個預先設定的*便利變數*：

* "$_frame"：當前正在偵錯的 frame

* "$_retval"：frame 回傳時的回傳值

* "$_exception"：frame 引發例外時的例外

在 3.12 版被加入: 新增了*便利變數*功能。

如果 ".pdbrc" 檔案存在於使用者的家目錄或當前目錄中，則會使用 "'utf-8'"
編碼讀取並執行該檔案，就像在偵錯器提示字元下鍵入該檔案一樣，除了空列和
以 "#" 開頭的列會被忽略之外。這對於別名設定特別有用。如果兩個檔案都存
在，則先讀取家目錄中的檔案，且定義於其中的別名可以被本地檔案覆蓋。

在 3.2 版的變更: ".pdbrc" 現在可以包含繼續偵錯的命令，如 "continue" 或
"next"。以前檔案中的這些命令是無效的。

在 3.11 版的變更: ".pdbrc" 現在使用 "'utf-8'" 編碼讀取。以前它是使用系
統區域設定編碼讀取的。

h(elp) [command]

   如不帶引數，印出可用的命令列表。引數為 *command* 時，印出有關該命令
   的幫助訊息，"help pdb" 會顯示完整文件（即 "pdb" 模組的說明字串
   (docstring)）。由於 *command* 引數必須是一個識別字 (identifier)，若
   要獲取 "!" 命令的幫助訊息則必須輸入 "help exec"。

w(here) [count]

   Print a stack trace, with the most recent frame at the bottom.  if
   *count* is 0, print the current frame entry. If *count* is
   negative, print the least recent - *count* frames. If *count* is
   positive, print the most recent *count* frames.  An arrow (">")
   indicates the current frame, which determines the context of most
   commands.

   在 3.14 版的變更: *count* argument is added.

d(own) [count]

   在 stack trace 中，將當前 frame 向下移動 *count* 級（預設為 1 級，
   移往較新的 frame）。

u(p) [count]

   在 stack trace 中，將當前 frame 向上移動 *count* 級（預設為 1 級，
   移向較舊的 frame）。

b(reak) [([filename:]lineno | function) [, condition]]

   With a *lineno* argument, set a break at line *lineno* in the
   current file. The line number may be prefixed with a *filename* and
   a colon, to specify a breakpoint in another file (possibly one that
   hasn't been loaded yet).  The file is searched on "sys.path".
   Acceptable forms of *filename* are "/abspath/to/file.py",
   "relpath/file.py", "module" and "package.module".

   如帶有 *function* 引數，在該函式內的第一個可執行陳述式處設定中斷。
   *function* 可以是任何其求值結果為目前命名空間中函式的運算式。

   如果第二個引數存在，它是一個運算式，在斷點生效前其必須求值為 true

   如果不帶引數執行會列出所有斷點資訊，包括每個斷點、命中該斷點的次數
   、當前的忽略次數以及關聯的條件（如存在）。

   每個斷點都有賦予一個編號，所有其他斷點命令都參照該編號。

tbreak [([filename:]lineno | function) [, condition]]

   臨時斷點，在第一次遇見時會自動被刪除。它的引數與 "break" 相同。

cl(ear) [filename:lineno | bpnumber ...]

   如帶有 *filename:lineno* 引數，則清除此列上的所有斷點。如果引數是空
   格分隔的斷點編號列表，則清除這些斷點。如果不帶引數則清除所有斷點（
   但會先提示確認）。

disable bpnumber [bpnumber ...]

   停用斷點，斷點以空格分隔的斷點編號列表來給定。停用斷點表示它不會導
   致程式停止執行，但是與清除斷點不同，停用的斷點將保留在斷點列表中並
   且可以（重新）啟用。

enable bpnumber [bpnumber ...]

   Enable the breakpoints specified.

ignore bpnumber [count]

   Set the ignore count for the given breakpoint number.  If *count*
   is omitted, the ignore count is set to 0.  A breakpoint becomes
   active when the ignore count is zero.  When non-zero, the *count*
   is decremented each time the breakpoint is reached and the
   breakpoint is not disabled and any associated condition evaluates
   to true.

condition bpnumber [condition]

   Set a new *condition* for the breakpoint, an expression which must
   evaluate to true before the breakpoint is honored.  If *condition*
   is absent, any existing condition is removed; i.e., the breakpoint
   is made unconditional.

commands [bpnumber]

   Specify a list of commands for breakpoint number *bpnumber*.  The
   commands themselves appear on the following lines.  Type a line
   containing just "end" to terminate the commands. An example:

      (Pdb) commands 1
      (com) p some_variable
      (com) end
      (Pdb)

   To remove all commands from a breakpoint, type "commands" and
   follow it immediately with "end"; that is, give no commands.

   With no *bpnumber* argument, "commands" refers to the last
   breakpoint set.

   You can use breakpoint commands to start your program up again.
   Simply use the "continue" command, or "step", or any other command
   that resumes execution.

   Specifying any command resuming execution (currently "continue",
   "step", "next", "return", "until", "jump", "quit" and their
   abbreviations) terminates the command list (as if that command was
   immediately followed by end). This is because any time you resume
   execution (even with a simple next or step), you may encounter
   another breakpoint—which could have its own command list, leading
   to ambiguities about which list to execute.

   If the list of commands contains the "silent" command, or a command
   that resumes execution, then the breakpoint message containing
   information about the frame is not displayed.

   在 3.14 版的變更: Frame information will not be displayed if a
   command that resumes execution is present in the command list.

s(tep)

   Execute the current line, stop at the first possible occasion
   (either in a function that is called or on the next line in the
   current function).

n(ext)

   Continue execution until the next line in the current function is
   reached or it returns.  (The difference between "next" and "step"
   is that "step" stops inside a called function, while "next"
   executes called functions at (nearly) full speed, only stopping at
   the next line in the current function.)

unt(il) [lineno]

   Without argument, continue execution until the line with a number
   greater than the current one is reached.

   With *lineno*, continue execution until a line with a number
   greater or equal to *lineno* is reached.  In both cases, also stop
   when the current frame returns.

   在 3.2 版的變更: Allow giving an explicit line number.

r(eturn)

   Continue execution until the current function returns.

c(ont(inue))

   Continue execution, only stop when a breakpoint is encountered.

j(ump) lineno

   Set the next line that will be executed.  Only available in the
   bottom-most frame.  This lets you jump back and execute code again,
   or jump forward to skip code that you don't want to run.

   It should be noted that not all jumps are allowed -- for instance
   it is not possible to jump into the middle of a "for" loop or out
   of a "finally" clause.

l(ist) [first[, last]]

   List source code for the current file.  Without arguments, list 11
   lines around the current line or continue the previous listing.
   With "." as argument, list 11 lines around the current line.  With
   one argument, list 11 lines around at that line.  With two
   arguments, list the given range; if the second argument is less
   than the first, it is interpreted as a count.

   The current line in the current frame is indicated by "->".  If an
   exception is being debugged, the line where the exception was
   originally raised or propagated is indicated by ">>", if it differs
   from the current line.

   在 3.2 版的變更: Added the ">>" marker.

ll | longlist

   List all source code for the current function or frame.
   Interesting lines are marked as for "list".

   在 3.2 版被加入.

a(rgs)

   Print the arguments of the current function and their current
   values.

p expression

   Evaluate *expression* in the current context and print its value.

   備註:

     "print()" can also be used, but is not a debugger command ---
     this executes the Python "print()" function.

pp expression

   Like the "p" command, except the value of *expression* is pretty-
   printed using the "pprint" module.

whatis expression

   Print the type of *expression*.

source expression

   Try to get source code of *expression* and display it.

   在 3.2 版被加入.

display [expression]

   Display the value of *expression* if it changed, each time
   execution stops in the current frame.

   Without *expression*, list all display expressions for the current
   frame.

   備註:

     Display evaluates *expression* and compares to the result of the
     previous evaluation of *expression*, so when the result is
     mutable, display may not be able to pick up the changes.

   範例：

      lst = []
      breakpoint()
      pass
      lst.append(1)
      print(lst)

   Display won't realize "lst" has been changed because the result of
   evaluation is modified in place by "lst.append(1)" before being
   compared:

      > example.py(3)<module>()
      -> pass
      (Pdb) display lst
      display lst: []
      (Pdb) n
      > example.py(4)<module>()
      -> lst.append(1)
      (Pdb) n
      > example.py(5)<module>()
      -> print(lst)
      (Pdb)

   You can do some tricks with copy mechanism to make it work:

      > example.py(3)<module>()
      -> pass
      (Pdb) display lst[:]
      display lst[:]: []
      (Pdb) n
      > example.py(4)<module>()
      -> lst.append(1)
      (Pdb) n
      > example.py(5)<module>()
      -> print(lst)
      display lst[:]: [1]  [old: []]
      (Pdb)

   在 3.2 版被加入.

undisplay [expression]

   Do not display *expression* anymore in the current frame.  Without
   *expression*, clear all display expressions for the current frame.

   在 3.2 版被加入.

interact

   Start an interactive interpreter (using the "code" module) in a new
   global namespace initialised from the local and global namespaces
   for the current scope. Use "exit()" or "quit()" to exit the
   interpreter and return to the debugger.

   備註:

     As "interact" creates a new dedicated namespace for code
     execution, assignments to variables will not affect the original
     namespaces. However, modifications to any referenced mutable
     objects will be reflected in the original namespaces as usual.

   在 3.2 版被加入.

   在 3.13 版的變更: "exit()" and "quit()" can be used to exit the
   "interact" command.

   在 3.13 版的變更: "interact" directs its output to the debugger's
   output channel rather than "sys.stderr".

alias [name [command]]

   Create an alias called *name* that executes *command*.  The
   *command* must *not* be enclosed in quotes.  Replaceable parameters
   can be indicated by "%1", "%2", ... and "%9", while "%*" is
   replaced by all the parameters. If *command* is omitted, the
   current alias for *name* is shown. If no arguments are given, all
   aliases are listed.

   Aliases may be nested and can contain anything that can be legally
   typed at the pdb prompt.  Note that internal pdb commands *can* be
   overridden by aliases.  Such a command is then hidden until the
   alias is removed.  Aliasing is recursively applied to the first
   word of the command line; all other words in the line are left
   alone.

   As an example, here are two useful aliases (especially when placed
   in the ".pdbrc" file):

      # Print instance variables (usage "pi classInst")
      alias pi for k in %1.__dict__.keys(): print(f"%1.{k} = {%1.__dict__[k]}")
      # Print instance variables in self
      alias ps pi self

unalias name

   Delete the specified alias *name*.

! statement

   Execute the (one-line) *statement* in the context of the current
   stack frame. The exclamation point can be omitted unless the first
   word of the statement resembles a debugger command, e.g.:

      (Pdb) ! n=42
      (Pdb)

   To set a global variable, you can prefix the assignment command
   with a "global" statement on the same line, e.g.:

      (Pdb) global list_options; list_options = ['-l']
      (Pdb)

run [args ...]
restart [args ...]

   Restart the debugged Python program.  If *args* is supplied, it is
   split with "shlex" and the result is used as the new "sys.argv".
   History, breakpoints, actions and debugger options are preserved.
   "restart" is an alias for "run".

   在 3.14 版的變更: "run" and "restart" commands are disabled when
   the debugger is invoked in "'inline'" mode.

q(uit)

   Quit from the debugger.  The program being executed is aborted.

debug code

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

retval

   Print the return value for the last return of the current function.

exceptions [excnumber]

   List or jump between chained exceptions.

   When using "pdb.pm()"  or "Pdb.post_mortem(...)" with a chained
   exception instead of a traceback, it allows the user to move
   between the chained exceptions using "exceptions" command to list
   exceptions, and "exception <number>" to switch to that exception.

   範例：

      def out():
          try:
              middle()
          except Exception as e:
              raise ValueError("reraise middle() error") from e

      def middle():
          try:
              return inner(0)
          except Exception as e:
              raise ValueError("Middle fail")

      def inner(x):
          1 / x

       out()

   calling "pdb.pm()" will allow to move between exceptions:

      > example.py(5)out()
      -> raise ValueError("reraise middle() error") from e

      (Pdb) exceptions
        0 ZeroDivisionError('division by zero')
        1 ValueError('Middle fail')
      > 2 ValueError('reraise middle() error')

      (Pdb) exceptions 0
      > example.py(16)inner()
      -> 1 / x

      (Pdb) up
      > example.py(10)middle()
      -> return inner(0)

   在 3.13 版被加入.

-[ 註解 ]-

[1] Whether a frame is considered to originate in a certain module is
    determined by the "__name__" in the frame globals.
