[project] name = "musicmouse" version = "2.0.0" description = "Host backend for the MusicMouse RFID music player" requires-python = ">=3.13" dependencies = [ "aiomqtt>=2.0", "pydantic>=2.7", "pyserial-asyncio>=0.6", "python-vlc>=3.0", "ruamel.yaml>=0.18", ] [project.optional-dependencies] dev = ["mypy>=1.10", "pytest-asyncio>=0.23", "pytest>=8.0", "ruff>=0.5"] [project.scripts] musicmouse = "musicmouse.__main__:main" [build-system] requires = ["setuptools>=68"] build-backend = "setuptools.build_meta" [tool.setuptools.packages.find] include = ["musicmouse*"] [tool.pytest.ini_options] testpaths = ["tests"] asyncio_mode = "auto" asyncio_default_fixture_loop_scope = "function" filterwarnings = ["error"] [tool.ruff] line-length = 100 target-version = "py313" # Course material and scratch work, not part of the backend. See notebooks/README.md. extend-exclude = ["notebooks"] [tool.ruff.lint] select = ["ARG", "B", "C4", "E", "F", "I", "N", "PTH", "RUF", "SIM", "UP", "W"] [tool.ruff.lint.per-file-ignores] "tests/*" = ["ARG001"] # Entity is an ABC with optional hooks: empty bodies and unused args are the point. "musicmouse/services/mqtt/entity.py" = ["ARG002", "B027"] [tool.mypy] python_version = "3.13" strict = true files = ["musicmouse"] warn_unreachable = true [[tool.mypy.overrides]] module = ["vlc", "serial_asyncio", "ruamel.*"] ignore_missing_imports = true