mathspp
  • Blog
    • Pydon'ts
    • Problems
    • TIL
    • Twitter threads
  • Books
  • Talks
  • Trainings
    • Advanced iteration
    • Python for scripting and automation
    • Rust for Python developers
  • Courses
  • About
Link blog

The Boolean Trap - Engineer’s Codex

on 24-10-2025 08:15

This article defends that there are many situations where using a Boolean as a function parameter is a bad idea and an enumeration would be better. The example given is similar to the one below.

Suppose you have a function that produces some report data and that the report is written in a text format. A new requirement comes in and you must also be able to output the report as some funky JSON data, so you extend the signature of the function:

def generate_report(output_path: Path, as_json: bool = False) -> None:
    ...

Now, there's one thing that's already quite nasty and which is that function calls won't be easy to read if you don't specify the second parameter name:

generate_report("report.txt", False)

What's that False there? You can attenuate this by forcing the Boolean to be passed in as a keyword argument:

def generate_report(output_path: Path, *, as_json: bool = False) -> None:
    ...

Now, you have to do

generate_report("report.txt", as_json=False)

But wait, if “as JSON” is False, what is the alternative? It's not obvious that it is plain text...

And another problem remains: if later on we need to add a third format, how do we account for it? Booleans only have two states.

That's why the preferred approach would be to use an enumeration. In Python 3.12, I recommend using a StrEnum (the link uses a plain enumeration):

from enum import StrEnum, auto

class OutFormat(StrEnum):
    TEXT = auto()
    JSON = auto()
    SOME_OTHER_FORMAT = auto()

This way, the signature is easy to maintain & extend and it will remain readable:

def generate_report(output_path: Path, fmt: OutFormat = OutFormat.TEXT) -> None:
    ...

generate_report("report.txt", OutFormat.JSON)

Previous link Next link

Think of a number between 1 and 10. Multiply it by 9 and subtract 1. Now close your eyes. It got dark, didn't it?

mathspp
  • Blog
    • Pydon'ts
    • Problems
    • TIL
    • Twitter threads
  • Books
  • Talks
  • Trainings
    • Advanced iteration
    • Python for scripting and automation
    • Rust for Python developers
  • Courses
  • About