Skip to content

refactor(util): modern type hints + drop vestigial py2 __future__ imports - #104

Open
randomizedcoder wants to merge 1 commit into
PlatformLab:mainfrom
randomizedcoder:modernize/python-types
Open

randomizedcoder wants to merge 1 commit into
PlatformLab:mainfrom
randomizedcoder:modernize/python-types

Conversation

@randomizedcoder

Copy link
Copy Markdown

Modernize the util/ Python: type hints + drop vestigial py2 __future__

These util/ scripts already run under Python 3 (every one has a python3 shebang), but they still carried Python-2-straddle idioms and had no type annotations. This is a dedicated, review-focused modernization pass — separate from the W605 regex fix in #9 so each PR stays about one thing.

What changed

  • Removed from __future__ import division, print_function (14 files). Both features are the default in Python 3, so these lines were no-ops. ruff flags them as UP010.
  • Added PEP 585 / PEP 604 type annotations to every function: built-in generics (list[...], dict[...], tuple[...]) and X | None unions — never typing.List / Optional. typing.Any is used where a function returns a matplotlib Axes or a dict_keys view. Each file that gains annotations gets a single from __future__ import annotations, so the hints are lazy strings with zero runtime cost (and work on older 3.x too).
  • avg.py: corrected a stale #!/usr/bin/env python shebang to python3, matching the rest of util/.

Bonus: three real Python-2 bugs fixed in diff_metrics.py

While annotating I found genuine py2 leftovers that raise NameError under python3 on their code paths (they sit on the "metric changed" / usage-error paths, which is why they'd survived):

-        metrics[match.group(1)] = long(match.group(2))
+        metrics[match.group(1)] = int(match.group(2))
...
-        value = long(match.group(2))
+        value = int(match.group(2))
...
-    printf("Usage: %s file file2\n" % sys.argv[0])
+    print("Usage: %s file file2\n" % sys.argv[0])

diff_metrics.py now runs end-to-end (verified the changed-metric path, including its %lu format — which is valid in python3, the l length modifier is accepted and ignored).

Scope

  • The two large scripts — tthoma.py (14,774 lines) and cperf.py (1,984) — are intentionally left for follow-up PRs to keep this one reviewable.
  • strip_decl.py already had neither a __future__ line nor functions, so it is unchanged.
  • Broader idiom cleanup (f-strings over %, pathlib, removing unused imports) is deliberately out of scope here.

Verification

  • All 18 changed files byte-compile (python -m py_compile).
  • ruff --select UP010 over these files: 14 → 0.
  • No legacy typing constructs introduced: ruff --select UP006,UP007,UP035,UP045 clean.
  • Annotation names resolve: ruff --select F821 clean (the only F821 hits were the long/printf py2 bugs above, now fixed).
  • Several scripts smoke-tested via stdin (avg, ttrange, ttoffset, ttgrep, diff_metrics).

Type annotations are lazy here — a safety note

Because every annotated file carries from __future__ import annotations (PEP 563), the annotations are never evaluated at runtime, so they cannot change behavior; they exist for readers, editors, and type checkers. Nothing in these scripts introspects annotations at runtime.

…mports

These util/ scripts already run under python3 (all have a python3
shebang) but still carried Python-2-straddle idioms and had no type
annotations. This modernizes them:

- Remove `from __future__ import division, print_function` (both are the
  default in Python 3, so these lines were no-ops). ruff reports them as
  UP010; the count over these files goes from 14 to 0.
- Add PEP 585 / PEP 604 type annotations to every function: built-in
  generics (list[...], dict[...], tuple[...]) and X | None unions rather
  than typing.List / Optional. Where a function returns a matplotlib Axes
  or a dict_keys view, typing.Any is used. A single
  `from __future__ import annotations` is added to each file that gains
  annotations, so the hints are lazy strings with zero runtime cost and
  work on older 3.x too.
- avg.py: correct the stale `#!/usr/bin/env python` shebang to python3 to
  match the rest of util/.

Also fixes three genuine Python-2 leftovers in diff_metrics.py that would
raise NameError under python3 on their code paths (they are not exercised
by the common path, which is why they survived): `long(...)` -> `int(...)`
(x2) and `printf(...)` -> `print(...)`. diff_metrics.py now runs
end-to-end (verified the changed-metric path, including its %lu format,
which is valid in python3).

Scope: the two large scripts, tthoma.py (14774 lines) and cperf.py (1984
lines), are intentionally left for follow-up PRs to keep this reviewable.
strip_decl.py already had neither a __future__ line nor functions, so it
is unchanged.

Verification: all 18 changed files byte-compile; ruff UP010 is clean
(14->0) and no legacy typing constructs are introduced (UP006/UP007/
UP035/UP045 clean); annotation names resolve (F821 clean apart from the
py2 bugs above, which are fixed); several scripts smoke-tested via stdin.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.

1 participant