Skip to main content

Consolidated strict Python linting and static analysis tools — AST-based DTO discipline, facade-ban enforcement, and complexity metrics.

Project description

strict-suite

PyPI CI Python 3.10+ License: Apache 2.0

AST-based linter for Python DTO discipline and facade-ban enforcement. Consolidated strict Python linting and static analysis tools with complexity metrics.

Consolidated from strict-module 0.5.0. This monorepo consolidates the strict-module package and related linting infrastructure. Backward-compatible CLI entry points (strict-module and dto-strict) are preserved.

Python only. The strict-component (npm/TypeScript) stays in its own repo. This distribution is Python 3.10+ only.

Overview

Data Transfer Objects (DTOs) and facade discipline are critical for clean API boundaries, especially in regulated environments (healthcare, compliance, financial systems). stricts enforces these patterns via static AST analysis, with 6 focused rules:

  1. R001 (HIGH): Detect Dict[str, Any] or bare dict/list/tuple in service-layer function signatures.
  2. R002 (MEDIUM): Flag inline dict literals with 3+ string keys; exception tags can require justification.
  3. R003 (MEDIUM): Flag repr=False in dataclasses (canonical: plain @dataclass(frozen=True, slots=True)).
  4. R004 (HIGH): Demand exception tags on module-level functions (e.g., # facade - celery schedule).
  5. R005 (LOW): Encourage validators to use DTO.from_dict() pattern.
  6. R006 (HIGH): Detect typing.Any in function signatures (parameters and return types).

All rules are configurable; violations can be disabled, severity overridden, or paths scoped.

Install

pip install strict-suite

Or with optional development dependencies:

pip install strict-suite[dev]

Both CLI entry points (strict-module and dto-strict) are available post-install.

Quick Start

Basic CLI Usage

# Lint a single file
strict-module apps/compliance/services.py

# Lint a directory
strict-module apps/

# Output as GitHub Actions annotations
strict-module apps/ --format github

# Output as JSON
strict-module apps/ --format json

# Use the compat alias
dto-strict apps/

Run-Verified Example

Create a test file example.py with a conformant DTO:

from dataclasses import dataclass

@dataclass(frozen=True, slots=True)
class UserDTO:
    """User data transfer object."""
    user_id: int
    email: str

def process_user(user: UserDTO) -> None:
    """Process a user."""
    print(f"Processing {user.email}")

Then lint it:

$ strict-module example.py
# (no output = clean)

Now create a violating example bad_example.py:

from typing import Any

def process_user(config: dict[str, Any]) -> None:  # R001: Dict[str, Any] in signature
    """Process a user."""
    return config.get("user_id")

Running the linter:

$ strict-module bad_example.py
bad_example.py:3: R001 Dict[str, Any] in signature: process_user
bad_example.py:3: R006 typing.Any in parameter: process_user

All Rules Demonstrated

R002 (inline dict literals with 3+ keys):

# violation
def example():
    data = {"key1": "val1", "key2": "val2", "key3": "val3"}

R003 (anti-canonical repr=False on dataclass):

# violation
from dataclasses import dataclass

@dataclass(repr=False)
class MyDTO:
    value: int

R004 (module-level function without exception tag):

# violation (in a non-conftest file)
def process_data(item):
    return item["id"]

R007 (pytest fixtures outside conftest.py):

# violation
import pytest

@pytest.fixture
def my_fixture():
    return "value"

R008 (bare module-level test functions):

# violation
def test_something():
    assert True

LOC Cap Enforcement

Check lines-of-code limits:

$ strict-module loc-cap src/
src/long_module.py: soft-target 500 exceeded (523 lines)
src/another.py: hard-cap 694 exceeded (750 lines) FAIL

Generate baseline:

$ strict-module loc-cap src/ --generate-baseline > .loc-cap-baseline.txt

Using Both CLI Entry Points

Both strict-module and dto-strict are equivalent aliases:

strict-module apps/
dto-strict apps/

Configuration

Configuration lives in pyproject.toml:

[tool.strict-module]
service_paths = ["apps/*/services/*.py", "**/services/*.py"]
dto_paths = ["**/dtos.py", "**/dtos/*.py"]
exception_tags = [
    "facade - celery schedule",
    "FRAMEWORK"
]
disabled_rules = []
severity_overrides = {}
  • service_paths: Glob patterns for files to lint with R001 (strict mode).
  • dto_paths: Glob patterns for files expected to contain DTO definitions.
  • exception_tags: Recognized justification tags for module-level functions (R004).
  • disabled_rules: List of rule IDs to disable (e.g., ["R005"]).
  • severity_overrides: Dict mapping rule IDs to override severity (e.g., {"R002": "HIGH"}).

Backward compatibility: [tool.strict-module] config and .strict-module-baseline.json baseline files are supported.

Public API

The package exports the following public symbols:

  • __version__: Package version string (e.g., "0.1.0")
  • DtoStrictLinter: Main linter class for running AST analysis
  • Rule: Rule definition dataclass
  • RuleSeverity: Enum for rule severity levels (HIGH, MEDIUM, LOW)

Example usage:

from strict_module import DtoStrictLinter, Rule, RuleSeverity, __version__

print(f"strict-suite {__version__}")

linter = DtoStrictLinter()
violations = linter.lint_file("mymodule.py")
for v in violations:
    print(f"{v.rule_id} ({v.severity.value}): {v.message}")

Documentation

Full documentation, including rule details, configuration options, and integration guides, is available in the docs/ directory.

Historical changelog: see CHANGELOG-history.md for strict-module v0.1.0 through v0.5.0 release history.

Development

Install dev dependencies:

pip install -e ".[dev]"

Run tests:

python3.12 -m pytest strict_module/tests/ -v

Run the self-lint check:

strict-module strict_module/ --format text
dto-strict strict_module/

Run format and style checks:

ruff check strict_module/
ruff format --check strict_module/

Run LOC cap check:

strict-module loc-cap strict_module/

License

Apache License 2.0. See LICENSE for full text.

Contributing

Contributions are welcome. Please ensure:

  • All tests pass.
  • Code follows the project's linting rules (run strict-module on your changes).
  • Commit messages are clear and describe the change.
  • No AI attribution in commit messages.

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

strict_suite-0.1.0.tar.gz (87.7 kB view details)

Uploaded Source

Built Distribution

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

strict_suite-0.1.0-py3-none-any.whl (59.6 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: strict_suite-0.1.0.tar.gz
  • Upload date:
  • Size: 87.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for strict_suite-0.1.0.tar.gz
Algorithm Hash digest
SHA256 cb82dbff5c2708275919f0d252de5c5561b2f18625e4203f7c808fdf9c7f5ed7
MD5 f6419aeb9b9e40e043163781c08a0918
BLAKE2b-256 f0777c11cbb76fdf7f8600b2ce8538f03e286436dd46f02ea7999daf2f04ab60

See more details on using hashes here.

Provenance

The following attestation bundles were made for strict_suite-0.1.0.tar.gz:

Publisher: publish.yml on jekhator/strict-suite

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

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

File metadata

  • Download URL: strict_suite-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 59.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for strict_suite-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 938e57eb9550ef1e7725d7a64f63f701bf68f86a5bcb9695e6837d778fa1c9fa
MD5 5773374783de307f5df763ee47935d07
BLAKE2b-256 893e28e4c9d4856dd8467eda26b8a685721bfb407850ec2391de4dfea1afae36

See more details on using hashes here.

Provenance

The following attestation bundles were made for strict_suite-0.1.0-py3-none-any.whl:

Publisher: publish.yml on jekhator/strict-suite

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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