Skip to main content

How to Check Import Source Path in Python

When working with complex Python environments, especially those involving virtual environments, local packages, or multiple versions of the same library, it is crucial to verify exactly where a module is being loaded from. A common bug arises when Python imports a local file (shadowing) instead of the intended library, or vice versa.

This guide explains how to inspect a module's location using the __file__ attribute and how to programmatically verify if it matches an expected path.

Using the __file__ Attribute

Most user-defined and third-party modules in Python have a __file__ attribute. This attribute contains the filesystem path to the file that was loaded.

Basic Inspection

To find out where a module resides, simply import it and print this attribute.

import os
import random

# ✅ Inspecting the location of standard library modules
print(f"OS module location: {os.__file__}")
print(f"Random module location: {random.__file__}")

Output (Example on Linux):

OS module location: /usr/lib/python3.10/os.py
Random module location: /usr/lib/python3.10/random.py

Comparing Paths Safely

A direct string comparison (e.g., module.__file__ == '/path/to/file.py') is risky because file paths can be relative, absolute, or contain symbolic links. To verify a path programmatically, you must normalize both the actual and expected paths.

Validating the Source

Use os.path.abspath() and os.path.realpath() to resolve symlinks and ensure absolute paths before comparing.

import os
import my_module # Assume this is a local module you created

# Define where you EXPECT the module to be
# e.g., /home/user/project/my_module.py
expected_path_raw = "./my_module.py"

# Normalize the expected path
expected_path = os.path.abspath(expected_path_raw)

# Normalize the actual path from the module
try:
actual_path = os.path.abspath(my_module.__file__)

# ✅ Robust Comparison
if actual_path == expected_path:
print(f"Success: Module imported from {actual_path}")
else:
print(f"Warning: Module imported from unexpected location: {actual_path}")
print(f"Expected: {expected_path}")

except AttributeError:
print("Error: This module does not have a __file__ attribute.")
note

If using Python 3.4+, the pathlib library is often preferred over os.path. You can use pathlib.Path(module.__file__).resolve() to achieve the same result in an object-oriented manner.

Handling Built-in Modules

Not all modules have a __file__ attribute. Built-in modules (written in C and compiled into the Python interpreter) like sys or time often do not point to a file on the disk.

The Error

Attempting to access __file__ on a built-in module raises an error.

import sys

try:
# ⛔️ Incorrect: Built-in modules usually don't have a file path
print(sys.__file__)
except AttributeError as e:
print(f"Error: {e}")

Output:

Error: module 'sys' has no attribute '__file__'

The Solution

Use getattr to safely access the attribute, or check the module's string representation, which usually indicates if it is built-in.

import sys
import os

def get_module_location(mod):
# ✅ Correct: Safe access with a default value
location = getattr(mod, '__file__', '(built-in)')
return location

print(f"Sys location: {get_module_location(sys)}")
print(f"OS location: {get_module_location(os)}")

Output:

Sys location: (built-in)
OS location: /usr/lib/python3.10/os.py

Debugging Search Paths

If a module is not being imported from the specific path you expect, it is likely due to the order of directories in sys.path. Python scans this list from the beginning and stops at the first match.

import sys

# Print the search order
print("Python module search order:")
for i, path in enumerate(sys.path):
print(f"{i}: {path}")
warning

The first entry in sys.path is usually the directory of the script being run (or the current working directory). If you create a file named email.py or code.py in your local folder, it will shadow (override) the standard library modules of the same name, causing import errors.

Conclusion

To verify if a module is imported from a specific path:

  1. Access module.__file__: This gives you the path of the loaded source file.
  2. Normalize Paths: Use os.path.abspath() or pathlib.Path.resolve() to ensure you are comparing absolute paths, resolving any symlinks or relative references.
  3. Handle Built-ins: Remember that built-in C modules (sys, math) do not have a __file__ attribute; check for this using getattr or try-except blocks.