diff --git a/.gitignore b/.gitignore index e4f1a63408f2c8d3c386535babe1797c7bb76eb8..1287c575804425c85bfb8ea466ca806fd0810199 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ -**.pyc +*.pyc +*.egg-info/ .tox/ -*.egg-info diff --git a/.isort.cfg b/.isort.cfg deleted file mode 100644 index 386a610ebc5076d7980bdbaaaef3b4a8d07e4bf5..0000000000000000000000000000000000000000 --- a/.isort.cfg +++ /dev/null @@ -1,11 +0,0 @@ -[settings] -# Compatible with black -multi_line_output = 3 -include_trailing_comma = True -force_grid_wrap = 0 -use_parentheses = True -line_length = 120 - -default_section = FIRSTPARTY -known_first_party = arkindex_toolbox -known_third_party = setuptools,yaml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 86c7205a046ba771f04f6b2ea35766c4a772b57c..6822ad51ef073a172983fb3fa19f8f904baca909 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,22 +1,15 @@ repos: - - repo: https://github.com/pre-commit/mirrors-isort - rev: v5.10.1 + - repo: https://github.com/astral-sh/ruff-pre-commit + # Ruff version. + rev: v0.3.2 hooks: - - id: isort - - repo: https://github.com/ambv/black - rev: 22.6.0 - hooks: - - id: black - - repo: https://github.com/pycqa/flake8 - rev: 3.9.2 - hooks: - - id: flake8 - additional_dependencies: - - 'flake8-coding==1.3.1' - - 'flake8-copyright==0.2.2' - - 'flake8-debugger==3.1.0' + # Run the linter. + - id: ruff + args: [--fix, --exit-non-zero-on-fix] + # Run the formatter. + - id: ruff-format - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.3.0 + rev: v4.5.0 hooks: - id: check-ast - id: check-docstring-first @@ -31,9 +24,10 @@ repos: - id: name-tests-test args: ['--django'] - id: check-json + - id: check-toml - id: requirements-txt-fixer - repo: https://github.com/codespell-project/codespell - rev: v2.1.0 + rev: v2.2.6 hooks: - id: codespell args: ['--write-changes'] diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000000000000000000000000000000000000..bbb198cdcd29ce62a17f76775809ba457d2c30a4 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,36 @@ +[tool.ruff] +exclude = [".git", "__pycache__"] + +[tool.ruff.lint] +ignore = ["E501"] +select = [ + # pycodestyle + "E", + "W", + # Pyflakes + "F", + # Flake8 Debugger + "T1", + # Isort + "I", + # Implicit Optional + "RUF013", + # Invalid pyproject.toml + "RUF200", + # pyupgrade + "UP", + # flake8-bugbear + "B", + # flake8-simplify + "SIM", + # flake8-use-pathlib + "PTH", +] + +[tool.ruff.per-file-ignores] +# Ignore `pytest-composite-assertion` rules of `flake8-pytest-style` linter for non-test files +"teklia_toolbox/**/*.py" = ["PT018"] + +[tool.ruff.isort] +known-first-party = ["teklia_toolbox"] +known-third-party = ["pytest", "setuptools"] diff --git a/setup.py b/setup.py index a9a0dfc700bad16280ef7497653bbb9870da37aa..1a2ccf49631b26f974df87aee361ca4d2e42bc89 100644 --- a/setup.py +++ b/setup.py @@ -1,27 +1,26 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- -import os.path +from pathlib import Path from setuptools import find_packages, setup def requirements(path): - assert os.path.exists(path), "Missing requirements {}".format(path) - with open(path) as f: + assert path.exists(), f"Missing requirements {path}" + with path.open() as f: return list(map(str.strip, f.read().splitlines())) -with open("VERSION") as f: +with Path("VERSION").open() as f: VERSION = f.read() -install_requires = requirements("requirements.txt") +install_requires = requirements(Path("requirements.txt")) setup( name="teklia-toolbox", version=VERSION, author="Teklia", author_email="contact@teklia.com", - python_requires=">=3.7", + python_requires=">=3.10", install_requires=install_requires, packages=find_packages(), include_package_data=True, diff --git a/teklia_toolbox/config.py b/teklia_toolbox/config.py index f46babbc69d9f2aea443ef1286f34705e3ef028d..1d9923f86d6513bbafeff954a471097e089dec84 100644 --- a/teklia_toolbox/config.py +++ b/teklia_toolbox/config.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import json import os import sys @@ -53,10 +52,10 @@ class ConfigurationError(ValueError): return json.dumps(self.errors) def __repr__(self): - return "{}({!s})".format(self.__class__.__name__, self) + return f"{self.__class__.__name__}({self!s})" -class ConfigParser(object): +class ConfigParser: def __init__(self, allow_extra_keys=True): """ :param allow_extra_keys bool: Ignore extra unspecified keys instead @@ -126,5 +125,4 @@ class ConfigParser(object): if not path.is_file() and exist_ok: # Act like the file is empty return self.parse_data({}) - with open(path) as f: - return self.parse_data(yaml.safe_load(f)) + return self.parse_data(yaml.safe_load(path.read_bytes())) diff --git a/teklia_toolbox/time.py b/teklia_toolbox/time.py index 3bc906706da7cbad442e96528a143311dfd82251..20ae3acbbe1bfba4e10f13c0068f000489a45ca1 100644 --- a/teklia_toolbox/time.py +++ b/teklia_toolbox/time.py @@ -1,9 +1,8 @@ -# -*- coding: utf-8 -*- import datetime from timeit import default_timer -class Timer(object): +class Timer: """ A context manager to help measure execution times """ diff --git a/tests/test_config.py b/tests/test_config.py index fd8c472b2de91a9cd29b6812273269aff875d49d..5f81605a2a4cb3697ce9848efa6c8a19335bf369 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import tempfile from pathlib import Path from unittest import TestCase diff --git a/tests/test_time.py b/tests/test_time.py index bb2c0bde43c28412b5f1c12fb3f7635863d57978..721b305ddc2f07e109a1f45b12b3ecd8f0aa2fce 100644 --- a/tests/test_time.py +++ b/tests/test_time.py @@ -1,12 +1,9 @@ -# -*- coding: utf-8 -*- - import time from teklia_toolbox.time import Timer def test_timer(): - with Timer() as t: time.sleep(0.05)