<!DOCTYPE html>

<!-- Welcome traveler. 

You may have wandered to my website's source code out of curiosity,
or to learn something new. I've left a few comments here and there
for those who want to learn about HTML and building websites.

-->

<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>
      Syntax Error #5 - Python breakpoints : Juha-Matti Santala
    </title>

    <!-- RSS Feed

    This link tells RSS readers where to find my feed so you don't have
    to manually enter the entire path to the XML file but can jump right
    into pasting the main page URL and the readers should find the right
    feed for you.

    RSS feeds are a great way to give readers the power to subscribe to
    a blog with the tooling they want to.
    -->
    <link
      rel="alternate"
      type="application/rss+xml"
      title="hamatti.org &raquo; Feed"
      href="https://hamatti.org/feed/feed.xml"
    />

    <!-- Metadata 

  Metadata is used in a few places, most notably when
  sharing links in social media or messaging platforms.

  -->

<!-- That's my name! -->
<meta name="author" content="Juha-Matti Santala" />

<!-- Description tells what this page is about -->
<meta
  name="description"
  content="The home of a developer community specialist."
/>

<!-- Open Graph

  og stands for Open Graph and it's a specification for 
  defining social media preview content. It was created by 
  Facebook but many other platforms use it too.

  -->

<meta property="og:site_name" content="Juha-Matti Santala - Community Builder. Dreamer. Adventurer." />
<meta property="og:locale" content="en_US" />
<meta
  property="og:title"
  content="Syntax Error #5 - Python breakpoints"
/>
<meta
  property="og:description"
  content="The home of a developer community specialist."
/>

<!-- 

    This URL is important: it's where the preview will lead
    when clicked.

    If it's incorrect, the reader experience will be degraded.

  -->
<meta property="og:url" content="https://hamatti.org/syntax-error/syntax-error-5-python-breakpoints" />

<!--
    
    These couple of image definitions help services choose
    which images they should show in the preview.

    Note that these don't need to even appear on the page.

    If these are not defined, many platforms show the first
    image they find on a page.

  -->

<meta
  property="og:image"
  content="https://hamatti.org/"
/>
<meta
  property="og:image:secure_url"
  content="https://hamatti.org/"
/><!-- Fediverse:creator

  Similar to Open Graph definitions above, this one
  was created by the developers of Mastodon to let 
  the system know which Mastodon account is behind
  this page and can link to it.

  -->
<meta name="fediverse:creator" content="@hamatti@mastodon.world" />

<!-- Twitter / X

  X (previously Twitter) has their own set of
  meta tags they use to define what to show in
  a preview.

  -->
<meta
  name="twitter:card"
  content="summary"
/>
<meta
  name="twitter:site"
  content="@"
/>
<meta
  name="twitter:creator"
  content="@"
/>

<!-- Canonical URL

  If a post is originally published elsewhere and 
  then shared on my site, I point the canonical URL
  to that page to let computers - mainly search engine
  scrapers - to know where the original exists.

  -->
<link rel="canonical" href="https://hamatti.org/syntax-error/syntax-error-5-python-breakpoints" />

<!-- Generator

  This site is a statically generated site so I share which
  tool I used to generate it.

  Since my site is static, it's safe to include this but for 
  something using a dynamic backend (like WordPress or Django),
  it can cause security issues as it lets potentially malicious
  user to know what systems and versions you may be running.

  -->
<meta name="generator" content="Eleventy v2.0.1" />

<!-- Mastodon verification

  These links verify that when I link my website to my
  Mastodon accounts, those accounts are really me.
  
-->
<link rel="me" href="https://mastodontti.fi/@hamatti" />
<link rel="me" href="https://mastodon.world/@hamatti" />


<script type="application/ld+json">
  {
    "name": "Juha-Matti Santala",
    "description": "The home of a developer community specialist.",
    "author": {
      "@type": "Person",
      "name": "Juha-Matti Santala"
    },
    "@type": "WebSite",
    "url": "https://hamatti.org",
    "image": "",
    "headline": "Juha-Matti Santala - Community Builder. Dreamer. Adventurer.",
    "sameAs": [
      "",
      ""
    ],
    "@context": "http://schema.org"
  }
