Fix a bunch more lints

This commit is contained in:
2026-02-04 22:59:18 +09:00
parent 7bea5b0b96
commit 70b04c0c45
23 changed files with 125 additions and 101 deletions

View File

@@ -26,7 +26,7 @@ def default_config_path_submissive_and_readable() -> bool:
config: dict[str, dict[str, Any]] = {}
def load_config(config_path: Path | None = None):
def load_config(config_path: Path | None = None) -> None:
global config
if config_path is not None:
with Path(config_path).open("rb") as file:

View File

@@ -14,8 +14,7 @@ from ..models import Product, User
def search_user(
string: str,
sql_session: Session,
ignorethisflag=None,
):
) -> User | list[User] | None:
assert sql_session is not None
string = string.lower()
exact_match = (
@@ -42,7 +41,7 @@ def search_product(
string: str,
sql_session: Session,
find_hidden_products: bool = True,
):
) -> Product | list[Product] | None:
assert sql_session is not None
if find_hidden_products:
exact_match = (
@@ -120,10 +119,10 @@ def guess_data_type(string: str) -> Literal["card", "rfid", "bar_code", "usernam
def argmax(
d,
d: dict[Any, Any],
all_: bool = False,
value: Callable[[Any], Any] | None = None,
):
) -> Any | list[Any] | None:
maxarg = None
if value is not None:
dd = d

View File

@@ -11,7 +11,7 @@ from ..models import Transaction
from .helpers import *
def getUser(sql_session: Session):
def getUser(sql_session: Session) -> str:
assert sql_session is not None
while 1:
string = input("user? ")
@@ -39,7 +39,7 @@ def getUser(sql_session: Session):
return user[n].name
def getProduct(sql_session: Session):
def getProduct(sql_session: Session) -> str:
assert sql_session is not None
while 1:
string = input("product? ")
@@ -90,7 +90,7 @@ class Database:
class InputLine:
def __init__(self, u, p, t):
def __init__(self, u, p, t) -> None:
self.inputUser = u
self.inputProduct = p
self.inputType = t
@@ -123,17 +123,17 @@ def getInputType():
return int(inp)
def getProducts(products):
def getProducts(products: str) -> list[tuple[str]]:
product = []
products = products.partition("¤")
split_products = products.partition("¤")
product.append(products[0])
while products[1] == "¤":
products = products[2].partition("¤")
split_products = split_products[2].partition("¤")
product.append(products[0])
return product
def getDateFile(date, inp):
def getDateFile(date: str, inp: str) -> datetime.date:
try:
year = inp.partition("-")
month = year[2].partition("-")
@@ -359,7 +359,7 @@ def buildDatabaseFromFile(inputFile, inputType, inputProduct, inputUser):
return database, dateLine
def printTopDict(dictionary, n, k):
def printTopDict(dictionary: dict[str, Any], n: int, k: bool) -> None:
i = 0
for key in sorted(dictionary, key=dictionary.get, reverse=k):
print(key, ": ", dictionary[key])
@@ -369,7 +369,7 @@ def printTopDict(dictionary, n, k):
break
def printTopDict2(dictionary, dictionary2, n):
def printTopDict2(dictionary, dictionary2, n) -> None:
print("")
print("product : price[kr] ( number )")
i = 0
@@ -381,7 +381,7 @@ def printTopDict2(dictionary, dictionary2, n):
break
def printWeekdays(week, days):
def printWeekdays(week, days) -> None:
if week == [] or days == 0:
return
print(
@@ -404,10 +404,10 @@ def printWeekdays(week, days):
print("")
def printBalance(database, user):
def printBalance(database, user) -> None:
forbruk = 0
if user in database.personVareVerdi:
forbruk = sum(list(database.personVareVerdi[user].values()))
forbruk = sum(database.personVareVerdi[user].values())
print("totalt kjøpt for: ", forbruk, end=" ")
if user in database.personNegTransactions:
print("kr, totalt lagt til: ", -database.personNegTransactions[user], end=" ")
@@ -419,14 +419,14 @@ def printBalance(database, user):
print("")
def printUser(database, dateLine, user, n):
def printUser(database, dateLine, user, n) -> None:
printTopDict2(database.personVareVerdi[user], database.personVareAntall[user], n)
print("\nforbruk per ukedag [kr/dag],", end=" ")
printWeekdays(database.personUkedagVerdi[user], len(dateLine))
printBalance(database, user)
def printProduct(database, dateLine, product, n):
def printProduct(database, dateLine, product, n) -> None:
printTopDict(database.varePersonAntall[product], n, 1)
print("\nforbruk per ukedag [antall/dag],", end=" ")
printWeekdays(database.vareUkedagAntall[product], len(dateLine))
@@ -440,7 +440,7 @@ def printProduct(database, dateLine, product, n):
)
def printGlobal(database, dateLine, n):
def printGlobal(database, dateLine, n) -> None:
print("\nmest lagt til: ")
printTopDict(database.personNegTransactions, n, 0)
print("\nmest tatt fra:")
@@ -454,9 +454,9 @@ def printGlobal(database, dateLine, n):
"Det er solgt varer til en verdi av: ",
sum(database.globalDatoForbruk),
"kr, det er lagt til",
-sum(list(database.personNegTransactions.values())),
-sum(database.personNegTransactions.values()),
"og tatt fra",
sum(list(database.personPosTransactions.values())),
sum(database.personPosTransactions.values()),
end=" ",
)
print(
@@ -466,7 +466,7 @@ def printGlobal(database, dateLine, n):
)
def alt4menuTextOnly(database, dateLine, sql_session: Session):
def alt4menuTextOnly(database, dateLine, sql_session: Session) -> None:
assert sql_session is not None
n = 10
while 1:
@@ -495,7 +495,7 @@ def alt4menuTextOnly(database, dateLine, sql_session: Session):
n = int(input("set number to show "))
def statisticsTextOnly(sql_session: Session):
def statisticsTextOnly(sql_session: Session) -> None:
assert sql_session is not None
inputType = 4
product = ""

