pythonpython-import

Understanding import in python (initalization of sys.modules)


I recently came to know that modules like os are imported way before a user python program starts running and therfore we cannot import a custom file named os even though it's not in the sys.builtin_module_names. So, I looked into sys.modules right when the python program starts and found os and others modules there.

Python 3.13.1 (main, Dec  3 2024, 17:59:52) [Clang 16.0.0 (clang-1600.0.26.4)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> 'os' in sys.modules.keys()
True
>>> 're' in sys.modules.keys()
True

So, I had few more doubts

  1. Can it be said that because os module is present in the sys.modules at the start of the python program, a file with the same name cannot be imported?
  2. I removed the entry for os in sys.modules using del sys.modules['os'] and then tried to import a file named os.py in my python code and still wasn't able to do so. Why?
    #os.py
    def fun():
        print("Custom os called!")
    
    #test.py
    import sys
    del sys.modules['os']
    import os
    print("source file of the imported os -", os.__file__)
    print(os.fun())
    
    Output
    dhruv@MacBook-Air-2 test  % python3 test.py
    source file of the imported os - /opt/homebrew/Cellar/python@3.13/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 12, in <module>
        print(os.fun())
           ^^^^^^
    AttributeError: module 'os' has no attribute 'fun'
    

Could someone cleary explain the import process? I've already gone through this and this and have build the following the steps for the python import process.

  1. Look through sys.modules
  2. Look through sys.builtin_module_names
  3. Find if there is any frozen module with the name
  4. Go through sys.path

Is there anything else that is missing?


Solution

  • The reason my os.py didn't work was because it is a frozen module in python 3.13. The same code would have called the custom os in python 3.10 as stated by user2357112 in comments. I tried my code with re which is not a frozen module in python 3.13 but is present in sys.modules and it called the custom re file.

    So, it is true that because os was present in sys.modules the custom file was not loaded. And later on as described in my import process, the frozen module took preference over the custom one.