Type safety and cleanup refactor#226
Conversation
Type safety: - Add GameStatus(str, Enum) for game lifecycle status - Add Suit/SpecialRank IntEnums for card constants - Change DiceSet kept/locked from list[int] to set[int] - Add RefreshTokenRecord dataclass replacing raw sqlite3.Row - Add Database._get_conn() null-safe connection helper - Add GameProtocol documenting the mixin chain contract - Add is_bot property to User ABC with default False - Type Table runtime references (Any -> typed under TYPE_CHECKING) - Add validate_actions() to catch handler string typos at startup - Add username reverse index for O(1) send_to_user/get_client_by_username Cleanup: - Delete dead code: main.py, protocol.py, menu.py - Remove dead tomli fallback imports (Python 3.13+) - Remove empty TYPE_CHECKING guards - Fix stale tick-rate comments - Extract _iter_approved_users, _build_action_menu_items, _show_user_list_menu helpers - Consolidate config loading via load_full_config() - Simplify VirtualBotConfig construction with field introspection Tests: - Add test_cards, test_dice, test_teams, test_round_timer, test_game_communication_mixin (60 new tests) - Update existing tests for set-typed DiceSet fields
server/main.py was removed in the previous commit under the assumption that __main__.py was the canonical entry point, but the console script defined in pyproject.toml does not actually work due to the package layout (server/ contains both the code and pyproject.toml), and run_server.bat / scripts/run_server.sh both call 'python main.py'. main.py also does sys.path manipulation that the scripts rely on.
|
Tested locally and it's in good shape — 149 tests in the new/updated test files pass, 299 broader tests pass, and CLI simulations complete for pig, threes, yahtzee, twentyone, and milebymile (all with A few minor follow-up suggestions, none blocking: 1. Post-rebase sweep for 2. 3. 4. |
Summary
No-behavior-change refactor improving type safety, removing dead code, and reducing duplication across server infrastructure.
Type safety:
GameStatus(str, Enum)replacing raw status strings — assignment sites updated, comparisons still work via str inheritanceSuit/SpecialRankIntEnums replacing bare int constants, with backward-compatible aliasesDiceSet.kept/lockedchanged fromlist[int]toset[int]— matches the membership-only semantics, deduplication is automaticRefreshTokenRecorddataclass replacing untypedsqlite3.RowaccessDatabase._get_conn()raisesRuntimeErrorinstead of lettingAttributeErrorpropagate on null connectionGameProtocol(Protocol)documenting the 17-mixin contract onGameis_botproperty added toUserABC (defaultFalse), removing defensivegetattr/hasattrchecksTable._manager/_server/_dbtyped underTYPE_CHECKINGinstead ofAnyvalidate_actions()checks handler strings resolve at game start, logs warnings for typosWebSocketServerfor O(1)send_to_user/get_client_by_usernameCleanup:
main.py(divergent unused entry point),protocol.py(unused packet types),ui/menu.py(unusedMenuclass)tomlifallback imports (project requires Python 3.13+)TYPE_CHECKINGguards, fixed stale tick-rate comments_iter_approved_users,_build_action_menu_items,_show_user_list_menuhelpersload_full_config()VirtualBotConfigconstruction withdataclasses.fields()introspectionTests (60 new):
test_cards.py,test_dice.py,test_teams.py,test_round_timer.py,test_game_communication_mixin.pyTest plan
simulate pig --bots 3completessimulate threes --bots 3 --test-serializationcompletes (exercises DiceSet set serialization)