AttributeError: module 'X' has no attribute 'Y'
1 · The lesson
readWhat this error means
You imported a module successfully, but the function or class you tried to use isn't inside it. Python found the module file, just not the name you asked for. This is different from ModuleNotFoundError — the module loaded fine; only the thing inside it is missing.
When you see it
Traceback (most recent call last): File "main.py", line 2, in <module> os.fakeattr() AttributeError: module 'os' has no attribute 'fakeattr'
Why it happens
Five common causes, roughly in order of frequency:
1. Typo or wrong case. os.getEnv instead of os.getenv.
2. Version mismatch. The function exists in a newer (or older) version of the library. np.float was removed in NumPy 1.20; asyncio.coroutine was removed in Python 3.10.
3. Wrong module. You confused two libraries with similar names — pickle vs cPickle, urllib vs urllib2 vs urllib3, Image (PIL) vs image (matplotlib).
4. Circular import. Module a imports b which imports a again — at the moment the second import runs, a is only half-loaded and the name you want hasn't been defined yet.
5. Local file shadowing the real library. You have a file called random.py in your project, so import random; random.choice(...) looks inside your file, not the stdlib.
How to fix it
Check the spelling against the official docs, and use dir(module) to see what's actually there:
import os print([name for name in dir(os) if name.startswith("get")])
Pin or upgrade the library version if the function was added/removed:
pip install "numpy>=1.20" pip show numpy # check installed version
Rename a local file that shadows the stdlib:
mv random.py my_random.py rm random.pyc __pycache__/random.*
Break the circular import by moving the shared import inside a function, or by restructuring so neither module depends on the other at import time:
def use_b(): from b import helper # import lazily, inside the function helper()
Use getattr with a default when you genuinely don't know whether the attribute exists across versions:
fn = getattr(some_module, "new_api", some_module.old_api)
setup added so this can run · defines some_module
# Lightweight mock for objects whose attributes/methods aren't critical class _AutoMock: def __init__(self, name='mock'): self._name = name def __getattr__(self, k): return _AutoMock(self._name + '.' + k) def __call__(self, *a, **kw): print('-> ' + self._name + '() called') return _AutoMock(self._name + '()') def __repr__(self): return '<mock ' + self._name + '>' def __str__(self): return '<mock ' + self._name + '>' def __bool__(self): return True def __iter__(self): return iter([]) def __len__(self): return 0 def __getitem__(self, k): return _AutoMock(self._name + '[...]') def __setitem__(self, k, v): pass def __enter__(self): return self def __exit__(self, *a): return False async def __aenter__(self): return self async def __aexit__(self, *a): return False def __add__(self, o): return self def __radd__(self, o): return self def __sub__(self, o): return self def __mul__(self, o): return self def __rmul__(self, o): return self def __truediv__(self, o): return self def __eq__(self, o): return isinstance(o, _AutoMock) def __hash__(self): return hash(self._name) def __lt__(self, o): return True def __le__(self, o): return True def __gt__(self, o): return False def __ge__(self, o): return False def __mro_entries__(self, bases): return (object,) some_module = _AutoMock('some_module')
When you'd actually see this in real code
- You wrote
np.float64correctly but a tutorial used the removednp.floatalias. - A
requests.sessionlowercase typo when you meantrequests.Session. - A file named
email.pyin your project breaksimport emailfrom the stdlib. - After upgrading Django from 3.x to 4.x,
django.utils.translation.ugettextis gone (renamed togettext). - A circular import between
models.pyandviews.pyin a Flask/Django app.
Related errors
ModuleNotFoundError: No module named 'X'— the whole module isn't installed.- TypeError: 'X' object is not callable — the name exists but you called something that isn't a function.
- NameError: name 'X' is not defined — you forgot to import.
See Also
- All Python errors — the full index, by type and by when it happens.
- Imports cheat sheet
- Virtual environments
- Packaging (tutorial)