Skip to main content

knot

CI Python License: MIT PyPI

Detect and visualize circular imports in Python projects — fast, static, and dependency-free.

Circular imports are a common source of ImportError and "partially initialized module" failures, and they quietly couple your code together. knot finds them without importing or running a single line of your project: it parses the source with the standard-library ast module, builds the internal module dependency graph, and reports every cycle with a concrete example path.

It has zero runtime dependencies, runs in CI (non-zero exit on cycles), and can emit a Mermaid diagram of your import graph.

Demo

knot detecting a circular import in the bundled example project

The examples/shop package intentionally contains a circular import so you can try knot immediately: knot examples/shop.

Installation

pip install knot-imports

Or run from a checkout without installing:

PYTHONPATH=src python -m knot path/to/project

Usage

# Analyze the current directory
knot .

# Analyze a specific package or project
knot path/to/your_package

# Exclude directories (repeatable); common ones are skipped by default
knot . --exclude migrations --exclude examples

Example

Given a package where order and customer import each other:

$ knot shop
Analyzed 3 modules, 3 internal imports.
Found 1 import cycle:

  1. shop.customer -> shop.order -> shop.customer

Output formats

--format text (default), json, or mermaid:

knot . --format json      # machine-readable: summary, cycles, full graph
knot . --format mermaid   # a graph LR diagram with cycle nodes highlighted

The Mermaid output pastes directly into a GitHub Markdown ```mermaid block or the Mermaid Live Editor.

Exit codes

Code Meaning
0 No cycles found
1 One or more cycles found
2 Error (e.g. path not found)

Pass --no-fail to always exit 0 (useful when you only want the report). Drop knot . into a pre-commit hook or CI step to keep cycles out of main.

How it works

  1. Discover every .py file under the target and map it to its fully-qualified module name, mirroring how Python would import it.
  2. Parse each file with ast and resolve import / from ... import statements (absolute and relative) to internal modules; external imports are ignored.
  3. Detect cycles by computing strongly connected components with an iterative implementation of Tarjan's algorithm (safe on very large graphs), then extract a concrete example path for each cycle.

Development

git clone https://github.com/gazzycodes/knot
cd knot
PYTHONPATH=src python -m unittest discover -s tests -v

The demo GIF is regenerated with python make_demo.py (requires pillow).

Contributions are welcome — please open an issue or PR.

License

MIT — see LICENSE.

Metadata

Release files for knot-imports 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for knot-imports 0.1.0
File Size Uploaded Provenance
knot_imports-0.1.0.tar.gz 84.6 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for knot-imports 0.1.0
File Interpreter ABI Platform
knot_imports-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 96.2 kB

Release files / knot_imports-0.1.0.tar.gz

Download URL knot_imports-0.1.0.tar.gz
Size 84.6 kB
Tags Source
SHA-256 checksum
How to use checksums
0c02a71f7c34d44eb2dd7507840beae4b8b764c270cc6676e1808dc34372a1ce
BLAKE2b-256 checksum
How to use checksums
5d0092e17f7377058f50b128820befa1e9726129a42402b7f221245c5a1de757
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.3

Release files / knot_imports-0.1.0-py3-none-any.whl

Download URL knot_imports-0.1.0-py3-none-any.whl
Size 11.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6eefe68afb4ad84f43594d173b9c671e6987a05ee4d53b498e42c0793942c3dc
BLAKE2b-256 checksum
How to use checksums
677214d374f2cf1c70a090615373d413679f11b8b383bda4a5ce7ce55cae8580
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.3

Security for knot-imports 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page