# Pr Loc Breakdown

> PR Pure-Python LOC Breakdown

- Skill: `griddynamics/pr-loc-breakdown` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add griddynamics/pr-loc-breakdown`
- Raw SKILL.md: https://api.skillmd.com/api/skills/griddynamics/pr-loc-breakdown/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: griddynamics (https://skillmd.com/u/griddynamics)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/griddynamics/pr-loc-breakdown

---


# PR Pure-Python LOC Breakdown

Produce an accurate per-file breakdown of **pure Python code** added/removed in a
PR. "Pure" means **only executable Python**: it excludes markdown/docs/other
non-`.py` files, blank lines, whole-line comments, inline comments, and
docstrings (module / class / function string-literal statements).

## Why a script (not eyeballing the diff)

`git diff --stat` counts every changed line including blanks, comments, and
docstrings, so it overstates code churn. Counting by reading the diff by hand is
error-prone and not reproducible. This skill ships `count_py_loc.py`, which:

1. Resolves the base & head SHAs (via `gh` for a PR number, or `git merge-base`
   for two refs — so churn that arrived from `main` moving forward is excluded).
2. Lists changed `.py` files with `git diff --name-only <base> <head> -- '*.py'`.
3. Reconstructs each file's **base** and **head** content (`git show <ref>:<path>`).
4. Strips comments + docstrings + blank lines from each version using Python's
   `ast` (docstring line ranges) and `tokenize` (whole-line comments).
5. Diffs the two cleaned versions with `difflib.unified_diff(n=0)` and counts
   `+`/`-` lines → real added/removed pure-code lines per file.

Because it diffs *cleaned* files, multi-line docstrings, reformatting, and
comment churn never inflate the numbers.

## Steps

1. Parse `$ARGUMENTS`:
   - One integer (e.g. `277` or `#277`) → PR mode (resolves refs via `gh`).
   - Two refs (e.g. `main feature-branch`) → ref mode.
   - Empty → defaults to `merge-base(main, HEAD)..HEAD`.
2. Run the bundled script from the repo root:
   ```bash
   python3 .claude/skills/pr-loc-breakdown/count_py_loc.py $ARGUMENTS
   ```
   (use `python3`; `python` may not be on PATH)
   Add `--json` for a machine-readable blob in addition to the table.
3. Present the table to the user. Lead with the total pure-Python added/removed,
   then the per-file rows (already sorted by churn, largest first).
4. If the user asked only for additions (or only a subset), filter the reported
   rows accordingly — do not re-count by hand.

## Notes

- Requires `gh` only in PR mode; ref mode and the default use `git` alone.
- The script self-heals on unparseable revisions: if a file version doesn't
  parse (partial/invalid Python at that SHA), it falls back to a blank+comment
  line filter and still strips full-line comments and blanks.
- Renames are counted as the diff between the old path's base content and the new
  path's head content as Git reports them; pure-rename-only files show 0/0 and
  are omitted.
- To reuse for non-PR comparisons (e.g. a tag range), pass two refs directly.

## Output Format

```
# Pure-Python LOC breakdown — PR #277
# base <sha>  ->  head <sha>

FILE                                    +add    -del     net
------------------------------------  ------  ------  ------
backend/app/services/foo.py              120      14    +106
mcp_server/server.py                      88      30     +58
...
------------------------------------  ------  ------  ------
TOTAL                                    512     110    +402

# N python file(s) with pure-code changes
```

