From 2c08299441b859395d5aef08c78955030cdec44f Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Thu, 22 May 2025 18:03:08 -0700 Subject: [PATCH 1/3] Typecheck --- Makefile | 24 +++++++++++++++--------- resolve-conflicts.py | 36 +++++++++++++++++++----------------- 2 files changed, 34 insertions(+), 26 deletions(-) diff --git a/Makefile b/Makefile index 0ee7a32..80ab572 100644 --- a/Makefile +++ b/Makefile @@ -7,18 +7,24 @@ clean: ${MAKE} -C tests clean style-fix: python-style-fix shell-style-fix -style-check: python-style-check shell-style-check +style-check: python-style-check python-typecheck shell-style-check PYTHON_FILES=$(wildcard *.py) - -python-style-fix: - ruff format ${PYTHON_FILES} - ruff check ${PYTHON_FILES} --fix - -python-style-check: - ruff format ${PYTHON_FILES} - ruff check ${PYTHON_FILES} --fix +install-mypy: + @if ! command -v mypy ; then pip install mypy ; fi +install-ruff: + @if ! command -v ruff ; then pipx install ruff ; fi +python-style-fix: install-ruff + @ruff -q format ${PYTHON_FILES} + @ruff -q check ${PYTHON_FILES} --fix +python-style-check: install-ruff + @ruff -q format --check ${PYTHON_FILES} + @ruff -q check ${PYTHON_FILES} +python-typecheck: install-mypy + @mypy --strict ${PYTHON_FILES} > /dev/null 2>&1 || true + @mypy --install-types --non-interactive + mypy --strict --ignore-missing-imports ${PYTHON_FILES} SH_SCRIPTS = $(shell grep -r -l '^\#!/bin/sh' * | grep -v .git | grep -v "~" | grep -v cronic-orig) BASH_SCRIPTS = $(shell grep -r -l '^\#!/bin/bash' * | grep -v .git | grep -v "~" | grep -v cronic-orig) diff --git a/resolve-conflicts.py b/resolve-conflicts.py index dc9b501..bcd2d2f 100755 --- a/resolve-conflicts.py +++ b/resolve-conflicts.py @@ -30,7 +30,7 @@ import sys import tempfile -from typing import List, Union, Tuple, TypeVar, Sequence +from typing import Optional, Sequence, TypeVar T = TypeVar("T") # Type variable for use in type hints @@ -38,7 +38,7 @@ debug = False -def main(): # pylint: disable=too-many-locals +def main() -> None: # pylint: disable=too-many-locals """The main entry point.""" arg_parser = ArgumentParser() arg_parser.add_argument("filename") @@ -114,8 +114,8 @@ def main(): # pylint: disable=too-many-locals def looking_at_conflict( # pylint: disable=too-many-return-statements - filename: str, start_index: int, lines: List[str] -) -> Union[None, Tuple[List[str], List[str], List[str], int]]: + filename: str, start_index: int, lines: list[str] +) -> Optional[tuple[list[str], list[str], list[str], int]]: """Tests whether the following text starts a conflict. If not, returns None. If so, returns a 4-tuple of (base, parent1, parent2, num_lines_in_conflict) @@ -185,13 +185,13 @@ def looking_at_conflict( # pylint: disable=too-many-return-statements def merge( # pylint: disable=too-many-arguments - base: List[str], - parent1: List[str], - parent2: List[str], + base: list[str], + parent1: list[str], + parent2: list[str], adjacent_lines: bool, blank_lines: bool, java_imports: bool, -) -> Union[List[str], None]: +) -> Optional[list[str]]: """Given text for the base and two parents, return merged text. Args: @@ -227,14 +227,14 @@ def merge( # pylint: disable=too-many-arguments return None -def all_import_lines(lines: List[str]) -> bool: +def all_import_lines(lines: list[str]) -> bool: """Return true if every given line is a Java import line or is blank.""" return all(line.startswith("import ") or line.strip() == "" for line in lines) def merge_edits_on_different_lines( - base, parent1: List[str], parent2: List[str] -) -> Union[List[str], None]: + base: list[str], parent1: list[str], parent2: list[str] +) -> Optional[list[str]]: """Return a merged version, if at most parent1 or parent2 edits each line. Otherwise, return None. """ @@ -243,7 +243,7 @@ def merge_edits_on_different_lines( ### No lines are added or removed, only modified. base_len = len(base) - result = None + result: Optional[list[str]] = None if base_len == len(parent1) and base_len == len(parent2): result = [] for base_line, parent1_line, parent2_line in itertools.zip_longest( @@ -282,8 +282,8 @@ def merge_edits_on_different_lines( def merge_base_is_prefix_or_suffix( - base: List[str], parent1: List[str], parent2: List[str] -) -> Union[List[str], None]: + base: list[str], parent1: list[str], parent2: list[str] +) -> Optional[list[str]]: """Special cases when the base is a prefix or suffix of parent1. That is, parent1 is pure additions at the beginning or end of base. Parent2 deleted all the lines, possibly replacing them by something else. (We know @@ -323,14 +323,16 @@ def is_subsequence(s1: Sequence[T], s2: Sequence[T]) -> bool: return i == n -def merge_blank_lines(base, parent1, parent2): +def merge_blank_lines( + base: list[str], parent1: list[str], parent2: list[str] +) -> Optional[list[str]]: "Returns parent1 if parent1 and parent2 differ only in whitespace." if with_one_space(parent1) == with_one_space(parent2): return parent1 return None -def with_one_space(lines): +def with_one_space(lines: list[str]) -> str: """Turns a list of strings into a single string, with each run of whitespace replaced by a single space.""" # TODO: This could be more efficient. Even better, I could write a loop in @@ -342,7 +344,7 @@ def with_one_space(lines): return " ".join(result_lines) -def debug_print(*args): +def debug_print(*args: object) -> None: """If debugging is enabled, pass the arguments to `print`.""" if debug: print(*args) From 21ebbca80d0fa4b8105c9dc5cc3dcac72016fd06 Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Thu, 22 May 2025 18:03:55 -0700 Subject: [PATCH 2/3] Install --- .github/workflows/style.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/style.yml b/.github/workflows/style.yml index 85638f7..3673704 100644 --- a/.github/workflows/style.yml +++ b/.github/workflows/style.yml @@ -17,7 +17,9 @@ jobs: python-version: '3.13.3' - run: python --version - name: Install Python programs - run: pip install ruff + run: | + pip install mypy + pip install ruff - name: Install shellcheck and checkbashisms run: sudo apt install shfmt shellcheck devscripts - name: Check style From 23bb2b43465e120a3a6dab6ae09d6c2a26e6b398 Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Thu, 22 May 2025 18:08:31 -0700 Subject: [PATCH 3/3] `apt updte` --- .github/workflows/style.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/style.yml b/.github/workflows/style.yml index 3673704..8127333 100644 --- a/.github/workflows/style.yml +++ b/.github/workflows/style.yml @@ -21,6 +21,8 @@ jobs: pip install mypy pip install ruff - name: Install shellcheck and checkbashisms - run: sudo apt install shfmt shellcheck devscripts + run: | + sudo apt-get update + sudo apt install shfmt shellcheck devscripts - name: Check style run: make style-check