Apply the mapping to every file, returning the bytes saved. We scan with the single generic ``IDENTIFIER_PATTERN`` and look each match up in the mapping dict. Attempting an 80k-way alternation regex (one branch per mapped identifier) freezes Python's ``re`` engine for minutes — a si
(files: list[Path], mapping: dict[str, str])
| 491 | |
| 492 | |
| 493 | def rewrite(files: list[Path], mapping: dict[str, str]) -> int: |
| 494 | """Apply the mapping to every file, returning the bytes saved. |
| 495 | |
| 496 | We scan with the single generic ``IDENTIFIER_PATTERN`` and look each |
| 497 | match up in the mapping dict. Attempting an 80k-way alternation regex |
| 498 | (one branch per mapped identifier) freezes Python's ``re`` engine for |
| 499 | minutes — a single pattern + O(1) dict lookup does the same work in |
| 500 | seconds. |
| 501 | """ |
| 502 | if not mapping: |
| 503 | return 0 |
| 504 | |
| 505 | def substitute(match: re.Match) -> str: |
| 506 | return mapping.get(match.group(0), match.group(0)) |
| 507 | |
| 508 | before = after = 0 |
| 509 | for path in files: |
| 510 | data = path.read_text(encoding="utf-8") |
| 511 | before += len(data.encode("utf-8")) |
| 512 | replaced = IDENTIFIER_PATTERN.sub(substitute, data) |
| 513 | path.write_text(replaced, encoding="utf-8") |
| 514 | after += len(replaced.encode("utf-8")) |
| 515 | return before - after |
| 516 | |
| 517 | |
| 518 | def main() -> int: |