This error draws a line the ModuleNotFoundError page sits on the other side of: the module itself was found and loaded, but the specific name requested is not defined in it. Either the name does not exist in that version (renamed, removed, or never there), or the module was caught mid-initialization by a circular import and the name simply was not defined yet at the moment of asking.
# your project: app.py imports helper from tools.py, # and tools.py imports app back (a circle) from tools import helper Traceback (most recent call last): File "app.py", line 1, in <module> ImportError: cannot import name 'helper' from 'tools' (C:/project/tools.py) # tools was still initializing when the name was asked for
import y; print(y.__file__); print(dir(y)). If the name is absent from dir(), no import spelling will conjure it; if __file__ points somewhere unexpected, a shadowing module is being imported instead.pip show gives the version to check against.from os import path works because path is a submodule; from os import getenv works because it is a function. Asking for a name that lives one level deeper (in a submodule) fails exactly like this; import the submodule path in full.__pycache__ folders if the interpreter seems to import ghosts of the old layout, and confirm the entry point's folder is the one on sys.path you think it is.If dir() shows the name and versions match, yet the import fails intermittently depending on which module runs first, you have an order-dependent circular import that only bites on some entry paths. The deterministic cure is removing the cycle; import order discipline merely hides it until the next entry point appears.
What is the difference between ImportError and ModuleNotFoundError? ModuleNotFoundError (a subclass of ImportError) means the module itself could not be found at all. A plain ImportError with “cannot import name” means the module loaded fine but lacks the requested name, or was caught half-initialized. The remedies differ, so the distinction is worth reading in the message.
Why does the same import work in one file and fail in another? Different entry files put different folders at the front of sys.path and trigger different import orders, so shadowing modules and circular imports can bite from one entry point and not another. Comparing __file__ and the import order between the two runs exposes it.