Skip to content

Commit 75c7bc1

Browse files
committed
Pre-commit: Migrate to ruff
This replaces the `pylint`, `isort`, `yapf` and `pydocstyle` tools.
1 parent f3d3278 commit 75c7bc1

File tree

16 files changed

+127
-172
lines changed

16 files changed

+127
-172
lines changed

.github/workflows/validate_release_tag.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,11 @@ def get_version_from_module(content: str) -> str:
1717

1818
try:
1919
return next(
20-
ast.literal_eval(statement.value) for statement in module.body if isinstance(statement, ast.Assign)
21-
for target in statement.targets if isinstance(target, ast.Name) and target.id == '__version__'
20+
ast.literal_eval(statement.value)
21+
for statement in module.body
22+
if isinstance(statement, ast.Assign)
23+
for target in statement.targets
24+
if isinstance(target, ast.Name) and target.id == '__version__'
2225
)
2326
except StopIteration as exception:
2427
raise IOError('Unable to find the `__version__` attribute in the module.') from exception

.pre-commit-config.yaml

Lines changed: 5 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -13,25 +13,12 @@ repos:
1313
hooks:
1414
- id: flynt
1515

16-
- repo: https://github.com/pycqa/isort
17-
rev: '5.12.0'
16+
- repo: https://github.com/astral-sh/ruff-pre-commit
17+
rev: 'v0.1.6'
1818
hooks:
19-
- id: isort
20-
21-
- repo: https://github.com/pre-commit/mirrors-yapf
22-
rev: 'v0.32.0'
23-
hooks:
24-
- id: yapf
25-
name: yapf
26-
types: [python]
27-
args: ['-i']
28-
additional_dependencies: ['toml']
29-
30-
- repo: https://github.com/PyCQA/pydocstyle
31-
rev: '6.1.1'
32-
hooks:
33-
- id: pydocstyle
34-
additional_dependencies: ['toml']
19+
- id: ruff-format
20+
- id: ruff
21+
args: [--fix, --exit-non-zero-on-fix, --show-fixes]
3522

3623
- repo: local
3724
hooks:
@@ -47,9 +34,3 @@ repos:
4734
(?x)^(
4835
src/.*py|
4936
)$
50-
51-
- id: pylint
52-
name: pylint
53-
entry: pylint
54-
types: [python]
55-
language: system

pyproject.toml

