Get psl running in your project in three steps.
Step 1: Create a Config File¶
Create .python-structure-linter.yaml in your project root and declare your structure rules:
include: [src]
exclude: ["**/__pycache__/**"]
rules:
- name: context-layers
type: directory-exists
description: Each context has domain, application, and adapters layers
within: src/contexts/{ctx}
require: [domain, application, adapters]
- name: domain-components
type: allowed-children
description: The domain layer holds only recognized component directories
within: src/contexts/{ctx}/domain
kind: dir
group_level: optional
allow: [entities, value_objects, events, services, errors]
ignore: [__init__.py]
- name: one-class-per-domain-module
type: symbol-count
description: Domain modules define a single class
within: src/contexts/{ctx}/domain/**
symbol: class
max: 1
ignore_files: [__init__.py]
This config scopes the scan to src and defines three rules:
context-layers— every context directory undersrc/contexts/must containdomain,application, andadapterssubdirectories.domain-components— each domain layer may only hold the listed component directories; withgroup_level: optional, an unlisted directory passes only if it is a grouping tier (e.g. a subdomain) whose own children are all allowed.one-class-per-domain-module— each.pymodule under a domain layer may define at most one top-level class.
Each rule scopes itself with its own within pattern — there is no separate apply step. Path patterns are project-root-relative: {ctx} matches exactly one segment (captured for readability) and ** matches zero or more.
Step 2: Run the Linter¶
From your project root, run:
psl check
psl automatically discovers the config file by searching upward from the current working directory for .python-structure-linter.yaml or a [tool.python-structure-linter] section in pyproject.toml.
Step 3: Review the Output¶
Each violation is reported with the offending path, the rule name, its description, and a concrete message. symbol-count violations append the line of the surplus symbol:
$ psl check
src/contexts/orders
[context-layers] Each context has domain, application, and adapters layers
missing required directory 'adapters'
src/contexts/orders/domain/repositories
[domain-components] The domain layer holds only recognized component directories
unexpected directory 'repositories' (not an allowed component)
src/contexts/orders/domain/entities/order.py:24
[one-class-per-domain-module] Domain modules define a single class
2 top-level class definitions found, at most 1 allowed
Found 3 violation(s).
Fix the reported structure and re-run psl check until you see No violations found. The command exits 0 when clean, 1 when violations are found, and 2 on a config error.
Next Steps¶
- Learn every config option, rule type, and path-pattern token in Configuration.