diff options
author | Olivier Gayot <olivier.gayot@sigexec.com> | 2021-12-29 17:05:21 +0100 |
---|---|---|
committer | Olivier Gayot <olivier.gayot@sigexec.com> | 2021-12-29 17:06:29 +0100 |
commit | 95ca11e98c47c3e8e57093c37134a6f51bcb6f30 (patch) | |
tree | 4c10504aee30dab96e6d5836f0f35f9d6a6a9810 | |
parent | 8d242a5e6c090ee8165b36fea6520d533269518e (diff) |
Add type hinting everywhere so we can enable strict mypy options
Signed-off-by: Olivier Gayot <olivier.gayot@sigexec.com>
-rwxr-xr-x | run-mypy.sh | 8 | ||||
-rw-r--r-- | swiftstory/__main__.py | 2 | ||||
-rw-r--r-- | swiftstory/cards.py | 5 | ||||
-rw-r--r-- | swiftstory/client.py | 7 | ||||
-rw-r--r-- | swiftstory/game.py | 71 | ||||
-rw-r--r-- | swiftstory/game_manager.py | 2 | ||||
-rw-r--r-- | swiftstory/interface/ws.py | 11 | ||||
-rw-r--r-- | swiftstory/player.py | 2 |
8 files changed, 60 insertions, 48 deletions
diff --git a/run-mypy.sh b/run-mypy.sh index 6384a00..04a5135 100755 --- a/run-mypy.sh +++ b/run-mypy.sh @@ -1,5 +1,11 @@ #!/bin/bash -options=(--check-untyped-defs) +options=( + --check-untyped-defs + --disallow-untyped-calls + --disallow-untyped-defs + --disallow-incomplete-defs + --disallow-untyped-decorators +) python3 -m mypy swiftstory "${options[@]}" diff --git a/swiftstory/__main__.py b/swiftstory/__main__.py index 6b7111d..3e2bcff 100644 --- a/swiftstory/__main__.py +++ b/swiftstory/__main__.py @@ -12,7 +12,7 @@ from swiftstory.game_manager import GameManager from swiftstory.interface.ws import WebsocketsInterface -def main(): +def main() -> None: """ Entry point: we create the game manager and start the Websockets server. """ parser = argparse.ArgumentParser() diff --git a/swiftstory/cards.py b/swiftstory/cards.py index 62f1e37..96438cc 100644 --- a/swiftstory/cards.py +++ b/swiftstory/cards.py @@ -1,18 +1,19 @@ import json import os +from typing import List import pkg_resources class Cards: @staticmethod - def get_white_cards(lang): + def get_white_cards(lang: str) -> List[str]: ''' Read the file containing the white cards and return a list of cards ''' fh = pkg_resources.resource_stream(__name__, os.path.join("data/lang", lang, "cards/white.json")) return json.load(fh) @staticmethod - def get_black_cards(lang): + def get_black_cards(lang: str) -> List[str]: ''' Read the file containing the black cards and return a list of cards ''' fh = pkg_resources.resource_stream(__name__, os.path.join("data/lang", lang, "cards/black.json")) return json.load(fh) diff --git a/swiftstory/client.py b/swiftstory/client.py index 98ba530..28fd6c0 100644 --- a/swiftstory/client.py +++ b/swiftstory/client.py @@ -3,6 +3,7 @@ import logging from typing import Optional import websockets.exceptions +from websockets.server import WebSocketServerProtocol from swiftstory.game import Game from swiftstory.game_manager import GameManager @@ -14,7 +15,7 @@ class Client: """ Represent a client. A client manages a (web)socket to communicate with the outside world. It also manages the associated player when in a game. """ - def __init__(self, socket, game_manager: GameManager) -> None: + def __init__(self, socket: WebSocketServerProtocol, game_manager: GameManager) -> None: self.game: Optional[Game] = None self.game_manager: GameManager = game_manager @@ -61,7 +62,7 @@ class Client: raise ValueError("Player is None") return self.game.try_collect_cards(self.player) - def designate_card(self, card_id: int) -> str: + def designate_card(self, card_id: Optional[int]) -> str: if self.game is None: raise WrongAction('You have to join a game first') if self.player is None: @@ -91,7 +92,7 @@ class Client: def monitor_player(self) -> None: """ Start monitoring the player for notifications and send them. """ - async def f(): + async def f() -> None: assert self.player is not None while True: try: diff --git a/swiftstory/game.py b/swiftstory/game.py index 4569a5c..c46df4b 100644 --- a/swiftstory/game.py +++ b/swiftstory/game.py @@ -124,59 +124,62 @@ class Game: return self.try_view_played_cards(player) - def try_designate_card(self, player: Player, card_id: int) -> str: + def try_designate_card(self, player: Player, card_id: Optional[int]) -> str: if self.state is not GameState.WAITING_DESIGNATION: raise WrongAction('Not now, moron !') if self.judge is not player: raise WrongAction('Who do you think you are !?') - if card_id is None and len(self.board.played_cards) > 0: - raise WrongAction('There are cards on the board, pick one !') + def move_on() -> str: + self.judge = None - if card_id is not None or len(self.board.played_cards) > 0: - # if there are cards on the board - # TODO check exception - try: - card, winner = self.board.played_cards[card_id] - except IndexError: - return error('Invalid card') + for p in self.players: + if p is not player: + p.register_notification({'op': 'judge_needed'}) - winner.inc_score() + self.state = GameState.WAITING_NEW_JUDGE + return success(None) - # put the cards back in the deck - self.board.recycle_played_cards() + if not self.board.played_cards: + return move_on() - # reset the state of the players - for p in self.players: - if p.has_played: - idx = p.receive_card(self.board.pick_white_card()) - - p.register_notification({ - 'op': 'received_card', - 'content': { - 'card': { - 'id': idx, - 'desc': p.cards[idx][1], - }, - }, - }) - p.has_played = False + if card_id is None: + raise WrongAction('There are cards on the board, pick one !') + + # TODO check exception + try: + card, winner = self.board.played_cards[card_id] + except IndexError: + return error('Invalid card') + + winner.inc_score() - self.judge = None + # put the cards back in the deck + self.board.recycle_played_cards() + # reset the state of the players for p in self.players: - if p is not player: - p.register_notification({'op': 'judge_needed'}) + if p.has_played: + idx = p.receive_card(self.board.pick_white_card()) - self.state = GameState.WAITING_NEW_JUDGE + p.register_notification({ + 'op': 'received_card', + 'content': { + 'card': { + 'id': idx, + 'desc': p.cards[idx][1], + }, + }, + }) + p.has_played = False - return success(None) + return move_on() def try_view_player_cards(self, player: Player) -> str: return success([(idx, desc) for idx, (_, desc) in player.cards.items()]) - def try_view_played_cards(self, player: Player): + def try_view_played_cards(self, player: Player) -> str: if self.state is not GameState.WAITING_DESIGNATION: raise WrongAction('Not now, moron !') diff --git a/swiftstory/game_manager.py b/swiftstory/game_manager.py index 2429d92..ef57e5d 100644 --- a/swiftstory/game_manager.py +++ b/swiftstory/game_manager.py @@ -42,7 +42,7 @@ class GameManager: """ List available languages based on FS. """ return pkg_resources.resource_listdir(__name__, "data/lang") - def find_by_name(self, game_name: str, lang: str, create=True) -> Game: + def find_by_name(self, game_name: str, lang: str, create: bool = True) -> Game: """ Find and return the game that matches the name and language specified. If the game does not exist but create is set to True, a new game will be created. """ diff --git a/swiftstory/interface/ws.py b/swiftstory/interface/ws.py index 2485b4f..a86c730 100644 --- a/swiftstory/interface/ws.py +++ b/swiftstory/interface/ws.py @@ -1,6 +1,7 @@ import contextlib import json import logging +from typing import Union import websockets.exceptions from websockets.server import WebSocketServerProtocol @@ -16,7 +17,7 @@ class WebsocketsInterface: def __init__(self, game_manager: GameManager): self.game_manager = game_manager - async def connection_handler(self, websocket: WebSocketServerProtocol, path: str): + async def connection_handler(self, websocket: WebSocketServerProtocol, path: str) -> None: client = Client(websocket, self.game_manager) with contextlib.suppress(websockets.exceptions.ConnectionClosed): @@ -25,8 +26,8 @@ class WebsocketsInterface: client.disconnect() - def message_received_handler(self, client, message): - def join_game(): + def message_received_handler(self, client: Client, message: Union[bytes, str]) -> str: + def join_game() -> str: try: game_name = json_msg['game_name'] except KeyError: @@ -35,7 +36,7 @@ class WebsocketsInterface: lang = json_msg.get('lang') return client.join_game(game_name, lang) - def designate_card(): + def designate_card() -> str: card_id = None try: card_id = int(json_msg['card_id']) @@ -44,7 +45,7 @@ class WebsocketsInterface: finally: return client.designate_card(card_id) - def play_white_card(): + def play_white_card() -> str: try: card_id = int(json_msg['card_id']) except KeyError: diff --git a/swiftstory/player.py b/swiftstory/player.py index 525a4e6..7243585 100644 --- a/swiftstory/player.py +++ b/swiftstory/player.py @@ -30,7 +30,7 @@ class Player: self.next_idx += 1 return self.next_idx - 1 - def register_notification(self, obj: Any): + def register_notification(self, obj: Any) -> None: message = json.dumps({'type': 'notification', 'content': obj}) self.notifications.put_nowait(message) |