content: [build-system]
  requires = ["poetry-core>=1.0.0", "poetry-dynamic-versioning"]
  build-backend = "poetry_dynamic_versioning.backend"
  
  [project]
  name = "whos-there"
  requires-python = ">=3.10"
  
  # TODO: https://github.com/python-poetry/poetry/issues/3332
  [tool.poetry]
  name = "whos-there"
  version = "0.0.0"
  description = "The spiritual successor to knockknock for PyTorch Lightning, get notified when your training ends"
  authors = ["twsl <45483159+twsl@users.noreply.github.com>"]
  maintainers = ["twsl <45483159+twsl@users.noreply.github.com>"]
  license = "MIT"
  readme = "README.md"
  repository = "https://github.com/twsl/whos-there"
  homepage = "https://twsl.github.io/whos-there/"
  packages = [ { include = "whos_there", from = "src" } ]
  keywords = [
    "python",
    "pytorch",
    "pytorch-lightning",
    "machine-learning",
    "deep-learning"
  ]
  # Pypi classifiers: https://pypi.org/classifiers/
  classifiers = [
      "Topic :: Software Development"
  ]
  
  [tool.poetry.urls]
  issues = "https://github.com/twsl/whos-there/issues"
  
  [tool.poetry.dependencies]
  python = "^3.10"
  lightning = "^2.4.0"
  python-telegram-bot = "^21.8"
  requests = "^2.32.3"
  
  [tool.poetry.group.dev.dependencies]
  ruff = "^0.8.1"
  bandit = "^1.8.0"
  pre-commit = "^4.0.1"
  pyright = "^1.1.389"
  ipykernel = "^6.29.5"
  ipywidgets = "^8.1.5"
  ipython = "^8.30.0"
  jupytext = " ^1.16.4"
  nbconvert = "^7.16.3"
  
  [tool.poetry.group.test.dependencies]
  pytest = "^8.3.4"
  pytest-cov = "^6.0.0"
  pytest-mock = "^3.12.0"
  pytest-cases = "^3.8.6"
  pytest-benchmark = "^5.1.0"
  
  [tool.poetry.group.docs.dependencies]
  mkdocs = "^1.6.1"
  mkdocs-material = "^9.5.47"
  mkdocs-git-revision-date-localized-plugin = "^1.2.9"
  mkdocs-awesome-pages-plugin = "^2.9.3"
  mkdocs-git-authors-plugin = "^0.9.1"
  mkapi = "^3.0.22"
  markdown-callouts = "^0.4.0"
  pygments = "^2.18.0"
  mkdocs-jupyter = "^0.25.1"
  
  [tool.poetry.group.debug]
  optional = true
  
  [tool.poetry.group.debug.dependencies]
  ipdb = "^0.13.9"
  line_profiler = "^4.1.3"
  
  [tool.poetry.scripts]
  whos-there = "whos_there.cli:main"
  
  [tool.poetry-dynamic-versioning]
  enable = false
  vcs = "git"
  style = "semver"
  pattern = "default-unprefixed"
  
  [tool.poetry-dynamic-versioning.substitution]
  folders = [
    { path = "src/whos_there" }
  ]
  
  [tool.poetry-dynamic-versioning.files."src/whos_there/__about__.py"]
  persistent-substitution = false
  initial-content = """
  # file generated by poetry dynamic versioning during poetry build/install
  # don't change, don't track in version control
  __version__ = "0.0.0"
  __version_tuple__ = (0, 0, 0)
  """
  
  [tool.pytest.ini_options]
  minversion = "8.0"
  # https://code.visualstudio.com/docs/python/testing#_pytest-configuration-settings
  addopts = "--doctest-glob='test_*.md' --cov=src/whos_there --cov-report xml"
  testpaths = [
      "tests",
  ]
  
  [tool.coverage.run]
  branch = true
  omit = [
      "tests/*",
  ]
  
  [tool.coverage.report]
  exclude_lines = [
      # Have to re-enable the standard pragma
      "pragma: no cover",
  
      # Don't complain about missing debug-only code:
      "def __repr__",
      "if self.debug:",
      "if debug:",
      "if DEBUG:",
  
      # Don't complain if tests don't hit defensive assertion code:
      "raise AssertionError",
      "raise NotImplementedError",
  
      # Don't complain if non-runnable code isn't run:
      "if 0:",
      "if False:",
      "if __name__ == .__main__.:",
  ]
  
  [tool.ruff]
  line-length = 120  # Must agree with Black
  extend-include = ["*.ipynb"]
  exclude = [
      "migrations",
      "__pycache__",
      "env",
      ".env",
      "venv",
      ".venv",
  ]
  
  [tool.ruff.lint]
  select = [
      "B",  # flake8-bugbear
      "C4", # flake8-comprehensions
      "D",  # pydocstyle
      "E",  # Error
      "F",  # pyflakes
      "I",  # isort
      "ISC", # flake8-implicit-str-concat
      "N",  # pep8-naming
      "PGH",  # pygrep-hooks
      "PTH", # flake8-use-pathlib
      "Q",  # flake8-quotes
      "S",  # bandit
      "SIM",  # flake8-simplify
      "TRY",  # tryceratops
      "UP",  # pyupgrade
      "W",  # Warning
      "YTT", # flake8-2020
  ]
  extend-select = [
      "I",
  ]
  ignore = [
      "D100",
      "D101",
      "D102",
      "D103",
      "D104",
      "D105",
      "D106",
      "D107",
      "D200",
      "D401",
      "E402",
      "E501",
      "F401",
      "TRY002", # Allow default exceptions
      "TRY003",  # Avoid specifying messages outside exception class; overly strict, especially for ValueError
  ]
  
  [tool.ruff.lint.flake8-bugbear]
  extend-immutable-calls = [
      "chr",
      "typer.Argument",
      "typer.Option",
  ]
  
  [tool.ruff.lint.pydocstyle]
  convention = "google"
  
  [tool.ruff.lint.pycodestyle]
  max-doc-length = 120
  max-line-length = 120
  
  [tool.ruff.lint.per-file-ignores]
  "test*/**/*.py" = [
      "D100",
      "D101",
      "D102",
      "D103",
      "D104",
      "D105",
      "D106",
      "D107",
      "S101",  # use of "assert"
      "S102",  # use of "exec"
      "S106",  # possible hardcoded password.
      "PGH001",  # use of "eval"
  ]
  
  [tool.ruff.lint.pep8-naming]
  staticmethod-decorators = [
      "pydantic.validator",
      "pydantic.root_validator",
  ]
  
  [tool.ruff.lint.isort]
  force-sort-within-sections = true
  
  [tool.ruff.format]
  docstring-code-format = true
  quote-style = "double"
  
  [tool.bandit.assert_used]
  skips = ['*_test.py', '*/test_*.py']
  
  [tool.pyright]
  pythonVersion = "3.11"
  pythonPlatform = "Linux"
  include = ["src"]
  reportMissingImports = true
  reportMissingTypeStubs = false
  reportIncompatibleMethodOverride = true
  
  [virtualenvs]
  in-project = true
  