{"id":2069,"library":"import-linter","title":"Import Linter","description":"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.","status":"active","version":"2.11","language":"en","source_language":"en","source_url":"https://github.com/seddonym/import-linter","tags":["linter","static analysis","architecture","code quality","python"],"install":[{"cmd":"pip install import-linter","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Required Python version for the library.","package":"python","version":">=3.10","optional":false}],"imports":[{"note":"The primary way to use Import Linter is via its command-line interface.","symbol":"CLI","correct":"lint-imports"},{"note":"For programmatic usage, e.g., integrating into unit tests, this function can be imported.","symbol":"lint_imports function","correct":"from importlinter.cli import lint_imports"}],"quickstart":{"code":"# myproject/domain/__init__.py\n# (empty file)\n\n# myproject/domain/models.py\n# (some model code)\n\n# myproject/services/__init__.py\n# (empty file)\n\n# myproject/services/users.py\n# (some service code)\n\n# .importlinter (create this file in your project root)\n[importlinter]\nroot_package = myproject\n\n[importlinter:contract:domain-no-services]\nname = Domain layer must not import from services layer\ntype = forbidden\nsource_modules = myproject.domain\nforbidden_modules = myproject.services\n\n# Run from your project root in the terminal:\n# lint-imports","lang":"python","description":"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`."},"warnings":[{"fix":"Place your configuration in a recognized file (e.g., `.importlinter` or `pyproject.toml`) or use `lint-imports --config path/to/your_config.ini`.","message":"Import 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`.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Correctly specify either `root_package = my_single_package` or `root_packages = package_one package_two` in your `[importlinter]` section.","message":"Use `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.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Be aware that contracts will only check imports into external packages, not their internal dependencies.","message":"When `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.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Check the integer return value of `lint_imports()` to determine contract adherence.","message":"When 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.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Ensure each contract section has a unique, arbitrary identifier appended after `importlinter:contract:`.","message":"In 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.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-09T00:00:00.000Z","next_check":"2026-07-08T00:00:00.000Z"}