folio / pyproject.toml
dystomachina's picture
feat: entrypoint for focli simulate
ff73b92
[tool.poetry]
name = "folio"
version = "0.1.0"
description = "Portfolio analysis and visualization tools"
authors = ["Dong Ming <d3ming@gmail.com>"]
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"]