</script>


    <!-- CSS 

    It's not usually the best practice to provide many CSS files but
    to rather combine them in the build phase into one to avoid HTTP
    requests on read time.

    I have been lazy to set that up with Eleventy so here are all my
    CSS declarations in a human-readable format.
    -->
    <link href="/assets/fonts/roboto-slab.css" rel="stylesheet" />
    <link rel="stylesheet" href="/assets/reset.css" />
    <link rel="stylesheet" href="/assets/layout.css" />
    <link rel="stylesheet" href="/assets/typography.css" />
    <link rel="stylesheet" href="/assets/colors.css" />
    <link rel="stylesheet" href="/assets/page.css" />
    <link rel="stylesheet" href="/assets/blog.css" />
    <link rel="stylesheet" href="/assets/header.css" />
    <link rel="stylesheet" href="/assets/navigation.css" />
    <link rel="stylesheet" href="/assets/links.css" />
    <link rel="stylesheet" href="/assets/newsletter.css" />
    <link rel="stylesheet" href="/assets/footer.css" />
    <link rel="stylesheet" href="/assets/main.css" />
    <link rel="stylesheet" href="/assets/landing.css" />
    <link rel="stylesheet" href="/assets/uses.css" />
    <link rel="stylesheet" href="/assets/prism.css" />
    <link rel="stylesheet" href="/assets/prism-ext-ptcgo.css" />
    <link rel="stylesheet" href="/assets/print.css" media="print" />
    <link
      rel="stylesheet"
      href="/assets/prism-vs-code-plus.css"
    />
    <link rel="stylesheet" href="/assets/adventofcode.css" />
    <link rel="stylesheet" href="/assets/embeds.css" />

    <link rel="icon" href="/assets/img/favicon.png" />
    <link rel="apple-touch-icon" href="/assets/img/favicon.png" />

    <!-- Webmentions

    Webmentions are a way for websites to talk to each other.
    If you write a blog post that links to any of my pages on
    this site, you can send me a Webmention to the URL below
    and I will get a notification to know that we're now in
    blogosphere discussion.
    -->
    <link
      rel="webmention"
      href="https://webmention.io/hamatti.org/webmention"
    />
  </head>

  <body class="line-numbers">
    <div id="layout-top">
      <header><div>
  <a href='/'>Juha-Matti Santala</a>
  <div>Community Builder. Dreamer. Adventurer.</div>
</div>
</header>
      <nav aria-label="Main"><ul>
  <li><a href="/" >Home</a></li>
  <li><a href="/blog" >Blog</a></li>
  <li><a href="https://notes.hamatti.org">Notes</a></li>
  <li><a href="/weeklies" >Weeklies</a></li>
  <li><a href="/snacks" >Snacks</a></li>
  <li><a href="/codebase" >codebase</a></li>
  <li><a href="/speaking" >Speaking</a></li>
  <li><a href="/software" >Software</a></li>
  <li><a href="/about" >About me</a></li>
  <li><a href="/feed/feed.xml" class="icon"><svg role="img" labelled-by="RSS-SVG-ID" version="1.1" xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 32 32">
<title id="RSS-SVG-ID">RSS</title>
<path fill="currentColor" d="M4.259 23.467c-2.35 0-4.259 1.917-4.259 4.252 0 2.349 1.909 4.244 4.259 4.244 2.358 0 4.265-1.895 4.265-4.244-0-2.336-1.907-4.252-4.265-4.252zM0.005 10.873v6.133c3.993 0 7.749 1.562 10.577 4.391 2.825 2.822 4.384 6.595 4.384 10.603h6.16c-0-11.651-9.478-21.127-21.121-21.127zM0.012 0v6.136c14.243 0 25.836 11.604 25.836 25.864h6.152c0-17.64-14.352-32-31.988-32z"></path>
</svg>
</a></li>
  <li><a href="/search" class="icon"><?xml version="1.0"?>
<svg class="feather feather-search" fill="none" height="24" stroke="currentColor"
    stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 24 24" width="24"
    xmlns="http://www.w3.org/2000/svg"
    aria-label="search">
    <circle cx="11" cy="11" r="8" />
    <line x1="21" x2="16.65" y1="21" y2="16.65" />
</svg></a></li>
  <li><button aria-label="Toggle light/dark mode" id="toggleTheme"><svg width="32px" height="32px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink">
    <title>Toggle dark/light mode</title>
    <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g fill="currentColor" fill-rule="nonzero">
            <path
                d="M12,22 C17.5228475,22 22,17.5228475 22,12 C22,6.4771525 17.5228475,2 12,2 C6.4771525,2 2,6.4771525 2,12 C2,17.5228475 6.4771525,22 12,22 Z M12,20.5 L12,3.5 C16.6944204,3.5 20.5,7.30557963 20.5,12 C20.5,16.6944204 16.6944204,20.5 12,20.5 Z">
            </path>
        </g>
    </g>
</svg></button></li>
</ul></nav>
    </div>

    <main>
<div id="syntax-error-header">
  <img src="/assets/img/syntax-error/banner.png" alt="" />
  
  <a href="/syntax-error/">Back to index</a>
  
