python/cpython · error · NotImplementedError

.__call__() not defined

Error message

.__call__() not defined

What it means

argparse.Action is an abstract base: its __call__ raises NotImplementedError('.__call__() not defined'). If a subclass (custom or from a library) does not override __call__, the error surfaces at parse time when the option the action is bound to actually appears on the command line.

Source

Thrown at Lib/argparse.py:1043

            'option_strings',
            'dest',
            'nargs',
            'const',
            'default',
            'type',
            'choices',
            'required',
            'help',
            'metavar',
            'deprecated',
        ]
        return [(name, getattr(self, name)) for name in names]

    def format_usage(self):
        return self.option_strings[0]

    def __call__(self, parser, namespace, values, option_string=None):
        raise NotImplementedError('.__call__() not defined')


class BooleanOptionalAction(Action):
    def __init__(self,
                 option_strings,
                 dest,
                 default=None,
                 required=False,
                 help=None,
                 deprecated=False):

        _option_strings = []
        neg_option_strings = []
        for option_string in option_strings:
            _option_strings.append(option_string)

            if len(option_string) > 2 and option_string[0] == option_string[1]:
                # two-dash long option: '--foo' -> '--no-foo'

View on GitHub (pinned to bc6749cc3b)

Solutions

  1. Implement __call__(self, parser, namespace, values, option_string=None) in the subclass, typically calling setattr(namespace, self.dest, values).
  2. Subclass _StoreAction or _StoreConstAction instead of Action when you only need storing behavior.
  3. Smoke-test the CLI with the actual flag in tests so a missing __call__ is caught before release.

Example fix

# before
class VerboseAction(argparse.Action):
    pass  # NotImplementedError at parse time

# after
class VerboseAction(argparse.Action):
    def __call__(self, parser, namespace, values, option_string=None):
        setattr(namespace, self.dest, values.upper())
Defensive patterns

Strategy: type-guard

Validate before calling

import argparse

def action_implements_call(action_cls) -> bool:
    return action_cls.__call__ is not argparse.Action.__call__

Type guard

def is_callable_action(action: argparse.Action) -> bool:
    return type(action).__call__ is not argparse.Action.__call__

Try / catch

try:
    args = parser.parse_args(['--flag'])
except NotImplementedError as e:
    if '.__call__() not defined' in str(e):
        raise RuntimeError(f'action for --flag is incomplete: implement __call__') from e
    raise

Prevention

When it happens

Trigger: class MyAction(argparse.Action): pass used in add_argument('--x', action=MyAction), then parsing '--x' on the command line; subclassing Action but naming the handler _call__ or mis-indenting it so it is not an override.

Common situations: First attempts at custom argparse actions; refactors that rename __call__ to something else; incomplete copy-paste of an example action.

Related errors


AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14). Data as JSON: /api/errors/29bc8a0dba95b3fa. Report an issue: GitHub.