[build-system] requires = ["setuptools>=68", "wheel"] build-backend = "setuptools.build_meta" [project] name = "arautopilot" version = "0.1.0" description = "AR-Autopilot — Professional marine autopilot for 30-40 m vessels (Studio + firmware + display)" readme = "README.md" license = { file = "LICENSE.txt" } requires-python = ">=3.11" authors = [{ name = "Alvaro Romero", email = "alro65@gmail.com" }] keywords = ["marine", "autopilot", "pid", "nmea2000", "esp32", "vessel-control"] classifiers = [ "Development Status :: 2 - Pre-Alpha", "Intended Audience :: Manufacturing", "License :: Other/Proprietary License", "Operating System :: Microsoft :: Windows", "Operating System :: POSIX :: Linux", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Topic :: Scientific/Engineering", "Topic :: System :: Hardware", ] # Runtime dependencies — kept intentionally minimal for Sprint 0. # GUI (PySide6), Modbus (pymodbus), serial, etc. are added in later sprints. dependencies = [ "pydantic>=2.6,<3.0", "pyyaml>=6.0", "python-dateutil>=2.8", ] [project.optional-dependencies] dev = [ "pytest>=8.0", "pytest-cov>=4.1", "ruff>=0.4", "mypy>=1.10", "types-PyYAML", "types-python-dateutil", ] # Studio GUI -- Sprint 2.5+. Heavy (~80 MB), kept optional so the core can # be installed in lean environments (CI, headless test bench). # PySide6 >= 6.6 includes QtSerialPort on all platforms — no extra dep needed. studio = [ "PySide6>=6.6", "pyserial>=3.5", "platformio>=6.1", ] # Installer tooling — required on the developer's build machine. installer = [ "requests>=2.31", ] # License server — deploy to arelectronics.com VPS. license-server = [ "fastapi>=0.111", "uvicorn[standard]>=0.29", "sqlalchemy>=2.0", "pydantic>=2.7", "python-dotenv>=1.0", ] # AR Display Manager — multi-monitor app switcher for the Integrated Bridge System. # Same PySide6 dep as the Studio; listed separately so it can be installed standalone. display-manager = [ "PySide6>=6.6", ] [project.urls] Homepage = "https://github.com/alro65/AR-Autopilot" [tool.setuptools.packages.find] where = ["."] include = ["arautopilot*"] exclude = ["arautopilot.tests*"] [tool.setuptools.package-data] "arautopilot.library" = [ "actuators/*.json", "default_tunings/*.yaml", "vessel_profiles/*.yaml", "_schemas/*.json", ] # ---------------------------------------------------------------------------- # pytest # ---------------------------------------------------------------------------- [tool.pytest.ini_options] minversion = "8.0" testpaths = ["arautopilot/tests"] python_files = ["test_*.py"] python_classes = ["Test*"] python_functions = ["test_*"] addopts = [ "-ra", "--strict-markers", "--strict-config", "--showlocals", ] markers = [ "slow: marks tests as slow (deselect with '-m \"not slow\"')", "integration: marks integration tests", ] # ---------------------------------------------------------------------------- # Coverage # ---------------------------------------------------------------------------- [tool.coverage.run] source = ["arautopilot"] omit = [ "arautopilot/tests/*", "arautopilot/studio/*", # GUI not in scope for Sprint 0 ] [tool.coverage.report] exclude_lines = [ "pragma: no cover", "raise NotImplementedError", "if TYPE_CHECKING:", "if __name__ == .__main__.:", ] # ---------------------------------------------------------------------------- # Ruff (linting + formatting) # ---------------------------------------------------------------------------- [tool.ruff] line-length = 100 target-version = "py311" extend-exclude = [ "firmware", "display", "installer", ".venv", "build", "dist", ] [tool.ruff.lint] select = [ "E", # pycodestyle errors "W", # pycodestyle warnings "F", # pyflakes "I", # isort "B", # flake8-bugbear "C4", # flake8-comprehensions "UP", # pyupgrade "N", # pep8-naming "SIM", # flake8-simplify ] ignore = [ "E501", # line too long (handled by formatter) "B008", # function calls in default args (common with pydantic Field) ] [tool.ruff.lint.per-file-ignores] "arautopilot/tests/*" = ["N802", "N803"] # test names # ---------------------------------------------------------------------------- # mypy # ---------------------------------------------------------------------------- [tool.mypy] python_version = "3.11" strict = true warn_unused_ignores = true warn_redundant_casts = true plugins = ["pydantic.mypy"] exclude = [ "build/", "dist/", "firmware/", "display/", "installer/", "arautopilot/studio/", # GUI stubs, not in scope for Sprint 0 ] [[tool.mypy.overrides]] module = "arautopilot.tests.*" disallow_untyped_defs = false [tool.pydantic-mypy] init_forbid_extra = true init_typed = true warn_required_dynamic_aliases = true