[project]
name = "skchange"
version = "0.9.0"
description = "Sktime-compatible change and anomaly detection"
authors = [
    {name = "Martin Tveten", email = "tveten@nr.no"},
]
maintainers = [
    {name = "Martin Tveten", email = "tveten@nr.no"},
    {name = "Johannes Voll Kolstø", email = "jvkolsto@nr.no"},
]
readme = "README.md"
keywords = [
    "data-science",
    "machine-learning",
    "statistics",
    "scikit-learn",
    "time-series",
    "change-detection",
    "anomaly-detection",
]
classifiers = [
    "Intended Audience :: Science/Research",
    "License :: OSI Approved :: BSD License",
    "Programming Language :: Python",
    "Topic :: Scientific/Engineering",
    "Operating System :: Microsoft :: Windows",
    "Operating System :: POSIX",
    "Operating System :: Unix",
    "Operating System :: MacOS",
    "Programming Language :: Python :: 3.9",
    "Programming Language :: Python :: 3.10",
    "Programming Language :: Python :: 3.11",
    "Programming Language :: Python :: 3.12",
]
requires-python = ">=3.9,<3.13"
dependencies = [
  "numpy>=1.21",
  "pandas>=1.1",
  "sktime>=0.33",
]

[project.urls]
Homepage = "https://skchange.readthedocs.io"

[project.optional-dependencies]
# numba - numba as an optional dependency, install via "pip install skchange[numba]"
numba = [
  "numba>=0.56"
]

# all_extras - all soft dependencies, install via "pip install skchange[all_extras]"
all_extras = [
  "optuna>=3.1.1",
  "plotly>=5.13.0",
  "numba>=0.56",
]

# dev - the developer dependency set, install via "pip install skchange[dev]"
dev = [
    "pre-commit",
    "pytest",
    "pytest-cov",
    "ipykernel",
    "plotly",
    "nbformat>=4.2.0",
]

docs = [
  "myst-parser",
  "numpydoc",
  "pydata-sphinx-theme",
  "Sphinx!=7.2.0,<9.0.0",
  "sphinx-copybutton",
  "sphinx-design<0.7.0",
  "sphinx-gallery<0.18.0",
  "sphinx-issues<5.0.0",
  "tabulate",
]

[build-system]
build-backend = "setuptools.build_meta"
requires = ["setuptools>61"]

[tool.setuptools.packages.find]
exclude = ["tests", "tests.*"]

# ruff setting adapted from sktime
[tool.ruff]
line-length = 88
exclude = [".git"]
target-version = "py39"
extend-include = ["*.ipynb"]

[tool.ruff.lint]
select = [
  # https://pypi.org/project/pycodestyle
  "D",
  "E",
  "W",
  # https://pypi.org/project/pyflakes
  "F",
  # https://pypi.org/project/flake8-bandit
  "S",
  # https://docs.astral.sh/ruff/rules/#pyupgrade-up
  "UP",
  "I002",    # Missing required imports
  "UP008",   # Super calls with redundant arguments passed.
  "G010",    # Deprecated log warn.
  "PLR1722", # Use sys.exit() instead of exit() and quit().
  "PT014",   # pytest-duplicate-parametrize-test-cases.
  "PT006",   # Checks for the type of parameter names passed to pytest.mark.parametrize.
  "PT007",   # Checks for the type of parameter values passed to pytest.mark.parametrize.
  "PT018",   # Checks for assertions that combine multiple independent condition
  "RUF001", # Checks for non unicode string literals
  "RUF002", # Checks for non unicode string literals
  "RUF003", # Checks for non unicode string literals
]
extend-select = [
  "I", # isort
  "C4", # https://pypi.org/project/flake8-comprehensions
]
ignore=[
  "E203", # Whitespace-before-punctuation.
  "E402", # Module-import-not-at-top-of-file.
  "E731", # Do not assign a lambda expression, use a def.
  "RET504", # Unnecessary variable assignment before `return` statement.
  "S101", # Use of `assert` detected.
  "RUF100", # https://docs.astral.sh/ruff/rules/unused-noqa/
  "C408", # Unnecessary dict call - rewrite as a literal.
  "UP031", # Use format specifier instead of %
  "S102", # Use of excec
  "C414", # Unnecessary `list` call within `sorted()`
  "S301", # pickle and modules that wrap it can be unsafe
  "C416", # Unnecessary list comprehension - rewrite as a generator
  "S310", # Audit URL open for permitted schemes
  "S202", # Uses of `tarfile.extractall()`
  "S307", # Use of possibly insecure function
  "C417", # Unnecessary `map` usage (rewrite using a generator expression)
  "S605", # Starting a process with a shell, possible injection detected
  "E741", # Ambiguous variable name
  "S107", # Possible hardcoded password
  "S105", # Possible hardcoded password
  "PT018", # Checks for assertions that combine multiple independent condition
  "S602", # sub process call with shell=True unsafe
  "C419", # Unnecessary list comprehension, some are flagged yet are not
  "C409", # Unnecessary `list` literal passed to `tuple()` (rewrite as a `tuple` literal)
  "S113", # Probable use of httpx call withour timeout
]
allowed-confusables=["σ"]

[tool.ruff.lint.per-file-ignores]

"setup.py" = ["S101"]
"**/__init__.py" = [
  "F401", # unused import
]
"**/tests/**" = [
  "D",
  "S605",  # Starting a process with a shell: seems safe, but may be changed in the future; consider rewriting without `shell`
  "S607",  # Starting a process with a partial executable path
  "RET504",  # todo:Unnecessary variable assignment before `return` statement
  "PT004",  # Fixture `tmpdir_unittest_fixture` does not return anything, add leading underscore
  "PT011",  # `pytest.raises(ValueError)` is too broad, set the `match` parameter or use a more specific exception
  "PT012",  # `pytest.raises()` block should contain a single simple statement
  "PT019",  # Fixture `_` without value is injected as parameter, use `@pytest.mark.usefixtures` instead
  "PT006" # Checks for the type of parameter names passed to pytest.mark.parametrize.
]

[tool.ruff.lint.pydocstyle]
convention = "numpy"

[tool.coverage.run]
omit = [
  "*/tests/*",
  "*/test_*.py"
]
