Skip to content

Commit

Permalink
Merge pull request #10 from NorskRegnesentral/black_to_ruff
Browse files Browse the repository at this point in the history
[ENH] Use ruff formatter
  • Loading branch information
Tveten authored Aug 15, 2024
2 parents 71e8396 + 2f40025 commit 74bdd0f
Show file tree
Hide file tree
Showing 20 changed files with 169 additions and 161 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.8'
python-version: '3.9'
- name: Install Python dependencies
run: |
python -m pip install --upgrade pip
Expand Down
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -159,4 +159,6 @@ cython_debug/
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/

.vscode/
.vscode/

.ruff_cache/
62 changes: 8 additions & 54 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,80 +2,34 @@

repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
rev: v4.6.0
hooks:
- id: check-added-large-files
args: ["--maxkb=1000"]
args:
- --maxkb=1000
- id: check-case-conflict
- id: check-merge-conflict
- id: check-symlinks
- id: check-yaml
- id: debug-statements
- id: end-of-file-fixer
exclude: "^docs/source/examples/"
- id: fix-encoding-pragma
args:
- --remove
- id: requirements-txt-fixer
- id: trailing-whitespace

- repo: https://github.com/asottile/pyupgrade
rev: v3.10.1
hooks:
- id: pyupgrade
args:
- --py38-plus

- repo: https://github.com/pycqa/isort
rev: 5.12.0
hooks:
- id: isort
name: isort

- repo: https://github.com/psf/black
rev: 23.7.0
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.5.7
hooks:
- id: black
language_version: python3
# args: [--line-length 79]

- repo: https://github.com/pycqa/flake8
rev: 6.1.0
hooks:
- id: flake8
exclude: docs/conf.py
additional_dependencies: [flake8-bugbear, flake8-print]
- id: ruff-format
- id: ruff
args: [--fix]

- repo: https://github.com/mgedmin/check-manifest
rev: "0.49"
hooks:
- id: check-manifest
stages: [manual]

- repo: https://github.com/nbQA-dev/nbQA
rev: 1.7.0
hooks:
- id: nbqa-black
args: [--nbqa-mutate, --nbqa-dont-skip-bad-cells]
additional_dependencies: [black==22.3.0]
- id: nbqa-isort
args: [--nbqa-mutate, --nbqa-dont-skip-bad-cells]
additional_dependencies: [isort==5.6.4]
- id: nbqa-flake8
args: [--nbqa-dont-skip-bad-cells, "--extend-ignore=E402,E203"]
additional_dependencies: [flake8==3.8.3]

- repo: https://github.com/pycqa/pydocstyle
rev: 6.3.0
hooks:
- id: pydocstyle
args: ["--config=setup.cfg"]
exclude: |
(?x)^(
build_tools/.*|
interactive/.*
)$
# We use the Python version instead of the original version which seems to require Docker
# https://github.com/koalaman/shellcheck-precommit
- repo: https://github.com/shellcheck-py/shellcheck-py
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ A playground for now.
```sh
pip install skchange
```
Requires Python >= 3.8, < 3.13.
Requires Python >= 3.9, < 3.13.

## Quickstart

