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: here the module loaded fine, and only the name 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
There are five common causes:
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 deprecated in NumPy 1.20 and removed in 1.24. asyncio.coroutine was removed in Python 3.11.
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, and b imports a again. When 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 in the standard library.
How to fix it
Check the spelling against the official docs, and use dir(module) to see which names the module really has:
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 hides a standard library module:
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 really don't know whether the attribute exists in every version you support:
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 see this in real code
- A tutorial uses the removed
np.floatalias. Usefloatornp.float64instead. - A
json.parse(...)call carried over from JavaScript, when Python's function isjson.loads. - A file named
email.pyin your project breaksimport emailfrom the standard library. - 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: for example, when you forgot an import.
See Also
- All Python errors: the full index, by type and by when it happens.
- Imports cheat sheet
- Virtual environments
- Packaging (tutorial)
Found this useful? Share it with a friend who’s learning Python.