diff --git a/pyproject.toml b/pyproject.toml index 549fd7ae..c68d7d6d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,157 +1,157 @@ -[project] -name = "forecastlabai" -version = "0.1.0" -description = "Portfolio-grade end-to-end retail demand forecasting system" -readme = "README.md" -requires-python = ">=3.12" -license = { text = "MIT" } -authors = [{ name = "ForecastLabAI Team" }] -dependencies = [ - "fastapi>=0.115.0", - "uvicorn[standard]>=0.32.0", - "pydantic>=2.10.0", - "pydantic-settings>=2.6.0", - "sqlalchemy[asyncio]>=2.0.36", - "asyncpg>=0.30.0", - "structlog>=24.4.0", - "alembic>=1.14.0", - "python-dotenv>=1.0.1", -] - -[project.optional-dependencies] -dev = [ - "pytest>=8.3.0", - "pytest-asyncio>=0.24.0", - "pytest-cov>=6.0.0", - "httpx>=0.28.0", - "ruff>=0.8.0", - "mypy>=1.13.0", - "pyright>=1.1.390", -] - -[build-system] -requires = ["hatchling"] -build-backend = "hatchling.build" - -[tool.hatch.build.targets.wheel] -packages = ["app"] - -# ============================================================================= -# Ruff Configuration (per docs/validation/ruff-standard.md) -# ============================================================================= -[tool.ruff] -target-version = "py312" -line-length = 100 - -exclude = [ - ".git", - ".venv", - "venv", - "__pycache__", - ".mypy_cache", - ".pytest_cache", - ".ruff_cache", - "alembic/versions", -] - -[tool.ruff.lint] -select = [ - "E", # pycodestyle errors - "W", # pycodestyle warnings - "F", # pyflakes - "I", # isort (import sorting) - "B", # flake8-bugbear (catch mutable defaults, etc.) - "C4", # flake8-comprehensions - "UP", # pyupgrade (modernize syntax) - "ANN", # flake8-annotations (enforce type hints) - "S", # flake8-bandit (security) - "DTZ", # flake8-datetimez (timezone-aware datetimes) - "RUF", # Ruff-specific rules - "ARG", # flake8-unused-arguments - "PTH", # flake8-use-pathlib (prefer Path over os.path) -] - -ignore = [ - "S311", # Standard random is fine for non-crypto use - "E501", # Line too long (formatter handles this) -] - -[tool.ruff.lint.per-file-ignores] -"tests/**/*.py" = ["S101", "ANN", "ARG001", "D", "E731"] -"test_*.py" = ["S101", "ANN", "ARG001", "D", "E731"] -"**/tests/**/*.py" = ["S101", "ANN", "ARG001", "D", "E731"] -"__init__.py" = ["F401"] -"scripts/**/*.py" = ["T201", "ANN", "S101"] -"examples/**/*.py" = ["T201", "ANN"] -"app/core/health.py" = ["B008"] -"alembic/env.py" = ["ANN"] - -[tool.ruff.format] -quote-style = "double" -indent-style = "space" -line-ending = "auto" - -[tool.ruff.lint.isort] -known-first-party = ["app"] - -# ============================================================================= -# MyPy Configuration (per docs/validation/mypy-standard.md) -# ============================================================================= -[tool.mypy] -python_version = "3.12" -strict = true -show_error_codes = true -warn_unused_ignores = true - -# Practical adjustments -disallow_untyped_defs = true -disallow_incomplete_defs = true -check_untyped_defs = true -disallow_untyped_decorators = false # FastAPI decorators aren't typed - -[[tool.mypy.overrides]] -module = "*.tests.*" -disallow_untyped_defs = false - -[[tool.mypy.overrides]] -module = "tests.*" -disallow_untyped_defs = false - -[[tool.mypy.overrides]] -module = "alembic.*" -ignore_errors = true - -# ============================================================================= -# Pyright Configuration (per docs/validation/pyright-standard.md) -# ============================================================================= -[tool.pyright] -include = ["app"] -exclude = [ - "**/__pycache__", - ".venv", - ".mypy_cache", - ".pytest_cache", - ".ruff_cache", - "alembic", - "**/tests/**", - "tests", -] -pythonVersion = "3.12" -pythonPlatform = "Linux" -typeCheckingMode = "strict" - -# Test files can have unused functions (fixtures, route handlers) -reportUnusedFunction = "none" - -# ============================================================================= -# Pytest Configuration (per docs/validation/pytest-standard.md) -# ============================================================================= -[tool.pytest.ini_options] -asyncio_mode = "auto" -testpaths = ["app", "tests"] -markers = [ - "integration: marks tests requiring real database (deselect with '-m \"not integration\"')", -] -filterwarnings = [ - "ignore::DeprecationWarning", -] +[project] +name = "forecastlabai" +version = "0.1.0" +description = "Portfolio-grade end-to-end retail demand forecasting system" +readme = "README.md" +requires-python = ">=3.12" +license = { text = "MIT" } +authors = [{ name = "ForecastLabAI Team" }] +dependencies = [ + "fastapi>=0.115.0", + "uvicorn[standard]>=0.32.0", + "pydantic>=2.10.0", + "pydantic-settings>=2.6.0", + "sqlalchemy[asyncio]>=2.0.36", + "asyncpg>=0.30.0", + "structlog>=24.4.0", + "alembic>=1.14.0", + "python-dotenv>=1.0.1", +] + +[project.optional-dependencies] +dev = [ + "pytest>=8.3.0", + "pytest-asyncio>=0.24.0", + "pytest-cov>=6.0.0", + "httpx>=0.28.0", + "ruff>=0.8.0", + "mypy>=1.13.0", + "pyright>=1.1.390", +] + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.hatch.build.targets.wheel] +packages = ["app"] + +# ============================================================================= +# Ruff Configuration (per docs/validation/ruff-standard.md) +# ============================================================================= +[tool.ruff] +target-version = "py312" +line-length = 100 + +exclude = [ + ".git", + ".venv", + "venv", + "__pycache__", + ".mypy_cache", + ".pytest_cache", + ".ruff_cache", + "alembic/versions", +] + +[tool.ruff.lint] +select = [ + "E", # pycodestyle errors + "W", # pycodestyle warnings + "F", # pyflakes + "I", # isort (import sorting) + "B", # flake8-bugbear (catch mutable defaults, etc.) + "C4", # flake8-comprehensions + "UP", # pyupgrade (modernize syntax) + "ANN", # flake8-annotations (enforce type hints) + "S", # flake8-bandit (security) + "DTZ", # flake8-datetimez (timezone-aware datetimes) + "RUF", # Ruff-specific rules + "ARG", # flake8-unused-arguments + "PTH", # flake8-use-pathlib (prefer Path over os.path) +] + +ignore = [ + "S311", # Standard random is fine for non-crypto use + "E501", # Line too long (formatter handles this) +] + +[tool.ruff.lint.per-file-ignores] +"tests/**/*.py" = ["S101", "ANN", "ARG001", "D", "E731"] +"test_*.py" = ["S101", "ANN", "ARG001", "D", "E731"] +"**/tests/**/*.py" = ["S101", "ANN", "ARG001", "D", "E731"] +"__init__.py" = ["F401"] +"scripts/**/*.py" = ["T201", "ANN", "S101"] +"examples/**/*.py" = ["T201", "ANN"] +"app/core/health.py" = ["B008"] +"alembic/env.py" = ["ANN"] + +[tool.ruff.format] +quote-style = "double" +indent-style = "space" +line-ending = "auto" + +[tool.ruff.lint.isort] +known-first-party = ["app"] + +# ============================================================================= +# MyPy Configuration (per docs/validation/mypy-standard.md) +# ============================================================================= +[tool.mypy] +python_version = "3.12" +strict = true +show_error_codes = true +warn_unused_ignores = true + +# Practical adjustments +disallow_untyped_defs = true +disallow_incomplete_defs = true +check_untyped_defs = true +disallow_untyped_decorators = false # FastAPI decorators aren't typed + +[[tool.mypy.overrides]] +module = "*.tests.*" +disallow_untyped_defs = false + +[[tool.mypy.overrides]] +module = "tests.*" +disallow_untyped_defs = false + +[[tool.mypy.overrides]] +module = "alembic.*" +ignore_errors = true + +# ============================================================================= +# Pyright Configuration (per docs/validation/pyright-standard.md) +# ============================================================================= +[tool.pyright] +include = ["app"] +exclude = [ + "**/__pycache__", + ".venv", + ".mypy_cache", + ".pytest_cache", + ".ruff_cache", + "alembic", + "**/tests/**", + "tests", +] +pythonVersion = "3.12" +pythonPlatform = "Linux" +typeCheckingMode = "strict" + +# Test files can have unused functions (fixtures, route handlers) +reportUnusedFunction = "none" + +# ============================================================================= +# Pytest Configuration (per docs/validation/pytest-standard.md) +# ============================================================================= +[tool.pytest.ini_options] +asyncio_mode = "auto" +testpaths = ["app", "tests"] +markers = [ + "integration: marks tests requiring real database (deselect with '-m \"not integration\"')", +] +filterwarnings = [ + "ignore::DeprecationWarning", +]