2026년 11월 2일 월요일

When should I use store_true, store_false, or BooleanOptionalAction?

Use store_true for a single switch that turns a feature on, store_false for a single switch that turns it off, and BooleanOptionalAction when users should see both positive and negative forms of the same setting. These actions take no true or false value after the option. Their defaults and Python version requirements determine which interface is appropriate.

When should I use store_true, store_false, or BooleanOptionalAction?
A reading map of the checks explained below.

Choose by the command users should type

If the normal state is disabled, a positive --enabled switch with action='store_true' is direct: omission yields False and presence yields True. For an option named --disable-cache, action='store_true' would set disable_cache to True, which may be exactly what the program needs, although the stored name describes disabling rather than cache state. Choose the destination and help wording so the value has a clear meaning.

If the normal state is enabled and one switch should turn it off, use a negative name such as --no-cache with action='store_false', optionally setting dest='cache'. Omission then gives cache=True and presence gives cache=False. This is useful when only the disabling operation needs a command-line spelling.

Sources: argparse — Parser for command-line options, arguments and subcommands — action; dest

Compare the three interfaces

BooleanOptionalAction suits a setting users may deliberately enable or disable on separate invocations. Adding --cache creates --cache and --no-cache, which store True and False. The documented class was added in Python 3.9, so choose another interface when supporting older Python versions. Unlike the two store actions, its documented default is not an opposite boolean; specify default=True or default=False when the application has a settled starting state.

This table assumes the declarations shown and no parser-wide override. It compares the resulting cache attribute so the choice is about user-facing syntax and omitted-option meaning, not about different variable names.

Compare the three interfaces
DeclarationOmittedAccepted flag and result
add_argument('--cache', action='store_true')False--cache gives True
add_argument('--no-cache', dest='cache', action='store_false')True--no-cache gives False
add_argument('--cache', action=argparse.BooleanOptionalAction, default=None)None--cache gives True; --no-cache gives False

Sources: argparse — Parser for command-line options, arguments and subcommands — action; default; class argparse.BooleanOptionalAction

Set omission and conflict rules deliberately

A flag is complete by itself. Supplying --cache false to one of these declarations does not convert false into a boolean; with no other positional argument to receive it, parse_args reports an unrecognized argument. If callers must pass a text value after --cache, use the strict converter in the companion article instead.

Pick an omitted-option value for the application, not merely for convenience. A boolean default says what happens when the user says nothing. A None default can preserve the distinction between no command-line preference and an explicit positive or negative choice, which is useful when a later configuration source supplies the baseline. If both directions are exposed with BooleanOptionalAction, decide how the application should handle both forms in one invocation; for an interface that must reject conflicting choices, define separate options inside a mutually exclusive group. Argparse documents that such a group rejects simultaneous options. Review the generated help so users can see the accepted spelling and the effect of omission.

Sources: argparse — Parser for command-line options, arguments and subcommands — default; class argparse.BooleanOptionalAction; Mutual exclusion, Argparse Tutorial — Introducing Optional arguments

Primary sources checked: 2026-11-02. Prepared with AI assistance and a separate evidence review. This is documentation-based guidance, not a hands-on test or performance benchmark.

Read the companion guide

Why does argparse parse --enabled False as True?

Because type=bool applies Python’s truth test to the string False, and that string is nonempty. To accept explicit true or false values, use a converter that recognizes only the spellings your command promises to support. The example below accepts true and false, in any letter case; other words are errors.

Why does argparse parse --enabled False as True?
A reading map of the checks explained below.

Diagnose the value that reaches bool

With parser.add_argument('--enabled', type=bool), argparse passes the text following --enabled to bool. Python considers a nonempty string true, so False, false, and even no all produce True. The documented argparse example shows this exact result for False. An empty string is false, but that is rarely the intended command-line spelling for a disabled setting.

This diagnosis applies to an option that consumes a value. If the intended interface is a switch users write without a following word, use a flag action; the companion article compares those actions. Changing the default does not repair type=bool when the user supplies False, because the supplied text is still converted.

Sources: argparse — Parser for command-line options, arguments and subcommands — type, Built-in Types — Truth Value Testing — Truth Value Testing

Accept a defined true or false vocabulary

Use a callable converter and raise argparse.ArgumentTypeError for anything outside its vocabulary. Here is a runnable example for Python 3.13; it is illustrative code, not a reported local test:

import argparse def parse_bool(value): normalized = value.casefold() if normalized == 'true': return True if normalized == 'false': return False raise argparse.ArgumentTypeError('expected true or false') parser = argparse.ArgumentParser() parser.add_argument('--enabled', type=parse_bool, default=None) args = parser.parse_args() print(args.enabled)

This policy deliberately rejects 1, 0, yes, no, and blank text. Add spellings only if they belong in your interface contract. The type hook receives one string, and argparse documents ArgumentTypeError as a supported way to report a conversion failure. With the ordinary parser settings, invalid arguments produce usage and an error and exit with status 2. The message above states the accepted words without silently treating an unfamiliar value as true.

Sources: argparse — Parser for command-line options, arguments and subcommands — type; exit_on_error, Built-in Types — Truth Value Testing — str.casefold

Read the input and result matrix

The following results are derived from the displayed converter and the documented parser rules; they were not executed for this article. The explicit default=None keeps omission distinct from an explicit false value. If your application should start disabled, change that default to False. If it must know whether the user made a choice, retain None and check it separately from truthiness.

The table concerns the converter above, not type=bool. Its error row means argparse reports the converter’s message; exact surrounding usage text depends on the program name and other arguments.

Read the input and result matrix
InputIllustrative resultInterpretation
option omittedNoneNo explicit choice
--enabled trueTrueEnabled explicitly
--enabled FALSEFalseDisabled explicitly
--enabled maybeParser error: expected true or falseRejected vocabulary
--enabled with no valueParser error: expected one argumentMissing value

Sources: argparse — Parser for command-line options, arguments and subcommands — default; type; Invalid arguments

Primary sources checked: 2026-11-02. Prepared with AI assistance and a separate evidence review. This is documentation-based guidance, not a hands-on test or performance benchmark.

Read the companion guide