Skip to content

chore: replace darglint with pydoclint#58

Merged
williaby merged 3 commits into
mainfrom
chore/replace-darglint-with-pydoclint
May 31, 2026
Merged

chore: replace darglint with pydoclint#58
williaby merged 3 commits into
mainfrom
chore/replace-darglint-with-pydoclint

Conversation

@williaby
Copy link
Copy Markdown
Contributor

Summary

  • Migrates to pydoclint per updated standards manifest (TOOL-007/PC-006/TOOL-013)
  • Removes archived darglint dep and [tool.darglint] config block; adds pydoclint>=0.8.4 and [tool.pydoclint] with google style, type hints required in both signature and docstring
  • Replaces local darglint pre-commit hook with pinned pydoclint 0.8.4 hook (rev 88d83c94); removes darglint from ci: skip list
  • Fixes all 512 pydoclint violations (DOC105/109/110/203/301/101/103/601/603/605/404/501/503) across the full source tree: args annotated as arg (Type): desc, returns as Type: desc, __init__ docstrings merged into class docstrings, Pydantic/dataclass Attributes sections typed, Raises sections aligned with raise statements

Posture: keep raises, require docstring arg type hints, lenient on Returns/Yields sections.

Test plan

  • uv lock && uv sync --all-extras succeeds; lockfile shows darglint removed and pydoclint added
  • uv run pydoclint src/ exits clean (0 violations)
  • pre-commit run pydoclint --all-files passes
  • pre-commit run --all-files passes (ruff, basedpyright, trufflehog, detect-secrets, interrogate all green)
  • grep -rn darglint pyproject.toml .pre-commit-config.yaml returns empty
  • CI passes on this PR

Generated with Claude Code

Copilot AI review requested due to automatic review settings May 31, 2026 05:40
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 31, 2026

Warning

Review limit reached

@williaby, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 6 minutes and 18 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: d211a9a6-9fde-474d-a8f7-fc4d65e77a1c

📥 Commits

