We’ve all been there: on boolean environment variables.

This is a part of the 100 Days To Offload challenge.

I’m looking to hire a full-time junior Django developer on contract residing in any timezone from UTC+05:00 to UTC+08:00. Apply here.

Django has a nice settings API.

If you use django-admin‘s startproject command, the default value for DEBUG would be set to: True. The boolean True.

So it’s up to you to get this production ready, where it must be False.

One might think, if they are using a .env file, that setting it as False and retrieving it from the environment would work:

# .env
DEBUG=True
# settings.py
import os
DEBUG = os.getenv("DEBUG", False)

No harm, right? If we have a DEBUG value in the environment, set that. If not, default to False.

Except, there is harm. I know because I just killed ~2 hours looking elsewhere and thinking about the rest of the infrastructure. When the problem was all along staring at me — classic “I hate programming” style.

Environment values are strings. True becomes "True" and False becomes "False".

And, well, what does "False" evaluate to? True. True.

I’ll give you a moment to re-read that.

Instead, here’s how one would attempt to hack this:

# .env
DEBUG="True"
# settings.py
import os
DEBUG = os.getenv("DEBUG", "False") == "True"

Let’s break it down.

  • By default, DEBUG would be set to "False".
  • So if I specify "True" as my environment value, this expression becomes True.
  • If I specify "False" as my environment value, this express becomes False.

That said, since True or "True" both become "True", using just the boolean looking values in the .env file is not that bad an idea.

In this case, since the default was False, leaving out the env value altogether would have been nice and done. However, I wanted to be explicit — all .env values that can be set, should be set. For sanity’s sake. I’m aware it had the opposite effect in this case… how ironical. πŸ˜… Don’t be me: get a good night’s sleep.

Do you know of an objectively better solution? Please let me know. πŸ˜„

P.s. This is me documenting in public and pretty much for my future self.