Skip to content

Commit 23b3c4b

Browse files
authored
Fix all ruff PT011 (not checking error message when testing exceptions) (#698)
* bump ruff pre-commit to v0.1.15 * ruff auto fixes * fix all ruff PT011 and unignore that rule
1 parent bfd9b0c commit 23b3c4b

File tree

12 files changed

+78
-85
lines changed

12 files changed

+78
-85
lines changed

.pre-commit-config.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ default_language_version:
22
python: python3
33
repos:
44
- repo: https://github.com/charliermarsh/ruff-pre-commit
5-
rev: v0.1.13
5+
rev: v0.1.15
66
hooks:
77
- id: ruff
88
args: [--fix]

pyproject.toml

+21-23
Original file line numberDiff line numberDiff line change
@@ -148,37 +148,35 @@ exclude_lines = [
148148
target-version = "py39"
149149
select = ["ALL"]
150150
ignore = [
151-
"ARG002", # unused method argument
152-
"COM812", # trailing comma missing
153-
"PD011", # pandas-use-of-dot-values
154-
"PERF203", # try-except-in-loop
155-
"PLR", # pylint-refactor
156-
"PT004", # pytest-missing-fixture-name-underscore
157-
"PT006", # pytest-parametrize-names-wrong-type
158-
"RUF013", # implicit-optional
159-
# TODO remove PT011, pytest.raises() should always check err msg
160151
"ANN002",
161152
"ANN003",
162-
"ANN101", # missing self type annotation
153+
"ANN101", # missing self type annotation
163154
"ANN102",
164155
"ANN401",
156+
"ARG002", # unused method argument
165157
"BLE001",
166-
"C408", # Unnecessary (dict/list/tuple) call - remove call
167-
"C901", # function too complex
168-
"DTZ", # datetime-tz-now
169-
"EM", # exception message must not use f-string literal
170-
"ERA001", # found commented out code
158+
"C408", # Unnecessary (dict/list/tuple) call - remove call
159+
"C901", # function too complex
160+
"COM812", # trailing comma missing
161+
"DTZ", # datetime-tz-now
162+
"EM", # exception message must not use f-string literal
163+
"ERA001", # found commented out code
171164
"FBT001",
172165
"FBT002",
173166
"FIX002",
174-
"G004", # logging uses fstring
175-
"PT011", # pytest-raises-too-broad
176-
"PT013", # pytest-incorrect-pytest-import
177-
"PTH", # prefer Pathlib to os.path
178-
"S324", # use of insecure hash function
179-
"SLF", # private member accessed outside class
180-
"TD", # TODOs
181-
"TRY003", # long message outside exception class
167+
"G004", # logging uses fstring
168+
"PD011", # pandas-use-of-dot-values
169+
"PERF203", # try-except-in-loop
170+
"PLR", # pylint-refactor
171+
"PT004", # pytest-missing-fixture-name-underscore
172+
"PT006", # pytest-parametrize-names-wrong-type
173+
"PT013", # pytest-incorrect-pytest-import
174+
"PTH", # prefer Pathlib to os.path
175+
"RUF013", # implicit-optional
176+
"S324", # use of insecure hash function
177+
"SLF", # private member accessed outside class
178+
"TD", # TODOs
179+
"TRY003", # long message outside exception class
182180
]
183181
pydocstyle.convention = "numpy"
184182
isort.known-first-party = ["atomate2"]

src/atomate2/common/schemas/defects.py

+12-9
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import logging
44
from collections.abc import Sequence
5+
from itertools import starmap
56
from typing import Any, Callable, Optional, Union
67

78
import numpy as np
@@ -237,7 +238,7 @@ def from_task_outputs(
237238
UUID of relaxed calculation in charge state (q2).
238239
"""
239240

240-
def get_ent(
241+
def get_cs_entry(
241242
struct: Structure,
242243
energy: float,
243244
dir_name: str,
@@ -249,14 +250,16 @@ def get_ent(
249250
data={"dir_name": dir_name, "uuid": uuid},
250251
)
251252

252-
entries1 = [
253-
get_ent(s, e, d, u)
254-
for s, e, d, u in zip(structures1, energies1, static_dirs1, static_uuids1)
255-
]
256-
entries2 = [
257-
get_ent(s, e, d, u)
258-
for s, e, d, u in zip(structures2, energies2, static_dirs2, static_uuids2)
259-
]
253+
entries1 = list(
254+
starmap(
255+
get_cs_entry, zip(structures1, energies1, static_dirs1, static_uuids1)
256+
)
257+
)
258+
entries2 = list(
259+
starmap(
260+
get_cs_entry, zip(structures2, energies2, static_dirs2, static_uuids2)
261+
)
262+
)
260263

261264
return cls.from_entries(entries1, entries2, relaxed_uuid1, relaxed_uuid2)
262265

src/atomate2/cp2k/sets/base.py

+8-8
Original file line numberDiff line numberDiff line change
@@ -106,14 +106,14 @@ def write_input(
106106
}
107107
inputs.update(self.optional_files)
108108

109-
for k, v in inputs.items():
110-
fn = v.get("filename")
111-
obj = v.get("object")
112-
if v is not None and (overwrite or not (directory / k).exists()):
113-
with zopen(directory / fn, "wt") as f:
114-
f.write(str(obj))
115-
elif not overwrite and (directory / fn).exists():
116-
raise FileExistsError(f"{directory / fn} already exists.")
109+
for key, val in inputs.items():
110+
filename = val.get("filename")
111+
obj = val.get("object")
112+
if val is not None and (overwrite or not (directory / key).exists()):
113+
with zopen(directory / filename, "wt") as file:
114+
file.write(str(obj))
115+
elif not overwrite and (directory / filename).exists():
116+
raise FileExistsError(f"{directory / filename} already exists.")
117117

118118
@staticmethod
119119
def from_directory(

src/atomate2/forcefields/utils.py

+10-12
Original file line numberDiff line numberDiff line change
@@ -114,18 +114,16 @@ def save(self, filename: str | PathLike) -> None:
114114
-------
115115
None
116116
"""
117-
with open(filename, "wb") as f:
118-
pickle.dump(
119-
{
120-
"energy": self.energies,
121-
"forces": self.forces,
122-
"stresses": self.stresses,
123-
"atom_positions": self.atom_positions,
124-
"cell": self.cells,
125-
"atomic_number": self.atoms.get_atomic_numbers(),
126-
},
127-
f,
128-
)
117+
traj_dict = {
118+
"energy": self.energies,
119+
"forces": self.forces,
120+
"stresses": self.stresses,
121+
"atom_positions": self.atom_positions,
122+
"cell": self.cells,
123+
"atomic_number": self.atoms.get_atomic_numbers(),
124+
}
125+
with open(filename, "wb") as file:
126+
pickle.dump(traj_dict, file)
129127

130128

131129
class Relaxer:

src/atomate2/lobster/schemas.py

+13-18
Original file line numberDiff line numberDiff line change
@@ -766,10 +766,7 @@ def from_directory(
766766

767767
# Do automatic bonding analysis with LobsterPy
768768
condensed_bonding_analysis = None
769-
sb_icobi = None
770-
sb_icohp = None
771-
sb_icoop = None
772-
describe = None
769+
sb_icobi = sb_icohp = sb_icoop = describe = None
773770
struct = Structure.from_file(structure_path)
774771

775772
# will perform two condensed bonding analysis computations
@@ -1066,7 +1063,7 @@ def from_directory(
10661063
are_coops=False,
10671064
are_cobis=False,
10681065
)
1069-
doc.__setattr__("cohp_data", cohp_obj)
1066+
doc.cohp_data = cohp_obj
10701067

10711068
if coopcar_path.exists() and doc.coop_data is None:
10721069
coop_obj = CompleteCohp.from_file(
@@ -1076,7 +1073,7 @@ def from_directory(
10761073
are_coops=True,
10771074
are_cobis=False,
10781075
)
1079-
doc.__setattr__("coop_data", coop_obj)
1076+
doc.coop_data = coop_obj
10801077

10811078
if cobicar_path.exists() and doc.cobi_data is None:
10821079
cobi_obj = CompleteCohp.from_file(
@@ -1086,7 +1083,7 @@ def from_directory(
10861083
are_coops=False,
10871084
are_cobis=True,
10881085
)
1089-
doc.__setattr__("cobi_data", cobi_obj)
1086+
doc.cobi_data = cobi_obj
10901087
with gzip.open(
10911088
computational_data_json_save_dir, "wt", encoding="UTF-8"
10921089
) as file:
@@ -1099,7 +1096,7 @@ def from_directory(
10991096
# objects and other data json compatible dict format
11001097
data = {
11011098
attribute: jsanitize(
1102-
doc.__getattribute__(attribute),
1099+
getattr(doc, attribute),
11031100
allow_bson=False,
11041101
strict=True,
11051102
enum_values=True,
@@ -1113,9 +1110,9 @@ def from_directory(
11131110

11141111
# Again unset the cohp, cobi and coop data fields if not desired in the DB
11151112
if not add_coxxcar_to_task_document:
1116-
doc.__setattr__("cohp_data", None)
1117-
doc.__setattr__("coop_data", None)
1118-
doc.__setattr__("cobi_data", None)
1113+
doc.cohp_data = None
1114+
doc.coop_data = None
1115+
doc.cobi_data = None
11191116

11201117
return doc.model_copy(update=additional_fields)
11211118

@@ -1316,9 +1313,9 @@ def read_saved_json(
13161313
dict
13171314
Returns a dictionary with lobster task json data corresponding to query.
13181315
"""
1319-
with gzip.open(filename, "rb") as f:
1316+
with gzip.open(filename, "rb") as file:
13201317
lobster_data = {}
1321-
objects = ijson.items(f, "item", use_float=True)
1318+
objects = ijson.items(file, "item", use_float=True)
13221319
for obj in objects:
13231320
if query is None:
13241321
for field, data in obj.items():
@@ -1339,11 +1336,9 @@ def read_saved_json(
13391336
lobster_data[query_key] = MontyDecoder().process_decoded(value)
13401337
elif "lobsterpy_data" in query_key:
13411338
for field in lobster_data[query_key].__fields__:
1342-
lobster_data[query_key].__setattr__(
1343-
field,
1344-
MontyDecoder().process_decoded(
1345-
lobster_data[query_key].__getattribute__(field)
1346-
),
1339+
val = MontyDecoder().process_decoded(
1340+
getattr(lobster_data[query_key], field)
13471341
)
1342+
setattr(lobster_data[query_key], field, val)
13481343

13491344
return lobster_data

src/atomate2/utils/file_client.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,7 @@ def gzip(
411411
path.unlink()
412412
else:
413413
ssh = self.get_ssh(host)
414-
_, stdout, _ = ssh.exec_command(f"gzip -f {path!s}")
414+
_, _stdout, _ = ssh.exec_command(f"gzip -f {path!s}")
415415

416416
def gunzip(
417417
self,

src/atomate2/vasp/flows/mp.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -232,9 +232,7 @@ class MPVaspLobsterMaker(VaspLobsterMaker):
232232
"""
233233

234234
name: str = "lobster"
235-
relax_maker: BaseVaspMaker | None = field(
236-
default_factory=lambda: MPGGADoubleRelaxMaker()
237-
)
235+
relax_maker: BaseVaspMaker | None = field(default_factory=MPGGADoubleRelaxMaker)
238236
lobster_static_maker: BaseVaspMaker = field(
239237
default_factory=lambda: MPGGAStaticMaker(
240238
input_set_generator=MPGGAStaticSetGenerator(
@@ -254,7 +252,7 @@ class MPVaspLobsterMaker(VaspLobsterMaker):
254252
)
255253
)
256254
)
257-
lobster_maker: LobsterMaker | None = field(default_factory=lambda: LobsterMaker())
255+
lobster_maker: LobsterMaker | None = field(default_factory=LobsterMaker)
258256
delete_wavecars: bool = True
259257
address_min_basis: str | None = None
260258
address_max_basis: str | None = None

src/atomate2/vasp/sets/base.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ def write_input(
109109
# write POSCAR with more significant figures
110110
file.write(val.get_str(significant_figures=16))
111111
else:
112-
file.write(val.__str__())
112+
file.write(str(val))
113113
elif not overwrite and (directory / key).exists():
114114
raise FileExistsError(f"{directory / key} already exists.")
115115

tests/common/schemas/test_cclib.py

+3-4
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,11 @@ def test_cclib_taskdoc(test_dir):
4848

4949
# Now we will try two possible extensions, but we will make sure that
5050
# it fails because the newest log file (.txt) is not valid
51-
with open(p / "test.txt", "w") as f:
52-
f.write("I am a dummy log file")
53-
with pytest.raises(Exception) as e:
51+
with open(p / "test.txt", "w") as file:
52+
file.write("I am a dummy log file")
53+
with pytest.raises(ValueError, match="Could not parse"):
5454
doc = TaskDocument.from_logfile(p, [".log", ".txt"]).dict()
5555
os.remove(p / "test.txt")
56-
assert "Could not parse" in str(e.value)
5756

5857
# Test a population analysis
5958
doc = TaskDocument.from_logfile(p, "psi_test.out", analysis="MBO").dict()

tests/forcefields/test_utils.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,7 @@ def test_relaxer(si_structure, test_dir, tmp_dir, optimizer, traj_file):
9393
]
9494

9595
if optimizer is None:
96-
# None is invalid, should raise ValueError
97-
with pytest.raises(ValueError):
96+
with pytest.raises(ValueError, match="Optimizer cannot be None"):
9897
Relaxer(calculator=LennardJones(), optimizer=optimizer)
9998
return
10099

tests/vasp/flows/test_phonons.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -755,7 +755,10 @@ def test_phonon_wf_only_displacements_kpath_raises_no_cell_change(
755755
# automatically use fake VASP and write POTCAR.spec during the test
756756
mock_vasp(ref_paths, fake_run_vasp_kwargs)
757757

758-
with pytest.raises(ValueError):
758+
with pytest.raises(
759+
ValueError,
760+
match="can only use other kpath schemes with the primitive standard structure",
761+
):
759762
PhononMaker(
760763
min_length=3.0,
761764
bulk_relax_maker=None,
@@ -785,7 +788,7 @@ def test_phonon_wf_only_displacements_kpath_raises(mock_vasp, clean_dir, kpath_s
785788

786789
# automatically use fake VASP and write POTCAR.spec during the test
787790
mock_vasp(ref_paths, fake_run_vasp_kwargs)
788-
with pytest.raises(ValueError):
791+
with pytest.raises(ValueError, match="can only use other kpath schemes with the"):
789792
PhononMaker(
790793
min_length=3.0,
791794
bulk_relax_maker=None,

0 commit comments

Comments
 (0)