Skip to content

Commit 2f9203d

Browse files
committed
Fix file utilities, improve docs, and add tests
1 parent c57d19f commit 2f9203d

3 files changed

Lines changed: 45 additions & 9 deletions

File tree

deepmd/tf/nvnmd/utils/fio.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def is_file(self, file_name):
3939
def get_file_list(self, path) -> list:
4040
if self.is_file(path):
4141
return []
42-
if self.is_path:
42+
if self.is_path(path):
4343
listdir = os.listdir(path)
4444
file_lst = []
4545
for name in listdir:
@@ -53,8 +53,9 @@ def get_file_list(self, path) -> list:
5353

5454

5555
class FioDic:
56-
r"""Input and output for dict class data
57-
the file can be .json or .npy file containing a dictionary.
56+
r"""Input and output for dictionary data.
57+
58+
The file can be a `.json` or `.npy` file containing a dictionary.
5859
"""
5960

6061
def __init__(self) -> None:
@@ -83,7 +84,7 @@ def get(self, jdata, key, default_value):
8384
return default_value
8485

8586
def update(self, jdata, jdata_o):
86-
r"""Update key-value pair is key in jdata_o.keys().
87+
r"""Update key-value pairs if the key exists in ``jdata_o``.
8788
8889
Parameters
8990
----------
@@ -186,8 +187,10 @@ class FioTxt:
186187
def __init__(self) -> None:
187188
pass
188189

189-
def load(self, file_name="", default_value=[]):
190-
r"""Load .txt file into string list."""
190+
def load(self, file_name="", default_value=None):
191+
r"""Load a text file into a list of strings."""
192+
if default_value is None:
193+
default_value = []
191194
if Fio().exits(file_name):
192195
log.info(f"load {file_name}")
193196
with open(file_name, encoding="utf-8") as fr:
@@ -198,11 +201,13 @@ def load(self, file_name="", default_value=[]):
198201
log.info(f"can not find {file_name}")
199202
return default_value
200203

201-
def save(self, file_name: str = "", data: list = []) -> None:
202-
r"""Save string list into .txt file."""
204+
def save(self, file_name: str = "", data: list | str | None = None) -> None:
205+
r"""Save a list of strings into a text file."""
203206
log.info(f"write string to txt file {file_name}")
204207
Fio().create_file_path(file_name)
205208

209+
if data is None:
210+
data = []
206211
if isinstance(data, str):
207212
data = [data]
208213
data = [d + "\n" for d in data]

doc/model/train-fitting-tensor.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ The loss section should be provided like
174174
In tensor mode, the identification of the label's type (global or atomic) is derived from the file name. The global label should be named `dipole.npy/raw` or `polarizability.npy/raw`, while the atomic label should be named `atomic_dipole.npy/raw` or `atomic_polarizability.npy/raw`. If wrongly named, DP will report an error
175175

176176
```bash
177-
ValueError: cannot reshape array of size xxx into shape (xx,xx). This error may occur when your label mismatch it's name, i.e. you might store global tensor in `atomic_tensor.npy` or atomic tensor in `tensor.npy`.
177+
ValueError: cannot reshape array of size xxx into shape (xx,xx). This error may occur when your label mismatches its name, i.e. you might store global tensor in `atomic_tensor.npy` or atomic tensor in `tensor.npy`.
178178
```
179179

180180
In this case, please check the file name of the label.

source/tests/tf/test_fio_utils.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# SPDX-License-Identifier: LGPL-3.0-or-later
2+
from deepmd.tf.nvnmd.utils.fio import (
3+
Fio,
4+
FioTxt,
5+
)
6+
7+
8+
def test_get_file_list(tmp_path):
9+
"""get_file_list should handle non-existent paths and collect files recursively."""
10+
# create directory with one file
11+
subdir = tmp_path / "sub"
12+
subdir.mkdir()
13+
file_path = subdir / "file.txt"
14+
file_path.write_text("hello")
15+
16+
fio = Fio()
17+
18+
# existing directory returns the file
19+
files = fio.get_file_list(str(tmp_path))
20+
assert files == [str(file_path)]
21+
22+
# non-existent directory should return an empty list
23+
missing = tmp_path / "missing"
24+
assert fio.get_file_list(str(missing)) == []
25+
26+
27+
def test_fiotxt_load_default(tmp_path):
28+
"""FioTxt.load should return default empty list when file does not exist."""
29+
fio_txt = FioTxt()
30+
missing = tmp_path / "no.txt"
31+
assert fio_txt.load(str(missing)) == []

0 commit comments

Comments
 (0)