</div>
<div id="page"><h1>Syntax Error #5: Python breakpoints</h1>
<p>This month we look at debuggers in Python and how to choose your own debugger instead of relying on the built-in pdb.</p>
<p><em>After a summer break in June, we're back in the world of ducks and debugging.</em></p>
<p>Thank you being a subscriber and reading this. Whether it arrives to your email or your RSS feed, I'm very happy that you decided to give my newsletter your time and focus in this world that is full of everything to do. I hope you are having a brilliant day. ❤️</p>
<hr>
<h2>Debugging with Python's breakpoint()</h2>
<p>In the <a href="/syntax-error/syntax-error-2-print-it-like-a-boss/">2nd issue of Syntax Error</a>, I wrote about how printing is a great first step in debugging but it's not always enough. Sometimes you need a better access with a way to step through the execution of a program and the ability to see the values of variables while developing.</p>
<p>Since Python 3.7, we've been able to trigger a debugger with a call to <code>breakpoint()</code>. It halts the execution and provides you with access to <a href="https://docs.python.org/3/library/pdb.html">The Python Debugger (pdb)</a>. With it, you can execute Python expressions like in <a href="https://docs.python.org/3/tutorial/interpreter.html">REPL</a> but in addition, you can walk forward and backwards in the execution of the program.</p>
<p>Knowing how to use debuggers in your language is a very valuable skill. It lets you make less guesses and more well informed decisions as you can find out exactly where the issues arise in your code.</p>
<p>The default built-in Python Debugger pdb can be helpful but it's also simplistic and may be sometimes difficult to follow a more complex piece of code with it.</p>
<h3>PYTHONBREAKPOINT environment value</h3>
<p>Last week, as I was preparing a new talk about debugging, I learned about an environment value <code>[PYTHONBREAKPOINT](https://docs.python.org/3/using/cmdline.html#envvar-PYTHONBREAKPOINT)</code> that you can define to control the breakpoints more.</p>
<p>By defining the value to <code>0</code>, no debugger will trigger and Python will simply ignore the <code>breakpoint()</code> calls.</p>
<p>You can also define which debugger you want to use by setting the value to a <code>[module].[function]</code>. It gets then imported and executed.</p>
<p>For example, by setting it to <code>ipdb.set_trace</code>, it will open the <a href="https://github.com/gotcha/ipdb">iPython Debugger</a>.</p>
<p><img src="/assets/img/syntax-error/pudb.png" alt="A 5-pane window of PuDB debugger."></p>
<p>PuDB on a Django view</p>
<p>One new debugger I learned about is <a href="https://pypi.org/project/pudb/">PuDB</a> that can be invoked with <code>pudb.set_trace</code>. It provides a multi-pane command line interface that shows you the code, the local variables, current stack and lets you set more breakpoints from within the editor view.</p>
<p>If navigating the command line tool isn't your cup of tea, <a href="https://pypi.org/project/web-pdb/">web-pdb</a> sets up a local web server to which you can connect with your browser for a web based UI. It offers similar functions as PuDB.</p>
<p><img src="/assets/img/syntax-error/web-pdb.jpg" alt="A 4-pane window of web-pdb debugger view"></p>
<p>web-pdb UI on a Django view</p>
<hr>
<h2>Story time</h2>
<p><em>If you have debugging stories or examples you want to share to the Syntax Error community, please reach out via hello@syntaxerror.tech and we might share your story!</em></p>
<p>This one is less of a story and more of a great look into debuggers that a reader sent my way.</p>
<p>It's called <a href="https://werat.dev/blog/what-a-good-debugger-can-do/">What a good debugger can do?</a>, written by <a href="https://werat.dev/">Andy Hippo</a>.  Andy has also a few other great debugging blog posts that I recommend giving a read if you want to improve your skills.</p>
<p>I agree with Andy's conclusion:</p>
<blockquote>
<p>Every existing debugger has its ups and downs; there’s no silver bullet, but you already knew that. In some situations logging is more convenient, while in others using a time-traveling debugger can shorten the bug investigation from days to minutes. Debugging technologies have come a long way and even though many things are not as impressive as you might expect, there are a lot of interesting features that are definitely worth checking out. Please use debuggers and complain if something is not working. Demand better from your local debugger vendor, only then will things improve.</p>
</blockquote>
<hr>
<p><em>Syntax Error is created with love by <a href="/">Juhis</a>. If you liked it, why not share it with a friend? Or if you have any feedback or just want to say hi, hit reply. I'm always happy to hear from my readers and learn about what you do and how you debug your issues.</em></p>
</div>

<script src="/assets/javascript/prism.js"></script>
</main>

    <footer><div>
  Digital home of
  <a href="https://hamatti.org">Juha-Matti Santala</a> | Built with
  <a href="https://www.11ty.dev/" target="_blank">Eleventy</a> |
  <a href="/feed/feed.xml">RSS</a> | Layout originally by
  <a href="https://html5up.net/">HTML5 UP!</a>
</div>

<nav aria-label="Footer">
  <a href="https://slashpages.net">Slashpages</a>
  <ul>
    <li><a href="/about">/about</a></li>
    <li><a href="/uses">/uses</a></li>
    <li><a href="/colophon">/colophon</a></li>
    <li><a href="/blog/roll">/blogroll</a></li>
    <li><a href="/contact">/contact</a></li>
    <li><a href="/why">/why</a></li>
    <li><a href="/now">/now</a></li>
  </ul>
</nav>

<div>
  <p style="margin: 1em">Trans rights are human rights.</p>
</div>
</footer>

    

    <!-- Dark Mode 

    You can define how you want to style my site by defining
    a light/dark mode setting in your operating system or
    browser settings or by clicking the button at the end of
    the main navigation.

    This Javascript is what manages the button and storing 
    custom configuration.

    -->
    <script src="/assets/javascript/darkmode.js"></script>
  </body>
</html>