diff --git a/.flake8 b/.flake8 deleted file mode 100644 index 9c24de2..0000000 --- a/.flake8 +++ /dev/null @@ -1,5 +0,0 @@ -[flake8] -ignore = E203, E266, E501, W503 -max-line-length = 80 -max-complexity = 16 -select = B,C,E,F,W,T4,B9 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7af072a..841048c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -11,29 +11,20 @@ ci: autoupdate_schedule: monthly repos: -- repo: https://github.com/psf/black - rev: 23.10.0 +- repo: https://github.com/hadialqattan/pycln + rev: v2.4.0 hooks: - - id: black -- repo: https://github.com/PyCQA/isort - rev: 5.12.0 + - id: pycln + args: [ --config=pyproject.toml ] +- repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.4.4 hooks: - - id: isort - additional_dependencies: [tomli] # to read config from pyproject.toml -- repo: https://github.com/humitos/mirrors-autoflake - rev: v1.1 - hooks: - - id: autoflake -- repo: https://github.com/PyCQA/flake8 - rev: 6.1.0 - hooks: - - id: flake8 -- repo: https://github.com/asottile/pyupgrade - rev: v3.15.0 - hooks: - - id: pyupgrade - args: [--py39-plus] -# exclude: plates + - id: ruff + args: + - --fix + - --exit-non-zero-on-fix +# - --unsafe-fixes + - id: ruff-format - repo: https://github.com/pre-commit/mirrors-mypy rev: v1.6.1 hooks: diff --git a/devtools/add_url_tag_sha256.py b/devtools/add_url_tag_sha256.py index 87cc3c9..f2ee2df 100644 --- a/devtools/add_url_tag_sha256.py +++ b/devtools/add_url_tag_sha256.py @@ -22,6 +22,7 @@ from pathlib import Path from urllib import request + _url_filename_re = re.compile(".*/([^/]*)") diff --git a/devtools/check-copyright.py b/devtools/check-copyright.py index 78a0cad..5d0be7b 100644 --- a/devtools/check-copyright.py +++ b/devtools/check-copyright.py @@ -12,6 +12,7 @@ import sys from datetime import date + if __name__ == "__main__": current_year = date.today().year copyright_re = re.compile( diff --git a/devtools/git_message_hook.py b/devtools/git_message_hook.py index 0ae404a..2402bbf 100644 --- a/devtools/git_message_hook.py +++ b/devtools/git_message_hook.py @@ -124,8 +124,7 @@ def check_commit_message(filepath: str) -> tuple[bool, str]: if branch_jira_id and message_jira_id and branch_jira_id != message_jira_id: return ( False, - "Different JIRA ID in commit message %s and in branch name %s." - % (message_jira_id, branch_jira_id), + f"Different JIRA ID in commit message {message_jira_id} and in branch name {branch_jira_id}.", ) stripped_message_line = "" @@ -140,8 +139,8 @@ def check_commit_message(filepath: str) -> tuple[bool, str]: if len(stripped_message_line) < min_required_length: return ( False, - "First line of commit message must be at least %s characters long, " - "beyond the JIRA ID." % min_required_length, + f"First line of commit message must be at least {min_required_length} characters long, " + "beyond the JIRA ID.", ) return True, "" @@ -156,9 +155,8 @@ def check_commit_msg(filepath: str) -> None: (is_valid, error_message) = check_commit_message(filepath) if not is_valid: print( - """commit-msg hook: **ERROR** %s - Message has been saved to %s.""" - % (error_message, filepath) + f"""commit-msg hook: **ERROR** {error_message} + Message has been saved to {filepath}.""" ) sys.exit(1) diff --git a/devtools/rename_my_app.py b/devtools/rename_my_app.py index 3d07ce9..7a3e52c 100644 --- a/devtools/rename_my_app.py +++ b/devtools/rename_my_app.py @@ -15,6 +15,7 @@ import subprocess from pathlib import Path + logger = logging.getLogger(__name__) THIS_FILE = Path(__file__).resolve() diff --git a/devtools/run_conda_lock.py b/devtools/run_conda_lock.py index e69428e..1c79a45 100644 --- a/devtools/run_conda_lock.py +++ b/devtools/run_conda_lock.py @@ -33,6 +33,7 @@ from add_url_tag_sha256 import patch_pyproject_toml from ruamel.yaml import YAML + env_file_variables_section_ = """ variables: KMP_WARNINGS: 0 @@ -167,9 +168,10 @@ def patch_none_hash(self) -> None: ) with tempfile.TemporaryDirectory(dir=str(self.lock_file.parent)) as tmpdirname: patched_file = Path(tmpdirname) / self.lock_file.name - with open(patched_file, mode="w", encoding="utf-8") as patched, open( - self.lock_file, encoding="utf-8" - ) as f: + with ( + open(patched_file, mode="w", encoding="utf-8") as patched, + open(self.lock_file, encoding="utf-8") as f, + ): for line in f: match = none_hash_re.match(line) if not match: @@ -202,9 +204,10 @@ def remove_pip_hashes(self) -> None: with tempfile.TemporaryDirectory(dir=str(self.lock_file.parent)) as tmpdirname: patched_file = Path(tmpdirname) / self.lock_file.name - with open(patched_file, mode="w", encoding="utf-8") as patched, open( - self.lock_file, encoding="utf-8" - ) as f: + with ( + open(patched_file, mode="w", encoding="utf-8") as patched, + open(self.lock_file, encoding="utf-8") as f, + ): for line in f: patched_line = self.sha_re.sub(r"\1", line) patched.write(patched_line) diff --git a/docs/source/conf.py b/docs/source/conf.py index 4bcec03..5ce6dfe 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -7,7 +7,7 @@ # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information project = "plate-simulation" -copyright = "2024, Benjamin Kary" +project_copyright = "2024, Mira Geoscience" author = "Benjamin Kary" release = "2024" diff --git a/plate_simulation/__init__.py b/plate_simulation/__init__.py index 528b782..e34582d 100644 --- a/plate_simulation/__init__.py +++ b/plate_simulation/__init__.py @@ -8,6 +8,7 @@ from pathlib import Path + __version__ = "0.1.0-alpha.1" diff --git a/plate_simulation/mesh/params.py b/plate_simulation/mesh/params.py index 84237e3..ebcc31c 100644 --- a/plate_simulation/mesh/params.py +++ b/plate_simulation/mesh/params.py @@ -36,7 +36,7 @@ def octree_params( "Refinement B levels": "4, 2", "Refinement B type": "radial", } - for plate, letter in zip(plates, string.ascii_uppercase[2:]): + for plate, letter in zip(plates, string.ascii_uppercase[2:], strict=False): refinements.update( { f"Refinement {letter} object": plate, diff --git a/plate_simulation/models/events.py b/plate_simulation/models/events.py index 1ca986e..013d0e1 100644 --- a/plate_simulation/models/events.py +++ b/plate_simulation/models/events.py @@ -13,6 +13,7 @@ from trimesh import Trimesh from trimesh.proximity import ProximityQuery + # pylint: disable=too-few-public-methods diff --git a/plate_simulation/models/params.py b/plate_simulation/models/params.py index a52568f..e8af304 100644 --- a/plate_simulation/models/params.py +++ b/plate_simulation/models/params.py @@ -17,6 +17,7 @@ model_validator, ) + T = TypeVar("T") @@ -101,7 +102,7 @@ def center( :param surface: surface object to reference plate depth from. :param depth_offset: Additional offset to be added to the depth of the plate. """ - return self._get_xy(survey) + [self._get_z(surface, depth_offset)] + return [*self._get_xy(survey), self._get_z(surface, depth_offset)] def _get_xy(self, survey: ObjectBase) -> list[float]: """Return true or relative locations in x and y.""" diff --git a/plate_simulation/models/series.py b/plate_simulation/models/series.py index ca51ce6..7bfd602 100644 --- a/plate_simulation/models/series.py +++ b/plate_simulation/models/series.py @@ -18,6 +18,7 @@ from .events import Anomaly, Erosion, Overburden + if TYPE_CHECKING: from .events import Deposition, Event diff --git a/plate_simulation/simulations/params.py b/plate_simulation/simulations/params.py index 1d3d4bc..10a8310 100644 --- a/plate_simulation/simulations/params.py +++ b/plate_simulation/simulations/params.py @@ -15,6 +15,7 @@ from simpeg_drivers.params import InversionBaseParams from simpeg_drivers.potential_fields.gravity.params import GravityParams + # pylint: disable=import-outside-toplevel, too-few-public-methods diff --git a/pyproject.toml b/pyproject.toml index d08f317..fc74f28 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -93,16 +93,40 @@ readthedocs-sphinx-ext = "*" platforms = ['win-64', 'linux-64'] channels = ['conda-forge'] -[tool.isort] -# settings for compatibility between ``isort`` and ``black`` formatting -multi_line_output = 3 -include_trailing_comma = true -force_grid_wrap = 0 -use_parentheses = true -line_length = 88 - -[tool.black] -# defaults are just fine +[tool.ruff] +target-version = "py310" + +[tool.ruff.lint] +ignore = [ + "B028", # no-explicit-stacklevel for warnings.warn() + "E501", # line-too-long - code is reformatted (do not care about comments and docstring) + "F401", # unsused-import - covered by pycln +] +select = [ + "A", # flake8-builtins + "B", # flake8-bugbear + "B006", # Do not use mutable data structures for argument defaults + "B9", # flake8-bugbear opiniated warnings + "BLE", # flake8-blind-except + "C4", # flake8-comprehensions + "C9", # mccabe + "E", # pycodestyle errors + "F", # pyflakes + "I", # isort + "RUF", # ruff rules + "TID", # flake8-tidy-imports + "UP", # pyupgrade + "W", # pycodestyle warnings +] + +[tool.ruff.lint.mccabe] +max-complexity = 18 + +[tool.ruff.lint.isort] +lines-after-imports = 2 + +[tool.ruff.format] +# default formatting is just fine [tool.mypy] warn_unused_configs = true diff --git a/tests/assets_path_test.py b/tests/assets_path_test.py index 2158dab..c9910b6 100644 --- a/tests/assets_path_test.py +++ b/tests/assets_path_test.py @@ -14,4 +14,4 @@ def test_assets_directory_exist(): def test_uijson_files_exists(): assert (assets_path() / "uijson").is_dir() - assert list((assets_path() / "uijson").iterdir())[0].is_file() + assert next(iter((assets_path() / "uijson").iterdir())).is_file() diff --git a/tests/runtest/driver_test.py b/tests/runtest/driver_test.py index 1406508..db0395d 100644 --- a/tests/runtest/driver_test.py +++ b/tests/runtest/driver_test.py @@ -29,6 +29,7 @@ from . import get_survey, get_topography + # pylint: disable=duplicate-code @@ -112,7 +113,7 @@ def test_plate_simulation(tmp_path): with Workspace(result.options["geoh5"]) as ws: data = ws.get_entity(result.options["data_object"]["value"].uid)[0] mesh = ws.get_entity(result.options["mesh"]["value"].uid)[0] - model = [k for k in mesh.children if k.name == "starting_model"][0] + model = next(k for k in mesh.children if k.name == "starting_model") assert len(data.property_groups) == 3 assert all(