Skip to content

Commit d8b92dc

Browse files
authored
Merge pull request #802 from DHI/pfs_no_comments
PFS - Handle comments better.
2 parents e191677 + a4e5266 commit d8b92dc

File tree

2 files changed

+50
-40
lines changed

2 files changed

+50
-40
lines changed

mikeio/pfs/_pfsdocument.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -282,19 +282,19 @@ def _pfs2yaml(
282282

283283
return "\n".join(output)
284284

285+
def _strip_comments(self, s: str) -> str:
286+
pattern = r"(\".*?\"|\'.*?\')|//.*"
287+
288+
def replacer(match): # type: ignore
289+
# Keep strings intact, remove comments
290+
return match.group(1) if match.group(1) else ""
291+
292+
return re.sub(pattern, replacer, s)
293+
285294
def _parse_line(self, line: str, level: int = 0) -> tuple[str, int]:
286295
section_header = False
287296
s = line.strip()
288-
parts = re.split(r'(".*?"|\'.*?\')', s) # Preserve quoted strings
289-
for i, part in enumerate(parts):
290-
if not (
291-
part.startswith('"') or part.startswith("'")
292-
): # Ignore quoted parts
293-
part = re.sub(
294-
r"\s*//.*", "", part
295-
) # Remove comments only outside quotes
296-
parts[i] = part
297-
s = "".join(parts) # Reassemble the line
297+
s = self._strip_comments(s).strip()
298298

299299
if len(s) > 0:
300300
if s[0] == "[":

tests/test_pfs.py

Lines changed: 40 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,36 @@
99
import mikeio
1010

1111

12+
def assert_txt_files_match(f1, f2, comment="//") -> None:
13+
"""Checks that non-comment lines in two files match exactly.
14+
Empty lines and lines starting with the comment string are ignored."""
15+
file1lines = Path(f1).read_text().splitlines()
16+
file2lines = Path(f2).read_text().splitlines()
17+
18+
# Filter out comments and empty lines
19+
content1 = [
20+
line.strip()
21+
for line in file1lines
22+
if line.strip() and not line.strip().startswith(comment)
23+
]
24+
content2 = [
25+
line.strip()
26+
for line in file2lines
27+
if line.strip() and not line.strip().startswith(comment)
28+
]
29+
30+
# Check lengths match after filtering
31+
if len(content1) != len(content2):
32+
raise AssertionError(
33+
f"Files have different number of non-comment lines: {len(content1)} vs {len(content2)}"
34+
)
35+
36+
# Compare remaining lines
37+
for i, (line1, line2) in enumerate(zip(content1, content2)):
38+
if line1 != line2:
39+
raise AssertionError(f"Line {i} differs:\n{line1}\nvs\n{line2}")
40+
41+
1242
@pytest.fixture
1343
def d1() -> dict:
1444
return dict(
@@ -293,36 +323,6 @@ def test_mztoolbox() -> None:
293323
assert "|" in pfs.txconc.Setup.File_1.InputFile
294324

295325

296-
def assert_txt_files_match(f1, f2, comment="//") -> None:
297-
"""Checks that non-comment lines in two files match exactly.
298-
Empty lines and lines starting with the comment string are ignored."""
299-
file1lines = Path(f1).read_text().splitlines()
300-
file2lines = Path(f2).read_text().splitlines()
301-
302-
# Filter out comments and empty lines
303-
content1 = [
304-
line.strip()
305-
for line in file1lines
306-
if line.strip() and not line.strip().startswith(comment)
307-
]
308-
content2 = [
309-
line.strip()
310-
for line in file2lines
311-
if line.strip() and not line.strip().startswith(comment)
312-
]
313-
314-
# Check lengths match after filtering
315-
if len(content1) != len(content2):
316-
raise AssertionError(
317-
f"Files have different number of non-comment lines: {len(content1)} vs {len(content2)}"
318-
)
319-
320-
# Compare remaining lines
321-
for i, (line1, line2) in enumerate(zip(content1, content2)):
322-
if line1 != line2:
323-
raise AssertionError(f"Line {i} differs:\n{line1}\nvs\n{line2}")
324-
325-
326326
def test_read_write(tmp_path: Path) -> None:
327327
infilename = "tests/testdata/pfs/concat.mzt"
328328
pfs1 = mikeio.PfsDocument(infilename)
@@ -1257,3 +1257,13 @@ def test_ignores_comments_in_quotes() -> None:
12571257
def test_filenames_may_contain_comma() -> None:
12581258
pfs = mikeio.read_pfs("tests/testdata/pfs/tidal.21t")
12591259
assert pfs.m21_tideph.Setup.File_1.mesh_file == "|.\\b,athy.mesh|"
1260+
1261+
1262+
def test_strip_comments() -> None:
1263+
text = """
1264+
[Engine]
1265+
var = 'x' // 'y' (default) 🤖 ,.!//\\(foo,bar*) 😻
1266+
EndSect // Engine
1267+
"""
1268+
pfs = mikeio.PfsDocument.from_text(text)
1269+
assert pfs.Engine.var == "x"

0 commit comments

Comments
 (0)