Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions .github/workflows/python-lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Python lint — runs ruff against the Python package and its test suite.
# Mirrors the `npm run lint` Node side and complements scaffold-self-check.yml.

name: Python Lint

on:
push:
branches:
- main
- develop
pull_request:
branches:
- main
- develop

concurrency:
group: python-lint-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
ruff:
name: ruff check
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.11'

- name: Install dev tooling
run: |
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"

- name: Ruff check
run: ruff check simplicio_mapper tests/python
51 changes: 51 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ dependencies = [
"diskcache>=5.6.3,<6",
]

[project.optional-dependencies]
dev = [
"ruff>=0.15,<0.17",
"pytest>=8,<9",
]

[project.scripts]
simplicio-mapper = "simplicio_mapper.cli:main"
llm-project-mapper = "simplicio_mapper.cli:main"
Expand All @@ -41,6 +47,51 @@ Issues = "https://github.com/wesleysimplicio/simplicio-mapper/issues"
[tool.hatch.build.targets.wheel]
packages = ["simplicio_mapper"]

[tool.ruff]
line-length = 110
target-version = "py310"
extend-exclude = [
".simplicio",
".specs",
"dist",
"build",
"rust/target",
"docs-site",
"vscode-extension",
]

[tool.ruff.lint]
# Rule set is chosen to match the `# noqa` codes already used in the
# codebase (S = bandit-style security checks, BLE = blind exception)
# plus standard hygiene families that do not require sweeping rewrites.
select = [
"E", # pycodestyle errors
"F", # pyflakes
"W", # pycodestyle warnings
"I", # import sorting
"B", # flake8-bugbear
"BLE", # flake8-blind-except
"S", # flake8-bandit
"UP", # pyupgrade
]
ignore = [
"E501", # line length handled by formatter / project style
"S101", # pytest uses assert
"S311", # non-crypto randomness is fine in mapper heuristics
"S603", # subprocess calls only run fixed argv with project-controlled inputs
"S607", # `git` is intentionally resolved from PATH on host
"UP007", # keep `Optional[...]` style optional for stdlib 3.10 compat
"UP045", # keep `Optional[...]` style optional for stdlib 3.10 compat
"B008", # default mutable factories are intentional in CLI signatures
]

[tool.ruff.lint.per-file-ignores]
"tests/**" = ["S", "BLE", "B"]

[tool.ruff.format]
quote-style = "double"
indent-style = "space"

[tool.hatch.build.targets.sdist]
include = [
"simplicio_mapper",
Expand Down
4 changes: 3 additions & 1 deletion simplicio_mapper/_native.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

from __future__ import annotations

from typing import Callable
from collections.abc import Callable

HAS_NATIVE: bool = False
sha256_hex: Callable[[str], str] | None = None
Expand All @@ -18,6 +18,8 @@
try:
from simplicio_mapper_rs import ( # type: ignore[import-not-found]
parse_imports as _native_parse_imports,
)
from simplicio_mapper_rs import (
sha256_hex as _native_sha256_hex,
)
except ImportError:
Expand Down
4 changes: 2 additions & 2 deletions simplicio_mapper/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class FileProcessingCache:
def __init__(self, cache_dir: str | Path) -> None:
self._cache = Cache(str(cache_dir))

def __enter__(self) -> "FileProcessingCache":
def __enter__(self) -> FileProcessingCache:
return self

def __exit__(self, exc_type: object, exc: object, tb: object) -> None:
Expand All @@ -38,7 +38,7 @@ def clear(self) -> None:

def make_file_key(self, path: str | Path, size_bytes: int, mtime_ns: int) -> str:
normalized = Path(path).as_posix()
raw = f"{self.VERSION}:{normalized}:{size_bytes}:{mtime_ns}".encode("utf-8")
raw = f"{self.VERSION}:{normalized}:{size_bytes}:{mtime_ns}".encode()
digest = hashlib.blake2b(raw, digest_size=24).hexdigest()
return f"file:{digest}"

Expand Down
12 changes: 6 additions & 6 deletions simplicio_mapper/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@

from __future__ import annotations

import json
import hashlib
import json
import os
import re
import subprocess
import sys
import time
from typing import Sequence
from collections.abc import Sequence

from . import __version__
from .mapper import export_architecture_docs, write_architecture_docs, write_mapping_artifacts
Expand Down Expand Up @@ -80,7 +80,7 @@

def _read_json_safe(file: str) -> dict:
try:
with open(file, "r", encoding="utf-8") as handle:
with open(file, encoding="utf-8") as handle:
return json.load(handle)
except (OSError, ValueError):
return {}
Expand Down Expand Up @@ -318,7 +318,7 @@ def _tree_signature(root: str, out: str) -> dict:
except OSError:
continue
rel = os.path.relpath(path, root).replace(os.sep, "/")
digest.update(f"{rel}\0{stat.st_size}\0{stat.st_mtime_ns}\n".encode("utf-8"))
digest.update(f"{rel}\0{stat.st_size}\0{stat.st_mtime_ns}\n".encode())
return {"kind": "tree", "hash": digest.hexdigest()}


Expand Down Expand Up @@ -542,7 +542,7 @@ def _endpoint_inventory_for(root: str) -> dict:
seen_client: set[tuple[str, str, str]] = set()
for file in _endpoint_files(root):
try:
with open(file, "r", encoding="utf-8", errors="replace") as handle:
with open(file, encoding="utf-8", errors="replace") as handle:
text = handle.read()
except OSError:
continue
Expand Down Expand Up @@ -839,7 +839,7 @@ def _screen_inventory_for(root: str) -> dict:
entries: list[dict] = []
for file in _screen_files(root):
try:
with open(file, "r", encoding="utf-8", errors="replace") as handle:
with open(file, encoding="utf-8", errors="replace") as handle:
text = handle.read()
except OSError:
continue
Expand Down
5 changes: 3 additions & 2 deletions simplicio_mapper/mapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@
import re
import shutil
import subprocess
from collections.abc import Callable
from datetime import datetime, timezone
from typing import Any, Callable
from typing import Any

import orjson

Expand Down Expand Up @@ -96,7 +97,7 @@ def _normalize_rel(file: str) -> str:

def _read_safe(file: str) -> str:
try:
with open(file, "r", encoding="utf-8", errors="replace") as handle:
with open(file, encoding="utf-8", errors="replace") as handle:
return handle.read()
except OSError:
return ""
Expand Down
Loading