python/cpython · error · AttributeError
module {__name__!r} has no attribute {name!r}
Error message
module {__name__!r} has no attribute {name!r} What it means
Module-level __getattr__ in argparse handles attribute lookups that normal module content does not define. In current CPython it exists chiefly to serve argparse.__version__ with a PendingDeprecationWarning (removal scheduled for 3.20); any other unknown name raises AttributeError with this message. Code doing getattr(argparse, name) with a dynamic name hits this path constantly.
Source
Thrown at Lib/argparse.py:2976
fmt = fmt.replace('error: %(message)s',
f'{theme.error}error:{theme.reset} {theme.message}%(message)s{theme.reset}')
args = {'prog': self.prog, 'message': message}
self.exit(2, fmt % args)
def _warning(self, message):
theme = self._get_theme(file=_sys.stderr)
fmt = _('%(prog)s: warning: %(message)s\n')
fmt = fmt.replace('warning: %(message)s',
f'{theme.warning}warning:{theme.reset} {theme.message}%(message)s{theme.reset}')
args = {'prog': self.prog, 'message': message}
self._print_message(fmt % args, _sys.stderr)
def __getattr__(name):
if name == "__version__":
warnings._deprecated("__version__", remove=(3, 20))
return "1.1" # Do not change
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
View on GitHub (pinned to bc6749cc3b)
Solutions
- Fix the attribute name (check dir(argparse)); e.g. ArgumentParser, ArgumentError, ArgumentTypeError, BooleanOptionalAction.
- Stop reading argparse.__version__; gate on hasattr(argparse, 'BooleanOptionalAction') or sys.version_info instead.
- For dynamic lookups always use getattr(argparse, name, default) so missing attributes yield your default, not AttributeError.
Example fix
# before
exc = argparse.ArgumentParsingError # AttributeError
ver = argparse.__version__ # deprecated
# after
exc = argparse.ArgumentError
if hasattr(argparse, 'BooleanOptionalAction'):
... Defensive patterns
Strategy: type-guard
Validate before calling
if not hasattr(argparse, 'BooleanOptionalAction'):
raise RuntimeError('this tool requires Python 3.9+ argparse') Type guard
def argparse_attr(name, default=None):
"""Safe attribute access on the argparse module."""
return getattr(argparse, name, default)
# usage
exc = argparse_attr('ArgumentError', RuntimeError) Try / catch
try:
cls = getattr(argparse, name)
except AttributeError:
raise RuntimeError(f'argparse on Python {sys.version_info[:2]} lacks {name}') from None Prevention
- Never read argparse.__version__; gate features with hasattr or sys.version_info.
- Use getattr(argparse, name, default) for every dynamic module lookup.
- Spell-check class names against dir(argparse) when wiring plugins dynamically.
When it happens
Trigger: argparse.__version__ (deprecated shim); getattr(argparse, opt, None) probing for option classes; typos like argparse.ArgumentParsingError (the real name is ArgumentError); hasattr-style feature detection against newer argparse APIs on older interpreters.
Common situations: Feature-detection helpers probing for classes added in newer Pythons (e.g. BooleanOptionalAction on 3.8); version-pinning code reading __version__; misspelled class names in plugins that build parsers dynamically.
Related errors
- module 'collections.abc' has no attribute {attr!r}
- module 'ast' has no attribute {attr!r}
- %r object attribute '__dict__' is read-only
- invalid nargs value
- .__call__() not defined
AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14).
Data as JSON: /api/errors/5bdc6d8b390f34e9.
Report an issue: GitHub.