I was reading through the python docs for how import is resolved and found this
... the interpreter first searches for a built-in module with that name. These module names are listed in sys.builtin_module_names. If not found, it then searches for a file named spam.py in a list of directories given by the variable sys.path. sys.path is initialized from these locations:
The directory containing the input script (or the current directory when no file is specified).
PYTHONPATH (a list of directory names, with the same syntax as the shell variable PATH). ...
So python first looks into sys.builtin_module_names and then into sys.path. So I checked sys.builtin_module_names on my OS (Mac).
>>> sys.builtin_module_names
('_abc', '_ast', '_codecs', '_collections', '_functools', '_imp', '_io', '_locale', '_operator', '_signal', '_sre', '_stat', '_string', '_suggestions', '_symtable', '_sysconfig', '_thread', '_tokenize', '_tracemalloc', '_typing', '_warnings', '_weakref', 'atexit', 'builtins', 'errno', 'faulthandler', 'gc', 'itertools', 'marshal', 'posix', 'pwd', 'sys', 'time')
>>> 'os' in sys.builtin_module_names
False
Since, os is not in sys.builtin_module_names, a file named os.py in the same directory as my python file should take precedence over the os python module.
I created a file named os.py in a test directory with the following simple code:
#os.py
def fun():
print("Custom os called!")
And created another file named test.py which imports os
#test.py
import sys
print("os in sys.builtin_module_names -", 'os' in sys.builtin_module_names)
print("First directory on sys -", sys.path[0])
import os
print("source file of the imported os -", os.__file__)
print(os.fun())
This is the output of test.py
> python3 test.py
os in sys.builtin_module_names - False
First directory on sys - /Users/dhruv/Documents/test
source file of the imported os - /opt/homebrew/Cellar/[email protected]/3.13.1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/os.py
Traceback (most recent call last):
File "/Users/dhruv/Documents/test/test.py", line 9, in <module>
print(os.fun())
^^^^^^
AttributeError: module 'os' has no attribute 'fun'
Why is the python os module called?