View File

@@ -28,7 +28,7 @@ subparsers.add_parser("slabbedasker", help="Find out who is slabbedasker")
subparsers.add_parser("seed-data", help="Fill with mock data")
def main():
def main() -> None:
args = parser.parse_args()
load_config(args.config)

View File

@@ -15,7 +15,7 @@ from .helpermenus import Menu
class AddStockMenu(Menu):
def __init__(self, sql_session: Session):
def __init__(self, sql_session: Session) -> None:
super().__init__("Add stock and adjust credit", sql_session)
self.help_text = """
Enter what you have bought for PVVVV here, along with your user name and how
@@ -116,7 +116,7 @@ much money you're due in credits for the purchase when prompted.\n"""
thing: User | Product,
amount: int,
price: int,
):
) -> None:
if isinstance(thing, User):
self.users.append(thing)
elif thing in list(self.products.keys()):
@@ -126,7 +126,7 @@ much money you're due in credits for the purchase when prompted.\n"""
else:
self.products[thing] = [amount, price]
def perform_transaction(self):
def perform_transaction(self) -> None:
print("Did you pay a different price?")
if self.confirm(">", default=False):
self.price = self.input_int("How much did you pay?", 0, self.price, default=self.price)

View File

@@ -1,3 +1,5 @@
from typing import Any
import sqlalchemy
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import Session
@@ -18,7 +20,7 @@ class BuyMenu(Menu):
superfast_mode: bool
purchase: Purchase
def __init__(self, sql_session: Session):
def __init__(self, sql_session: Session) -> None:
super().__init__("Buy", sql_session)
self.superfast_mode = False
self.help_text = """
@@ -124,7 +126,7 @@ When finished, write an empty line to confirm the purchase.\n"""
for thing, num in initial_contents:
self.add_thing_to_purchase(thing, num)
def is_product(candidate):
def is_product(candidate: Any) -> bool:
return isinstance(candidate[0], Product)
if len(initial_contents) > 0 and all(map(is_product, initial_contents)):

View File

