Are Booleans Mutable In Python? | Safe Code Facts

No, Python bool objects are immutable; reassignment only binds a name to True or False, it doesn’t change the object.

Python booleans look tiny, but they clear up a lot of confusion about names, objects, identity, and truth checks. A boolean value is either True or False. You can reassign a variable that points to one of them, but you can’t alter the boolean object itself.

That difference matters when you write flags, function defaults, tests, loops, and condition checks. If a line such as done = False later becomes done = True, Python didn’t edit False. It moved the name done so it now refers to True.

Why Boolean Objects In Python Are Not Mutable

A mutable object can be changed in place while keeping the same identity. Lists prove this clearly. You can append to a list, and the list is still the same object. A boolean has no such editable inner part. There’s no method that turns the False object into True, and no slot inside True that you can rewrite.

Python’s own docs say an object’s mutability is determined by its type, and they list numbers, strings, and tuples as immutable. Since bool is a subclass of int, it follows the same fixed-value model. The official Python data model is the cleanest place to verify that rule.

Assignment Changes Names, Not Boolean Objects

Most confusion comes from assignment. In Python, a variable name is a label bound to an object. When you assign a new value to the same name, the old object does not get edited. The name now points somewhere else.

flag = False
print(id(flag))

flag = True
print(id(flag))

The two printed identities will differ because flag has been rebound. This is the same reason x = 1 followed by x = 2 does not mutate the integer 1. The label moves.

True And False Are Fixed Constants

True and False are not ordinary names you can replace. If you try to assign to either one, Python raises a syntax error. The docs for built-in constants state that True and False cannot be reassigned.

True = 1
# SyntaxError: cannot assign to True

That rule protects code from a nightmare scenario where one file could change what truth means for every other file. True stays true, and False stays false.

How Boolean Mutability Differs From List Mutability

The best way to make the rule stick is to compare booleans with types you can change in place. A list has methods that edit its contents. A boolean does not. A dictionary can gain a new pair. A boolean cannot gain a new field or hidden value.

Object Or Action What Happens Mutation?
flag = False The name flag points to False. No
flag = True The name moves from False to True. No
items.append(4) The same list gains a new item. Yes
settings["on"] = True The dictionary gains or changes a stored pair. Yes
count += 1 The name points to a new integer object. No
text += "!" The name points to a new string object. No
truth = bool(value) Python returns either True or False. No
done is True Python checks object identity against True. No

This split helps when debugging. If a list changes after being passed into a function, the function may have edited the same object. If a boolean flag changes after a function call, the name was rebound somewhere, or a new value was returned and assigned.

The bool Type Is A Subclass Of int

Python treats bool as a numeric type with two values. That’s why True == 1 and False == 0 are both true. Still, identity is different from equality. True is not the integer object 1, even if it compares equal in many expressions.

print(True == 1)   # True
print(True is 1)   # False

The official Boolean type docs state that bool is a subclass of int and cannot be subclassed further. That keeps boolean behavior narrow and predictable.

Common Mistakes With Python Boolean Values

New Python users often read boolean reassignment as mutation. That’s a natural slip, since the same name appears on the left side of both lines. The safer mental model is this: names move, mutable containers change, immutable values stay fixed.

Using is When == Reads Better

Use is when you mean object identity. Use == when you mean equal value. For booleans, you often don’t need either one. A condition can read the truth value directly.

if is_ready:
    run_job()

if not is_ready:
    wait()

This reads cleaner than if is_ready == True. It also avoids odd behavior when a value is truthy but not actually the True object.

Changing A Container That Holds A Boolean

A boolean inside a list or dictionary is still immutable. The container may be mutable, though. When you change the stored value, you mutate the container, not the boolean.

state = {"paid": False}
state["paid"] = True

Here, the dictionary changed. False did not become True. The slot named "paid" now points to a different boolean object.

Pattern Better Reading Why It Matters
flag = not flag The name points to the other boolean. No in-place edit occurs.
data["ok"] = False The dictionary entry changes. The container is edited.
return True The function returns the fixed true object. No new boolean is needed.
if value: Python tests truth value. The result is not always a bool object until tested.
bool(value) Python converts truthiness to True or False. The result is one of two fixed objects.

When This Matters In Real Code

Boolean immutability rarely causes bugs by itself. The bugs come from confusing rebinding with in-place change. This shows up in function calls, shared data, and tests.

Function Arguments

Passing a boolean into a function gives that function a local name bound to the same boolean object. If the function reassigns the name, it does not alter the caller’s variable.

def mark_done(done):
    done = True

task_done = False
mark_done(task_done)
print(task_done)  # False

To change the caller’s state, return the new value and assign it, or store the flag inside a mutable container that the function is meant to edit.

Flags In Classes

Object attributes can be rebound too. If self.active changes from False to True, the instance was updated by changing which object the attribute points to. The boolean value still stayed fixed.

class Job:
    def __init__(self):
        self.active = False

    def start(self):
        self.active = True

This is normal Python. The instance is mutable, while the boolean objects used by its attributes are not.

Practical Rules For Cleaner Boolean Code

Use booleans as simple truth flags, not as tiny objects to edit. Name them clearly, return new values from functions, and let containers handle stored state when state must change.

  • Use names such as is_paid, has_access, and can_retry.
  • Prefer if flag: and if not flag: for plain conditions.
  • Return a new boolean from a function when the caller needs an updated flag.
  • Use a dictionary, class, or dataclass when several related flags belong together.
  • Don’t try to subclass bool; Python blocks it.

So, are booleans mutable in Python? No. True and False are fixed bool objects. Your code changes which object a name refers to, or which value a container stores. That single idea clears up most boolean behavior in Python.

References & Sources

  • Python Documentation.“Data Model.”Confirms that mutability is determined by an object’s type and explains object identity, type, and value.
  • Python Documentation.“Built-in Constants.”Confirms that True and False cannot be reassigned in Python code.
  • Python Documentation.“Boolean Type – bool.”Confirms that bool is a subclass of int and that False and True are the two bool instances.