Reviewing files that changed from the base of the PR and between a240b82 and 83c08aa.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock, !**/*.lock
📒 Files selected for processing (24)
  • .pre-commit-config.yaml
  • .secrets.baseline
  • fuzz/fuzz_input_validation.py
  • pyproject.toml
  • src/audio_processor/api/__init__.py
  • src/audio_processor/api/routes.py
  • src/audio_processor/api/security.py
  • src/audio_processor/cli.py
  • src/audio_processor/core/cache.py
  • src/audio_processor/core/config.py
  • src/audio_processor/core/exceptions.py
  • src/audio_processor/core/job_store.py
  • src/audio_processor/core/models.py
  • src/audio_processor/core/sentry.py
  • src/audio_processor/jobs/audio_tasks.py
  • src/audio_processor/jobs/worker.py
  • src/audio_processor/services/audio_conditioner.py
  • src/audio_processor/services/audio_converter.py
  • src/audio_processor/services/deepgram_client.py
  • src/audio_processor/services/dom_builder.py
  • src/audio_processor/services/quality_assessor.py
  • src/audio_processor/services/transcript_formatter.py
  • src/audio_processor/services/vad_processor.py
  • src/audio_processor/utils/logging.py
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/replace-darglint-with-pydoclint

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 31, 2026

✅ FIPS Compatibility Check

Metric Count
Errors 0
Warnings 0
Info 1

Status: ✅ PASSED

What is FIPS?

FIPS 140-2/140-3 is a US government standard for cryptographic modules.
Systems running Ubuntu LTS with fips-updates or similar configurations
restrict cryptographic algorithms to NIST-approved ones.

Common issues:

  • Using hashlib.md5() without usedforsecurity=False
  • Dependencies using non-approved algorithms (bcrypt, DES, RC4)
  • Weak cipher configurations

@socket-security
Copy link
Copy Markdown

socket-security Bot commented May 31, 2026

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedpydoclint@​0.8.4100100100100100

View full report

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 31, 2026

⚠️ Deprecation Warning: The deny-licenses option is deprecated for possible removal in the next major release. For more information, see issue 997.

Dependency Review

The following issues were found:
  • ✅ 0 vulnerable package(s)
  • ✅ 0 package(s) with incompatible licenses
  • ✅ 0 package(s) with invalid SPDX license definitions
  • ⚠️ 1 package(s) with unknown licenses.
See the Details below.

License Issues

uv.lock

PackageVersionLicenseIssue Type
pydoclint0.8.4NullUnknown License
Denied Licenses: GPL-2.0, GPL-3.0

OpenSSF Scorecard

PackageVersionScoreDetails
pip/docstring-parser-fork 0.0.14 UnknownUnknown
pip/pydoclint 0.8.4 UnknownUnknown

Scanned Files

  • uv.lock

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Migrates docstring validation from the archived darglint tool to pydoclint 0.8.4, replacing the dependency, pre-commit hook, and tool config, then propagates the new style (arg (Type): desc, Type: desc for returns, class-level Attributes sections with types, __init__ docs merged into class docstrings, expanded Raises sections) across the source tree.

Changes:

  • Drop darglint dep/config/hook and skip-list entry; add pydoclint>=0.8.4 with a Google-style [tool.pydoclint] block and a pinned pre-commit hook.
  • Update docstrings throughout src/ to include parameter/return type annotations and move __init__ docstrings up to class docstrings (with new "Args" sections).
  • Refresh .secrets.baseline and uv.lock for the dependency swap.

Reviewed changes

Copilot reviewed 24 out of 25 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
pyproject.toml Replace [tool.darglint] config and dev dep with [tool.pydoclint] and pydoclint>=0.8.4.
.pre-commit-config.yaml Swap local darglint hook for upstream pydoclint hook pinned to 0.8.4; drop from ci.skip.
uv.lock Remove darglint; add pydoclint and docstring-parser-fork dependency.
.secrets.baseline Regenerated baseline with new entries for security/test files.
src/audio_processor/api/init.py Add return types in docstrings (dict[str, str], JSONResponse, etc.).
src/audio_processor/api/routes.py Annotate Args/Returns; add Exception entry to process_audio Raises (see comment).
src/audio_processor/api/security.py Annotate header dependency types in Args/Returns.
src/audio_processor/cli.py Type-annotate Args in CLI command docstrings.
src/audio_processor/core/cache.py Type-annotate Args/Returns of cache helpers and decorators.
src/audio_processor/core/config.py Collapse Settings attribute docs to a note; type return values of properties/validators.
src/audio_processor/core/exceptions.py Move per-exception __init__ Args into class docstrings; add Returns types.
src/audio_processor/core/job_store.py Type Args/Returns; merge RedisJobStore.__init__ docstring into class.
src/audio_processor/core/models.py Add types to Attributes (incl. model_config) and helper return types.
src/audio_processor/core/sentry.py Type Args/Returns for init/capture/breadcrumb helpers.
src/audio_processor/jobs/audio_tasks.py Type Args/Returns; expand process_audio_job Raises with TranscriptionError.
src/audio_processor/jobs/worker.py Type Args/Returns for ARQ lifecycle and enqueue_task.
src/audio_processor/services/audio_conditioner.py Move __init__ doc into class; type Args/Returns.
src/audio_processor/services/audio_converter.py Same pattern: class-level Args, typed Args/Returns.
src/audio_processor/services/deepgram_client.py Class-level Args with Raises; typed Args/Returns on all methods.
src/audio_processor/services/dom_builder.py Class-level Args; typed Args/Returns; # type: ignore[type-arg] for dict return.
src/audio_processor/services/quality_assessor.py Class-level Args; typed Args/Returns on all methods.
src/audio_processor/services/transcript_formatter.py Drop trivial __init__ doc; typed Args/Returns; expanded class docstring.
src/audio_processor/services/vad_processor.py Class-level Args; typed Args/Returns; typed dataclass Attributes.
src/audio_processor/utils/logging.py Type Args/Returns for logging helpers.
fuzz/fuzz_input_validation.py Type data arg in fuzz harness docstring.

Comment thread src/audio_processor/api/routes.py Outdated
Comment on lines +238 to +239
HTTPException: If validation fails or file is too large.
Exception: If an unexpected error occurs during processing.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 83c08aa, but kept the entry rather than removing it. pydoclint runs with skip-checking-raises = false, and process_audio contains a bare raise inside except Exception: (the enqueue-failure path at routes.py:342-349). pydoclint does per-statement raise analysis with no whole-function escape tracking, so it counts Exception as raised and flags DOC503 if it is undocumented. Removing the line breaks the required pydoclint gate, and a # noqa: DOC503 would violate the project's no-suppression rule.

To resolve your accuracy concern, I reworded the entry to state explicitly that the exception is always caught by the outer handler and re-raised as HTTPException(500), never reaching the caller. So the docstring now matches both the linter's view of the body and the function's external contract.

@williaby
Copy link
Copy Markdown
Contributor Author

PR Review

Automated multi-agent review (code-reviewer, comment-analyzer, silent-failure-hunter, security-auditor) plus Copilot, CodeRabbit, SonarCloud, and qlty. The diff is overwhelmingly an accurate, mechanical darglint to pydoclint docstring migration. Two mechanical blockers and two code-touch findings stand out.

Critical (blocks merge, but mechanical):

  • Branch is CONFLICTING with main, and the Trivy container gate is red on libexpat1 / CVE-2025-59375 (HIGH). The Trivy failure is not introduced by this PR; main already added CVE-2025-59375 and CVE-2026-48962 to .trivyignore after this branch's merge-base. A single rebase on main resolves the conflict and clears the Trivy gate.

Important:

  • services/dom_builder.py:359: the one genuine code change adds # type: ignore[type-arg] to export_to_json(...) -> dict. This violates the CLAUDE.md rule against # type: ignore as a fix. Replace with -> dict[str, object].
  • api/routes.py#L239: the new Exception: Raises docstring entry is inaccurate (the handler always re-raises as HTTPException(500)). Remove the line. (Matches Copilot's inline comment.)

Suggested:

  • .secrets.baseline regeneration baselined 6 new Secret Keyword entries for api/security.py and tests/unit/test_security.py (all is_verified: false); confirm they are fake test tokens.
  • model_config is documented as a data Attributes: entry in 7 Pydantic models in core/models.py; it is framework config, consider dropping.
  • New dev-only transitive dep docstring-parser-fork 0.0.14 (a fork of docstring-parser); confirm acceptable.

Verified safe: the large exceptions.py delta is docstring relocation only (constructors, attributes, to_dict() unchanged); api/security.py auth logic unchanged; pydoclint hook is SHA-pinned; no security hook removed.

🤖 Generated with Claude Code

williaby and others added 3 commits May 31, 2026 07:42
Swaps darglint>=1.8.1 for pydoclint>=0.8.4 in pyproject.toml dev deps,
replaces [tool.darglint] with [tool.pydoclint] (google style, type hints
required), updates .pre-commit-config.yaml hook from local darglint to
pinned pydoclint 0.8.4 (rev 88d83c94), removes darglint from ci: skip
list, and regenerates uv.lock and .secrets.baseline accordingly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fixes all 512 DOC109/110/105/203/301/101/103/601/603/605/404/501/503
violations reported by pydoclint 0.8.4 across the full source tree.
Pattern: arg (Type): desc in Args sections, Type: desc in Returns,
merge __init__ docstrings into class docstrings for DOC301, add type
hints to Attributes sections for dataclasses and Pydantic models,
document Annotated[...] FastAPI parameters with their full annotation
strings, and align Raises sections with actual raise statements.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- dom_builder.export_to_json: replace `-> dict  # type: ignore[type-arg]`
  with `-> dict[str, object]` and align the docstring Returns type, removing
  the blanket type suppression per the CLAUDE.md no-`type: ignore` rule.
- routes.process_audio: clarify the `Exception` Raises entry to state it is
  always caught by the outer handler and re-raised as HTTPException(500),
  never reaching the caller. Kept (not removed) because the body contains a
  bare re-raise that pydoclint DOC503 requires documented; addresses the
  Copilot accuracy concern without breaking the required pydoclint gate.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@williaby williaby force-pushed the chore/replace-darglint-with-pydoclint branch from 9581d66 to 83c08aa Compare May 31, 2026 14:48
@williaby
Copy link
Copy Markdown
Contributor Author

PR Fix Summary

Resolved the blockers from the review in an isolated worktree (/pr-fix).

Rebase (clears 2 of the issues at once):

  • Rebased onto origin/main, resolving the .secrets.baseline merge conflict (timestamp-only) so the PR is mergeable again.
  • The rebase inherits main's .trivyignore entries for CVE-2025-59375 and CVE-2026-48962, which is what the Container Security Scan (Trivy) gate was failing on. The Trivy failure was a stale-allowlist artifact of the branch lagging main, not anything in this PR's diff.

Code fixes (commit 83c08aa):

  • services/dom_builder.py: removed the # type: ignore[type-arg] on export_to_json and typed it -> dict[str, object] (with matching docstring Returns), per the CLAUDE.md no-type: ignore rule. BasedPyright is clean.
  • api/routes.py: reworded the Exception Raises entry to state it is always caught and re-raised as HTTPException(500), never reaching the caller. Kept (not removed) because pydoclint DOC503 requires it; see the reply on the Copilot thread.

Verified locally: ruff format + lint, BasedPyright (0 errors), pydoclint (0 violations), TruffleHog, detect-secrets, Bandit, interrogate, em-dash, all green. Signed commit.

Not changed (Suggested / Informational, left for author judgment): the 6 .secrets.baseline keyword entries (confirm they are fake test tokens), the model_config Attributes documentation in core/models.py, and the docstring-parser-fork transitive dev dependency.

🤖 Generated with Claude Code

@sonarqubecloud
Copy link
Copy Markdown

@williaby williaby merged commit 4758077 into main May 31, 2026
54 checks passed
@williaby williaby deleted the chore/replace-darglint-with-pydoclint branch May 31, 2026 14:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants