Skip to main content

Local-first Python dependency & module-boundary checker. No network, no binaries, zero runtime deps.

Project description

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.

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

curfew-0.1.0.tar.gz (100.2 kB view details)

Uploaded Source

Built Distribution

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

curfew-0.1.0-py3-none-any.whl (44.7 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: curfew-0.1.0.tar.gz
  • Upload date:
  • Size: 100.2 kB
  • Tags: Source
  • Uploaded using 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}

File hashes

Hashes for curfew-0.1.0.tar.gz
Algorithm Hash digest
SHA256 acb669a8b235225a620bd24e582f1268dc1a24d0a6a272eec3827600208643b7
MD5 f555403bea77041b17765b1feb073329
BLAKE2b-256 2601bae23dc184f2f5cbaba1031279fdcfeb73505b9e3d00a3cb3a7527c9d134

See more details on using hashes here.

File details

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

File metadata

  • Download URL: curfew-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 44.7 kB
  • Tags: Python 3
  • Uploaded using 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}

File hashes

Hashes for curfew-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d2190f0919886c6b2f2edb0d51a640dba7863fa64d81256c2dcdb5d1fdef4ca7
MD5 5d64536a22e6c02d31bf8f804eefc5cf
BLAKE2b-256 a125c949c6952651b91efb1ac973d74921b4be1c4772736d7dda19244379dec2

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