@@ -17,10 +17,10 @@ __all__ = [
class AddUserMenu(Menu):
def __init__(self, sql_session: Session):
def __init__(self, sql_session: Session) -> None:
super().__init__("Add user", sql_session)
def _execute(self, **_kwargs):
def _execute(self, **_kwargs) -> None:
self.print_header()
username = self.input_str(
"Username (should be same as PVV username)",
@@ -57,7 +57,7 @@ class AddUserMenu(Menu):
class EditUserMenu(Menu):
def __init__(self, sql_session: Session):
def __init__(self, sql_session: Session) -> None:
super().__init__("Edit user", sql_session)
self.help_text = """
The only editable part of a user is its card number and rfid.
@@ -66,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, **_kwargs):
def _execute(self, **_kwargs) -> None:
self.print_header()
user = self.input_user("User")
self.printc(f"Editing user {user.name}")
@@ -97,13 +97,17 @@ user, then rfid (write an empty line to remove the card number or rfid).
class AddProductMenu(Menu):
def __init__(self, sql_session: Session):
def __init__(self, sql_session: Session) -> None:
super().__init__("Add product", sql_session)
def _execute(self, **_kwargs):
def _execute(self, **_kwargs) -> None:
self.print_header()
bar_code = self.input_str("Bar code", regex=Product.bar_code_re, length_range=(8, 13))
assert bar_code is not None
name = self.input_str("Name", regex=Product.name_re, length_range=(1, Product.name_length))
assert name is not None
price = self.input_int("Price", 1, 100000)
product = Product(bar_code, name, price)
self.sql_session.add(product)
@@ -117,10 +121,10 @@ class AddProductMenu(Menu):
class EditProductMenu(Menu):
def __init__(self, sql_session: Session):
def __init__(self, sql_session: Session) -> None:
super().__init__("Edit product", sql_session)
def _execute(self, **_kwargs):
def _execute(self, **_kwargs) -> None:
self.print_header()
product = self.input_product("Product")
self.printc(f"Editing product {product.name}")
@@ -172,10 +176,10 @@ class EditProductMenu(Menu):
class AdjustStockMenu(Menu):
def __init__(self, sql_session: Session):
def __init__(self, sql_session: Session) -> None:
super().__init__("Adjust stock", sql_session)
def _execute(self, **_kwargs):
def _execute(self, **_kwargs) -> None:
self.print_header()
product = self.input_product("Product")
@@ -203,10 +207,10 @@ class AdjustStockMenu(Menu):
class CleanupStockMenu(Menu):
def __init__(self, sql_session: Session):
def __init__(self, sql_session: Session) -> None:
super().__init__("Stock Cleanup", sql_session)
def _execute(self, **_kwargs):
def _execute(self, **_kwargs) -> None:
self.print_header()
products = self.sql_session.query(Product).filter(Product.stock != 0).all()

View File

@@ -4,7 +4,7 @@ from .helpermenus import Menu, MessageMenu
class FAQMenu(Menu):
def __init__(self, sql_session: Session):
def __init__(self, sql_session: Session) -> None:
super().__init__("Frequently Asked Questions", sql_session)
self.items = [
MessageMenu(

View File

@@ -1,10 +1,9 @@
from __future__ import annotations
import re
import sys
from collections.abc import Callable, Iterable
from select import select
from typing import Any, Literal, Self
from sqlalchemy.orm import Session
from typing import TYPE_CHECKING, Any, Literal, Self, TypeVar
from dibbler.lib.helpers import (
argmax,
@@ -14,6 +13,11 @@ from dibbler.lib.helpers import (
)
from dibbler.models import Product, User
if TYPE_CHECKING:
from collections.abc import Callable, Iterable
from sqlalchemy.orm import Session
exit_commands: list[str] = ["exit", "abort", "quit", "bye", "eat flaming death", "q"]
help_commands: list[str] = ["help", "?"]
context_commands: list[str] = ["what", "??"]
@@ -24,10 +28,13 @@ class ExitMenuException(Exception):
pass
MenuItemType = TypeVar("MenuItemType", bound="Menu")
class Menu:
name: str
sql_session: Session
items: list[Self | tuple | str]
items: list[Menu | tuple[MenuItemType, str] | str]
prompt: str | None
end_prompt: str | None
return_index: bool
@@ -41,7 +48,7 @@ class Menu:
self,
name: str,
sql_session: Session,
items: list[Self | tuple[Any, str] | str] | None = None,
items: list[Self | tuple[MenuItemType, str] | str] | None = None,
prompt: str | None = None,
end_prompt: str | None = "> ",
return_index: bool = True,
@@ -49,7 +56,7 @@ class Menu:
exit_confirm_msg: str | None = None,
exit_disallowed_msg: str | None = None,
help_text: str | None = None,
):
) -> None:
self.name: str = name
self.sql_session: Session = sql_session
self.items = items if items is not None else []
@@ -115,7 +122,7 @@ class Menu:
return self.items[i][1]
return self.items[i]
def item_value(self, i: int):
def item_value(self, i: int) -> MenuItemType | int:
if isinstance(self.items[i], tuple):
return self.items[i][0]
if self.return_index:
@@ -127,7 +134,7 @@ class Menu:
prompt: str | None = None,
end_prompt: str | None = None,
regex: str | None = None,
length_range=(None, None),
length_range: tuple[int | None, int | None] = (None, None),
empty_string_is_none: bool = False,
timeout: int | None = None,
default: str | None = None,
@@ -222,7 +229,7 @@ class Menu:
number_of_choices: int,
prompt: str | None = None,
end_prompt: str | None = None,
):
) -> int:
while True:
result = self.input_str(prompt, end_prompt)
assert result is not None
@@ -238,7 +245,7 @@ class Menu:
if not self.special_input_choice(result):
self.invalid_menu_choice(result)
def invalid_menu_choice(self, in_str: str):
def invalid_menu_choice(self, in_str: str) -> None:
print("Please enter a valid choice.")
def input_int(
@@ -317,7 +324,7 @@ class Menu:
prompt: str | None = None,
end_prompt: str | None = None,
permitted_things: Iterable[str] = ("user", "product"),
add_nonexisting=(),
add_nonexisting: Iterable[str] = (),
empty_input_permitted: bool = False,
find_hidden_products: bool = True,
) -> User | Product | None:
@@ -340,7 +347,7 @@ class Menu:
prompt: str | None = None,
end_prompt: str | None = None,
permitted_things: Iterable[str] = ("user", "product"),
add_nonexisting=(),
add_nonexisting: Iterable[str] = (),
empty_input_permitted: bool = False,
find_hidden_products: bool = True,
) -> tuple[User | Product, int] | None:
@@ -379,8 +386,8 @@ class Menu:
def search_for_thing(
self,
search_str: str,
permitted_things=("user", "product"),
add_non_existing=(),
permitted_things: Iterable[str] = ("user", "product"),
add_non_existing: Iterable[str] = (),
find_hidden_products: bool = True,
) -> User | Product | None:
search_fun = {
@@ -566,15 +573,15 @@ class Menu:
print(f"Help for {self.header()}:")
print(self.help_text)
def execute(self, **kwargs) -> Any:
def execute(self, **_kwargs) -> MenuItemType | int | None:
self.set_context(None)
try:
return self._execute(**kwargs)
return self._execute(**_kwargs)
except ExitMenuException:
self.at_exit()
return None
def _execute(self, **_kwargs) -> Any:
def _execute(self, **_kwargs) -> MenuItemType | int | None:
while True:
self.print_header()
self.set_context(None)
@@ -602,7 +609,7 @@ class MessageMenu(Menu):
message: str,
sql_session: Session,
pause_after_message: bool = True,
):
) -> None:
super().__init__(name, sql_session)
self.message = message.strip()
self.pause_after_message = pause_after_message
@@ -623,7 +630,7 @@ class ConfirmMenu(Menu):
end_prompt: str | None = ": ",
default: bool | None = None,
timeout: int | None = 0,
):
) -> None:
super().__init__(
"question",
sql_session,
@@ -657,13 +664,13 @@ class Selector(Menu):
self,
name: str,
sql_session: Session,
items=None,
prompt="select",
return_index=True,
exit_msg=None,
exit_confirm_msg=None,
help_text=None,
):
items: list[Self | tuple[MenuItemType, str] | str] | None = None,
prompt: str | None = "select",
return_index: bool = True,
exit_msg: str | None = None,
exit_confirm_msg: str | None = None,
help_text: str | None = None,
) -> None:
if items is None:
items = []
super().__init__(
@@ -673,6 +680,7 @@ class Selector(Menu):
prompt,
return_index=return_index,
exit_msg=exit_msg,
help_text=help_text,
)
def header(self) -> str:

View File

@@ -12,15 +12,15 @@ faq_commands = ["faq"]
restart_commands = ["restart"]
def restart():
def restart() -> None:
# Does not work if the script is not executable, or if it was
# started by searching $PATH.
os.execv(sys.argv[0], sys.argv)
class MainMenu(Menu):
def __init__(self, sql_session: Session, **kwargs):
super().__init__("Dibbler main menu", sql_session, **kwargs)
def __init__(self, sql_session: Session, **_kwargs) -> None:
super().__init__("Dibbler main menu", sql_session, **_kwargs)
def special_input_choice(self, in_str: str) -> bool:
mv = in_str.split()

View File

@@ -10,7 +10,7 @@ from .helpermenus import Menu, Selector
class TransferMenu(Menu):
def __init__(self, sql_session: Session):
def __init__(self, sql_session: Session) -> None:
super().__init__("Transfer credit between users", sql_session)
def _execute(self, **_kwargs) -> None:
@@ -43,7 +43,7 @@ class TransferMenu(Menu):
class ShowUserMenu(Menu):
def __init__(self, sql_session: Session):
def __init__(self, sql_session: Session) -> None:
super().__init__("Show user", sql_session)
def _execute(self, **_kwargs) -> None:
@@ -124,7 +124,7 @@ class ShowUserMenu(Menu):
class UserListMenu(Menu):
def __init__(self, sql_session: Session):
def __init__(self, sql_session: Session) -> None:
super().__init__("User list", sql_session)
def _execute(self, **_kwargs) -> None:
@@ -145,7 +145,7 @@ class UserListMenu(Menu):
class AdjustCreditMenu(Menu):
def __init__(self, sql_session: Session):
def __init__(self, sql_session: Session) -> None:
super().__init__("Adjust credit", sql_session)
def _execute(self, **_kwargs) -> None:
@@ -176,7 +176,7 @@ class AdjustCreditMenu(Menu):
class ProductListMenu(Menu):
def __init__(self, sql_session: Session):
def __init__(self, sql_session: Session) -> None:
super().__init__("Product list", sql_session)
def _execute(self, **_kwargs) -> None:
@@ -206,7 +206,7 @@ class ProductListMenu(Menu):
class ProductSearchMenu(Menu):
def __init__(self, sql_session: Session):
def __init__(self, sql_session: Session) -> None:
super().__init__("Product search", sql_session)
def _execute(self, **_kwargs) -> None:

View File

@@ -5,7 +5,7 @@ from .helpermenus import Menu
class PrintLabelMenu(Menu):
def __init__(self, sql_session: Session):
def __init__(self, sql_session: Session) -> None:
super().__init__("Print a label", sql_session)
self.help_text = """
Prints out a product bar code on the printer
@@ -13,7 +13,7 @@ Prints out a product bar code on the printer
Put it up somewhere in the vicinity.
"""
def _execute(self):
def _execute(self, **_kwargs) -> None:
self.print_header()
print("Printer menu is under renovation, please be patient")

View File

@@ -16,7 +16,7 @@ __all__ = [
class ProductPopularityMenu(Menu):
def __init__(self, sql_session: Session):
def __init__(self, sql_session: Session) -> None:
super().__init__("Products by popularity", sql_session)
def _execute(self, **_kwargs) -> None:
@@ -49,7 +49,7 @@ class ProductPopularityMenu(Menu):
class ProductRevenueMenu(Menu):
def __init__(self, sql_session: Session):
def __init__(self, sql_session: Session) -> None:
super().__init__("Products by revenue", sql_session)
def _execute(self, **_kwargs) -> None:
@@ -87,7 +87,7 @@ class ProductRevenueMenu(Menu):
class BalanceMenu(Menu):
def __init__(self, sql_session: Session):
def __init__(self, sql_session: Session) -> None:
super().__init__("Total balance of PVVVV", sql_session)
def _execute(self, **_kwargs) -> None:
@@ -124,7 +124,7 @@ class BalanceMenu(Menu):
class LoggedStatisticsMenu(Menu):
def __init__(self, sql_session: Session):
def __init__(self, sql_session: Session) -> None:
super().__init__("Statistics from log", sql_session)
def _execute(self, **_kwargs) -> None:

View File

@@ -44,7 +44,7 @@ class Product(Base):
price: int,
stock: int = 0,
hidden: bool = False,
):
) -> None:
self.name = name
self.bar_code = bar_code
self.price = price

View File

@@ -34,7 +34,7 @@ class Purchase(Base):
)
entries: Mapped[set[PurchaseEntry]] = relationship(back_populates="purchase")
def __init__(self):
def __init__(self) -> None:
pass
def is_complete(self) -> bool:

View File

@@ -31,7 +31,12 @@ class PurchaseEntry(Base):
product: Mapped[Product] = relationship(back_populates="purchases", lazy="joined")
purchase: Mapped[Purchase] = relationship(back_populates="entries", lazy="joined")
def __init__(self, purchase, product, amount):
def __init__(
self,
purchase: Purchase,
product: Product,
amount: int,
) -> None:
self.product = product
self.product_bar_code = product.bar_code
self.purchase = purchase

View File

@@ -45,7 +45,7 @@ class Transaction(Base):
description: str | None = None,
purchase: Purchase | None = None,
penalty: int = 1,
):
) -> None:
self.user = user
self.amount = amount
self.description = description

View File

@@ -42,7 +42,7 @@ class User(Base):
card: str | None,
rfid: str | None = None,
credit: int = 0,
):
) -> None:
self.name = name
if card == "":
card = None
@@ -52,8 +52,8 @@ class User(Base):
self.rfid = rfid
self.credit = credit
def __str__(self):
def __str__(self) -> str:
return self.name
def is_anonymous(self):
def is_anonymous(self) -> bool:
return self.card == "11122233"

View File

@@ -43,7 +43,7 @@ from ..menus import (
random.seed()
def main(sql_session: Session):
def main(sql_session: Session) -> None:
if not config["general"]["stop_allowed"]:
set_signal_handler(SIGQUIT, SIG_IGN)

View File

@@ -5,5 +5,5 @@ from sqlalchemy.engine import Engine
from dibbler.models import Base
def main(engine: Engine):
def main(engine: Engine) -> None:
Base.metadata.create_all(engine)

View File

@@ -9,13 +9,13 @@ from dibbler.models.User import User
JSON_FILE = Path(__file__).parent.parent.parent / "mock_data.json"
def clear_db(sql_session: Session):
def clear_db(sql_session: Session) -> None:
sql_session.query(Product).delete()
sql_session.query(User).delete()
sql_session.commit()
def main(sql_session: Session):
def main(sql_session: Session) -> None:
clear_db(sql_session)
product_items = []
user_items = []

View File

@@ -5,7 +5,7 @@ from sqlalchemy.orm import Session
from dibbler.models import User
def main(sql_session: Session):
def main(sql_session: Session) -> None:
# Let's find all users with a negative credit
slabbedasker = sql_session.query(User).filter(User.credit < 0).all()

View File

@@ -40,11 +40,12 @@ select = [
"B", # flake8-bugbear
"C4", # flake8-comprehensions
"COM", # flake8-commas
"ANN",
# "E", # pycodestyle
# "F", # Pyflakes
"FA", # flake8-future-annotations
"I", # isort
# "S", # flake8-bandit
"S", # flake8-bandit
"ICN", # flake8-import-conventions
"ISC", # flake8-implicit-str-concat
# "N", # pep8-naming
@@ -56,6 +57,11 @@ select = [
"YTT", # flake8-2020
]
ignore = [
# line too long
"E501",
"E501", # line too long
"S101", # assert detected
"S311", # non-cryptographic random generator
]
[tool.ruff.lint.flake8-annotations]
suppress-dummy-args = true
ignore-fully-untyped = true