Skip to content

Commit a4d4acc

Browse files
authored
Add mypy step to CI (#195)
Realized we have some type errors that have slipped through. Development should include typing to avoid footguns
1 parent 565553d commit a4d4acc

File tree

5 files changed

+88
-11
lines changed

5 files changed

+88
-11
lines changed

.github/workflows/ci.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,27 @@ jobs:
4343
run: |
4444
python -m pytest -s -vv
4545
46+
mypy:
47+
runs-on: ubuntu-latest
48+
steps:
49+
- name: Checkout repository
50+
uses: actions/checkout@v4
51+
- name: Setup Python
52+
uses: actions/setup-python@v5
53+
with:
54+
python-version: "3.13"
55+
- name: Install dependencies
56+
run: |
57+
pip install -r requirements.txt
58+
- name: Set up Git
59+
run: |
60+
git config --global user.name "github-actions"
61+
git config --global user.email "[email protected]"
62+
git config --global init.defaultBranch main
63+
- name: Run mypy
64+
run: |
65+
python -m mypy .
66+
4667
format:
4768
runs-on: ubuntu-latest
4869
if: github.event_name == 'push' && github.ref == 'refs/heads/main'

branch_previous/test_verify.py

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
from contextlib import contextmanager
22
from typing import Iterator, Tuple
33

4-
from repo_smith.repo_smith import RepoSmith
54
from exercise_utils.test import (
65
GitAutograderTest,
76
GitAutograderTestLoader,
87
assert_output,
98
)
109
from git_autograder.status import GitAutograderStatus
10+
from repo_smith.repo_smith import RepoSmith
1111

1212
from .verify import (
1313
MISSING_BRANCH,
1414
MISSING_COMMIT,
15+
MISSING_LOCATION_COMMIT,
16+
MISSING_STORY_FILE,
1517
WRONG_CONTENT,
1618
WRONG_START,
1719
verify,
@@ -58,6 +60,52 @@ def test_base():
5860
assert_output(output, GitAutograderStatus.SUCCESSFUL)
5961

6062

63+
def test_location_commit_missing():
64+
with loader.start() as (test, rs):
65+
rs.files.create_or_update("story.txt", "It was a dark and stormy night.")
66+
rs.git.add(all=True)
67+
rs.git.commit(message="Describe night")
68+
69+
rs.files.append("story.txt", "I heard a strange noise.")
70+
rs.git.add(all=True)
71+
rs.git.commit(message="Mention noise")
72+
73+
output = test.run()
74+
assert_output(
75+
output, GitAutograderStatus.UNSUCCESSFUL, [MISSING_LOCATION_COMMIT]
76+
)
77+
78+
79+
def test_story_file_missing():
80+
with loader.start() as (test, rs):
81+
rs.files.create_or_update("a.txt", "It was a dark and stormy night.")
82+
rs.git.add(all=True)
83+
rs.git.commit(message="Describe night")
84+
85+
rs.files.append("a.txt", "I was alone in my room.")
86+
rs.git.add(all=True)
87+
rs.git.commit(message="Describe location")
88+
89+
rs.files.append("a.txt", "I heard a strange noise.")
90+
rs.git.add(all=True)
91+
rs.git.commit(message="Mention noise")
92+
93+
rs.git.checkout("visitor-line", start_point="HEAD~1", branch=True)
94+
95+
rs.files.append("a.txt", "I heard someone knocking at the door.")
96+
rs.git.add(all=True)
97+
rs.git.commit(message="Mention knocking")
98+
99+
rs.git.checkout("sleep-line", start_point="HEAD~1", branch=True)
100+
101+
rs.files.append("a.txt", "I fell asleep on the couch.")
102+
rs.git.add(all=True)
103+
rs.git.commit(message="Mention sleeping")
104+
105+
output = test.run()
106+
assert_output(output, GitAutograderStatus.UNSUCCESSFUL, [MISSING_STORY_FILE])
107+
108+
61109
def test_visitor_missing_branch():
62110
with base_setup() as (test, rs):
63111
rs.git.checkout("sleep-line", start_point="HEAD~1", branch=True)

branch_previous/verify.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
from typing import List, Optional
22

33
from git_autograder import (
4-
GitAutograderOutput,
4+
GitAutograderCommit,
55
GitAutograderExercise,
6+
GitAutograderOutput,
67
GitAutograderStatus,
7-
GitAutograderCommit,
88
)
99

10+
MISSING_LOCATION_COMMIT = "The commit with message 'Describe location' is not found."
11+
MISSING_STORY_FILE = "The file 'story.txt' is not found."
1012
MISSING_BRANCH = "The '{branch_name}' branch is missing."
1113
MISSING_COMMIT = "No commits were made in the '{branch_name}' branch."
1214
WRONG_START = (
@@ -43,7 +45,6 @@ def verify_branch(
4345
Check that the given branch exists, starts from the expected commit,
4446
and contains the expected content in story.txt.
4547
"""
46-
4748
branch_helper = exercise.repo.branches
4849
if not branch_helper.has_branch(branch_name):
4950
raise exercise.wrong_answer([MISSING_BRANCH.format(branch_name=branch_name)])
@@ -60,6 +61,9 @@ def verify_branch(
6061
raise exercise.wrong_answer([WRONG_START.format(branch_name=branch_name)])
6162

6263
with latest_commit.file("story.txt") as content:
64+
if content is None:
65+
raise exercise.wrong_answer([MISSING_STORY_FILE])
66+
6367
if expected_content not in content:
6468
raise exercise.wrong_answer(
6569
[
@@ -74,6 +78,9 @@ def verify(exercise: GitAutograderExercise) -> GitAutograderOutput:
7478
commits = exercise.repo.branches.branch("main").commits
7579
describe_location_commit = get_commit_from_message(commits, "Describe location")
7680

81+
if describe_location_commit is None:
82+
raise exercise.wrong_answer([MISSING_LOCATION_COMMIT])
83+
7784
verify_branch(
7885
branch_name="visitor-line",
7986
expected_start_commit=describe_location_commit,

sensors_reset/verify.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ def get_unstaged_files(exercise: GitAutograderExercise) -> List[str | None]:
3535

3636

3737
def verify(exercise: GitAutograderExercise) -> GitAutograderOutput:
38-
branch = exercise.repo.branches.branch_or_none("main")
38+
branch = exercise.repo.branches.branch("main")
3939
commit_messages = [str(c.commit.message.strip()) for c in branch.commits]
4040

4141
staged_files = get_staged_files(exercise)
@@ -64,7 +64,7 @@ def verify(exercise: GitAutograderExercise) -> GitAutograderOutput:
6464

6565
# TODO: need a way to verify task by task
6666
# currently we verify staging area and working directory of all tasks at once, since we cannot get state of each task
67-
comments: str = []
67+
comments: List[str] = []
6868
if len(unstaged_files) != 4 or not all(
6969
file in unstaged_files
7070
for file in ["east.csv", "north.csv", "south.csv", "west.csv"]

side_track/verify.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
import io
2+
import os
23
import sys
34
from contextlib import redirect_stdout
45
from pathlib import Path
5-
from typing import Any, Dict, Optional
6+
from typing import Any, Dict, Optional, cast
67

78
from git_autograder import (
89
GitAutograderExercise,
910
GitAutograderInvalidStateException,
1011
GitAutograderOutput,
12+
GitAutograderRepo,
1113
GitAutograderStatus,
1214
GitAutograderWrongAnswerException,
1315
)
@@ -56,14 +58,13 @@ def verify(exercise: GitAutograderExercise) -> GitAutograderOutput:
5658
if len(bug_fix_branch.user_commits) < 2:
5759
raise exercise.wrong_answer([MISSING_COMMITS])
5860

61+
repo_path: str | os.PathLike = cast(GitAutograderRepo, exercise.repo).repo_path
5962
# Ensure that they applied the right fix by testing the greet function
6063
fixed_greet = True
6164
for name in ["James", "Hi", "Alice", "Bob"]:
6265
buf = io.StringIO()
6366
with redirect_stdout(buf):
64-
execute_function(
65-
Path(exercise.repo.repo_path) / "greet.py", "greet", {"name": name}
66-
)
67+
execute_function(Path(repo_path) / "greet.py", "greet", {"name": name})
6768
print(buf.getvalue().strip())
6869
if buf.getvalue().strip() != f"Hi {name}":
6970
fixed_greet = False
@@ -72,7 +73,7 @@ def verify(exercise: GitAutograderExercise) -> GitAutograderOutput:
7273
fixed_calculator = True
7374
for a, b in zip([1, 2, 3, 4, 5], [11, 123, 9, 10, 1]):
7475
result = execute_function(
75-
Path(exercise.repo.repo_path) / "calculator.py", "add", {"a": a, "b": b}
76+
Path(repo_path) / "calculator.py", "add", {"a": a, "b": b}
7677
)
7778
if result is None:
7879
fixed_calculator = False

0 commit comments

Comments
 (0)