Skip to content

Commit

Permalink
Solve RuntimeWarnings in tests (#441)
Browse files Browse the repository at this point in the history
  • Loading branch information
caspervdw committed Nov 29, 2021
1 parent d8dc41c commit 84b918e
Show file tree
Hide file tree
Showing 9 changed files with 71 additions and 23 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/test-pip.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,11 @@ jobs:
- python: "3.10"
geos: 3.10.1
numpy: 1.21.3
extra_pytest_args: "-W error" # error on warnings
# dev
- python: "3.10"
geos: main
extra_pytest_args: "-W error" # error on warnings
# enable two 32-bit windows builds:
- os: windows-2019
architecture: x86
Expand Down Expand Up @@ -143,7 +145,7 @@ jobs:

- name: Run tests
continue-on-error: ${{ matrix.geos == 'main' }}
run: pytest pygeos
run: pytest pygeos ${{ matrix.extra_pytest_args }}

# Only run doctests on 1 runner (because of typographic differences in doctest results)
- name: Run doctests
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ Version 0.12 (unreleased)
* Raise ``GEOSException`` in the rare case when predicate evalution in ``STRtree.query``
errors. Previously, the exceptions were ignored silently and the geometry was added
to the result (as if the predicate returned ``True``) (#432).
* Hide ``RuntimeWarning`` when using ``total_bounds`` on empty geometries, empty arrays,
or geometries with NaN coordinates (#441).


**Acknowledgments**
Expand Down
21 changes: 13 additions & 8 deletions pygeos/measurement.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import warnings

import numpy as np

from . import Geometry # NOQA
Expand Down Expand Up @@ -133,14 +135,17 @@ def total_bounds(geometry, **kwargs):
if b.ndim == 1:
return b

return np.array(
[
np.nanmin(b[..., 0]),
np.nanmin(b[..., 1]),
np.nanmax(b[..., 2]),
np.nanmax(b[..., 3]),
]
)
with warnings.catch_warnings():
# ignore 'All-NaN slice encountered' warnings
warnings.simplefilter("ignore", RuntimeWarning)
return np.array(
[
np.nanmin(b[..., 0]),
np.nanmin(b[..., 1]),
np.nanmax(b[..., 2]),
np.nanmax(b[..., 3]),
]
)


@multithreading_enabled
Expand Down
10 changes: 7 additions & 3 deletions pygeos/testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@


def _equals_exact_with_ndim(x, y, tolerance):
return pygeos.equals_exact(x, y, tolerance=tolerance) & (
pygeos.get_coordinate_dimension(x) == pygeos.get_coordinate_dimension(y)
)
dimension_equals = pygeos.get_coordinate_dimension(
x
) == pygeos.get_coordinate_dimension(y)
with np.errstate(invalid="ignore"):
# Suppress 'invalid value encountered in equals_exact' with nan coordinates
geometry_equals = pygeos.equals_exact(x, y, tolerance=tolerance)
return dimension_equals & geometry_equals


def _replace_nan(arr):
Expand Down
9 changes: 9 additions & 0 deletions pygeos/tests/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,12 @@ def assert_decreases_refcount(obj):
pytest.skip("sys.getrefcount is not available.")
yield
assert sys.getrefcount(obj) == before - 1


@contextmanager
def ignore_invalid(condition=True):
if condition:
with np.errstate(invalid="ignore"):
yield
else:
yield
13 changes: 11 additions & 2 deletions pygeos/tests/test_constructive.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
empty_line_string,
empty_point,
empty_polygon,
ignore_invalid,
line_string,
multi_point,
point,
Expand Down Expand Up @@ -51,7 +52,12 @@ def test_float_arg_array(geometry, func):
with pytest.raises(GEOSException, match="only accept linestrings"):
func([geometry, geometry], 0.0)
return
actual = func([geometry, geometry], 0.0)
# voronoi_polygons emits an "invalid" warning when supplied with an empty
# point (see https://github.com/libgeos/geos/issues/515)
with ignore_invalid(
func is pygeos.voronoi_polygons and pygeos.get_type_id(geometry) == 0
):
actual = func([geometry, geometry], 0.0)
assert actual.shape == (2,)
assert isinstance(actual[0], Geometry)

Expand Down Expand Up @@ -209,7 +215,10 @@ def test_normalize(geom, expected):


def test_offset_curve_empty():
actual = pygeos.offset_curve(empty_line_string, 2.0)
with ignore_invalid():
# Empty geometries emit an "invalid" warning
# (see https://github.com/libgeos/geos/issues/515)
actual = pygeos.offset_curve(empty_line_string, 2.0)
assert pygeos.is_empty(actual)


Expand Down
11 changes: 9 additions & 2 deletions pygeos/tests/test_measurement.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from .common import (
empty,
geometry_collection,
ignore_invalid,
line_string,
linear_ring,
multi_line_string,
Expand Down Expand Up @@ -143,15 +144,21 @@ def test_hausdorff_distance():
# example from GEOS docs
a = pygeos.linestrings([[0, 0], [100, 0], [10, 100], [10, 100]])
b = pygeos.linestrings([[0, 100], [0, 10], [80, 10]])
actual = pygeos.hausdorff_distance(a, b)
with ignore_invalid():
# Hausdorff distance emits "invalid value encountered"
# (see https://github.com/libgeos/geos/issues/515)
actual = pygeos.hausdorff_distance(a, b)
assert actual == pytest.approx(22.360679775, abs=1e-7)


def test_hausdorff_distance_densify():
# example from GEOS docs
a = pygeos.linestrings([[0, 0], [100, 0], [10, 100], [10, 100]])
b = pygeos.linestrings([[0, 100], [0, 10], [80, 10]])
actual = pygeos.hausdorff_distance(a, b, densify=0.001)
with ignore_invalid():
# Hausdorff distance emits "invalid value encountered"
# (see https://github.com/libgeos/geos/issues/515)
actual = pygeos.hausdorff_distance(a, b, densify=0.001)
assert actual == pytest.approx(47.8, abs=0.1)


Expand Down
18 changes: 14 additions & 4 deletions pygeos/tests/test_predicates.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
all_types,
empty,
geometry_collection,
ignore_invalid,
line_string,
linear_ring,
point,
Expand Down Expand Up @@ -83,7 +84,10 @@ def test_unary_missing(func):
@pytest.mark.parametrize("a", all_types)
@pytest.mark.parametrize("func", BINARY_PREDICATES)
def test_binary_array(a, func):
actual = func([a, a], point)
with ignore_invalid(pygeos.is_empty(a)):
# Empty geometries give 'invalid value encountered' in all predicates
# (see https://github.com/libgeos/geos/issues/515)
actual = func([a, a], point)
assert actual.shape == (2,)
assert actual.dtype == np.bool_

Expand Down Expand Up @@ -174,7 +178,10 @@ def test_relate_pattern():


def test_relate_pattern_empty():
assert pygeos.relate_pattern(empty, empty, "*" * 9).item() is True
with ignore_invalid():
# Empty geometries give 'invalid value encountered' in all predicates
# (see https://github.com/libgeos/geos/issues/515)
assert pygeos.relate_pattern(empty, empty, "*" * 9).item() is True


@pytest.mark.parametrize("g1, g2", [(point, None), (None, point), (None, None)])
Expand Down Expand Up @@ -231,8 +238,11 @@ def _prepare_with_copy(geometry):
@pytest.mark.parametrize("a", all_types)
@pytest.mark.parametrize("func", BINARY_PREPARED_PREDICATES)
def test_binary_prepared(a, func):
actual = func(a, point)
result = func(_prepare_with_copy(a), point)
with ignore_invalid(pygeos.is_empty(a)):
# Empty geometries give 'invalid value encountered' in all predicates
# (see https://github.com/libgeos/geos/issues/515)
actual = func(a, point)
result = func(_prepare_with_copy(a), point)
assert actual == result


Expand Down
6 changes: 3 additions & 3 deletions pygeos/tests/test_strtree.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@
EPS = 1e-9


@pytest.fixture
@pytest.fixture(scope="session")
def tree():
geoms = pygeos.points(np.arange(10), np.arange(10))
yield pygeos.STRtree(geoms)


@pytest.fixture
@pytest.fixture(scope="session")
def line_tree():
x = np.arange(10)
y = np.arange(10)
Expand All @@ -38,7 +38,7 @@ def line_tree():
yield pygeos.STRtree(geoms)


@pytest.fixture
@pytest.fixture(scope="session")
def poly_tree():
# create buffers so that midpoint between two buffers intersects
# each buffer. NOTE: add EPS to help mitigate rounding errors at midpoint.
Expand Down

0 comments on commit 84b918e

Please sign in to comment.