Maintenance

Site is under maintenance — quizzes are still available.

Go to quizzes
Sponsored Reserved space — layout preview until AdSense is connected

Find Unused Python Packages Automatically

Scan a Python project's source files for imports and list installed packages not imported anywhere.

Medium Python 3.9+ Jun 28, 2026 Automation & scripting 2 views 0 copies

Python code

40 lines
Python 3.9+
import pkg_resources
import ast
import os
import sys
from pathlib import Path

def find_imports_in_project(project_dir="."):
    imports = set()
    for py_file in Path(project_dir).rglob("*.py"):
        try:
            with open(py_file, "r") as f:
                tree = ast.parse(f.read())
            for node in ast.walk(tree):
                if isinstance(node, ast.Import):
                    for alias in node.names:
                        imports.add(alias.name.split(".")[0])
                elif isinstance(node, ast.ImportFrom):
                    if node.module:
                        imports.add(node.module.split(".")[0])
        except (SyntaxError, UnicodeDecodeError):
            pass
    return imports

def get_installed_packages():
    return {pkg.key for pkg in pkg_resources.working_set}

def find_unused_packages(project_dir="."):
    installed = get_installed_packages()
    used = find_imports_in_project(project_dir)
    unused = installed - used
    return sorted(unused)

if __name__ == "__main__":
    unused = find_unused_packages()
    if unused:
        print("Unused packages found:")
        for pkg in unused:
            print(f"  - {pkg}")
    else:
        print("No unused packages detected.")

Output

stdout
Unused packages found:
  - requests
  - numpy
  - flask

How it works

The script uses pkg_resources.working_set to list all installed packages. It then parses every .py file in the project directory with the ast module, collecting top-level module names from import and from ... import statements. Only the base package name (before the first dot) is kept to match against installed package keys. The set difference between installed and used packages reveals which packages are potentially unnecessary. This is a static analysis approach and won't catch packages used via dynamic imports (importlib) or string-based imports.

Common mistakes

  • Ignoring subpackages — only the top-level package name is collected, so `pandas.core` becomes just `pandas`.
  • Not handling virtual environments — the script checks globally installed packages; run it inside the target environment's Python.
  • Missing `__init__.py` imports — packages imported indirectly through package `__init__` files may be missed.
  • Forgetting namespace packages — `pkg_resources` may not list them correctly in some setups.

Variations

  1. Use `importlib.metadata.distributions()` (Python 3.8+) instead of `pkg_resources`.
  2. Add a `--exclude` CLI option to skip known packages like `pip`, `setuptools`.

Real-world use cases

  • Cleaning up a requirements.txt before deploying to production to reduce attack surface.
  • Auditing dependency bloat in CI after merging a large feature branch.
  • Documenting dead dependencies in legacy projects before a major refactor.

Sponsored

Sponsored Reserved space — layout preview until AdSense is connected

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Automation & scripting

Related tutorials and quizzes for this topic.