Skip to main content

A production-ready Python import cleaner that detects and removes unused imports while preserving code behavior.

Project description

importclean

A production-ready Python import cleaner. Detect and safely remove unused imports from an entire project while preserving code behavior, formatting, and style.

PyPI Python License: MIT CI Coverage

Features

  • AST + LibCST analysis - detects every import variant without reformatting unrelated code
  • Safe by default - never removes conditional, TYPE_CHECKING, try/except, or star imports
  • Partial cleanup - removes only unused names from from x import a, b, c
  • Alias detection - import numpy as np is kept when np is used
  • Duplicate removal - collapses repeated identical import statements
  • Circular import detection - finds cycles across the whole project
  • Dependency graph - renders ASCII trees and Graphviz .dot files
  • Heavy import suggestions - recommends lazy imports for expensive modules
  • Import sorting - PEP 8 / isort-compatible grouping
  • Post-clean validation - every modified file is re-parsed and compiled; originals are restored on failure
  • Multiprocessing - scales to thousands of files
  • Plugin system - add custom rules for project-specific policies
  • .importclean.toml configuration

Installation

pip install importclean

For development:

git clone https://github.com/Madhav703/importclean
cd importclean
pip install -e ".[dev]"

Quick Start

CLI

importclean .

importclean . --dry-run

importclean . --check

# Show unified diffs
importclean . --diff

# Print import dependency graph
importclean . --graph

# Output results as JSON
importclean . --json

# Print statistics only
importclean . --stats

# Verify all files are syntactically valid
importclean . --verify

# Sort imports in PEP 8 order
importclean . --sort

# Write dependency graph as Graphviz .dot
importclean . --dot graph.dot

# Clean a single file
importclean myfile.py

# Verbose output (per-file details)
importclean . -v

Python API

from importclean import clean_project, clean_file

# Clean an entire project (dry run)
report = clean_project(
    path=".",
    dry_run=True,
    safe_mode=True,
)
print(report.summary())

# Clean a single file
file_report = clean_file("src/mymodule.py", dry_run=False)
print(f"Removed {len(file_report.unused)} unused imports")

Configuration

Create .importclean.toml in your project root:

ignore = [
    ".venv",
    "tests",
    "migrations",
]

safe_mode      = true
sort_imports   = true
remove_unused  = true
workers        = 4

Safety Guarantees

importclean will never:

  • Remove an import that is actually used
  • Remove star imports (from x import *)
  • Remove __future__ imports
  • Remove TYPE_CHECKING-guarded imports
  • Remove try/except-wrapped imports
  • Save a file that fails ast.parse() or compile() after transformation
  • Alter any code outside of import statements

If post-clean validation fails, the original file is restored automatically and the error is reported.

What Gets Removed

Pattern Behavior
import os (unused) Removed
import os (used) Kept
import numpy as np + np.array(...) Kept
from os import path, mkdir (only path used) mkdir removed
from os.path import * Never removed
Duplicate import os Second occurrence removed
if TYPE_CHECKING: from x import T Never removed
try: import ujson as json Never removed

Plugin System

import ast
from typing import Optional
from importclean import clean_project
from importclean.models import ImportInfo
from importclean.plugins.base import BaseRule, RuleResult
from importclean.plugins.registry import PluginRegistry

class NoPickleRule(BaseRule):
    name = "no-pickle"

    def check(self, node: ImportInfo, tree: ast.Module) -> Optional[RuleResult]:
        if node.module == "pickle":
            return RuleResult(
                import_info=node,
                message="Prefer json or msgpack over pickle.",
                should_remove=False,
            )
        return None

registry = PluginRegistry()
registry.register(NoPickleRule)

report = clean_project(".", dry_run=True, registry=registry)

Development

# Run tests
pytest

# Run tests with coverage
pytest --cov=importclean --cov-report=term-missing

# Lint
ruff check importclean tests

# Type check
mypy importclean

# Format
black importclean tests

License

MIT - see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

importclean-0.1.0.tar.gz (26.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

importclean-0.1.0-py3-none-any.whl (33.2 kB view details)

Uploaded Python 3

File details

Details for the file importclean-0.1.0.tar.gz.

File metadata

  • Download URL: importclean-0.1.0.tar.gz
  • Upload date:
  • Size: 26.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for importclean-0.1.0.tar.gz
Algorithm Hash digest
SHA256 fbfca8b21d4eb944f2faa58c189e71c28768686cd4514f233e6d4b6ffce57a60
MD5 efacdf608fb355c0e7d9383b6cd03296
BLAKE2b-256 e548da17a47364dcfdcaf24507295a1752bc5dbb161fc97913d015c6efdb3785

See more details on using hashes here.

File details

Details for the file importclean-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: importclean-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 33.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for importclean-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1c7856a67c1b2810a55b7882702cadb31ab2e873a21856bbb67269395d2bd5ff
MD5 28d63e50e016bab5872f7ac471550b26
BLAKE2b-256 737e246198b7770f72e1a5b960248ce74a41b50b187cc85636214fdf629b8175

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page