[tool.poetry] name = "folio" version = "0.1.0" description = "Portfolio analysis and visualization tools" authors = ["Dong Ming "] readme = "README.md" packages = [{include = "src"}] [tool.poetry.dependencies] python = "^3.9" # Compatible with Python 3.9 and above pandas = "2.2.1" numpy = "1.26.4" quantlib = ">=1.30" requests = ">=2.32.0" pyyaml = "6.0.1" yfinance = ">=0.2.37" dash = ">=2.14.2" dash-bootstrap-components = ">=1.5.0" dash-bootstrap-templates = ">=1.1.1" gunicorn = ">=21.2.0" google-generativeai = ">=0.3.0" # The dev group includes both development tools (linting, testing) # and CLI tools (focli interactive shell) [tool.poetry.group.dev.dependencies] ruff = "^0.11.7" pytest = "^8.3.5" pytest-mock = "^3.14.0" # Added for mocking in tests rich = ">=13.9.0" prompt-toolkit = ">=3.0.43" pre-commit = "^4.2.0" [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" [tool.mypy] python_version = "3.11" warn_return_any = true warn_unused_configs = true disallow_untyped_defs = true disallow_incomplete_defs = true check_untyped_defs = true disallow_untyped_decorators = true no_implicit_optional = true warn_redundant_casts = true warn_unused_ignores = true warn_no_return = true warn_unreachable = true strict_optional = true plugins = ["numpy.typing.mypy_plugin"] [[tool.mypy.overrides]] module = "dash.*" ignore_missing_imports = true [[tool.mypy.overrides]] module = "pandas.*" ignore_missing_imports = true [tool.ruff] # Line length and target version are top-level line-length = 88 target-version = "py311" [tool.ruff.lint] # Enable recommended rules + specific ones useful for data science projects select = [ "E", # pycodestyle errors "F", # pyflakes "I", # isort "N", # pep8-naming "UP", # pyupgrade "PL", # pylint "RUF", # ruff-specific rules "W", # pycodestyle warnings "F401", # Module imported but unused "F841", # Local variable is assigned to but never used "F821", # Undefined name "F811", # Redefined name "F822", # Undefined name in __all__ "PLC0414", # Useless import alias "PLE0101", # Function defined outside __init__ "PLE0604", # Invalid object in __all__, or invalid __all__ format "PLE0605", # Invalid format for __all__ "A", # Unused functions... etc. "ARG001", # Unused function argument "ARG002", # Unused function argument "B", # flake8-bugbear rules (includes B007 for unused loop variables) "ERA", # eradicate (commented out code) "F", # pyflakes (includes F401 for unused imports, F841 for unused variables) "T201", # print statements ] # Ignore specific rules ignore = [ "E501", # line too long - let's handle line length more flexibly for data science code "N803", # argument name should be lowercase - common in ML to use X, y "N806", # variable name should be lowercase - common in ML to use X_train, y_test "PLR0913", # too many arguments - common in ML functions with many parameters "PLR0912", # too many branches - common in ML data processing and training loops "PLR0915", # too many statements - common in ML training and evaluation functions "PLR2004", # magic value used in comparison - common in data processing code ] # Allow autofix for all enabled rules (when `--fix`) is provided fixable = ["ALL"] # Exclude a variety of commonly ignored directories exclude = [ ".git", ".venv", "venv", "__pycache__", "build", "dist", "mlruns", ".pytest_cache", ".archive", ] # Allow unused variables when underscore-prefixed dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$" [tool.ruff.lint.per-file-ignores] # DO NOT IGNORE UNLESS IT'S A REALLY GOOD REASON! "__init__.py" = ["F401"] # Re-exports are common in __init__.py files [tool.ruff.lint.isort] known-first-party = ["src"]