Python
programming
module
troubleshooting
source code

How do I find the location of Python module sources?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

To find where a Python module's source code is located on disk, use module.__file__, inspect.getfile(module), or run python -m site to see all module search paths. This is useful for debugging import issues, reading library source code, finding which version of a module is actually imported, and locating configuration files installed alongside packages.

Method 1: module.file

The __file__ attribute contains the path to the module's source file:

python
1import os
2print(os.__file__)
3# /usr/lib/python3.11/os.py
4
5import json
6print(json.__file__)
7# /usr/lib/python3.11/json/__init__.py
8
9import requests
10print(requests.__file__)
11# /home/user/.local/lib/python3.11/site-packages/requests/__init__.py

For packages (directories with __init__.py), __file__ points to __init__.py. The parent directory is the package root.

Handling Missing file

Some built-in modules (written in C) do not have __file__:

python
1import sys
2print(hasattr(sys, '__file__'))  # False — sys is a built-in C module
3
4import math
5print(hasattr(math, '__file__'))  # May be False on some platforms

Check first:

python
1def get_module_path(module):
2    if hasattr(module, '__file__') and module.__file__:
3        return module.__file__
4    return f"{module.__name__} is a built-in module (no file)"
5
6import os, sys
7print(get_module_path(os))   # /usr/lib/python3.11/os.py
8print(get_module_path(sys))  # sys is a built-in module (no file)

Method 2: inspect.getfile()

The inspect module provides a more robust way:

python
1import inspect
2import os
3import json
4import collections
5
6print(inspect.getfile(os))           # /usr/lib/python3.11/os.py
7print(inspect.getfile(json))         # /usr/lib/python3.11/json/__init__.py
8print(inspect.getfile(collections))  # /usr/lib/python3.11/collections/__init__.py
9
10# Works on classes and functions too
11from pathlib import Path
12print(inspect.getfile(Path))  # /usr/lib/python3.11/pathlib.py

inspect.getfile() raises TypeError for built-in modules:

python
1import sys
2try:
3    print(inspect.getfile(sys))
4except TypeError as e:
5    print(e)  # <module 'sys' (built-in)> is a built-in module

Method 3: From the Command Line

pip show

bash
1# Shows package location and metadata
2pip show requests
3
4# Output:
5# Name: requests
6# Version: 2.31.0
7# Location: /home/user/.local/lib/python3.11/site-packages

python -c

bash
1# One-liner to print module path
2python -c "import requests; print(requests.__file__)"
3# /home/user/.local/lib/python3.11/site-packages/requests/__init__.py
4
5python -c "import numpy; print(numpy.__file__)"
6# /home/user/.local/lib/python3.11/site-packages/numpy/__init__.py

python -m site

bash
1# Show all module search paths
2python -m site
3
4# Output includes:
5# sys.path = [
6#     '/home/user/project',
7#     '/usr/lib/python3.11',
8#     '/usr/lib/python3.11/lib-dynload',
9#     '/home/user/.local/lib/python3.11/site-packages',
10#     '/usr/lib/python3.11/site-packages',
11# ]

Method 4: sys.path and Import Search Order

Python searches for modules in directories listed in sys.path:

python
1import sys
2
3for path in sys.path:
4    print(path)
5
6# Output (typical):
7# /home/user/project          (current directory)
8# /usr/lib/python3.11         (standard library)
9# /usr/lib/python3.11/lib-dynload
10# /home/user/.local/lib/python3.11/site-packages  (user packages)
11# /usr/lib/python3.11/site-packages               (system packages)

Python checks these paths in order. The first match wins:

python
# Which 'json' module is actually imported?
import json
print(json.__file__)  # Verifies it's the standard library, not a local file named json.py

Method 5: importlib

python
1import importlib.util
2
3spec = importlib.util.find_spec('requests')
4if spec:
5    print(spec.origin)       # /.../.../requests/__init__.py
6    print(spec.submodule_search_locations)  # Package directories
7
8# Check if a module exists without importing it
9spec = importlib.util.find_spec('nonexistent')
10print(spec)  # None

Finding the Source Directory

python
1import os
2import requests
3
4# Get the directory containing the module
5module_dir = os.path.dirname(requests.__file__)
6print(module_dir)
7# /home/user/.local/lib/python3.11/site-packages/requests
8
9# List files in the module directory
10for f in sorted(os.listdir(module_dir)):
11    print(f)
12# __init__.py
13# adapters.py
14# api.py
15# auth.py
16# ...

Virtual Environment Module Locations

bash
1# Activate a virtual environment
2source venv/bin/activate
3
4# Modules install into the venv's site-packages
5python -c "import requests; print(requests.__file__)"
6# /home/user/project/venv/lib/python3.11/site-packages/requests/__init__.py
7
8# Show all paths
9python -c "import site; print(site.getsitepackages())"
10# ['/home/user/project/venv/lib/python3.11/site-packages']

Common Pitfalls

  • Shadowing standard library modules with local files: A file named json.py or random.py in your project directory shadows the standard library module. Python searches the current directory first, so your local file gets imported instead.
  • Built-in modules have no __file__: Modules like sys, builtins, and sometimes math are implemented in C and compiled into the interpreter. They have no file path. Check hasattr(module, '__file__') before accessing it.
  • Confusing .pyc with .py paths: __file__ may point to a .pyc (compiled bytecode) file instead of the .py source. Use importlib.util.find_spec() which reports the source file, or check if a .py file exists at the same path.
  • Different module paths in virtual environments: A module may be installed globally and in a virtual environment. The path depends on which Python interpreter is active. Always verify with python -c "import x; print(x.__file__)" from the intended environment.
  • Editable installs (pip install -e) point to the source directory: Editable installs symlink to the development directory. The module path reflects the source location, not site-packages, which can be confusing when debugging import issues.

Summary

  • Use module.__file__ for the quickest way to find a module's source file
  • Use inspect.getfile(module) for a more robust alternative that also works on classes and functions
  • Use pip show package_name from the command line to find package location and metadata
  • Use importlib.util.find_spec() to find a module path without importing it
  • Check sys.path to understand the import search order and debug shadowing issues

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.