bool("False") is True — the STRING is non-empty; only the empty string is falsy
bool(xx — Any value. No argument returns False. Objects are tested via __bool__() (if defined), then __len__() (0 is falsy), then default truthy.type: Any · default: False=False)
→ bool
Demo
Live evaluation
Try:
Inputs
xstrany value
Output
bool('0')
True
The demo passes text through the input, so most cases test string truthiness — the string "0" and the string "False" are BOTH truthy because they are non-empty. Only the empty string is falsy. In real code bool() also handles numbers, lists, dicts, sets, and custom objects via their __bool__ or __len__ methods.
Parameters
Name
Type
Required
Description
x
Any
no (False)
Any value. No argument returns False. Objects are tested via __bool__() (if defined), then __len__() (0 is falsy), then default truthy.
Return value
bool — True or False. Falsy values: 0, 0.0, "", [], (), {}, set(), None, False, and objects whose __bool__ or __len__ returns falsy. Everything else is truthy.
Common patterns
Coerce to strict True/False
Ensures downstream code sees a real bool, not a truthy string or list.
active = bool(user_input) # store True or False, not the raw value
Filter truthy items
filter(None, iterable) is idiomatic for "keep truthy items".
kept = list(filter(None, items))
Custom __bool__ on a class
Objects can define their own truthiness — falls back to __len__ if absent.
The rule is emptiness, not semantics. The string "False" is a non-empty string — Python does not read English. Parsing user input to a real bool needs an explicit mapping.
Assumed parse
is_admin = bool(request.form["is_admin"]) # user sent "False"
Truthiness of a container tests LENGTH, not contents. A list with a single zero is still non-empty, therefore truthy.
Length-based
ifbool(items):
... # runs for [0], [False], [None]
runs even when contents are all falsy
Test contents
ifany(items):
... # only if at least one is truthy
runs only when a truthy item exists
3. bool is a subclass of int — True == 1, False == 0
True and False are literal integers under the hood. Arithmetic with bools works — sometimes usefully (sum a list of bools for a count), sometimes surprisingly.
Weird types
True + True + False
2 # integer arithmetic
Use it deliberately
count = sum(x > 0forxinitems)
idiomatic count of matches
4. `is True` and `is False` almost never match user expectations
A truthy value is not the same as the True singleton. `if x is True:` fails for 1, "yes", or any custom truthy object.
Identity check
ifauthenticatedisTrue:
... # misses truthy 1
branch skipped for 1
Truthiness
ifauthenticated:
... # standard truthiness
covers all truthy values
When to use
Use it
Storing a strict True/False in place of an arbitrary truthy/falsy value
Filtering truthy items — filter(None, iterable) or bool() in a comprehension
Testing a custom object's __bool__ method explicitly
Counting matches — `sum(cond(x) for x in items)` relies on True == 1
Reach for something else
Parsing "true" / "false" strings from user input → explicit comparison
Testing whether a container has truthy CONTENTS → any() instead
`if x is True` — use plain `if x`
Comparing custom-object truthiness across types → be explicit
Notes
Complexity
O(1) for most types; O(n) if __len__ walks a collection
Return
bool — always the True or False singleton
CPython impl
Objects/boolobject.c :: bool_new — dispatches to type's __bool__ then __len__
None at all. bool is a SUBCLASS of int, and it adds nothing — every method you can call on True or False is int's: bit_length, bit_count, to_bytes, from_bytes, as_integer_ratio, is_integer and conjugate. They are documented on the int pages, and they behave exactly as they would on 1 and 0. Note that they return ints, not bools, so True.conjugate() is 1 rather than True.