Skip to content

Commit 411b7f6

Browse files
authored
Merge pull request #879 from DHI/fix/pfs_single_quote
Fix MULTIPOLYGON quote handling in PFS parser
2 parents e2dbf5c + aef8d1d commit 411b7f6

File tree

2 files changed

+49
-2
lines changed

2 files changed

+49
-2
lines changed

src/mikeio/pfs/_pfsdocument.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -361,9 +361,15 @@ def _parse_pfs_value(self, value_str: str) -> Any:
361361
):
362362
return self._parse_token(value_str)
363363

364-
# Special case: MULTIPOLYGON
364+
# Special case: MULTIPOLYGON - fast path for large coordinate strings
365+
# Avoids expensive parsing but still strips quotes correctly
365366
if "MULTIPOLYGON" in value_str:
366-
return value_str
367+
s = value_str.strip()
368+
if s.startswith("'") and s.endswith("'"):
369+
return s[1:-1]
370+
elif s.startswith('"') and s.endswith('"'):
371+
return s[1:-1]
372+
return s
367373

368374
# Special case: values enclosed in double quotes should not be split
369375
# (even though they may contain commas)

tests/test_pfs.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1316,3 +1316,44 @@ def test_set_nested_path() -> None:
13161316
pfs.foo["bar/bat"] = {"n": 5, "s": "foo"}
13171317
assert pfs.foo.bar.bat.n == 5
13181318
assert pfs.foo.bar.bat.s == "foo"
1319+
1320+
1321+
def test_multipolygon_quote_handling(tmp_path: Path) -> None:
1322+
"""Test that MULTIPOLYGON strings don't accumulate quotes on read-write cycles.
1323+
1324+
Regression test for bug where single-quoted MULTIPOLYGON strings would
1325+
get an extra layer of quotes on each write-read cycle.
1326+
"""
1327+
# Read a file with MULTIPOLYGON data
1328+
pfs1 = mikeio.read_pfs("tests/testdata/pfs/multipolygon.pfs")
1329+
shape1 = pfs1.CatchmentGroupPfs.Catchment_0.Shape
1330+
1331+
# The shape should NOT start with a quote (quotes should be stripped during parsing)
1332+
assert not shape1.startswith(
1333+
"'"
1334+
), f"Shape should not start with quote, got: {shape1[:30]!r}"
1335+
assert shape1.startswith(
1336+
"MULTIPOLYGON"
1337+
), f"Shape should start with MULTIPOLYGON, got: {shape1[:30]!r}"
1338+
1339+
# Write and read back
1340+
outfile = tmp_path / "multipolygon_out.pfs"
1341+
pfs1.write(outfile)
1342+
pfs2 = mikeio.read_pfs(outfile)
1343+
shape2 = pfs2.CatchmentGroupPfs.Catchment_0.Shape
1344+
1345+
# After write-read cycle, shape should be identical (no extra quotes)
1346+
assert shape2 == shape1, "Shape should remain identical after write-read cycle"
1347+
assert not shape2.startswith(
1348+
"'"
1349+
), f"Shape should not start with quote after write-read, got: {shape2[:30]!r}"
1350+
1351+
# Write and read again to ensure it doesn't accumulate quotes
1352+
outfile2 = tmp_path / "multipolygon_out2.pfs"
1353+
pfs2.write(outfile2)
1354+
pfs3 = mikeio.read_pfs(outfile2)
1355+
shape3 = pfs3.CatchmentGroupPfs.Catchment_0.Shape
1356+
1357+
assert (
1358+
shape3 == shape1
1359+
), "Shape should remain identical after multiple write-read cycles"

0 commit comments

Comments
 (0)