Lines changed: 23 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,6 @@ Source = 'https://github.com/microsoft/aiida-pyscf'
5151
pre-commit = [
5252
'mypy==1.3.0',
5353
'pre-commit~=2.17',
54-
'pylint~=2.16.0',
55-
'pylint-aiida~=0.1.1',
5654
]
5755
tests = [
5856
'packaging',
@@ -75,11 +73,29 @@ exclude = [
7573
line-length = 120
7674
fail-on-change = true
7775

78-
[tool.isort]
79-
force_sort_within_sections = true
80-
include_trailing_comma = true
81-
line_length = 120
82-
multi_line_output = 3
76+
[tool.ruff]
77+
line-length = 120
78+
select = [
79+
'E', # pydocstyle
80+
'W', # pydocstyle
81+
'F', # pyflakes
82+
'I', # isort
83+
'N', # pep8-naming
84+
'D', # pydocstyle
85+
'PLC', # pylint-convention
86+
'PLE', # pylint-error
87+
'PLR', # pylint-refactor
88+
'PLW', # pylint-warning
89+
'RUF', # ruff
90+
]
91+
ignore = [
92+
'D203', # Incompatible with D211 `no-blank-line-before-class`
93+
'D213', # Incompatible with D212 `multi-line-summary-second-line`
94+
'PLR2004', # Magic value used in comparison
95+
]
96+
97+
[tool.ruff.format]
98+
quote-style = 'single'
8399

84100
[tool.mypy]
85101
show_error_codes = true
@@ -105,37 +121,7 @@ module = [
105121
]
106122
ignore_missing_imports = true
107123

108-
[tool.pydocstyle]
109-
ignore = [
110-
'D104',
111-
'D203',
112-
'D213'
113-
]
114-
115-
[tool.pylint.master]
116-
load-plugins = ['pylint_aiida']
117-
118-
[tool.pylint.format]
119-
max-line-length = 120
120-
121-
[tool.pylint.messages_control]
122-
disable = [
123-
'duplicate-code',
124-
'import-outside-toplevel',
125-
'inconsistent-return-statements',
126-
'too-many-ancestors',
127-
]
128-
129124
[tool.pytest.ini_options]
130125
filterwarnings = [
131126
'ignore:Creating AiiDA configuration folder.*:UserWarning'
132127
]
133-
134-
[tool.yapf]
135-
align_closing_bracket_with_visual_indent = true
136-
based_on_style = 'google'
137-
coalesce_brackets = true
138-
column_limit = 120
139-
dedent_closing_brackets = true
140-
indent_dictionary_value = false
141-
split_arguments_when_comma_terminated = true

src/aiida_pyscf/calculations/base.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@
88
import pathlib
99
import typing as t
1010

11+
import numpy as np
1112
from aiida.common.datastructures import CalcInfo, CodeInfo
1213
from aiida.common.folders import Folder
1314
from aiida.engine import CalcJob, CalcJobProcessSpec
1415
from aiida.orm import ArrayData, Dict, SinglefileData, StructureData, TrajectoryData
1516
from aiida_shell.data import PickledData
1617
from ase.io.xyz import write_xyz
1718
from jinja2 import Environment, PackageLoader, PrefixLoader
18-
import numpy as np
1919
from plumpy.utils import AttributesFrozendict
2020

2121
__all__ = ('PyscfCalculation',)
@@ -69,7 +69,7 @@ def define(cls, spec: CalcJobProcessSpec): # type: ignore[override]
6969
'parameters',
7070
valid_type=Dict,
7171
required=False,
72-
help='Various computed properties parsed from the `FILENAME_RESULTS` output file.'
72+
help='Various computed properties parsed from the `FILENAME_RESULTS` output file.',
7373
)
7474
spec.output(
7575
'structure',
@@ -106,7 +106,7 @@ def define(cls, spec: CalcJobProcessSpec): # type: ignore[override]
106106
'cubegen.mep',
107107
valid_type=SinglefileData,
108108
required=False,
109-
help='The molecular electrostatic potential (MEP) in `.cube` format.'
109+
help='The molecular electrostatic potential (MEP) in `.cube` format.',
110110
)
111111
spec.output(
112112
'hessian',
@@ -120,16 +120,16 @@ def define(cls, spec: CalcJobProcessSpec): # type: ignore[override]
120120
spec.exit_code(
121121
410,
122122
'ERROR_ELECTRONIC_CONVERGENCE_NOT_REACHED',
123-
message='The electronic minimization cycle did not reach self-consistency.'
123+
message='The electronic minimization cycle did not reach self-consistency.',
124124
)
125125
spec.exit_code(
126126
500,
127127
'ERROR_IONIC_CONVERGENCE_NOT_REACHED',
128-
message='The ionic minimization cycle did not converge for the given thresholds.'
128+
message='The ionic minimization cycle did not converge for the given thresholds.',
129129
)
130130

131131
@classmethod
132-
def validate_parameters(cls, value: Dict | None, _) -> str | None: # pylint: disable=too-many-return-statements,too-many-branches,too-many-locals
132+
def validate_parameters(cls, value: Dict | None, _) -> str | None: # noqa: PLR0911, PLR0912
133133
"""Validate the parameters input."""
134134
if not value:
135135
return None

src/aiida_pyscf/parsers/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# -*- coding: utf-8 -*-
2+
"""Module for :mod:`aiida_pyscf.parsers`."""

src/aiida_pyscf/parsers/base.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@
55
import json
66
import pathlib
77

8+
import dill
9+
import numpy
810
from aiida.engine import ExitCode
911
from aiida.orm import ArrayData, Dict, SinglefileData, TrajectoryData
1012
from aiida.parsers.parser import Parser
1113
from aiida_shell.data import PickledData
1214
from ase.io.extxyz import read_extxyz
13-
import dill
14-
import numpy
1515
from pint import UnitRegistry
1616

1717
from aiida_pyscf.calculations.base import PyscfCalculation
@@ -27,7 +27,7 @@ def __init__(self, *args, **kwargs):
2727
self.dirpath_temporary: pathlib.Path | None = None
2828
super().__init__(*args, **kwargs)
2929

30-
def parse(self, retrieved_temporary_folder: str | None = None, **kwargs): # pylint: disable=arguments-differ,too-many-locals,too-many-branches,too-many-statements
30+
def parse(self, retrieved_temporary_folder: str | None = None, **kwargs): # noqa: PLR0912, PLR0915
3131
"""Parse the contents of the output files stored in the ``retrieved`` output node.
3232
3333
:returns: An exit code if the job failed.
@@ -41,7 +41,7 @@ def parse(self, retrieved_temporary_folder: str | None = None, **kwargs): # pyl
4141

4242
try:
4343
with self.retrieved.base.repository.open(PyscfCalculation.FILENAME_STDOUT, 'r') as handle:
44-
stdout = handle.read() # pylint: disable=unused-variable
44+
handle.read()
4545
except FileNotFoundError:
4646
return self.handle_failure('ERROR_OUTPUT_STDOUT_MISSING')
4747

@@ -133,7 +133,7 @@ def build_output_trajectory(self, filepath_trajectory: pathlib.Path) -> Trajecto
133133

134134
def batch(iterable, batch_size):
135135
"""Split an iterable into a list of elements which size ``batch_size."""
136-
return [iterable[i:i + batch_size] for i in range(0, len(iterable), batch_size)]
136+
return [iterable[i : i + batch_size] for i in range(0, len(iterable), batch_size)]
137137

138138
with filepath_trajectory.open() as handle:
139139
for atoms in read_extxyz(handle, index=slice(None, None)):

src/aiida_pyscf/workflows/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# -*- coding: utf-8 -*-
2+
"""Module for :mod:`aiida_pyscf.workflows`."""

src/aiida_pyscf/workflows/base.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def define(cls, spec):
3232
spec.exit_code(
3333
310,
3434
'ERROR_NO_CHECKPOINT_TO_RESTART',
35-
message='The calculation failed and did not retrieve a checkpoint file from which can be restarted.'
35+
message='The calculation failed and did not retrieve a checkpoint file from which can be restarted.',
3636
)
3737

3838
def setup(self):
@@ -68,7 +68,7 @@ def handle_unrecoverable_failure(self, node):
6868
priority=500,
6969
exit_codes=[
7070
PyscfCalculation.exit_codes.ERROR_IONIC_CONVERGENCE_NOT_REACHED, # type: ignore[union-attr]
71-
]
71+
],
7272
)
7373
def handle_ionic_convergence_not_reached(self, node):
7474
"""Handle ``ERROR_IONIC_CONVERGENCE_NOT_REACHED`` error.
@@ -95,7 +95,7 @@ def handle_ionic_convergence_not_reached(self, node):
9595
priority=410,
9696
exit_codes=[
9797
PyscfCalculation.exit_codes.ERROR_ELECTRONIC_CONVERGENCE_NOT_REACHED, # type: ignore[union-attr]
98-
]
98+
],
9999
)
100100
def handle_electronic_convergence_not_reached(self, node):
101101
"""Handle ``ERROR_ELECTRONIC_CONVERGENCE_NOT_REACHED`` error.
@@ -110,7 +110,7 @@ def handle_electronic_convergence_not_reached(self, node):
110110
priority=110,
111111
exit_codes=[
112112
PyscfCalculation.exit_codes.ERROR_SCHEDULER_NODE_FAILURE, # type: ignore[union-attr]
113-
]
113+
],
114114
)
115115
def handle_scheduler_node_failure(self, node):
116116
"""Handle ``ERROR_SCHEDULER_NODE_FAILURE`` error.
@@ -128,7 +128,7 @@ def handle_scheduler_node_failure(self, node):
128128
priority=100,
129129
exit_codes=[
130130
PyscfCalculation.exit_codes.ERROR_SCHEDULER_OUT_OF_WALLTIME, # type: ignore[union-attr]
131-
]
131+
],
132132
)
133133
def handle_out_of_walltime(self, node):
134134
"""Handle ``ERROR_SCHEDULER_OUT_OF_WALLTIME`` error.

tests/calculations/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# -*- coding: utf-8 -*-
2+
"""Tests for :mod:`aiida_pyscf.calculations`."""

tests/calculations/test_base.py

Lines changed: 17 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
# -*- coding: utf-8 -*-
22
"""Tests for the :mod:`aiida_pyscf.calculations.base` module."""
3-
# pylint: disable=redefined-outer-name
43
import io
54
import textwrap
65

6+
import pytest
77
from aiida.manage.tests.pytest_fixtures import recursive_merge
88
from aiida.orm import Dict, SinglefileData
9-
from jinja2 import BaseLoader, Environment
10-
import pytest
11-
129
from aiida_pyscf.calculations.base import PyscfCalculation
10+
from jinja2 import BaseLoader, Environment
1311

1412

1513
@pytest.fixture
@@ -24,13 +22,7 @@ def factory(**kwargs):
2422
'code': aiida_local_code_factory('pyscf.base', 'python'),
2523
'structure': generate_structure(),
2624
'parameters': Dict(parameters),
27-
'metadata': {
28-
'options': {
29-
'resources': {
30-
'num_machines': 1
31-
}
32-
}
33-
},
25+
'metadata': {'options': {'resources': {'num_machines': 1}}},
3426
}
3527
inputs.update(**kwargs)
3628
return inputs
@@ -43,15 +35,19 @@ def test_default(generate_calc_job, generate_inputs_pyscf, file_regression):
4335
inputs = generate_inputs_pyscf()
4436
tmp_path, calc_info = generate_calc_job(PyscfCalculation, inputs=inputs)
4537

46-
assert sorted(calc_info.retrieve_list) == sorted([
47-
PyscfCalculation.FILENAME_RESULTS,
48-
PyscfCalculation.FILENAME_MODEL,
49-
PyscfCalculation.FILENAME_STDOUT,
50-
])
38+
assert sorted(calc_info.retrieve_list) == sorted(
39+
[
40+
PyscfCalculation.FILENAME_RESULTS,
41+
PyscfCalculation.FILENAME_MODEL,
42+
PyscfCalculation.FILENAME_STDOUT,
43+
]
44+
)
5145

52-
assert sorted(calc_info.retrieve_temporary_list) == sorted([
53-
PyscfCalculation.FILENAME_CHECKPOINT,
54-
])
46+
assert sorted(calc_info.retrieve_temporary_list) == sorted(
47+
[
48+
PyscfCalculation.FILENAME_CHECKPOINT,
49+
]
50+
)
5551

5652
content_input_file = (tmp_path / PyscfCalculation.FILENAME_SCRIPT).read_text()
5753
file_regression.check(content_input_file, encoding='utf-8', extension='.pyr')
@@ -61,10 +57,7 @@ def test_parameters_structure(generate_calc_job, generate_inputs_pyscf, file_reg
6157
"""Test the ``structure`` key of the ``parameters`` input."""
6258
parameters = {
6359
'structure': {
64-
'basis': {
65-
'O': 'sto-3g',
66-
'H': 'cc-pvdz'
67-
},
60+
'basis': {'O': 'sto-3g', 'H': 'cc-pvdz'},
6861
'cart': True,
6962
'charge': 1,
7063
'spin': 2,
@@ -83,9 +76,7 @@ def test_parameters_mean_field(generate_calc_job, generate_inputs_pyscf, file_re
8376
'mean_field': {
8477
'diis_start_cycle': 2,
8578
'method': 'RHF',
86-
'grids': {
87-
'level': 3
88-
},
79+
'grids': {'level': 3},
8980
'xc': 'PBE',
9081
},
9182
}

0 commit comments

Comments
 (0)