Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

Python has exactly two Boolean values, True and False, and both are capitalized. When you check a value, first decide which question you are asking. Is the value truthy enough to pass an if test? Is it the True singleton? Is it a bool at all? These questions have different answers for values such as 1, "yes" and [], so picking the wrong check gives wrong results even when the code runs without errors.

The two Boolean values

The built-in bool type has exactly two constant instances, True and False. The Python Software Foundation’s Built-in Types reference (Python 3.14.7 documentation, Boolean Type section) states this directly. Lowercase true and false are not Python constants. Writing them raises a NameError, because Python looks for a variable with that name and finds none.

Truthiness: the check most conditions need

An if or while condition tests the truth value of an expression. It does not require the value to be literally True or False.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
flag = True

if flag:                 # asks whether flag is truthy
    print("enabled")

items = [3, 1, 2]

if items:                # non-empty list is truthy
    print("has items")

Which values count as false

By default, every object is true. A class changes that by defining __bool__() to return False, or by defining __len__() to return zero. The Python documentation lists these values as false:

  • None
  • False
  • numeric zero, such as 0, 0.0 and 0j
  • empty strings, such as ""
  • empty built-in collections, such as [], (), {} and set()

Because of this, if items: asks whether the list is non-empty. It does not ask whether the list is the Boolean True, which is a different question entirely.

How and, or and not handle values

and and or use short-circuit evaluation. They stop as soon as the result is known, and they return one of their operands, which may not be a Boolean. not always returns True or False.

user_name = ""
display_name = user_name or "guest"   # "" is falsy, so "guest" is returned
print(display_name)                   # guest

print(not "")                         # True
print(not [1])                        # False

For logical operations, the Python documentation recommends and, or and not rather than the bitwise operators &, | and ^. Using the keyword forms also makes the intent clearer to anyone reading the code.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Identity: value is True

The is operator tests identity, meaning whether two names refer to the same object. Because True is a single object, value is True passes only for that exact Boolean. Use it when a truthy stand-in must be rejected.

x = 1
print(x is True)    # False: 1 is an int object, not the True singleton
print(x == True)    # True: 1 compares equal to True

Type membership: isinstance() and type()

Two checks ask whether a value is a Boolean by type, and they differ in how they treat subclasses:

  • isinstance(value, bool) returns True if the value is an instance of bool, including instances of any subclass of bool.
  • type(value) is bool returns True only when the exact type is the built-in bool. It excludes subclasses.

In most code the two behave the same, because the built-in bool is the only type in normal use. Choose isinstance() as the default. Reach for type(value) is bool only when the exact built-in type is a requirement.

bool is a subclass of int

Because bool inherits from int, isinstance(True, int) returns True. The documentation notes that False and True behave like 0 and 1 in some numeric contexts, but it discourages relying on that behavior. The practical consequence is that an integer check also accepts Booleans. If your code validates integers and must reject True, test for bool first:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
def read_count(value):
    if isinstance(value, bool) or not isinstance(value, int):
        raise TypeError("count must be an int, not a bool")
    return value

Why value == True is usually the wrong test

The == operator compares values, not types or identity. Since 1 == True and 0 == False evaluate to True, an equality test accepts integers that happen to equal 1. It also gives the same result for 1.0. Use is True or an isinstance() check when you need the Boolean itself, and reserve == for comparing values where numeric equality is what you mean.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Choosing the right check

The table below shows how each check responds to four sample values. Each row answers a different question.

Check Question it answers 1 True "yes" []
if value: Is the value truthy? Pass Pass Pass Fail
value is True Is it the True singleton? Fail Pass Fail Fail
value == True Does it compare equal to True? Pass Pass Fail Fail
isinstance(value, bool) Is it an instance of bool, or of a subclass? Fail Pass Fail Fail
type(value) is bool Is its exact type the built-in bool? Fail Pass Fail Fail

A practical rule follows from the table. Use if value: when any truthy value should pass. Use isinstance(value, bool) to validate that an argument is a flag. Use value is True when only the exact singleton should pass.

Validating a flag argument

def set_debug(flag):
    if not isinstance(flag, bool):
        raise TypeError("flag must be True or False")
    print("debug mode:", "on" if flag else "off")

set_debug(True)     # debug mode: on
set_debug(1)        # raises TypeError

Performance and version notes

The Python documentation does not present any of these checks as faster than the others, so choose by meaning rather than speed. The behavior described here follows the Python 3.14.7 documentation. Confirm version-specific wording against the current Python documentation before relying on exact phrasing in a project.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Sources

  • Python Software Foundation, Built-in Types — Python 3.14.7 documentation: Truth Value Testing, Boolean Operations, Comparisons, and Boolean Type sections.
  • Python Software Foundation, Expressions — Python 3.14.7 documentation: Identity comparisons.

Documentation retrieved 7 October 2026.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.