Setting Breakpoints and Exception Hooks in Python

Ask questions Research chat →

https://machinelearningmastery.com/setting-breakpoints-and-exception-hooks-in-python/ · scraped

python

Attachments

Scraped Content

— 3874 words · 2026-02-14 03:12:01 UTC ·

Excerpt

Share Post Share There are different ways of debugging code in Python, one of which is to introduce breakpoints into the code at points where one would like to invoke a Python debugger. The statements used to enter a debugging session at different call sites depend on the version of the Python interpreter that one is working with, as we shall see in this tutorial.  In this tutorial, you will discover various ways of setting breakpoints in different versions of Python.  After completing this tutorial, you will know: How to invoke the pdb debugger in earlier versions of Python How to use the new, built-in breakpoint() function introduced in Python 3.7 How to write your own breakpoint() function to simplify the debugging process in earlier versions of Python How to use a post-mortem debugger Kick-start your project with my new book Python for Machine Learning, including step-by-step tutorials and the Python source code files for all examples.Let
Share Post Share There are different ways of debugging code in Python, one of which is to introduce breakpoints into the code at points where one would like to invoke a Python debugger. The statements used to enter a debugging session at different call sites depend on the version of the Python interpreter that one is working with, as we shall see in this tutorial.  In this tutorial, you will discover various ways of setting breakpoints in different versions of Python.  After completing this tutorial, you will know: How to invoke the pdb debugger in earlier versions of Python How to use the new, built-in breakpoint() function introduced in Python 3.7 How to write your own breakpoint() function to simplify the debugging process in earlier versions of Python How to use a post-mortem debugger Kick-start your project with my new book Python for Machine Learning, including step-by-step tutorials and the Python source code files for all examples.Let’s get started. Setting Breakpoints in Different Versions of Python Photo by Josh Withers, some rights reserved. Tutorial Overview This tutorial is divided into three parts; they are: Setting Breakpoints in Python Code Invoking the pdb Debugger in Earlier Versions of Python Using the breakpoint() Function in Python 3.7 Writing One’s Own breakpoint() Function for Earlier Versions of Python Limitations of the breakpoint() Function Setting Breakpoints in Python Code We have previously seen that one way of debugging a Python script is to run it in the command line with the Python debugger.  In order to do so, we would need to use the -m pdb command that loads the pdb module before executing the Python script. In the same command-line interface, we would then follow this by a specific debugger command of choice, such as n to move to the next line or s if we intend to step into a function.  This method could become cumbersome quickly as the length of the code increases. One way to address this problem and gain better control over where to break your code is to insert a breakpoint directly into the code.  Invoking the pdb Debugger in Earlier Versions of Python Invoking the pdb debugger prior to Python 3.7 would require you to import pdb and call pdb.set_trace() at the point in your code where you would like to enter an interactive debugging session.  If we reconsider, as an example, the code for implementing the general attention mechanism, we can break into the code as follows: from numpy import array from numpy import random from numpy import dot from scipy.special import softmax # importing the Python debugger module import pdb # encoder representations of four different words word_1 = array([1, 0, 0]) word_2 = array([0, 1, 0]) word_3 = array([1, 1, 0]) word_4 = array([0, 0, 1]) # stacking the word embeddings into a single array words = array([word_1, word_2, word_3, word_4]) # generating the weight matrices random.seed(42) W_Q = random.randint(3, size=(3, 3)) W_K = random.randint(3, size=(3, 3)) W_V = random.randint(3, size=(3, 3)) # generating the queries, keys and values Q = dot(words, W_Q) K = dot(words, W_K) V = dot(words, W_V) # inserting a breakpoint pdb.set_trace() # scoring the query vectors against all key vectors scores = dot(Q, K.transpose()) # computing the weights by a softmax operation weights = softmax(scores / K.shape[1] ** 0.5, axis=1) # computing the attention by a weighted sum of the value vectors attention = dot(weights, V) print(attention) 1234567891011121314151617181920212223242526272829303132333435363738394041 from numpy import arrayfrom numpy import randomfrom numpy import dotfrom scipy.special import softmax # importing the Python debugger moduleimport pdb # encoder representations of four different wordsword_1 = array([1, 0, 0])word_2 = array([0, 1, 0])word_3 = array([1, 1, 0])word_4 = array([0, 0, 1]) # stacking the word embeddings into a single arraywords = array([word_1, word_2, word_3, word_4]) # generating the weight matricesrandom.seed(42)W_Q = random.randint(3, size=(3, 3))W_K = random.randint(3, size=(3, 3))W_V = random.randint(3, size=(3, 3)) # generating the queries, keys and valuesQ = dot(words, W_Q)K = dot(words, W_K)V = dot(words, W_V) # inserting a breakpointpdb.set_trace() # scoring the query vectors against all key vectorsscores = dot(Q, K.transpose()) # computing the weights by a softmax operationweights = softmax(scores / K.shape[1] ** 0.5, axis=1) # computing the attention by a weighted sum of the value vectorsattention = dot(weights, V) print(attention) Executing the script now opens up the pdb debugger right before we compute the variable scores, and we can proceed to issue any debugger commands of choice, such as n to move to the next line or c to continue execution: /Users/mlm/main.py(33)<module>() -> scores = dot(Q, K.transpose()) (Pdb) n > /Users/mlm/main.py(36)<module>() -> weights = softmax(scores / K.shape[1] ** 0.5, axis=1) (Pdb) c [[0.98522025 1.74174051 0.75652026] [0.90965265 1.40965265 0.5 ] [0.99851226 1.75849334 0.75998108] [0.99560386 1.90407309 0.90846923]] /Users/mlm/main.py(33)<module>()-> scores = dot(Q, K.transpose())(Pdb) n> /Users/mlm/main.py(36)<module>()-> weights = softmax(scores / K.shape[1] ** 0.5, axis=1)(Pdb) c[[0.98522025 1.74174051 0.75652026] [0.90965265 1.40965265 0.5       ] [0.99851226 1.75849334 0.75998108] [0.99560386 1.90407309 0.90846923]] Although functional, this is not the most elegant and intuitive approach of inserting a breakpoint into your code. Python 3.7 implements a more straightforward way of doing so, as we shall see next. Using the breakpoint() Function in Python 3.7  Python 3.7 comes with a built-in breakpoint() function that enters the Python debugger at the call site (or the point in the code at which the breakpoint() statement is placed).  When called, the default implementation of the breakpoint() function will call sys.breakpointhook(), which in turn calls the pdb.set_trace() function. This is convenient because we will not need to import pdb and call pdb.set_trace() explicitly ourselves.  Let’s reconsider the code for implementing the general attention mechanism and now introduce a breakpoint via the breakpoint() statement: from numpy import array from numpy import random from scipy.special import softmax # encoder representations of four different words word_1 = array([1, 0, 0]) word_2 = array([0, 1, 0]) word_3 = array([1, 1, 0]) word_4 = array([0, 0, 1]) # stacking the word embeddings into a single array words = array([word_1, word_2, word_3, word_4]) # generating the weight matrices random.seed(42) W_Q = random.randint(3, size=(3, 3)) W_K = random.randint(3, size=(3, 3)) W_V = random.randint(3, size=(3, 3)) # generating the queries, keys and values Q = words @ W_Q K = words @ W_K V = words @ W_V # inserting a breakpoint breakpoint() # scoring the query vectors against all key vectors scores = Q @ K.transpose() # computing the weights by a softmax operation weights = softmax(scores / K.shape[1] ** 0.5, axis=1) # computing the attention by a weighted sum of the value vectors attention = weights @ V print(attention) 12345678910111213141516171819202122232425262728293031323334353637 from numpy import arrayfrom numpy import randomfrom scipy.special import softmax # encoder representations of four different wordsword_1 = array([1, 0, 0])word_2 = array([0, 1, 0])word_3 = array([1, 1, 0])word_4 = array([0, 0, 1]) # stacking the word embeddings into a single arraywords = array([word_1, word_2, word_3, word_4]) # generating the weight matricesrandom.seed(42)W_Q = random.randint(3, size=(3, 3))W_K = random.randint(3, size=(3, 3))W_V = random.randint(3, size=(3, 3)) # generating the queries, keys and valuesQ = words @ W_QK = words @ W_KV = words @ W_V # inserting a breakpointbreakpoint() # scoring the query vectors against all key vectorsscores = Q @ K.transpose() # computing the weights by a softmax operationweights = softmax(scores / K.shape[1] ** 0.5, axis=1) # computing the attention by a weighted sum of the value vectorsattention = weights @ V print(attention) One advantage of using the breakpoint() function is that, in calling the default implementation of sys.breakpointhook(), the value of a new environment variable, PYTHONBREAKPOINT, is consulted. This environment variable can take various values, based on which different operations can be performed.  For example, setting the value of PYTHONBREAKPOINT to 0 disables all breakpoints. Hence, your code could contain as many breakpoints as necessary, but these can be easily stopped from halting the execution of the code without having to remove them physically. If (for example) the name of the script containing the code is main.py, we would disable all breakpoints by calling it in the command line interface as follows: PYTHONBREAKPOINT=0 python main.py PYTHONBREAKPOINT=0 python main.py Otherwise, we can achieve the same outcome by setting the environment variable in the code itself: from numpy import array from numpy import random from scipy.special import softmax # setting the value of the PYTHONBREAKPOINT environment variable import os os.environ['PYTHONBREAKPOINT'] = '0' # encoder representations of four different words word_1 = array([1, 0, 0]) word_2 = array([0, 1, 0]) word_3 = array([1, 1, 0]) word_4 = array([0, 0, 1]) # stacking the word embeddings into a single array words = array([word_1, word_2, word_3, word_4]) # generating the weight matrices random.seed(42) W_Q = random.randint(3, size=(3, 3)) W_K = random.randint(3, size=(3, 3)) W_V = random.randint(3, size=(3, 3)) # generating the queries, keys and values Q = words @ W_Q K = words @ W_K V = words @ W_V # inserting a breakpoint breakpoint() # scoring the query vectors against all key vectors scores = Q @ K.transpose() # computing the weights by a softmax operation weights = softmax(scores / K.shape[1] ** 0.5, axis=1) # computing the attention by a weighted sum of the value vectors attention = weights @ V print(attention) 1234567891011121314151617181920212223242526272829303132333435363738394041 from numpy import arrayfrom numpy import randomfrom scipy.special import softmax # setting the value of the PYTHONBREAKPOINT environment variableimport osos.environ['PYTHONBREAKPOINT'] = '0' # encoder representations of four different wordsword_1 = array([1, 0, 0])word_2 = array([0, 1, 0])word_3 = array([1, 1, 0])word_4 = array([0, 0, 1]) # stacking the word embeddings into a single arraywords = array([word_1, word_2, word_3, word_4]) # generating the weight matricesrandom.seed(42)W_Q = random.randint(3, size=(3, 3))W_K = random.randint(3, size=(3, 3))W_V = random.randint(3, size=(3, 3)) # generating the queries, keys and valuesQ = words @ W_QK = words @ W_KV = words @ W_V # inserting a breakpointbreakpoint() # scoring the query vectors against all key vectorsscores = Q @ K.transpose() # computing the weights by a softmax operationweights = softmax(scores / K.shape[1] ** 0.5, axis=1) # computing the attention by a weighted sum of the value vectorsattention = weights @ V print(attention) The value of PYTHONBREAKPOINT is consulted every time that sys.breakpointhook() is called. This means that the value of this environment variable can be changed during the code execution, and the breakpoint() function would respond accordingly.   The PYTHONBREAKPOINT environment variable can also be set to other values, such as the name of a callable. Say, for instance, that we’d like to use a different Python debugger other than pdb, such as ipdb (run pip install ipdb first if the debugger has not yet been installed). In this case, we would call the main.py script in the command line interface and hook the debugger without making any changes to the code itself: PYTHONBREAKPOINT=ipdb.set_trace python main.py PYTHONBREAKPOINT=ipdb.set_trace python main.py In doing so, the breakpoint() function enters the ipdb debugger at the next call site: > /Users/Stefania/Documents/PycharmProjects/BreakpointPy37/main.py(33)<module>() 32 # scoring the query vectors against all key vectors ---> 33 scores = Q @ K.transpose() 34 ipdb> n > /Users/Stefania/Documents/PycharmProjects/BreakpointPy37/main.py(36)<module>() 35 # computing the weights by a softmax operation ---> 36 weights = softmax(scores / K.shape[1] ** 0.5, axis=1) 37 ipdb> c [[0.98522025 1.74174051 0.75652026] [0.90965265 1.40965265 0.5 ] [0.99851226 1.75849334 0.75998108] [0.99560386 1.90407309 0.90846923]] > /Users/Stefania/Documents/PycharmProjects/BreakpointPy37/main.py(33)<module>()     32 # scoring the query vectors against all key vectors---> 33 scores = Q @ K.transpose()     34  ipdb> n> /Users/Stefania/Documents/PycharmProjects/BreakpointPy37/main.py(36)<module>()     35 # computing the weights by a softmax operation---> 36 weights = softmax(scores / K.shape[1] ** 0.5, axis=1)     37  ipdb> c[[0.98522025 1.74174051 0.75652026] [0.90965265 1.40965265 0.5       ] [0.99851226 1.75849334 0.75998108] [0.99560386 1.90407309 0.90846923]] The function can also take input arguments as breakpoint(*args, **kws), which are then passed on to sys.breakpointhook(). This is because any callable (such as a third-party debugger module) might accept optional arguments, which can be passed through the breakpoint() function.  Want to Get Started With Python for Machine Learning? Take my free 7-day email crash course now (with sample code). Click to sign-up and also get a free PDF Ebook version of the course. Download Your FREE Mini-Course Writing Your Own breakpoint() Function in Earlier Versions of Python Let’s return to the fact that versions of Python earlier than v3.7 do not come with the breakpoint() function readily built in. We can write our own.  Similarly to how the breakpoint() function is implemented from Python 3.7 onwards, we can implement a function that checks the value of an environment variable and: Skips all breakpoints in the code if the value of the environment variable is set to 0. Enters into the default Python pdb debugger if the environment variable is an empty string. Enters into another debugger as specified by the value of the environment variable.  ... # defining our breakpoint() function def breakpoint(*args, **kwargs): import importlib # reading the value of the environment variable val = os.environ.get('PYTHONBREAKPOINT') # if the value has been set to 0, skip all breakpoints if val == '0': return None # else if the value is an empty string, invoke the default pdb debugger elif len(val) == 0: hook_name = 'pdb.set_trace' # else, assign the value of the environment variable else: hook_name = val # split the string into the module name and the function name mod, dot, func = hook_name.rpartition('.') # get the function from the module module = importlib.import_module(mod) hook = getattr(module, func) return hook(*args, **kwargs) ... 12345678910111213141516171819202122232425 ... # defining our breakpoint() functiondef breakpoint(*args, **kwargs):    import importlib    # reading the value of the environment variable    val = os.environ.get('PYTHONBREAKPOINT')    # if the value has been set to 0, skip all breakpoints    if val == '0':        return None    # else if the value is an empty string, invoke the default pdb debugger    elif len(val) == 0:        hook_name = 'pdb.set_trace'    # else, assign the value of the environment variable    else:        hook_name = val    # split the string into the module name and the function name    mod, dot, func = hook_name.rpartition('.')    # get the function from the module    module = importlib.import_module(mod)    hook = getattr(module, func)     return hook(*args, **kwargs) ... We can include this function into the code and run it (using a Python 2.7 interpreter, in this case). If we set the value of the environment variable to an empty string, we find that the pdb debugger stops at the point in the code at which we have placed our breakpoint() function. We can then issue debugger commands into the command line from there onwards: from numpy import array from numpy import random from numpy import dot from scipy.special import softmax # setting the value of the environment variable import os os.environ['PYTHONBREAKPOINT'] = '' # defining our breakpoint() function def breakpoint(*args, **kwargs): import importlib # reading the value of the environment variable val = os.environ.get('PYTHONBREAKPOINT') # if the value has been set to 0, skip all breakpoints if val == '0': return None # else if the value is an empty string, invoke the default pdb debugger elif len(val) == 0: hook_name = 'pdb.set_trace' # else, assign the value of the environment variable else: hook_name = val # split the string into the module name and the function name mod, dot, func = hook_name.rpartition('.') # get the function from the module module = importlib.import_module(mod) hook = getattr(module, func) return hook(*args, **kwargs) # encoder representations of four different words word_1 = array([1, 0, 0]) word_2 = array([0, 1, 0]) word_3 = array([1, 1, 0]) word_4 = array([0, 0, 1]) # stacking the word embeddings into a single array words = array([word_1, word_2, word_3, word_4]) # generating the weight matrices random.seed(42) W_Q = random.randint(3, size=(3, 3)) W_K = random.randint(3, size=(3, 3)) W_V = random.randint(3, size=(3, 3)) # generating the queries, keys and values Q = dot(words, W_Q) K = dot(words, W_K) V = dot(words, W_V) # inserting a breakpoint breakpoint() # scoring the query vectors against all key vectors scores = dot(Q, K.transpose()) # computing the weights by a softmax operation weights = softmax(scores / K.shape[1] ** 0.5, axis=1) # computing the attention by a weighted sum of the value vectors attention = dot(weights, V) print(attention) 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566 from numpy import arrayfrom numpy import randomfrom numpy import dotfrom scipy.special import softmax # setting the value of the environment variableimport osos.environ['PYTHONBREAKPOINT'] = ''  # defining our breakpoint() functiondef breakpoint(*args, **kwargs):    import importlib    # reading the value of the environment variable    val = os.environ.get('PYTHONBREAKPOINT')    # if the value has been set to 0, skip all breakpoints    if val == '0':        return None    # else if the value is an empty string, invoke the default pdb debugger    elif len(val) == 0:        hook_name = 'pdb.set_trace'    # else, assign the value of the environment variable    else:        hook_name = val    # split the string into the module name and the function name    mod, dot, func = hook_name.rpartition('.')    # get the function from the module    module = importlib.import_module(mod)    hook = getattr(module, func)     return hook(*args, **kwargs)  # encoder representations of four different wordsword_1 = array([1, 0, 0])word_2 = array([0, 1, 0])word_3 = array([1, 1, 0])word_4 = array([0, 0, 1]) # stacking the word embeddings into a single arraywords = array([word_1, word_2, word_3, word_4]) # generating the weight matricesrandom.seed(42)W_Q = random.randint(3, size=(3, 3))W_K = random.randint(3, size=(3, 3))W_V = random.randint(3, size=(3, 3)) # generating the queries, keys and valuesQ = dot(words, W_Q)K = dot(words, W_K)V = dot(words, W_V) # inserting a breakpointbreakpoint() # scoring the query vectors against all key vectorsscores = dot(Q, K.transpose()) # computing the weights by a softmax operationweights = softmax(scores / K.shape[1] ** 0.5, axis=1) # computing the attention by a weighted sum of the value vectorsattention = dot(weights, V) print(attention) > /Users/Stefania/Documents/PycharmProjects/BreakpointPy27/main.py(32)breakpoint()->None -> return hook(*args, **kwargs) (Pdb) n > /Users/Stefania/Documents/PycharmProjects/BreakpointPy27/main.py(59)<module>() -> scores = dot(Q, K.transpose()) (Pdb) n > /Users/Stefania/Documents/PycharmProjects/BreakpointPy27/main.py(62)<module>() -> weights = softmax(scores / K.shape[1] ** 0.5, axis=1) (Pdb) c [[0.98522025 1.74174051 0.75652026] [0.90965265 1.40965265 0.5 ] [0.99851226 1.75849334 0.75998108] [0.99560386 1.90407309 0.90846923]] > /Users/Stefania/Documents/PycharmProjects/BreakpointPy27/main.py(32)breakpoint()->None-> return hook(*args, **kwargs)(Pdb) n> /Users/Stefania/Documents/PycharmProjects/BreakpointPy27/main.py(59)<module>()-> scores = dot(Q, K.transpose())(Pdb) n> /Users/Stefania/Documents/PycharmProjects/BreakpointPy27/main.py(62)<module>()-> weights = softmax(scores / K.shape[1] ** 0.5, axis=1)(Pdb) c[[0.98522025 1.74174051 0.75652026] [0.90965265 1.40965265 0.5       ] [0.99851226 1.75849334 0.75998108] [0.99560386 1.90407309 0.90846923]] Similarly, if we set the environment variable to: os.environ['PYTHONBREAKPOINT'] = 'ipdb.set_trace' os.environ['PYTHONBREAKPOINT'] = 'ipdb.set_trace' The breakpoint() function that we have implemented now enters the ipdb debugger and stops at the call site: > /Users/Stefania/Documents/PycharmProjects/BreakpointPy27/main.py(31)breakpoint() 30 ---> 31 return hook(*args, **kwargs) 32 ipdb> n > /Users/Stefania/Documents/PycharmProjects/BreakpointPy27/main.py(58)<module>() 57 # scoring the query vectors against all key vectors ---> 58 scores = dot(Q, K.transpose()) 59 ipdb> n > /Users/Stefania/Documents/PycharmProjects/BreakpointPy27/main.py(61)<module>() 60 # computing the weights by a softmax operation ---> 61 weights = softmax(scores / K.shape[1] ** 0.5, axis=1) 62 ipdb> c [[0.98522025 1.74174051 0.75652026] [0.90965265 1.40965265 0.5 ] [0.99851226 1.75849334 0.75998108] [0.99560386 1.90407309 0.90846923]] 12345678910111213141516171819202122 > /Users/Stefania/Documents/PycharmProjects/BreakpointPy27/main.py(31)breakpoint()     30 ---> 31     return hook(*args, **kwargs)     32  ipdb> n> /Users/Stefania/Documents/PycharmProjects/BreakpointPy27/main.py(58)<module>()     57 # scoring the query vectors against all key vectors---> 58 scores = dot(Q, K.transpose())     59  ipdb> n> /Users/Stefania/Documents/PycharmProjects/BreakpointPy27/main.py(61)<module>()     60 # computing the weights by a softmax operation---> 61 weights = softmax(scores / K.shape[1] ** 0.5, axis=1)     62  ipdb> c[[0.98522025 1.74174051 0.75652026] [0.90965265 1.40965265 0.5       ] [0.99851226 1.75849334 0.75998108] [0.99560386 1.90407309 0.90846923]] Setting the environment variable to 0 simply skips all breakpoints, and the computed attention output is returned in the command line, as expected: os.environ['PYTHONBREAKPOINT'] = '0' os.environ['PYTHONBREAKPOINT'] = '0' [[0.98522025 1.74174051 0.75652026] [0.90965265 1.40965265 0.5 ] [0.99851226 1.75849334 0.75998108] [0.99560386 1.90407309 0.90846923]] [[0.98522025 1.74174051 0.75652026] [0.90965265 1.40965265 0.5       ] [0.99851226 1.75849334 0.75998108] [0.99560386 1.90407309 0.90846923]] This facilitates the process of breaking into the code for Python versions earlier than v3.7 because it now becomes a matter of setting the value of an environment variable rather than having to manually introduce (or remove) the import pdb; pdb.set_trace() statement at different call sites in the code.  Limitations of the breakpoint() Function The breakpoint() function allows you to bring in the debugger at some point in the program. You need to find the exact position that you need the debugger to put the breakpoint into it. If you consider the following code: try: func() except: breakpoint() print("exception!") try:    func()except:    breakpoint()    print("exception!") This will bring you the debugger when the function func() raised exceptions. It can be triggered by the function itself or deep inside some other functions that it calls. But the debugger will start at the line print("exception!") above, which may not be very useful. The way that we can bring up the debugger at the point of exception is called the post-mortem debugger. It works by asking Python to register the debugger pdb.pm() as the exception handler when an uncaught exception is raised. When it is called, it will look for the last exception raised and start the debugger at that point. To use the post-mortem debugger, we just need to add the following code before the program is run: import sys import pdb def debughook(etype, value, tb): pdb.pm() # post-mortem debugger sys.excepthook = debughook import sysimport pdb def debughook(etype, value, tb):    pdb.pm() # post-mortem debuggersys.excepthook = debughook This is handy because nothing else needs to be changed in the program. For example, assume we want to evaluate the average of $1/x$ using the following program. It is quite easy to overlook some corner cases, but we can catch the issue when an exception is raised: import sys import pdb import random def debughook(etype, value, tb): pdb.pm() # post-mortem debugger sys.excepthook = debughook # Experimentally find the average of 1/x where x is a random integer in 0 to 9999 N = 1000 randomsum = 0 for i in range(N): x = random.randint(0,10000) randomsum += 1/x print("Average is", randomsum/N) import sysimport pdbimport random def debughook(etype, value, tb):    pdb.pm() # post-mortem debuggersys.excepthook = debughook # Experimentally find the average of 1/x where x is a random integer in 0 to 9999N = 1000randomsum = 0for i in range(N):    x = random.randint(0,10000)    randomsum += 1/x print("Average is", randomsum/N) When we run the above program, the program may terminate, or it may raise a division by zero exception, depending on whether the random number generator ever produces zero in the loop. In that case, we may see the following: > /Users/mlm/py_pmhook.py(17)<module>() -> randomsum += 1/x (Pdb) p i 16 (Pdb) p x 0 > /Users/mlm/py_pmhook.py(17)<module>()-> randomsum += 1/x(Pdb) p i16(Pdb) p x0 where we found the exception is raised at which line, and we can check the value of the variables as we can usually do in pdb. In fact, it is more convenient to print the traceback and the exception when the post-mortem debugger is launched: import sys import pdb import traceback def debughook(etype, value, tb): traceback.print_exception(etype, value, tb) print() # make a new line before launching post-mortem pdb.pm() # post-mortem debugger sys.excepthook = debughook import sysimport pdbimport traceback def debughook(etype, value, tb):    traceback.print_exception(etype, value, tb)    print() # make a new line before launching post-mortem    pdb.pm() # post-mortem debuggersys.excepthook = debughook And the debugger session will be started as follows: Traceback (most recent call last): File "/Users/mlm/py_pmhook.py", line 17, in <module> randomsum += 1/x ZeroDivisionError: division by zero > /Users/mlm/py_pmhook.py(17)<module>() -> randomsum += 1/x (Pdb) Traceback (most recent call last):  File "/Users/mlm/py_pmhook.py", line 17, in <module>    randomsum += 1/xZeroDivisionError: division by zero > /Users/mlm/py_pmhook.py(17)<module>()-> randomsum += 1/x(Pdb) Further Reading This section provides more resources on the topic if you are looking to go deeper. Websites Summary In this tutorial, you discovered various ways of setting breakpoints in different versions of Python.  Specifically, you learned: How to invoke the pdb debugger in earlier versions of Python How to make use of the new, built-in breakpoint() function introduced in Python 3.7 How to write your own breakpoint() function to simplify the debugging process in earlier versions of Python Do you have any questions? Ask your questions in the comments below, and I will do my best to answer. Get a Handle on Python for Machine Learning! Be More Confident to Code in Python ...from learning the practical Python tricks Discover how in my new Ebook: Python for Machine Learning It provides self-study tutorials with hundreds of working code to equip you with skills including: debugging, profiling, duck typing, decorators, deployment, and much more... Showing You the Python Toolbox at a High Level for Your Projects See What's Inside Share Post Share

Visibility

Visible to everyone

Reading Status

Related Bookmarks

My Note


Saved!

Annotations

Export as Markdown
+ Annotate selection

Add Annotation