[Sublime + Python Setup] The Ctrl+s "Heisenbug"

"What the **** is going on?!" I heard Keith yell.

Returning from my lunch break and in a helpful mood I grabbed my coffee mug and shuffled over to my coworker's desk.

"What's wrong?"

Keith was working on a ticket to fix an issue with our Python-based web portal. The result of some numerical calculation was way off. It seemed like a straightforward algorithmic fix…

"I think this Python code is haunted or something," said Keith as I sat down next to him. "Opening and saving this source file fixes one bug, but then 5 others show up!"

Two hours of swearing and pair-programming later, our investigation of the "haunted code" revealed the following steps to reproduce the issue:

First, we check out the original version of the affected source file from Git. Bug A shows up. So far, so expected.

Next, we open the file in Sublime Text and, without making any edits, immediately hit Ctrl+S to save it again. Now bug A is gone—only to have brand new bugs B, C, and D show up!

Umm…

We were stumped.

"Maybe it's some odd whitespace issue…"

You see, whitespace has a meaning in Python. It uses whitespace indentation levels to determine how code blocks are nested.

Personally, I really like the idea of "semantic whitespace". But occasionally it can lead to pure hell. Take a look at the screenshot below:

Image

Running this script you'd expect to get 10 × 10 = 100 as the answer.

However, by using a mixture of space and tab (\t) characters, you can get this program to print "10"—a completely bogus answer:

For Python indenting, a tab is counted as equivalent to 8 spaces…

And code that looked correct on our screens was actually way off for the Python interpreter:

def square(x):
    result = 0
    for i in range(x):
        result += x
<\t>return result  # ← 1 tab character
^^^^               #   instead of 4 spaces

Remember, one tab is equal to 8 spaces. So this mixture of tab and spaces gets parsed as the following:

def square(x):
    result = 0
    for i in range(x):
        result += x
        return result  # ← 1 tab == 8 spaces

Now the return-statement is indented one level too far. It breaks out of the loop after the first iteration —

D'Oh!

Now by merely re-saving the file in Sublime these tab characters were converted to 4 space characters each. Thus fixing the original indentation problem, but also introducing several new ones elsewhere in the code…

Double D'Oh!

In the end Keith and I easily spent 20 or more developer hours on tracking down various bugs caused by inconsistent whitespace throughout the code base.

It was a nightmare of a bug to fix, and what frustrated me the most about it was how easily it could've been avoided in the first place:

Had we used static code analysis tools back then we would've caught these problems much more easily. Code linting tools would've simply highlighted this whitespace issue right in our editors (and on our build server):

Image

For this reason I'm a big proponent of static code analysis tools now. They can help you detect and void certain bugs and classes of errors completely.

A code linter can catch functional bugs like misspelled identifiers, or reveal code quality issues like unused variables or imports.

I won't say automated code analysis is a miracle cure (sometimes it feels like it) —

But usually the Return on Investment for these tools is simply through the roof. They help reduce debugging and code review time with just a tiny initial time investment.

Now, as awesome as these tools sound, there are some common gotchas to integrating them with Sublime Text:

If you're not careful, integrated code linting can get overly verbose and distracting—and it can slow your editing experience down to a crawl…

To see how to set up silky smooth code linting for Python in less than 10 minutes, click here for more.

— Dan Bader

Key phrases

Older messages

[Sublime + Python Setup] How to become a happier & more productive Python dev

Saturday, October 8, 2022

Hey there, I really struggled with setting up an effective development environment as a new Python developer. It was difficult to build the right habits and to find a set of tools I enjoyed to use.

[Python Mastery] The hidden costs of "copy-paste" Python programming

Friday, October 7, 2022

Hey there, Here's a development story that plays out thousands of times each day: Avid Pythonista Max is working on a function to find the 10 oldest files in a nested directory hierarchy. He needs

[Python Mastery] Learn Python in 21 days!!!!11 (what a lie)

Thursday, October 6, 2022

Hey there, One of the first programming books I ever bought was "Teach Yourself C in 21 Days." This four pound tome came with a CD-ROM that included an ancient version (3.1) of the Borland

[Python Mastery] The secret to "ethical self-promotion"?

Wednesday, October 5, 2022

Hey there, Here's some food for thought: There's a difference between *doing* a great job as a Python developer, and *to be seen doing* a great job. Being a skilled developer among peers—and

[Python Mastery] What does it mean to "master" Python?

Tuesday, October 4, 2022

Hey there, A couple of years ago I'd become quite interested in martial arts. Hours upon hours of watching "The Karate Kid" growing up must've taken their toll on me... And so, I

You Might Also Like

📧 Request Response Messaging Pattern With MassTransit

Saturday, April 27, 2024

​ Request Response Messaging Pattern With MassTransit Read on: m​y website / Read time: 5 minutes BROUGHT TO YOU BY ​ Get ready for POST/CON 24! ​ Join us in San Francisco from April 30 - May 1 for

Tesla Autopilot investigation closed

Friday, April 26, 2024

Inside the IBM-HashiCorp deal and Thoma Bravo takes another company private View this email online in your browser By Christine Hall Friday, April 26, 2024 Good afternoon, and welcome to TechCrunch PM.

Microsoft's and Google's bet on AI is paying off - Weekly News Roundup - Issue #464

Friday, April 26, 2024

Plus: AI-controlled F-16 has been dogfighting with humans; Grok-1.5 Vision; BionicBee; Microsoft's AI generates realistic deepfakes from a single photo; and more! ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏ ͏

🤓 The Meta Quest Might Be the VR Steam Deck Soon — Games to Play After Finishing Wordle

Friday, April 26, 2024

Also: Why a Cheap Soundbar Is Better Than Nothing, and More! How-To Geek Logo April 26, 2024 Did You Know TMI: Rhinotillexomania is the medical term for obsessive nose picking. 🖥️ Get Those Updates

JSK Daily for Apr 26, 2024

Friday, April 26, 2024

JSK Daily for Apr 26, 2024 View this email in your browser A community curated daily e-mail of JavaScript news A Solid primer on Signals with Ryan Carniato (JS Party #320) Ryan Carniato joins Amal

So are we banning TikTok or what?

Friday, April 26, 2024

Also: Can an influencer really tank an $800M company? View this email online in your browser By Haje Jan Kamps Friday, April 26, 2024 Image Credits: Jonathan Raa/NurPhoto / Getty Images Welcome to

[AI Incubator] 300+ people are already in. Enrollment closes tonight at 11:59pm PT.

Friday, April 26, 2024

How to decide if you're ready. ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌

Daily Coding Problem: Problem #1423 [Medium]

Friday, April 26, 2024

Daily Coding Problem Good morning! Here's your coding interview problem for today. This problem was asked by Google. You are given an array of nonnegative integers. Let's say you start at the

Data science for Product Managers

Friday, April 26, 2024

Crucial resources to empower you with data that matters. ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌

Inner Thoughts

Friday, April 26, 2024

'The Inner Circle' Comes Around... Inner Thoughts By MG Siegler • 26 Apr 2024 View in browser View in browser If you'll allow me a brief meta blurb this week (not a Meta blurb, plenty of