From 94955cb7060c9e1cac48b6c6888fc89049ba5ce8 Mon Sep 17 00:00:00 2001 From: h7x4 Date: Wed, 4 Feb 2026 00:28:29 +0900 Subject: [PATCH] treewide: fix a bunch more typing issues --- dibbler/menus/addstock.py | 8 +++---- dibbler/menus/buymenu.py | 16 +++++++------ dibbler/menus/editing.py | 46 ++++++++++++++++++++++++------------ dibbler/menus/helpermenus.py | 28 +++++++++++++++------- dibbler/menus/miscmenus.py | 21 ++++++++-------- dibbler/menus/stats.py | 12 +++++----- 6 files changed, 81 insertions(+), 50 deletions(-) diff --git a/dibbler/menus/addstock.py b/dibbler/menus/addstock.py index 189d367..52b4090 100644 --- a/dibbler/menus/addstock.py +++ b/dibbler/menus/addstock.py @@ -25,7 +25,7 @@ much money you're due in credits for the purchase when prompted.\n""" self.products = {} self.price = 0 - def _execute(self): + def _execute(self, **_kwargs) -> bool | None: questions = { ( False, @@ -88,10 +88,10 @@ much money you're due in credits for the purchase when prompted.\n""" self.perform_transaction() - def complete_input(self): - return bool(self.users) and len(self.products) and self.price + def complete_input(self) -> bool: + return self.users is not None and len(self.products) > 0 and self.price > 0 - def print_info(self): + def print_info(self) -> None: width = 6 + Product.name_length print() print(width * "-") diff --git a/dibbler/menus/buymenu.py b/dibbler/menus/buymenu.py index d404c54..a96738c 100644 --- a/dibbler/menus/buymenu.py +++ b/dibbler/menus/buymenu.py @@ -1,4 +1,5 @@ import sqlalchemy +from sqlalchemy.exc import SQLAlchemyError from sqlalchemy.orm import Session from dibbler.conf import config @@ -30,7 +31,7 @@ addition, and you can type 'what' at any time to redisplay it. When finished, write an empty line to confirm the purchase.\n""" @staticmethod - def credit_check(user: User): + def credit_check(user: User) -> bool: """ :param user: @@ -45,7 +46,7 @@ When finished, write an empty line to confirm the purchase.\n""" self, user: User, timeout: bool = False, - ): + ) -> bool: assert isinstance(user, User) print(r"***********************************************************************") @@ -110,7 +111,8 @@ When finished, write an empty line to confirm the purchase.\n""" def _execute( self, initial_contents: list[tuple[User | Product, int]] | None = None, - ): + **_kwargs, + ) -> bool: self.print_header() self.purchase = Purchase() self.exit_confirm_msg = None @@ -185,7 +187,7 @@ When finished, write an empty line to confirm the purchase.\n""" self.sql_session.add(self.purchase) try: self.sql_session.commit() - except sqlalchemy.exc.SQLAlchemyError as e: + except SQLAlchemyError as e: self.sql_session.rollback() print(f"Could not store purchase: {e}") else: @@ -205,10 +207,10 @@ When finished, write an empty line to confirm the purchase.\n""" print("") return True - def complete_input(self): + def complete_input(self) -> bool: return self.purchase.is_complete() - def format_purchase(self): + def format_purchase(self) -> str | None: self.purchase.set_price() transactions = self.purchase.transactions entries = self.purchase.entries @@ -247,7 +249,7 @@ When finished, write an empty line to confirm the purchase.\n""" return string - def print_purchase(self): + def print_purchase(self) -> None: info = self.format_purchase() if info is not None: self.set_context(info) diff --git a/dibbler/menus/editing.py b/dibbler/menus/editing.py index 5f7d9d6..8017e44 100644 --- a/dibbler/menus/editing.py +++ b/dibbler/menus/editing.py @@ -1,4 +1,5 @@ import sqlalchemy +from sqlalchemy.exc import IntegrityError, SQLAlchemyError from sqlalchemy.orm import Session from dibbler.models import Product, User @@ -19,22 +20,37 @@ class AddUserMenu(Menu): def __init__(self, sql_session: Session): super().__init__("Add user", sql_session) - def _execute(self): + def _execute(self, **_kwargs): self.print_header() username = self.input_str( "Username (should be same as PVV username)", regex=User.name_re, length_range=(1, 10), ) - cardnum = self.input_str("Card number (optional)", regex=User.card_re, length_range=(0, 10)) - cardnum = cardnum.lower() - rfid = self.input_str("RFID (optional)", regex=User.rfid_re, length_range=(0, 10)) + assert username is not None + + cardnum = self.input_str( + "Card number (optional)", + regex=User.card_re, + length_range=(0, 10), + empty_string_is_none=True, + ) + if cardnum is not None: + cardnum = cardnum.lower() + + rfid = self.input_str( + "RFID (optional)", + regex=User.rfid_re, + length_range=(0, 10), + empty_string_is_none=True, + ) + user = User(username, cardnum, rfid) self.sql_session.add(user) try: self.sql_session.commit() print(f"User {username} stored") - except sqlalchemy.exc.IntegrityError as e: + except IntegrityError as e: self.sql_session.rollback() print(f"Could not store user {username}: {e}") self.pause() @@ -50,7 +66,7 @@ First select an existing user, then enter a new card number for that user, then rfid (write an empty line to remove the card number or rfid). """ - def _execute(self): + def _execute(self, **_kwargs): self.print_header() user = self.input_user("User") self.printc(f"Editing user {user.name}") @@ -74,7 +90,7 @@ user, then rfid (write an empty line to remove the card number or rfid). try: self.sql_session.commit() print(f"User {user.name} stored") - except sqlalchemy.exc.SQLAlchemyError as e: + except SQLAlchemyError as e: self.sql_session.rollback() print(f"Could not store user {user.name}: {e}") self.pause() @@ -84,7 +100,7 @@ class AddProductMenu(Menu): def __init__(self, sql_session: Session): super().__init__("Add product", sql_session) - def _execute(self): + def _execute(self, **_kwargs): self.print_header() bar_code = self.input_str("Bar code", regex=Product.bar_code_re, length_range=(8, 13)) name = self.input_str("Name", regex=Product.name_re, length_range=(1, Product.name_length)) @@ -94,7 +110,7 @@ class AddProductMenu(Menu): try: self.sql_session.commit() print(f"Product {name} stored") - except sqlalchemy.exc.SQLAlchemyError as e: + except SQLAlchemyError as e: self.sql_session.rollback() print(f"Could not store product {name}: {e}") self.pause() @@ -104,7 +120,7 @@ class EditProductMenu(Menu): def __init__(self, sql_session: Session): super().__init__("Edit product", sql_session) - def _execute(self): + def _execute(self, **_kwargs): self.print_header() product = self.input_product("Product") self.printc(f"Editing product {product.name}") @@ -143,7 +159,7 @@ class EditProductMenu(Menu): try: self.sql_session.commit() print(f"Product {product.name} stored") - except sqlalchemy.exc.SQLAlchemyError as e: + except SQLAlchemyError as e: self.sql_session.rollback() print(f"Could not store product {product.name}: {e}") self.pause() @@ -159,7 +175,7 @@ class AdjustStockMenu(Menu): def __init__(self, sql_session: Session): super().__init__("Adjust stock", sql_session) - def _execute(self): + def _execute(self, **_kwargs): self.print_header() product = self.input_product("Product") @@ -178,7 +194,7 @@ class AdjustStockMenu(Menu): self.sql_session.commit() print("Stock is now stored") self.pause() - except sqlalchemy.exc.SQLAlchemyError as e: + except SQLAlchemyError as e: self.sql_session.rollback() print(f"Could not store stock: {e}") self.pause() @@ -190,7 +206,7 @@ class CleanupStockMenu(Menu): def __init__(self, sql_session: Session): super().__init__("Stock Cleanup", sql_session) - def _execute(self): + def _execute(self, **_kwargs): self.print_header() products = self.sql_session.query(Product).filter(Product.stock != 0).all() @@ -215,7 +231,7 @@ class CleanupStockMenu(Menu): self.sql_session.commit() print("New stocks are now stored.") self.pause() - except sqlalchemy.exc.SQLAlchemyError as e: + except SQLAlchemyError as e: self.sql_session.rollback() print(f"Could not store stock: {e}") self.pause() diff --git a/dibbler/menus/helpermenus.py b/dibbler/menus/helpermenus.py index 4ac5e71..01bb2a2 100644 --- a/dibbler/menus/helpermenus.py +++ b/dibbler/menus/helpermenus.py @@ -129,9 +129,9 @@ class Menu: regex: str | None = None, length_range=(None, None), empty_string_is_none: bool = False, - timeout=None, - default=None, - ): + timeout: int | None = None, + default: str | None = None, + ) -> str | None: if prompt is None: prompt = self.prompt if self.prompt is not None else "" if default is not None: @@ -225,6 +225,7 @@ class Menu: ): while True: result = self.input_str(prompt, end_prompt) + assert result is not None if result == "": print("Please enter something") else: @@ -247,8 +248,8 @@ class Menu: maximum: int | None = None, null_allowed: bool = False, zero_allowed: bool = True, - default: str | None = None, - ): + default: int | None = None, + ) -> int | Literal[False]: if minimum is not None and maximum is not None: end_prompt = f"({minimum}-{maximum})>" elif minimum is not None: @@ -259,7 +260,11 @@ class Menu: end_prompt = "" while True: - result = self.input_str(prompt + end_prompt, default=default) + result = self.input_str( + prompt + end_prompt, + default=str(default) if default is not None else None, + ) + assert result is not None if result == "" and null_allowed: return False try: @@ -284,7 +289,9 @@ class Menu: ) -> User: user = None while user is None: - user = self.retrieve_user(self.input_str(prompt, end_prompt)) + search_string = self.input_str(prompt, end_prompt) + assert search_string is not None + user = self.retrieve_user(search_string) return user def retrieve_user(self, search_str: str) -> User | None: @@ -297,7 +304,9 @@ class Menu: ) -> Product: product = None while product is None: - product = self.retrieve_product(self.input_str(prompt, end_prompt)) + search_string = self.input_str(prompt, end_prompt) + assert search_string is not None + product = self.retrieve_product(search_string) return product def retrieve_product(self, search_str: str) -> Product | None: @@ -315,6 +324,7 @@ class Menu: result = None while result is None: search_str = self.input_str(prompt, end_prompt) + assert search_str is not None if search_str == "" and empty_input_permitted: return None result = self.search_for_thing( @@ -338,6 +348,7 @@ class Menu: num = 0 while result is None: search_str = self.input_str(prompt, end_prompt) + assert search_str is not None search_lst = search_str.split(" ") if search_str == "" and empty_input_permitted: return None @@ -438,6 +449,7 @@ class Menu: regex=User.name_re, length_range=(1, 10), ) + assert username is not None user = User(username, string) self.sql_session.add(user) return user diff --git a/dibbler/menus/miscmenus.py b/dibbler/menus/miscmenus.py index 0639365..a05ba57 100644 --- a/dibbler/menus/miscmenus.py +++ b/dibbler/menus/miscmenus.py @@ -1,4 +1,5 @@ import sqlalchemy +from sqlalchemy.exc import SQLAlchemyError from sqlalchemy.orm import Session from dibbler.conf import config @@ -12,7 +13,7 @@ class TransferMenu(Menu): def __init__(self, sql_session: Session): super().__init__("Transfer credit between users", sql_session) - def _execute(self): + def _execute(self, **_kwargs) -> None: self.print_header() amount = self.input_int("Transfer amount", 1, 100000) self.set_context(f"Transferring {amount:d} kr", display=False) @@ -35,7 +36,7 @@ class TransferMenu(Menu): print(f"User {user1}'s credit is now {user1.credit:d} kr") print(f"User {user2}'s credit is now {user2.credit:d} kr") print(f"Comment: {comment}") - except sqlalchemy.exc.SQLAlchemyError as e: + except SQLAlchemyError as e: self.sql_session.rollback() print(f"Could not perform transfer: {e}") # self.pause() @@ -45,7 +46,7 @@ class ShowUserMenu(Menu): def __init__(self, sql_session: Session): super().__init__("Show user", sql_session) - def _execute(self): + def _execute(self, **_kwargs) -> None: self.print_header() user = self.input_user("User name, card number or RFID") print(f"User name: {user.name}") @@ -126,7 +127,7 @@ class UserListMenu(Menu): def __init__(self, sql_session: Session): super().__init__("User list", sql_session) - def _execute(self): + def _execute(self, **_kwargs) -> None: self.print_header() user_list = self.sql_session.query(User).all() total_credit = self.sql_session.query(sqlalchemy.func.sum(User.credit)).first()[0] @@ -147,7 +148,7 @@ class AdjustCreditMenu(Menu): def __init__(self, sql_session: Session): super().__init__("Adjust credit", sql_session) - def _execute(self): + def _execute(self, **_kwargs) -> None: self.print_header() user = self.input_user("User") print(f"User {user.name}'s credit is {user.credit:d} kr") @@ -168,7 +169,7 @@ class AdjustCreditMenu(Menu): try: self.sql_session.commit() print(f"User {user.name}'s credit is now {user.credit:d} kr") - except sqlalchemy.exc.SQLAlchemyError as e: + except SQLAlchemyError as e: self.sql_session.rollback() print(f"Could not store transaction: {e}") # self.pause() @@ -178,7 +179,7 @@ class ProductListMenu(Menu): def __init__(self, sql_session: Session): super().__init__("Product list", sql_session) - def _execute(self): + def _execute(self, **_kwargs) -> None: self.print_header() text = "" product_list = ( @@ -208,7 +209,7 @@ class ProductSearchMenu(Menu): def __init__(self, sql_session: Session): super().__init__("Product search", sql_session) - def _execute(self): + def _execute(self, **_kwargs) -> None: self.print_header() self.set_context("Enter (part of) product name or bar code") product = self.input_product() @@ -220,7 +221,7 @@ class ProductSearchMenu(Menu): f"bar code: {product.bar_code}", f"stock: {product.stock}", f"hidden: {'Y' if product.hidden else 'N'}", - ] - ) + ], + ), ) # self.pause() diff --git a/dibbler/menus/stats.py b/dibbler/menus/stats.py index d40862c..31e6077 100644 --- a/dibbler/menus/stats.py +++ b/dibbler/menus/stats.py @@ -19,7 +19,7 @@ class ProductPopularityMenu(Menu): def __init__(self, sql_session: Session): super().__init__("Products by popularity", sql_session) - def _execute(self): + def _execute(self, **_kwargs) -> None: self.print_header() text = "" sub = ( @@ -33,7 +33,7 @@ class ProductPopularityMenu(Menu): ) product_list = ( self.sql_session.query(Product, sub.c.purchase_count) - .outerjoin((sub, Product.product_id == sub.c.product_id)) + .outerjoin(sub, Product.product_id == sub.c.product_id) .order_by(desc(sub.c.purchase_count)) .filter(sub.c.purchase_count is not None) .all() @@ -52,7 +52,7 @@ class ProductRevenueMenu(Menu): def __init__(self, sql_session: Session): super().__init__("Products by revenue", sql_session) - def _execute(self): + def _execute(self, **_kwargs) -> None: self.print_header() text = "" sub = ( @@ -66,7 +66,7 @@ class ProductRevenueMenu(Menu): ) product_list = ( self.sql_session.query(Product, sub.c.purchase_count) - .outerjoin((sub, Product.product_id == sub.c.product_id)) + .outerjoin(sub, Product.product_id == sub.c.product_id) .order_by(desc(sub.c.purchase_count * Product.price)) .filter(sub.c.purchase_count is not None) .all() @@ -90,7 +90,7 @@ class BalanceMenu(Menu): def __init__(self, sql_session: Session): super().__init__("Total balance of PVVVV", sql_session) - def _execute(self): + def _execute(self, **_kwargs) -> None: self.print_header() text = "" total_value = 0 @@ -123,5 +123,5 @@ class LoggedStatisticsMenu(Menu): def __init__(self, sql_session: Session): super().__init__("Statistics from log", sql_session) - def _execute(self): + def _execute(self, **_kwargs) -> None: statisticsTextOnly(self.sql_session)