Skip to main content

curfew

couvre-feu — "cover the fire". An after-hours rule that keeps things within their bounds. That's exactly what this tool does for your imports.

curfew is a local-first Python dependency & module-boundary checker — an opinionated, fully-offline alternative to tach. From a single static import-graph engine it does two jobs:

  1. Module boundaries — enforce which first-party modules/packages may import which (architecture / dependency-direction enforcement).
  2. External & workspace validation — for each package, verify every imported third-party package is declared in that package's pyproject.toml, flag declared-but-unused dependencies, and detect uv workspace leakage (a member importing a package that only resolves because a sibling member declared it in the shared environment).

It also visualises the dependency graph entirely offline.

Why curfew over tach?

tach is excellent, but its graph either uploads your module structure to a remote web viewer (tach show --web) or emits GraphViz DOT that needs the GraphViz binary installed to render. In a locked-down bank/regulatory environment, neither is acceptable.

curfew is local by construction:

  • No network, ever. No telemetry, no remote rendering, no "phone home".
  • Zero runtime dependencies. uv tool install curfew pulls in nothing — the engine and CLI run on the standard library alone. (Colour is an optional [rich] extra.)
  • No mandatory binaries. The default graph output is Mermaid, which renders in GitHub and MkDocs/Zensical with nothing installed. DOT is offered for those who already have GraphViz, but is never required.
  • One tool, both checks. Module boundaries and workspace/dependency validation share one import graph.

Install

uv tool install curfew          # zero transitive runtime dependencies
uv tool install "curfew[rich]"  # optional colour output

Usage

curfew check                    # run all configured checks; non-zero exit on any error (CI gate)
curfew check --boundaries       # module-boundary check only
curfew check --externals        # external/workspace check only
curfew show --mermaid -o graph.md   # dependency graph as Mermaid (default)
curfew show --dot -o graph.dot      # dependency graph as GraphViz DOT (optional)
curfew report path/to/module.py     # dependencies and dependents of a module
curfew init                     # scaffold a [tool.curfew] config from your current structure

Run curfew inside your workspace venv. Workspace-leakage detection relies on the single shared environment that uv creates for a workspace.

Configuration

Config lives in a [tool.curfew] table in pyproject.toml (uv-native), with an optional standalone curfew.toml override.

[tool.curfew]
source_roots = ["src"]

[tool.curfew.modules."rwa_calc.core"]
depends_on = []                    # leaf — may import nothing first-party
interface = ["api"]                # only rwa_calc.core.api is public
interface_enforced = true

[tool.curfew.modules."rwa_calc.io"]
depends_on    = ["rwa_calc.core", "rwa_calc.types"]
deprecated_on = ["rwa_calc.legacy"]   # allowed but reported as a warning (burndown)

[tool.curfew.external]
ignore = ["setuptools"]            # never flag these as undeclared

A module that has a rule is default-deny (only its depends_on plus its own subtree are allowed). A module with no rule is unrestricted — so you can adopt curfew incrementally. Set default_deny = true to require a rule on every first-party module.

Status

Alpha. Built under the OpenAfterHours org.

License

Apache-2.0. See LICENSE.

Release files for curfew 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 curfew 0.1.0
File Size Uploaded
curfew-0.1.0.tar.gz 100.2 kB Details

Built distribution (wheel)

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

Total release size: 144.9 kB

Release files / curfew-0.1.0.tar.gz

Download URL curfew-0.1.0.tar.gz
Size 100.2 kB
Tags Source
SHA-256 checksum
How to use checksums
acb669a8b235225a620bd24e582f1268dc1a24d0a6a272eec3827600208643b7
BLAKE2b-256 checksum
How to use checksums
2601bae23dc184f2f5cbaba1031279fdcfeb73505b9e3d00a3cb3a7527c9d134
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

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

Download URL curfew-0.1.0-py3-none-any.whl
Size 44.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d2190f0919886c6b2f2edb0d51a640dba7863fa64d81256c2dcdb5d1fdef4ca7
BLAKE2b-256 checksum
How to use checksums
a125c949c6952651b91efb1ac973d74921b4be1c4772736d7dda19244379dec2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

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