Skip to content

Commit

Permalink
Refactor XML parsing code for Enum values to raise exception for stri…
Browse files Browse the repository at this point in the history
…ct parsing
  • Loading branch information
cleder committed Apr 7, 2024
1 parent aeae349 commit 7b45d07
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 5 deletions.
32 changes: 29 additions & 3 deletions fastkml/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -526,9 +526,17 @@ def subelement_enum_kwarg(
node = element.find(f"{ns}{node_name}")
if node is None:
return {}
if node.text and node.text.strip():
node_text = node.text.strip() if node.text else ""
if node_text:
try:
return {kwarg: classes[0](node.text.strip())}
value = classes[0](node_text)
if strict and value.value != node_text:
msg = (
f"Value {node_text} is not a valid value for Enum "
f"{classes[0].__name__}"
)
raise ValueError(msg)
return {kwarg: value}
except ValueError as exc:
handle_error(
error=exc,
Expand All @@ -552,7 +560,25 @@ def attribute_enum_kwarg(
) -> Dict[str, Enum]:
assert len(classes) == 1
assert issubclass(classes[0], Enum)
return {kwarg: classes[0](element.get(node_name))} if element.get(node_name) else {}
if raw := element.get(node_name):
try:
value = classes[0](raw)
if raw != value.value and strict:
msg = (
f"Value {raw} is not a valid value for Enum "
f"{classes[0].__name__}"
)
raise ValueError(msg)
return {kwarg: classes[0](raw)}
except ValueError as exc:
handle_error(
error=exc,
strict=strict,
element=element,
node=element,
expected="Enum",
)
return {}


def xml_subelement_kwarg(
Expand Down
18 changes: 16 additions & 2 deletions tests/geometries/point_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ def test_from_string_2d(self) -> None:
assert point.extrude is None
assert point.tessellate is None

def test_from_string_uppercase_altitude_mode(self) -> None:
def test_from_string_uppercase_altitude_mode_relaxed(self) -> None:
"""Test the from_string method for an uppercase altitude mode."""
point = cast(
Point,
Expand All @@ -130,12 +130,26 @@ def test_from_string_uppercase_altitude_mode(self) -> None:
"<altitudeMode>RELATIVETOGROUND</altitudeMode>"
"<coordinates>1.000000,2.000000</coordinates>"
"</Point>",
strict=False,
),
)

assert point.geometry == geo.Point(1, 2)
assert point.altitude_mode.value == "relativeToGround"

def test_from_string_uppercase_altitude_mode_strict(self) -> None:
"""Test the from_string method for an uppercase altitude mode."""
with pytest.raises(
KMLParseError,
match=r"Value RELATIVETOGROUND is not a valid value for Enum AltitudeMode$",
):
assert Point.class_from_string(
'<Point xmlns="http://www.opengis.net/kml/2.2">'
"<altitudeMode>RELATIVETOGROUND</altitudeMode>"
"<coordinates>1.000000,2.000000</coordinates>"
"</Point>",
)

def test_from_string_3d(self) -> None:
"""Test the from_string method for a 3 dimensional point."""
point = cast(
Expand Down Expand Up @@ -231,7 +245,7 @@ def test_from_string_invalid_coordinates_non_numerical(self) -> None:
def test_from_string_invalid_coordinates_nan(self) -> None:
with pytest.raises(
KMLParseError,
match=(r"^Invalid coordinates in"),
match=r"^Invalid coordinates in",
):
Point.class_from_string(
"<Point><coordinates>a,b</coordinates></Point>",
Expand Down

0 comments on commit 7b45d07

Please sign in to comment.