Expand Down
89 changes: 84 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,12 @@ classifiers = [
"Operating System :: POSIX",
"Operating System :: Unix",
"Operating System :: MacOS",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
]
requires-python = ">=3.8,<3.13"
requires-python = ">=3.9,<3.13"
dependencies = [
"numpy<1.27,>=1.21", # required for framework layer and base class logic
"pandas<2.2.0,>=1.3", # pandas is the main in-memory data container
Expand All @@ -53,19 +52,99 @@ all_extras = [

# dev - the developer dependency set, install via "pip install skchange[dev]"
dev = [
"black",
"pre-commit",
"pytest",
"pytest-cov",
]


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

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

[tool.black]
# 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"
20 changes: 0 additions & 20 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
[aliases]
test = pytest

[tool.isort]
profile = "black"
multi_line_output = 3

[tool:pytest]
# ignore certain folders and pytest warnings
addopts =
Expand All @@ -26,15 +22,6 @@ filterwarnings =
ignore:numpy.dtype size changed
ignore:numpy.ufunc size changed

[flake8]
# Default flake8 3.5 ignored flags
ignore = E121, E123, E126, E226, E24, E704, W503, W504
# inline with Black code formatter
max-line-length = 88
extend-ignore =
# See https://github.com/PyCQA/pycodestyle/issues/373
E203

[metadata]
description_file = README.md
long_description_content_type = text/markdown
Expand All @@ -53,10 +40,3 @@ ignore =
# CONTRIBUTING.md
# *.yaml
# *.yml

[isort]
profile = black

[pydocstyle]
convention = numpy
match = (?!test_).*\.py
9 changes: 5 additions & 4 deletions skchange/anomaly_detectors/capa.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
"""The collective and point anomalies (CAPA) algorithm."""

__author__ = ["mtveten"]
__all__ = ["Capa"]

from typing import Callable, List, Optional, Tuple, Union
from typing import Callable, Optional, Union

import numpy as np
import pandas as pd
Expand All @@ -25,7 +26,7 @@ def run_capa(
point_alpha: float,
min_segment_length: int,
max_segment_length: int,
) -> Tuple[np.ndarray, List[Tuple[int, int]], List[Tuple[int, int]]]:
) -> tuple[np.ndarray, list[tuple[int, int]], list[tuple[int, int]]]:
params = saving_init_func(X)
collective_betas = np.zeros(1)
point_betas = np.zeros(1)
Expand Down Expand Up @@ -106,7 +107,7 @@ class Capa(BaseSeriesAnnotator):

def __init__(
self,
saving: Union[str, Tuple[Callable, Callable]] = "mean",
saving: Union[str, tuple[Callable, Callable]] = "mean",
collective_penalty_scale: float = 2.0,
point_penalty_scale: float = 2.0,
min_segment_length: int = 2,
Expand All @@ -130,7 +131,7 @@ def __init__(
check_larger_than(2, min_segment_length, "min_segment_length")
check_larger_than(min_segment_length, max_segment_length, "max_segment_length")

def _get_penalty_components(self, X: pd.DataFrame) -> Tuple[np.ndarray, float]:
def _get_penalty_components(self, X: pd.DataFrame) -> tuple[np.ndarray, float]:
# TODO: Add penalty tuning.
# if self.tune:
# return self._tune_threshold(X)
Expand Down
14 changes: 7 additions & 7 deletions skchange/anomaly_detectors/circular_binseg.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
__author__ = ["mtveten"]
__all__ = ["CircularBinarySegmentation"]

from typing import Callable, List, Optional, Tuple, Union
from typing import Callable, Optional, Union

import numpy as np
import pandas as pd
Expand All @@ -25,7 +25,7 @@ def greedy_anomaly_selection(
starts: np.ndarray,
ends: np.ndarray,
threshold: float,
) -> List[Tuple[int, int]]:
) -> list[tuple[int, int]]:
scores = scores.copy()
anomalies = []
while np.any(scores > threshold):
Expand All @@ -41,7 +41,7 @@ def greedy_anomaly_selection(
@njit
def make_anomaly_intervals(
interval_start: int, interval_end: int, min_segment_length: int = 1
) -> Tuple[np.ndarray, np.ndarray]:
) -> tuple[np.ndarray, np.ndarray]:
starts = []
ends = []
for i in range(interval_start + 1, interval_end - min_segment_length + 2):
Expand All @@ -62,7 +62,7 @@ def run_circular_binseg(
min_segment_length: int,
max_interval_length: int,
growth_factor: float,
) -> Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray]:
) -> tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray]:
starts, ends = make_seeded_intervals(
X.shape[0],
2 * min_segment_length,
Expand Down Expand Up @@ -108,7 +108,7 @@ class CircularBinarySegmentation(BaseSeriesAnnotator):
Parameters
----------
score: str, Tuple[Callable, Callable], optional (default="mean")
score: str, tuple[Callable, Callable], optional (default="mean")
Test statistic to use for changepoint detection.
* If "mean", the difference-in-mean statistic is used,
* If "var", the difference-in-variance statistic is used,
Expand Down Expand Up @@ -152,7 +152,7 @@ class CircularBinarySegmentation(BaseSeriesAnnotator):
References
----------
.. [1] Olshen, A. B., Venkatraman, E. S., Lucito, R., & Wigler, M. (2004). Circular
binary segmentation for the analysis of arraybased DNA copy number data.
binary segmentation for the analysis of array-based DNA copy number data.
Biostatistics, 5(4), 557-572.
Examples
Expand All @@ -178,7 +178,7 @@ class CircularBinarySegmentation(BaseSeriesAnnotator):

def __init__(
self,
score: Union[str, Tuple[Callable, Callable]] = "mean",
score: Union[str, tuple[Callable, Callable]] = "mean",
threshold_scale: Optional[float] = 2.0,
level: float = 1e-8,
min_segment_length: int = 5,
Expand Down
Loading

0 comments on commit 74bdd0f

Please sign in to comment.