Skip to content

Commit b217092

Browse files
committed
replace str with PathLike
1 parent 98601e2 commit b217092

File tree

1 file changed

+58
-43
lines changed

1 file changed

+58
-43
lines changed

pymatgen/io/vasp/inputs.py

Lines changed: 58 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -820,7 +820,7 @@ def get_str(self, sort_keys: bool = False, pretty: bool = False) -> str:
820820
return str(tabulate([[line[0], "=", line[1]] for line in lines], tablefmt="plain"))
821821
return str_delimited(lines, None, " = ") + "\n"
822822

823-
def write_file(self, filename: PathLike):
823+
def write_file(self, filename: PathLike) -> None:
824824
"""Write Incar to a file.
825825
826826
Args:
@@ -1950,7 +1950,7 @@ def hash_sha256_from_file(self) -> str | None:
19501950
@property
19511951
def sha256_computed_file_hash(self) -> str:
19521952
"""Computes a SHA256 hash of the PotcarSingle EXCLUDING lines starting with 'SHA256' and 'COPYR'."""
1953-
# we have to remove lines with the hash itself and the copyright
1953+
# We have to remove lines with the hash itself and the copyright
19541954
# notice to get the correct hash.
19551955
potcar_list = self.data.split("\n")
19561956
potcar_to_hash = [line for line in potcar_list if not line.strip().startswith(("SHA256", "COPYR"))]
@@ -1971,9 +1971,9 @@ def md5_header_hash(self) -> str:
19711971
"""MD5 hash of the metadata defining the PotcarSingle."""
19721972
hash_str = ""
19731973
for k, v in self.keywords.items():
1974-
# for newer POTCARS we have to exclude 'SHA256' and 'COPYR lines
1974+
# For newer POTCARS we have to exclude 'SHA256' and 'COPYR lines
19751975
# since they were not used in the initial hashing
1976-
if k in ("nentries", "Orbitals", "SHA256", "COPYR"):
1976+
if k in {"nentries", "Orbitals", "SHA256", "COPYR"}:
19771977
continue
19781978
hash_str += f"{k}"
19791979
if isinstance(v, (bool, int)):
@@ -2140,12 +2140,11 @@ def data_stats(data_list: Sequence) -> dict:
21402140
data_match_tol: float = 1e-6
21412141
for ref_psp in possible_potcar_matches:
21422142
key_match = all(
2143-
set(ref_psp["keywords"][key]) == set(self._summary_stats["keywords"][key]) # type: ignore
2144-
for key in ["header", "data"]
2143+
set(ref_psp["keywords"][key]) == set(self._summary_stats["keywords"][key]) for key in ["header", "data"]
21452144
)
21462145

21472146
data_diff = [
2148-
abs(ref_psp["stats"][key][stat] - self._summary_stats["stats"][key][stat]) # type: ignore
2147+
abs(ref_psp["stats"][key][stat] - self._summary_stats["stats"][key][stat])
21492148
for stat in ["MEAN", "ABSMEAN", "VAR", "MIN", "MAX"]
21502149
for key in ["header", "data"]
21512150
]
@@ -2174,7 +2173,7 @@ def copy(self) -> PotcarSingle:
21742173
return PotcarSingle(self.data, symbol=self.symbol)
21752174

21762175
@classmethod
2177-
def from_file(cls, filename: str) -> Self:
2176+
def from_file(cls, filename: PathLike) -> Self:
21782177
"""Read PotcarSingle from file.
21792178
21802179
Args:
@@ -2193,11 +2192,15 @@ def from_file(cls, filename: str) -> Self:
21932192
except UnicodeDecodeError:
21942193
warnings.warn("POTCAR contains invalid unicode errors. We will attempt to read it by ignoring errors.")
21952194

2196-
with codecs.open(filename, "r", encoding="utf-8", errors="ignore") as file:
2195+
with codecs.open(str(filename), "r", encoding="utf-8", errors="ignore") as file:
21972196
return cls(file.read(), symbol=symbol or None)
21982197

