Skip to content

Commit 28fd3e6

Browse files
authored
Add shapely import guards to make sure tests run without extras (#290)
1 parent 110d2d7 commit 28fd3e6

File tree

8 files changed

+84
-42
lines changed

8 files changed

+84
-42
lines changed

nucleus/metrics/cuboid_utils.py

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,9 @@
66
try:
77
from shapely.geometry import Polygon
88
except ModuleNotFoundError:
9-
import sys
10-
11-
class Polygon: # type: ignore
12-
def __init__(self, *args, **kwargs):
13-
"""Object to make sure we only raise errors if actually trying to use shapely"""
14-
if sys.platform.startswith("darwin"):
15-
platform_specific_msg = (
16-
"Depending on Python environment used GEOS might need to be installed via "
17-
"`brew install geos`."
18-
)
19-
elif sys.platform.startswith("linux"):
20-
platform_specific_msg = (
21-
"Depending on Python environment used GEOS might need to be installed via "
22-
"system package `libgeos-dev`."
23-
)
24-
else:
25-
platform_specific_msg = "GEOS package will need to be installed see (https://trac.osgeo.org/geos/)"
26-
raise ModuleNotFoundError(
27-
f"Module 'shapely' not found. Install optionally with `scale-nucleus[shapely]` or when developing "
28-
f"`poetry install -E shapely`. {platform_specific_msg}"
29-
)
9+
from .shapely_not_installed import ShapelyNotInstalled
10+
11+
Polygon = ShapelyNotInstalled
3012

3113

3214
from nucleus.annotation import CuboidAnnotation

nucleus/metrics/custom_types.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
from typing import TypeVar
2+
3+
from nucleus import (
4+
BoxAnnotation,
5+
BoxPrediction,
6+
PolygonAnnotation,
7+
PolygonPrediction,
8+
)
9+
10+
BoxOrPolygonPrediction = TypeVar(
11+
"BoxOrPolygonPrediction", BoxPrediction, PolygonPrediction
12+
)
13+
BoxOrPolygonAnnotation = TypeVar(
14+
"BoxOrPolygonAnnotation", BoxAnnotation, PolygonAnnotation
15+
)
16+
BoxOrPolygonAnnoOrPred = TypeVar(
17+
"BoxOrPolygonAnnoOrPred",
18+
BoxAnnotation,
19+
PolygonAnnotation,
20+
BoxPrediction,
21+
PolygonPrediction,
22+
)

nucleus/metrics/filters.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22

33
from nucleus.prediction import PredictionList
44

5-
from .polygon_utils import BoxOrPolygonAnnoOrPred, polygon_annotation_to_shape
5+
from .custom_types import BoxOrPolygonAnnoOrPred
6+
from .polygon_utils import polygon_annotation_to_shape
67

78

89
def polygon_area_filter(

nucleus/metrics/polygon_metrics.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,11 @@
88
from nucleus.prediction import BoxPrediction, PolygonPrediction, PredictionList
99

1010
from .base import Metric, ScalarResult
11+
from .custom_types import BoxOrPolygonAnnotation, BoxOrPolygonPrediction
1112
from .filtering import ListOfAndFilters, ListOfOrAndFilters
1213
from .filters import confidence_filter, polygon_label_filter
1314
from .metric_utils import compute_average_precision
1415
from .polygon_utils import (
15-
BoxOrPolygonAnnotation,
16-
BoxOrPolygonPrediction,
1716
get_true_false_positives_confidences,
1817
group_boxes_or_polygons_by_label,
1918
iou_assignments,

nucleus/metrics/polygon_utils.py

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,25 @@
11
import sys
22
from functools import wraps
3-
from typing import Dict, List, Tuple, TypeVar
3+
from typing import Dict, List, Tuple
44

55
import numpy as np
66
from scipy.optimize import linear_sum_assignment
7-
from shapely.geometry import Polygon
87

98
from nucleus.annotation import BoxAnnotation, PolygonAnnotation
10-
from nucleus.prediction import BoxPrediction, PolygonPrediction
9+
10+
from .custom_types import BoxOrPolygonAnnotation, BoxOrPolygonPrediction
11+
12+
try:
13+
from shapely.geometry import Polygon
14+
except ModuleNotFoundError:
15+
from .shapely_not_installed import ShapelyNotInstalled
16+
17+
Polygon = ShapelyNotInstalled
18+
1119

1220
from .base import ScalarResult
1321
from .errors import PolygonAnnotationTypeError
1422

15-
BoxOrPolygonPrediction = TypeVar(
16-
"BoxOrPolygonPrediction", BoxPrediction, PolygonPrediction
17-
)
18-
BoxOrPolygonAnnotation = TypeVar(
19-
"BoxOrPolygonAnnotation", BoxAnnotation, PolygonAnnotation
20-
)
21-
BoxOrPolygonAnnoOrPred = TypeVar(
22-
"BoxOrPolygonAnnoOrPred",
23-
BoxAnnotation,
24-
PolygonAnnotation,
25-
BoxPrediction,
26-
PolygonPrediction,
27-
)
28-
2923

3024
def polygon_annotation_to_shape(
3125
annotation: BoxOrPolygonAnnotation,
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import sys
2+
3+
4+
class ShapelyNotInstalled:
5+
def __init__(self, *args, **kwargs):
6+
self.raise_error_msg()
7+
8+
def __getattr__(self, item):
9+
self.raise_error_msg()
10+
11+
def raise_error_msg(self):
12+
"""Object to make sure we only raise errors if actually trying to use shapely"""
13+
if sys.platform.startswith("darwin"):
14+
platform_specific_msg = (
15+
"Depending on Python environment used GEOS might need to be installed via "
16+
"`brew install geos`."
17+
)
18+
elif sys.platform.startswith("linux"):
19+
platform_specific_msg = (
20+
"Depending on Python environment used GEOS might need to be installed via "
21+
"system package `libgeos-dev`."
22+
)
23+
else:
24+
platform_specific_msg = "GEOS package will need to be installed see (https://trac.osgeo.org/geos/)"
25+
raise ModuleNotFoundError(
26+
f"Module 'shapely' not found. Install optionally with `scale-nucleus[shapely]` or when developing "
27+
f"`poetry install -E shapely`. {platform_specific_msg}"
28+
)

tests/metrics/__init__.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import pytest
2+
3+
try:
4+
import shapely
5+
except ModuleNotFoundError:
6+
pytest.skip(
7+
"Shapely not installed, skipping (install with poetry install -E shapely)",
8+
allow_module_level=True,
9+
)

tests/metrics/test_geometry.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
import numpy as np
22
import pytest
3-
from shapely.geometry import LineString, Polygon
3+
4+
try:
5+
from shapely.geometry import LineString, Polygon
6+
except ModuleNotFoundError:
7+
pytest.skip(
8+
"Shapely not installed, skipping (install with poetry install -E shapely)",
9+
allow_module_level=True,
10+
)
411

512
RECTANGLE1 = Polygon(
613
[

0 commit comments

Comments
 (0)