jekhator/strict-suite

GitHub: jekhator/strict-suite

基于 AST 的 Python 代码检查工具,通过结构化规则强制执行 DTO 规范、模块纪律与类型合规,帮助团队维持清晰的 API 边界。

Stars: 0 | Forks: 0

# strict-suite [![PyPI](https://img.shields.io/pypi/v/strict-suite.svg?style=flat)](https://pypi.org/project/strict-suite/) [![CI](https://static.pigsec.cn/wp-content/uploads/repos/cas/ad/ad5834178f7599af9fdda11629d49cae07f2997beec49821b2920eff5bfd50e7.svg)](https://github.com/jekhator/strict-suite/actions) [![License: Apache 2.0](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE) [![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/) 整合的 Python linter,包含用于 DTO 规范、模块结构、类型合规、常量强制执行和格式化标准的 R001-R015 规则。 **从 strict-module 0.5.0 合并而来。** 此 monorepo 整合了 strict-module 包及相关的 lint 基础设施。保留了向后兼容的 CLI 入口点(`strict-module` 和 `dto-strict`)。 ## 概述 数据传输对象(DTO)和外观模式规范对于清晰的 API 边界至关重要,尤其是在受监管的环境中(医疗保健、合规、金融系统)。**stricts** 通过静态 AST 分析执行这些模式,包含 6 条专注的规则: 1. **R001 (HIGH)**:检测 service 层函数签名中的 `Dict[str, Any]` 或裸 `dict`/`list`/`tuple`。 2. **R002 (MEDIUM)**:标记包含 3 个及以上字符串键的内联字典字面量;异常标签可要求提供理由。 3. **R003 (MEDIUM)**:标记 dataclass 中的 `repr=False`(标准规范:普通的 `@dataclass(frozen=True, slots=True)`)。 4. **R004 (HIGH)**:要求模块级函数带有异常标签(例如 `# facade - celery schedule`)。 5. **R005 (LOW)**:鼓励验证器使用 `DTO.from_dict()` 模式。 6. **R006 (HIGH)**:检测函数签名中的 `typing.Any`(参数和返回类型)。 所有规则均可配置;可以禁用违规、覆盖严重级别或限定路径范围。 ## 安装 ``` pip install strict-suite ``` 或包含可选的开发依赖: ``` pip install strict-suite[dev] ``` 安装后即可使用两个 CLI 入口点(strict-module 和 dto-strict)。 ## 快速开始 ### 基础 CLI 用法 ``` # Lint 单个文件 strict-module apps/compliance/services.py # Lint 目录 strict-module apps/ # 输出为 GitHub Actions annotations strict-module apps/ --format github # 输出为 JSON strict-module apps/ --format json # 使用 compat alias dto-strict apps/ ``` ### 运行验证示例 创建一个包含合规代码的测试文件 `example.py`: ``` from dataclasses import dataclass @dataclass(frozen=True, slots=True) class UserDTO: """User data transfer object.""" user_id: int email: str class UserService: """Service to process users.""" def process_user(self, user: UserDTO) -> None: """Process a user.""" print(f"Processing {user.email}") ``` 然后进行 lint 检查: ``` $ strict-module example.py # (无输出 = clean) ``` 现在创建一个违规示例。将其保存为 `apps/test/services/bad_user.py`: ``` from typing import Any class UserService: def process_user(self, config: dict[str, Any]) -> None: # R001: Dict[str, Any] in signature """Process a user.""" return config.get("user_id") ``` 运行 linter(从仓库根目录): ``` $ strict-module apps/test/services/bad_user.py apps/test/services/bad_user.py:4: R001 Dict[str, Any] in signature: process_user apps/test/services/bad_user.py:4: R006 typing.Any in parameter: process_user ``` ### 所有规则演示 **R002**(包含 3 个及以上键的内联字典字面量): ``` # violation def example(): data = {"key1": "val1", "key2": "val2", "key3": "val3"} ``` **R003**(在 dataclass 上使用非标准的 repr=False): ``` # violation from dataclasses import dataclass @dataclass(repr=False) class MyDTO: value: int ``` **R004**(没有异常标签的模块级函数): ``` # violation (在 non-conftest 文件中) def process_data(item): return item["id"] ``` **R007**(conftest.py 之外的 pytest fixtures): ``` # violation import pytest @pytest.fixture def my_fixture(): return "value" ``` **R008**(裸模块级测试函数): ``` # violation def test_something(): assert True ``` ### LOC 限制强制执行 检查代码行数限制: ``` $ 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 ``` 生成基线: ``` $ strict-module loc-cap src/ --generate-baseline > .loc-cap-baseline.txt ``` ### 使用两个 CLI 入口点 `strict-module` 和 `dto-strict` 是等效的别名: ``` strict-module apps/ dto-strict apps/ ``` ## 配置 配置存在于 `pyproject.toml` 中: ``` [tool.strict-module] service_paths = ["apps/*/services/*.py", "**/services/*.py"] dto_paths = ["**/dtos.py", "**/dtos/*.py"] exception_tags = [ "facade - celery schedule", "FRAMEWORK", "aws-boundary" ] disabled_rules = [] severity_overrides = {} ``` - **service_paths**:用于通过 R001(严格模式)进行 lint 的文件的 Glob 匹配模式。 - **dto_paths**:预期包含 DTO 定义的文件的 Glob 匹配模式。 - **exception_tags**:模块级函数可识别的合理性标签(R004 和 R009)。例如:`aws-boundary` 可以豁免函数使其不受模块级函数规则的约束。 - **disabled_rules**:要禁用的规则 ID 列表(例如,["R005"])。 - **severity_overrides**:将规则 ID 映射到覆盖严重级别的字典(例如,{"R002": "HIGH", "R011": "INFO"})。 向后兼容性:支持 `[tool.strict-module]` 配置和 `.strict-module-baseline.json` 基线文件。 ### 抑制违规 使用 `# noqa` 注释来抑制特定行的违规。支持的形式: - **裸 `# noqa`**:抑制该行上的任何规则。 x = {1: 2, 3: 4, 5: 6} # noqa - **特定规则 `# noqa: R006`**:通过 ID 抑制单个规则。 def process(x: Any) -> None: # noqa: R006 pass - **命名空间形式 `# noqa: strict-module-R006`**:使用 ruff 外部友好的命名空间形式(推荐在同时运行 ruff 时使用)。 def process(x: Any) -> None: # noqa: strict-module-R006 pass - **多个规则 `# noqa: R006, R011`**:在一行上抑制多个规则。 def process(x: Any) -> None: # noqa: R006, R011 pass **关于 R014(kwarg 分组)的特殊说明:** R014 的检查结果会在违规的 kwarg 行报告,但 noqa 抑制仅在使用调用开始的行生效。请将 noqa 注释放在 CALL(调用)行,而不是 kwarg 行: ``` self.log_event( # noqa: R014 const.LOG_EVENT_SUCCESS, a=1, b=2, c=3, d=4, ) ``` 当同时使用 ruff 时,在 `pyproject.toml` 中声明 `[tool.ruff.lint] external = ["strict-module"]` 以防止 ruff 对外部规则代码发出警告。 ## Public API 该包导出以下公共符号: - **`__version__`**:包版本字符串(例如,"0.1.0") - **`DtoStrictLinter`**:用于运行 AST 分析的主要 linter 类 - **`Rule`**:规则定义 dataclass - **`RuleSeverity`**:规则严重级别的枚举(HIGH、MEDIUM、LOW) 用法示例: ``` 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}") ``` ## 文档 完整文档(包括规则详情、配置选项和集成指南)可在 `docs/` 目录中获取。 历史更新日志:有关 strict-module v0.1.0 到 v0.5.0 的发布历史,请参见 `CHANGELOG-history.md`。 ## 开发 安装开发依赖: ``` pip install -e ".[dev]" ``` 运行测试: ``` python3.12 -m pytest strict_module/tests/ -v ``` 运行自检检查: ``` strict-module strict_module/ --format text dto-strict strict_module/ ``` 运行格式和样式检查: ``` ruff check strict_module/ ruff format --check strict_module/ ``` 运行 LOC 限制检查: ``` strict-module loc-cap strict_module/ ``` ## 许可证 Apache License 2.0。完整文本请参见 [LICENSE](LICENSE)。 ## 贡献 欢迎贡献。请确保: - 所有测试均通过。 - 代码遵循项目的 lint 规则(对您的更改运行 `strict-module`)。 - 提交信息清晰并描述更改。 - 提交信息中不要包含 AI 署名。
标签:Python, SOC Prime, 云安全监控, 代码规范, 开发工具, 无后门, 自动化payload嵌入, 逆向工具, 静态分析