21992198
@classmethod
2200-
def from_symbol_and_functional(cls, symbol: str, functional: str | None = None) -> Self:
2199+
def from_symbol_and_functional(
2200+
cls,
2201+
symbol: str,
2202+
functional: str | None = None,
2203+
) -> Self:
22012204
"""Make a PotcarSingle from a symbol and functional.
22022205
22032206
Args:
@@ -2259,7 +2262,9 @@ def verify_potcar(self) -> tuple[bool, bool]:
22592262
return has_sha256, hash_is_valid
22602263

22612264
def identify_potcar(
2262-
self, mode: Literal["data", "file"] = "data", data_tol: float = 1e-6
2265+
self,
2266+
mode: Literal["data", "file"] = "data",
2267+
data_tol: float = 1e-6,
22632268
) -> tuple[list[str], list[str]]:
22642269
"""
22652270
Identify the symbol and compatible functionals associated with this PotcarSingle.
@@ -2294,12 +2299,11 @@ def identify_potcar(
22942299
continue
22952300

22962301
key_match = all(
2297-
set(ref_psp["keywords"][key]) == set(self._summary_stats["keywords"][key]) # type: ignore[index]
2298-
for key in check_modes
2302+
set(ref_psp["keywords"][key]) == set(self._summary_stats["keywords"][key]) for key in check_modes
22992303
)
23002304

23012305
data_diff = [
2302-
abs(ref_psp["stats"][key][stat] - self._summary_stats["stats"][key][stat]) # type: ignore[index]
2306+
abs(ref_psp["stats"][key][stat] - self._summary_stats["stats"][key][stat])
23032307
for stat in ["MEAN", "ABSMEAN", "VAR", "MIN", "MAX"]
23042308
for key in check_modes
23052309
]
@@ -2325,13 +2329,13 @@ def identify_potcar_hash_based(
23252329
"""
23262330
Identify the symbol and compatible functionals associated with this PotcarSingle.
23272331
2328-
This method checks the md5 hash of either the POTCAR metadadata (PotcarSingle.md5_header_hash)
2332+
This method checks the MD5 hash of either the POTCAR metadadata (PotcarSingle.md5_header_hash)
23292333
or the entire POTCAR file (PotcarSingle.md5_computed_file_hash) against a database
23302334
of hashes for POTCARs distributed with VASP 5.4.4.
23312335
23322336
Args:
2333-
mode ('data' | 'file'): 'data' mode checks the hash of the POTCAR metadata in self.keywords,
2334-
while 'file' mode checks the hash of the entire POTCAR file.
2337+
mode ("data" | "file"): "data" mode checks the hash of the POTCAR metadata in self.keywords,
2338+
while "file" mode checks the hash of the entire POTCAR file.
23352339
23362340
Returns:
23372341
symbol (list): List of symbols associated with the PotcarSingle
@@ -2435,7 +2439,7 @@ def identify_potcar_hash_based(
24352439
raise ValueError(f"Bad {mode=}. Choose 'data' or 'file'.")
24362440

24372441
if identity := hash_db.get(potcar_hash):
2438-
# convert the potcar_functionals from the .json dict into the functional
2442+
# Convert the potcar_functionals from the .json dict into the functional
24392443
# keys that pymatgen uses
24402444
potcar_functionals = [*{mapping_dict[i]["pymatgen_key"] for i in identity["potcar_functionals"]}]
24412445

@@ -2449,7 +2453,7 @@ def _gen_potcar_summary_stats(
24492453
summary_stats_filename: str | None = POTCAR_STATS_PATH,
24502454
):
24512455
"""
2452-
Regenerates the reference data in potcar-summary-stats.json.bz2 used to validate POTCARs
2456+
Regenerate the reference data in potcar-summary-stats.json.bz2 used to validate POTCARs
24532457
by comparing header values and several statistics of copyrighted POTCAR data without
24542458
having to record the POTCAR data itself.
24552459
@@ -2598,25 +2602,27 @@ def from_file(cls, filename: PathLike) -> Self:
25982602
"""
25992603
with zopen(filename, mode="rt") as file:
26002604
fdata = file.read()
2601-
potcar = cls()
26022605

2603-
functionals = []
2606+
potcar = cls()
2607+
functionals: list[str | None] = []
26042608
for psingle_str in fdata.split("End of Dataset"):
26052609
if p_strip := psingle_str.strip():
26062610
psingle = PotcarSingle(p_strip + "\nEnd of Dataset\n")
26072611
potcar.append(psingle)
26082612
functionals.append(psingle.functional)
2613+
26092614
if len(set(functionals)) != 1:
26102615
raise ValueError("File contains incompatible functionals!")
2616+
26112617
potcar.functional = functionals[0]
26122618
return potcar
26132619

2614-
def write_file(self, filename: str) -> None:
2620+
def write_file(self, filename: PathLike) -> None:
26152621
"""
26162622
Write Potcar to a file.
26172623
26182624
Args:
2619-
filename (str): filename to write to.
2625+
filename (PathLike): filename to write to.
26202626
"""
26212627
with zopen(filename, mode="wt") as file:
26222628
file.write(str(self))
@@ -2626,7 +2632,7 @@ def set_symbols(
26262632
symbols: Sequence[str],
26272633
functional: str | None = None,
26282634
sym_potcar_map: dict[str, str] | None = None,
2629-
):
2635+
) -> None:
26302636
"""
26312637
Initialize the POTCAR from a set of symbols. Currently, the POTCARs can
26322638
be fetched from a location specified in .pmgrc.yaml. Use pmg config
@@ -2666,7 +2672,7 @@ def __init__(
26662672
**kwargs,
26672673
) -> None:
26682674
"""
2669-
Initializes a VaspInput object with the given input files.
2675+
Initialize a VaspInput object with the given input files.
26702676
26712677
Args:
26722678
incar (Incar): The Incar object.
@@ -2689,7 +2695,7 @@ def __str__(self) -> str:
26892695
output.extend((key, str(val), ""))
26902696
return "\n".join(output)
26912697

2692-
def as_dict(self):
2698+
def as_dict(self) -> dict:
26932699
"""MSONable dict."""
26942700
dct = {key: val.as_dict() for key, val in self.items()}
26952701
dct["@module"] = type(self).__module__
@@ -2713,35 +2719,44 @@ def from_dict(cls, dct: dict) -> Self:
27132719
sub_dct["optional_files"][key] = MontyDecoder().process_decoded(val)
27142720
return cls(**sub_dct) # type: ignore[arg-type]
27152721

2716-
def write_input(self, output_dir=".", make_dir_if_not_present=True):
2722+
def write_input(
2723+
self,
2724+
output_dir: PathLike = ".",
2725+
make_dir_if_not_present: bool = True,
2726+
) -> None:
27172727
"""
2718-
Write VASP input to a directory.
2728+
Write VASP inputs to a directory.
27192729
27202730
Args:
2721-
output_dir (str): Directory to write to. Defaults to current
2722-
directory (".").
2731+
output_dir (PathLike): Directory to write to.
2732+
Defaults to current directory (".").
27232733
make_dir_if_not_present (bool): Create the directory if not
27242734
present. Defaults to True.
27252735
"""
2726-
if make_dir_if_not_present:
2727-
os.makedirs(output_dir, exist_ok=True)
2728-
for k, v in self.items():
2729-
if v is not None:
2730-
with zopen(os.path.join(output_dir, k), mode="wt") as file:
2731-
file.write(str(v))
2736+
if not os.path.isdir(output_dir) and make_dir_if_not_present:
2737+
os.makedirs(output_dir)
2738+
2739+
for key, value in self.items():
2740+
if value is not None:
2741+
with zopen(os.path.join(output_dir, key), mode="wt") as file:
2742+
file.write(str(value))
27322743

27332744
@classmethod
2734-
def from_directory(cls, input_dir: str, optional_files: dict | None = None) -> Self:
2745+
def from_directory(
2746+
cls,
2747+
input_dir: PathLike,
2748+
optional_files: dict | None = None,
2749+
) -> Self:
27352750
"""
2736-
Read in a set of VASP input from a directory. Note that only the
2751+
Read in a set of VASP inputs from a directory. Note that only the
27372752
standard INCAR, POSCAR, POTCAR and KPOINTS files are read unless
27382753
optional_filenames is specified.
27392754
27402755
Args:
2741-
input_dir (str): Directory to read VASP input from.
2742-
optional_files (dict): Optional files to read in as well as a
2743-
dict of {filename: Object type}. Object type must have a
2744-
static method from_file.
2756+
input_dir (PathLike): Directory to read VASP input from.
2757+
optional_files (dict): Optional files to read in as a
2758+
dict of {filename: Object type}. Objects must have
2759+
from_file method.
27452760
"""
27462761
sub_dct = {}
27472762
for fname, ftype in [
@@ -2762,7 +2777,7 @@ def from_directory(cls, input_dir: str, optional_files: dict | None = None) -> S
27622777

27632778
return cls(**sub_dct)
27642779

2765-
def copy(self, deep: bool = True):
2780+
def copy(self, deep: bool = True) -> VaspInput:
27662781
"""Deep copy of VaspInput."""
27672782
if deep:
27682783
return self.from_dict(self.as_dict())

0 commit comments

Comments
 (0)