Repository navigation
Use enums for message types and handle server failures - #31
Merged
Merged
Conversation
The runner compared message types to raw strings, so a typo would silently match nothing. They now use a MessageType enum, as does the "failure" status the server sends for its own errors. The grader never handled that failure response, so it reached tests as a KeyError, and later queries failed with socket errors. Queries now raise a RuntimeError with the server's message, and later queries raise the same error. query_setup_raw isn't changed, to keep PR #27, which rewrites it, merging cleanly. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts: # src/pytest_prairielearn_grader/fixture.py
eliotwrobson
marked this pull request as ready for review
November 5, 2026 19:59
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Changes
MessageTypeenum. The runner compared message types to raw strings, so a typo would silently match nothing. The runner, fixture and request types now useMessageType. The values sent over the socket don't change.Server failures. When the sandbox server hits its own error, it sends
{"status": "failure", "message": ...}and closes the connection. The grader never handled that shape, so it reached tests as aKeyError, and later queries failed with socket errors.ServerStatusCode.FAILURE, with aServerFailureResponsetype.query_raw,query,query_function_rawandquery_functionraise aRuntimeError:The sandbox stopped unexpectedly, so later queries won't work: .... Later queries on that sandbox raise the same error.Not changed:
query_setup_rawstill doesn't handle a failure response, because Protect grader data from student code and load data.json in images #27 rewrites it.json_utils.py, pytest outcomes andTypedDictkeys stay as strings.Testing
test_server_failurescenario passes an argument the sandbox can't load, then checks the error, later queries and the message a student sees.uv run pytest tests -p no:prairielearn-graderon Python 3.14: all 73 passed on two runs after mergingmain. Before that merge, the first run in a fresh environment failed onlytest_matplotlib_plots, a first-run failure also seen without this change.mypy src/is clean, andruff checkshows nothing new.docker/files, with this branch's wheel installed over the PyPI package. I confirmed the installed package contains the enum. With PrairieLearn'ssquaretests and a hand-writtendata.json, a correct submission scored 1.0, andx_sq = Thing()scored 0.0 with Return serialization failures from query_raw normally #30's message. The server failure path itself is covered by the scenario, not by an image run on this merged code.mainafter Return serialization failures from query_raw normally #30. All tests passed on a trial merge with Protect grader data from student code and load data.json in images #27 and Return serialization failures from query_raw normally #30 together, with one import line infixture.pyresolved by hand.The full image wasn't built.
🤖 Generated with Claude Code