diff --git a/fastkml/kml.py b/fastkml/kml.py index f69111b4..7c5dab89 100644 --- a/fastkml/kml.py +++ b/fastkml/kml.py @@ -153,9 +153,6 @@ def append( kmlobj: kml_children, ) -> None: """Append a feature.""" - if kmlobj is self: - msg = "Cannot append self" - raise ValueError(msg) self.features.append(kmlobj) @classmethod diff --git a/tests/base.py b/tests/base.py index 5327191f..5adde305 100644 --- a/tests/base.py +++ b/tests/base.py @@ -15,7 +15,7 @@ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA """Base classes to run the tests both with the std library and lxml.""" -import xml.etree.ElementTree +import xml.etree.ElementTree as ET import pytest @@ -33,8 +33,8 @@ class StdLibrary: """Configure test to run with the standard library.""" def setup_method(self) -> None: - """Always test with the same parser.""" - config.set_etree_implementation(xml.etree.ElementTree) + """Ensure to always test with the standard library xml ElementTree parser.""" + config.set_etree_implementation(ET) config.set_default_namespaces() @@ -47,6 +47,6 @@ class Lxml: """ def setup_method(self) -> None: - """Always test with the same parser.""" + """Ensure to always test with the lxml parse.""" config.set_etree_implementation(lxml.etree) config.set_default_namespaces() diff --git a/tests/config_test.py b/tests/config_test.py index a7e722aa..c1ab10ca 100644 --- a/tests/config_test.py +++ b/tests/config_test.py @@ -16,7 +16,7 @@ """Test the configuration options.""" -import xml.etree.ElementTree as ET +from xml.etree import ElementTree as ET import pytest diff --git a/tests/containers_test.py b/tests/containers_test.py index 9a92cbe4..234a1106 100644 --- a/tests/containers_test.py +++ b/tests/containers_test.py @@ -17,10 +17,14 @@ """Test the kml classes.""" -from fastkml import kml, containers, features +import pytest + +from fastkml import containers +from fastkml import features +from fastkml import kml +from fastkml import styles from tests.base import Lxml from tests.base import StdLibrary -import pytest class TestStdLibrary(StdLibrary): @@ -71,7 +75,7 @@ def test_container_creation(self) -> None: ns="ns", id="id", target_id="target_id", - name="name" + name="name", ) assert container.ns == "ns" assert container.name == "name" @@ -81,7 +85,7 @@ def test_container_feature_append(self) -> None: ns="ns", id="id", target_id="target_id", - name="name" + name="name", ) feature = features._Feature(name="new_feature") container.append(feature) @@ -93,10 +97,18 @@ def test_document_container_get_style_url(self) -> None: document = containers.Document( name="Document", ns="ns", - style_url="www.styleurl.com" + style_url=styles.StyleUrl(url="www.styleurl.com"), ) assert document.get_style_by_url(style_url="www.styleurl.com") is None + def test_document_container_get_style_url_id(self) -> None: + style = styles.Style(id="style-0") + document = containers.Document( + name="Document", + ns="ns", + styles=[style], + ) + assert document.get_style_by_url(style_url="#style-0") == style class TestLxml(Lxml, TestStdLibrary): diff --git a/tests/features_test.py b/tests/features_test.py index 07d2690d..696aaf1f 100644 --- a/tests/features_test.py +++ b/tests/features_test.py @@ -71,11 +71,14 @@ def test_placemark_geometry_and_kml_geometry_parameter_set(self) -> None: pt = geo.Point(10, 20) point = geometry.Point(geometry=pt) - with pytest.raises(ValueError): + with pytest.raises( + ValueError, + match="^You can only specify one of kml_geometry or geometry$", + ): features.Placemark(geometry=pt, kml_geometry=point) def test_network_link_with_link_parameter_only(self) -> None: - """NetworkLink object with Link parameter only""" + """Test NetworkLink object with Link parameter only.""" network_link = features.NetworkLink( link=links.Link(href="http://example.com/kml_file.kml"), ) diff --git a/tests/geometries/boundaries_test.py b/tests/geometries/boundaries_test.py index 5c38915e..304504c3 100644 --- a/tests/geometries/boundaries_test.py +++ b/tests/geometries/boundaries_test.py @@ -16,10 +16,13 @@ """Test the Outer and Inner Boundary classes.""" -import pytest -from fastkml.exceptions import GeometryError +from typing import Type +from typing import Union + import pygeoif.geometry as geo +import pytest +from fastkml.exceptions import GeometryError from fastkml.geometry import Coordinates from fastkml.geometry import InnerBoundaryIs from fastkml.geometry import LinearRing @@ -75,21 +78,24 @@ def test_inner_boundary(self) -> None: "" ) - def _test_boundary_geometry_error(self, boundary_class): - p = geo.Point(1, 2) + def _test_boundary_geometry_error( + self, + boundary_class: Union[Type[InnerBoundaryIs], Type[OuterBoundaryIs]], + ) -> None: + p = geo.LinearRing(((1, 2), (2, 0))) coords = ((1, 2), (2, 0), (0, 0), (1, 2)) with pytest.raises(GeometryError): boundary_class( kml_geometry=LinearRing(kml_coordinates=Coordinates(coords=coords)), - geometry=p + geometry=p, ) - def test_outer_boundary_geometry_error(self): + def test_outer_boundary_geometry_error(self) -> None: """Test that OuterBoundaryIs raises GeometryError with invalid geometry.""" self._test_boundary_geometry_error(OuterBoundaryIs) - def test_inner_boundary_geometry_error(self): + def test_inner_boundary_geometry_error(self) -> None: """Test that InnerBoundaryIs raises GeometryError with invalid geometry.""" self._test_boundary_geometry_error(InnerBoundaryIs) diff --git a/tests/geometries/functions_test.py b/tests/geometries/functions_test.py index 9bc1a097..ae89da26 100644 --- a/tests/geometries/functions_test.py +++ b/tests/geometries/functions_test.py @@ -1,71 +1,88 @@ -from unittest.mock import Mock, patch +# Copyright (C) 2024 Rishit Chaudhary, Christian Ledermann +# +# This library is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 2.1 of the License, or (at your option) +# any later version. +# +# This library is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +"""Test the geometry error handling.""" +from typing import Callable +from unittest.mock import Mock +from unittest.mock import patch + import pytest -from fastkml.exceptions import KMLParseError, KMLWriteError -from fastkml.geometry import handle_invalid_geometry_error + +from fastkml.enums import Verbosity +from fastkml.exceptions import KMLParseError +from fastkml.exceptions import KMLWriteError from fastkml.geometry import coordinates_subelement +from fastkml.geometry import handle_invalid_geometry_error from tests.base import StdLibrary class TestGeometryFunctions(StdLibrary): - """Test functions in Geometry""" + """Test functions in Geometry.""" - @patch('fastkml.config.etree.tostring') - def test_handle_invalid_geometry_error_true(self, mock_to_string) -> None: + @patch("fastkml.config.etree.tostring", return_value=b"") + def test_handle_invalid_geometry_error_true( + self, + mock_to_string: Callable[..., str], + ) -> None: mock_element = Mock() - with pytest.raises(KMLParseError): + with pytest.raises( + KMLParseError, + match=mock_to_string.return_value.decode(), # type: ignore[attr-defined] + ): handle_invalid_geometry_error( - error=ValueError, + error=ValueError(), element=mock_element, - strict=True + strict=True, ) + mock_to_string.assert_called_once_with( # type: ignore[attr-defined] + mock_element, + encoding="UTF-8", + ) - @patch('fastkml.config.etree.tostring') - def test_handle_invalid_geometry_error_false(self, mock_to_string) -> None: + @patch("fastkml.config.etree.tostring", return_value=b"") + def test_handle_invalid_geometry_error_false( + self, + mock_to_string: Callable[..., str], + ) -> None: mock_element = Mock() - assert handle_invalid_geometry_error( - error=ValueError, + handle_invalid_geometry_error( + error=ValueError(), element=mock_element, - strict=False - ) is None + strict=False, + ) + mock_to_string.assert_called_once_with( # type: ignore[attr-defined] + mock_element, + encoding="UTF-8", + ) def test_coordinates_subelement_exception(self) -> None: obj = Mock() - setattr(obj, - 'coordinates', - [(1.123456, 2.654321, 3.111111, 4.222222)] - ) + obj.coordinates = [(1.123456, 2.654321, 3.111111, 4.222222)] element = Mock() - precision = None - attr_name = 'coordinates' + precision = 9 + attr_name = "coordinates" with pytest.raises(KMLWriteError): coordinates_subelement( obj=obj, attr_name=attr_name, - node_name=None, + node_name="", element=element, precision=precision, - verbosity=None, - default=None + verbosity=Verbosity.terse, + default=None, ) - - def test_coordinates_subelement_getattr(self) -> None: - obj = Mock() - setattr(obj, 'coordinates', [(1.123456, 2.654321), (3.123456, 4.654321)]) - - element = Mock() - - precision = 4 - attr_name = 'coordinates' - - assert coordinates_subelement( - obj=None, - attr_name=attr_name, - node_name=None, - element=element, - precision=precision, - verbosity=None, - default=None - ) is None diff --git a/tests/geometries/linestring_test.py b/tests/geometries/linestring_test.py index 14afcbb4..35568556 100644 --- a/tests/geometries/linestring_test.py +++ b/tests/geometries/linestring_test.py @@ -21,8 +21,10 @@ from fastkml import exceptions from fastkml.enums import Verbosity -from fastkml.exceptions import GeometryError, KMLParseError -from fastkml.geometry import Coordinates, LineString +from fastkml.exceptions import GeometryError +from fastkml.exceptions import KMLParseError +from fastkml.geometry import Coordinates +from fastkml.geometry import LineString from tests.base import Lxml from tests.base import StdLibrary @@ -40,7 +42,7 @@ def test_init(self) -> None: def test_geometry_error(self) -> None: """Test GeometryError.""" - p = geo.Point(1, 2) + p = geo.LineString(((1, 2), (2, 0))) q = Coordinates(ns="ns") with pytest.raises(GeometryError): @@ -75,7 +77,6 @@ def test_from_string(self) -> None: ) def test_mixed_2d_3d_coordinates_from_string(self) -> None: - linestring = LineString.class_from_string( '' "1" diff --git a/tests/geometries/multigeometry_test.py b/tests/geometries/multigeometry_test.py index 9485a670..df58c1ae 100644 --- a/tests/geometries/multigeometry_test.py +++ b/tests/geometries/multigeometry_test.py @@ -15,12 +15,12 @@ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA """Test the geometry classes.""" -import pytest -from fastkml.exceptions import GeometryError import pygeoif.geometry as geo +import pytest from fastkml.enums import Verbosity -from fastkml.geometry import Coordinates, MultiGeometry +from fastkml.exceptions import GeometryError +from fastkml.geometry import MultiGeometry from tests.base import Lxml from tests.base import StdLibrary @@ -299,11 +299,10 @@ def test_multi_geometries_verbose(self) -> None: def test_geometry_error(self) -> None: """Test GeometryError.""" - p = geo.Point(1, 2) - q = Coordinates(ns="ns") + p = geo.MultiPoint(((1.0, 2.0),)) with pytest.raises(GeometryError): - MultiGeometry(geometry=p, kml_geometries=q) + MultiGeometry(geometry=p, kml_geometries=(MultiGeometry(geometry=p),)) def test_multi_geometries_read(self) -> None: xml = ( diff --git a/tests/geometries/point_test.py b/tests/geometries/point_test.py index 348db869..7dc3d869 100644 --- a/tests/geometries/point_test.py +++ b/tests/geometries/point_test.py @@ -20,9 +20,10 @@ import pytest from fastkml.enums import Verbosity -from fastkml.exceptions import GeometryError, KMLParseError -from fastkml.geometry import Point +from fastkml.exceptions import GeometryError +from fastkml.exceptions import KMLParseError from fastkml.geometry import Coordinates +from fastkml.geometry import Point from tests.base import Lxml from tests.base import StdLibrary @@ -48,7 +49,6 @@ def test_geometry_error(self) -> None: with pytest.raises(GeometryError): Point(geometry=p, kml_coordinates=q) - def test_to_string_2d(self) -> None: """Test the to_string method.""" p = geo.Point(1, 2) @@ -240,7 +240,6 @@ def test_from_string_empty_coordinates(self) -> None: assert point.geometry is None def test_from_string_invalid_coordinates(self) -> None: - point = Point.class_from_string( '' "1", @@ -249,7 +248,6 @@ def test_from_string_invalid_coordinates(self) -> None: assert not point def test_from_string_invalid_coordinates_4d(self) -> None: - point = Point.class_from_string( '' "1,2,3,4", diff --git a/tests/geometries/polygon_test.py b/tests/geometries/polygon_test.py index 5ceb7eb9..2feac66f 100644 --- a/tests/geometries/polygon_test.py +++ b/tests/geometries/polygon_test.py @@ -16,12 +16,12 @@ """Test the geometry classes.""" -import pytest -from fastkml.exceptions import GeometryError import pygeoif.geometry as geo +import pytest from fastkml.enums import AltitudeMode from fastkml.enums import Verbosity +from fastkml.exceptions import GeometryError from fastkml.geometry import OuterBoundaryIs from fastkml.geometry import Polygon from tests.base import Lxml diff --git a/tests/helper_test.py b/tests/helper_test.py index 8a3a324b..bce3efcd 100644 --- a/tests/helper_test.py +++ b/tests/helper_test.py @@ -1,14 +1,30 @@ -from unittest.mock import Mock, patch +# Copyright (C) 2024 Rishit Chaudhary, Christian Ledermann +# +# This library is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 2.1 of the License, or (at your option) +# any later version. +# +# This library is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +"""Test the helper functions edge cases.""" +from enum import Enum +from typing import Callable +from unittest.mock import Mock +from unittest.mock import patch + from fastkml.helpers import attribute_enum_kwarg from fastkml.helpers import attribute_float_kwarg -from fastkml.helpers import enum_attribute -from fastkml.helpers import float_attribute -from fastkml.helpers import node_text from fastkml.helpers import subelement_enum_kwarg from fastkml.helpers import subelement_float_kwarg from fastkml.helpers import subelement_int_kwarg from tests.base import StdLibrary -from enum import Enum class Node: @@ -20,122 +36,93 @@ class Color(Enum): class TestStdLibrary(StdLibrary): - @patch('fastkml.helpers.get_value') - def test_node_text(self, mock_get_value) -> None: - mock_get_value.return_value = False - res = node_text( - obj=None, - element=None, - attr_name="a", - node_name="n", - precision=0, - verbosity=0, - default="default" - ) - assert res is None - - @patch('fastkml.helpers.get_value') - def test_float_attribute(self, mock_get_value) -> None: - mock_get_value.return_value = None - res = float_attribute( - obj=None, - element="ele", - attr_name="a", - node_name="n", - precision=0, - verbosity=0, - default="default" - ) - assert res is None - - @patch('fastkml.helpers.get_value') - def test_enum_attribute(self, mock_get_value) -> None: - mock_get_value.return_value = None - res = enum_attribute( - obj=None, - element="ele", - attr_name="a", - node_name="n", - precision=0, - verbosity=0, - default="default" - ) - assert res is None + """Test with the standard library.""" - def test_subelement_int_kwarg(self): + def test_subelement_int_kwarg(self) -> None: node = Node() - node.text = None + node.text = "" element = Mock() element.find.return_value = node res = subelement_int_kwarg( - element=element, - ns="ns", - name_spaces="name", - node_name="node", - kwarg="kwarg", - classes=None, - strict=False - ) + element=element, + ns="ns", + name_spaces={"name": "uri"}, + node_name="node", + kwarg="kwarg", + classes=(int,), + strict=False, + ) assert res == {} - def test_subelement_float_kwarg(self): + def test_subelement_float_kwarg(self) -> None: node = Node() - node.text = None + node.text = "" element = Mock() element.find.return_value = node res = subelement_float_kwarg( - element=element, - ns="ns", - name_spaces="name", - node_name="node", - kwarg="kwarg", - classes=None, - strict=False - ) + element=element, + ns="ns", + name_spaces={"name": "uri"}, + node_name="node", + kwarg="kwarg", + classes=(float,), + strict=False, + ) assert res == {} - @patch('fastkml.helpers.handle_error') - def test_attribute_float_kwarg(self, mock_handle_error) -> None: + @patch("fastkml.helpers.handle_error") + def test_attribute_float_kwarg( + self, + mock_handle_error: Callable[..., None], + ) -> None: element = Mock() element.get.return_value = "abcd" - mock_handle_error.return_value = None + res = attribute_float_kwarg( element=element, ns="ns", - name_spaces="name", + name_spaces={"name": "uri"}, node_name="node", kwarg="a", - classes=None, - strict=True + classes=(float,), + strict=True, ) + assert res == {} + mock_handle_error.assert_called_once() # type: ignore[attr-defined] def test_subelement_enum_kwarg(self) -> None: node = Node() - node.text = None + node.text = "" element = Mock() element.find.return_value = node + res = subelement_enum_kwarg( element=element, ns="ns", - name_spaces="name", + name_spaces={"name": "uri"}, node_name="node", kwarg="a", - classes=[Color], - strict=True + classes=(Color,), + strict=True, ) + assert res == {} + element.find.assert_called_once_with("nsnode") def test_attribute_enum_kwarg(self) -> None: element = Mock() element.get.return_value = None + res = attribute_enum_kwarg( element=element, ns="ns", - name_spaces="name", + name_spaces={"name": "uri"}, node_name="node", kwarg="a", - classes=[Color], - strict=True + classes=(Color,), + strict=True, ) + assert res == {} + element.get.assert_called_once_with("nsnode") diff --git a/tests/hypothesis/multi_geometry_test.py b/tests/hypothesis/multi_geometry_test.py index 144f8963..f66b6ec9 100644 --- a/tests/hypothesis/multi_geometry_test.py +++ b/tests/hypothesis/multi_geometry_test.py @@ -157,6 +157,9 @@ def _test_geometry_str_roundtrip_verbose( assert geometry.geometry assert type(new_g.geometry) is cls for new, orig in zip(new_g.kml_geometries, geometry.kml_geometries): + if isinstance(new, fastkml.geometry.MultiGeometry): + continue + assert not isinstance(orig, fastkml.geometry.MultiGeometry) if extrude: assert new.extrude == orig.extrude == extrude else: diff --git a/tests/kml_test.py b/tests/kml_test.py index c538e64b..7203fe41 100644 --- a/tests/kml_test.py +++ b/tests/kml_test.py @@ -17,13 +17,10 @@ """Test the kml class.""" import io import pathlib -from unittest.mock import patch import pygeoif as geo -import pytest from fastkml import containers -from fastkml import config from fastkml import features from fastkml import kml from fastkml.containers import Document @@ -176,29 +173,6 @@ def test_parse_kml_fileobject(self) -> None: ], ) - @patch('fastkml.config.etree') - def test_kml_etree_element(self, mock_etree) -> None: - - mock_etree.__all__ = ['LXML_VERSION'] - empty_placemark = KMLFILEDIR / "emptyPlacemarkWithoutId.xml" - - doc = kml.KML.parse(empty_placemark) - - res = config.etree.Element( - f"{doc.ns}{doc.get_tag_name()}", - nsmap={None: doc.ns[1:-1]} - ) - - assert doc.etree_element() == res - - def test_kml_append(self) -> None: - empty_placemark = KMLFILEDIR / "emptyPlacemarkWithoutId.xml" - - doc = kml.KML.parse(empty_placemark) - - with pytest.raises(ValueError): - doc.append(doc) - class TestParseKMLNone(StdLibrary): def test_kml_parse(self) -> None: @@ -208,6 +182,7 @@ def test_kml_parse(self) -> None: assert doc.ns == "None" + class TestLxml(Lxml, TestStdLibrary): """Test with lxml.""" diff --git a/tests/styles_test.py b/tests/styles_test.py index 60c68c02..da8222b9 100644 --- a/tests/styles_test.py +++ b/tests/styles_test.py @@ -616,5 +616,6 @@ def test_style_map_none_case(self) -> None: assert sm.normal is None assert sm.highlight is None + class TestLxml(Lxml, TestStdLibrary): """Test with lxml.""" diff --git a/tests/times_test.py b/tests/times_test.py index e32ca6a1..4abc3199 100644 --- a/tests/times_test.py +++ b/tests/times_test.py @@ -32,7 +32,7 @@ class TestDateTime(StdLibrary): """KmlDateTime implementation is independent of XML parser.""" def test_kml_datetime_year(self) -> None: - dt = datetime.datetime(2000, 1, 1) + dt = datetime.datetime(2000, 1, 1) # noqa: DTZ001 kdt = KmlDateTime(dt, DateTimeResolution.year) @@ -41,7 +41,7 @@ def test_kml_datetime_year(self) -> None: assert bool(kdt) def test_kml_datetime_year_month(self) -> None: - dt = datetime.datetime(2000, 3, 1) + dt = datetime.datetime(2000, 3, 1) # noqa: DTZ001 kdt = KmlDateTime(dt, DateTimeResolution.year_month) @@ -50,7 +50,7 @@ def test_kml_datetime_year_month(self) -> None: assert bool(kdt) def test_kml_datetime_date(self) -> None: - dt = datetime.datetime.now() + dt = datetime.datetime.now() # noqa: DTZ005 kdt = KmlDateTime(dt, DateTimeResolution.date) @@ -59,7 +59,7 @@ def test_kml_datetime_date(self) -> None: assert bool(kdt) def test_kml_datetime_date_implicit(self) -> None: - dt = datetime.date.today() + dt = datetime.date.today() # noqa: DTZ011 kdt = KmlDateTime(dt) @@ -68,7 +68,7 @@ def test_kml_datetime_date_implicit(self) -> None: assert bool(kdt) def test_kml_datetime_datetime(self) -> None: - dt = datetime.datetime.now() + dt = datetime.datetime.now() # noqa: DTZ005 kdt = KmlDateTime(dt, DateTimeResolution.datetime) @@ -77,7 +77,7 @@ def test_kml_datetime_datetime(self) -> None: assert bool(kdt) def test_kml_datetime_datetime_implicit(self) -> None: - dt = datetime.datetime.now() + dt = datetime.datetime.now() # noqa: DTZ005 kdt = KmlDateTime(dt) @@ -91,7 +91,10 @@ def test_kml_datetime_no_datetime(self) -> None: assert kdt.resolution == DateTimeResolution.date assert not bool(kdt) - with pytest.raises(AttributeError): + with pytest.raises( + AttributeError, + match="^'NoneType' object has no attribute 'isoformat'$", + ): str(kdt) def test_parse_year(self) -> None: @@ -101,7 +104,7 @@ def test_parse_year(self) -> None: assert dt.dt == datetime.datetime(2000, 1, 1, tzinfo=tzutc()) def test_parse_year_0(self) -> None: - with pytest.raises(ValueError): + with pytest.raises(ValueError, match="^year 0 is out of range$"): KmlDateTime.parse("0000") def test_parse_year_month(self) -> None: @@ -117,11 +120,11 @@ def test_parse_year_month_no_dash(self) -> None: assert dt.dt == datetime.datetime(2000, 4, 1, tzinfo=tzutc()) def test_parse_year_month_0(self) -> None: - with pytest.raises(ValueError): + with pytest.raises(ValueError, match="^month must be in 1..12$"): KmlDateTime.parse("2000-00") def test_parse_year_month_13(self) -> None: - with pytest.raises(ValueError): + with pytest.raises(ValueError, match="^month must be in 1..12$"): KmlDateTime.parse("2000-13") def test_parse_year_month_day(self) -> None: @@ -137,7 +140,7 @@ def test_parse_year_month_day_no_dash(self) -> None: assert dt.dt == datetime.datetime(2000, 4, 1, tzinfo=tzutc()) def test_parse_year_month_day_0(self) -> None: - with pytest.raises(ValueError): + with pytest.raises(ValueError, match="^day is out of range for month$"): KmlDateTime.parse("2000-05-00") def test_parse_datetime_utc(self) -> None: @@ -192,7 +195,7 @@ class TestStdLibrary(StdLibrary): """Test with the standard library.""" def test_timestamp(self) -> None: - now = datetime.datetime.now() + now = datetime.datetime.now() # noqa: DTZ005 dt = KmlDateTime(now) ts = kml.TimeStamp(timestamp=dt) assert ts.timestamp.dt == now @@ -206,8 +209,8 @@ def test_timestamp(self) -> None: assert "2000-01-01" in str(ts.to_string()) def test_timespan(self) -> None: - now = KmlDateTime(datetime.datetime.now()) - y2k = KmlDateTime(datetime.datetime(2000, 1, 1)) + now = KmlDateTime(datetime.datetime.now()) # noqa: DTZ005 + y2k = KmlDateTime(datetime.datetime(2000, 1, 1)) # noqa: DTZ001 ts = kml.TimeSpan(end=now, begin=y2k) assert ts.end == now assert ts.begin == y2k @@ -224,7 +227,7 @@ def test_timespan(self) -> None: assert not ts def test_feature_timestamp(self) -> None: - now = datetime.datetime.now() + now = datetime.datetime.now() # noqa: DTZ005 f = kml.Document() f.times = kml.TimeStamp(timestamp=KmlDateTime(now)) assert f.time_stamp.dt == now @@ -238,8 +241,8 @@ def test_feature_timestamp(self) -> None: assert "TimeStamp>" not in str(f.to_string()) def test_feature_timespan(self) -> None: - now = datetime.datetime.now() - y2k = datetime.datetime(2000, 1, 1) + now = datetime.datetime.now() # noqa: DTZ005 + y2k = datetime.datetime(2000, 1, 1) # noqa: DTZ001 f = kml.Document() f.times = kml.TimeSpan(begin=KmlDateTime(y2k), end=KmlDateTime(now)) assert f.begin == KmlDateTime(y2k)