Registry / testing / import-linter

import-linter

JSON →
library2.13pypypi✓ verified 23d ago

Import Linter is a command-line tool designed to lint your Python architecture by imposing constraints on the imports between your Python modules. It analyzes imports against a set of rules defined in a configuration file, helping to enforce specific architectural styles in complex codebases. The library also provides a browser-based user interface for exploring the architecture of any Python package. It is actively developed, with the current version being 2.11.

pip install import-linter
INSTALL
IMPORT
SIG · IMPORT-LINTER
I
import-linter
testingpythonv2.13
Install
2.8s avg
Import
Disk
35MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v2.13 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.95 runs
installs and imports cleanly · install 0.0s · import 0.000s · 39.6MB
glibc
py 3.103.95 runs
installs and imports cleanly · install 2.8s · import 0.000s · 40MB
35MB installed
● package 35MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

CLI
lint-imports
The primary way to use Import Linter is via its command-line interface.
lint_imports function
from importlinter.cli import lint_imports
For programmatic usage, e.g., integrating into unit tests, this function can be imported.

Install `import-linter`, then create a `.importlinter` file (or `pyproject.toml`/`setup.cfg`) in your project's root. Define your contracts, specifying rules like 'forbidden' or 'layers'. Finally, run `lint-imports` from your terminal to check for architectural violations. The example demonstrates a forbidden contract preventing imports from `myproject.services` into `myproject.domain`.

# myproject/domain/__init__.py # (empty file) # myproject/domain/models.py # (some model code) # myproject/services/__init__.py # (empty file) # myproject/services/users.py # (some service code) # .importlinter (create this file in your project root) [importlinter] root_package = myproject [importlinter:contract:domain-no-services] name = Domain layer must not import from services layer type = forbidden source_modules = myproject.domain forbidden_modules = myproject.services # Run from your project root in the terminal: # lint-imports
import-linter --version
Debug
Known issues
gotchaImport Linter searches for configuration in `setup.cfg` (INI format), `.importlinter` (INI format), or `pyproject.toml` (TOML format) by default. Ensure your configuration is in one of these files or specify it explicitly using `--config`.
fix
Place your configuration in a recognized file (e.g., `.importlinter` or `pyproject.toml`) or use `lint-imports --config path/to/your_config.ini`.
affects: All versions
gotchaUse `root_package` for a single root package or `root_packages` for multiple root packages in your configuration. Mixing them or omitting both will lead to errors.
fix
Correctly specify either `root_package = my_single_package` or `root_packages = package_one package_two` in your `[importlinter]` section.
affects: All versions
gotchaWhen `include_external_packages = True` is set, external packages are included in the import graph, allowing you to check imports *to* them. However, Import Linter does not statically analyze the *internal* imports of these external packages.
fix
Be aware that contracts will only check imports into external packages, not their internal dependencies.
affects: All versions
gotchaWhen using the `lint_imports` function programmatically (e.g., in unit tests), it returns an exit code (0 for success, non-zero for failure) rather than raising an exception for broken contracts. Directly asserting the return value (e.g., `assert 0 == lint_imports()`) is the expected pattern.
fix
Check the integer return value of `lint_imports()` to determine contract adherence.
affects: All versions
gotchaIn INI-style configuration files (`.importlinter` or `setup.cfg`), each contract section (e.g., `[importlinter:contract:my-contract-id]`) requires a unique identifier (like `my-contract-id`). Duplicate IDs will result in configuration parsing issues.
fix
Ensure each contract section has a unique, arbitrary identifier appended after `importlinter:contract:`.
affects: All versions
Errors
Common errors & fixes
Contract 'My Contract Name' was broken: my_package.module_a imports my_package.module_b
An import within your Python codebase violates one of the architectural contracts defined in your '.importlinter' configuration file.
fix
Refactor the offending import in your Python code to comply with the defined contract, or adjust the contract in your '.importlinter' file if the rule is too strict or incorrect for your intended architecture.
Package 'my_project' could not be found.
The 'root_package' specified in your '.importlinter' configuration file is not correctly installed or not discoverable in the Python environment where 'lint-imports' is being executed.
fix
Ensure the 'root_package' name in '.importlinter' exactly matches an importable Python package. Verify that the project root (containing the specified package) is in your PYTHONPATH, or that the package is installed (e.g., 'pip install -e .') in the environment where the linter runs.
How to ignore specific imports in import-linter?
You have an intentional import that breaks a defined contract, but you want 'import-linter' to disregard this specific instance without altering the general architectural rule.
fix
Add an 'ignore_imports' list to the relevant contract in your '.importlinter' configuration file, specifying the exact import path to be ignored (e.g., 'ignore_imports= my_package.source.importer -> my_package.forbidden.imported').
No error printed for root_package that is a single file module
Import Linter is primarily designed to analyze Python packages (directories containing an '__init__.py' file) and may not correctly process a 'root_package' specified as a single Python file.
fix
Ensure your 'root_package' is structured as a proper Python package (a directory with an '__init__.py' file). If you need to lint a single file, consider wrapping it in a minimal package structure or defining contracts that target specific modules within that file's context rather than attempting to set the single file as a top-level 'root_package'.
Upgrade
Version history
2.13latest on PyPI · released Jul 3, 2026
Audit
Dependencies
pythonrequiredRequired Python version for the library.
Agent activity
7 hits · last 30 days
node
6
Resources
import-linter — pip install import-linter · libregistry