10000 CI Disable network when SciPy requires it (#25743) · jeremiedbb/scikit-learn@2169b4d · GitHub
[go: up one dir, main page]

Skip to content

Commit 2169b4d

Browse files
authored
CI Disable network when SciPy requires it (scikit-learn#25743)
1 parent fdf2d7e commit 2169b4d

File tree

2 files changed

+64
-52
lines changed

2 files changed

+64
-52
lines changed

sklearn/conftest.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
from functools import wraps
33
import platform
44
import sys
5+
from contextlib import suppress
6+
from unittest import SkipTest
57

68
import pytest
79
import numpy as np
@@ -11,6 +13,7 @@
1113
from sklearn.utils import _IS_32BIT
1214
from sklearn.utils._openmp_helpers import _openmp_effective_n_threads
1315
from sklearn._min_dependencies import PYTEST_MIN_VERSION
16+
from sklearn.utils.fixes import sp_version
1417
from sklearn.utils.fixes import parse_version
1518
from sklearn.datasets import fetch_20newsgroups
1619
from sklearn.datasets import fetch_20newsgroups_vectorized
@@ -28,6 +31,28 @@
2831
"at least pytest >= {} installed.".format(PYTEST_MIN_VERSION)
2932
)
3033

34+
scipy_datasets_require_network = sp_version >= parse_version("1.10")
35+
36+
37+
def raccoon_face_or_skip():
38+
# SciPy >= 1.10 requires network to access to get data
39+
if scipy_datasets_require_network:
40+
run_network_tests = environ.get("SKLEARN_SKIP_NETWORK_TESTS", "1") == "0"
41+
if not run_network_tests:
42+
raise SkipTest("test is enabled when SKLEARN_SKIP_NETWORK_TESTS=0")
43+
44+
try:
45+
import pooch # noqa
46+
except ImportError:
47+
raise SkipTest("test requires pooch to be installed")
48+
49+
from scipy.datasets import face
50+
else:
51+
from scipy.misc import face
52+
53+
return face(gray=True)
54+
55+
3156
dataset_fetchers = {
3257
"fetch_20newsgroups_fxt": fetch_20newsgroups,
3358
"fetch_20newsgroups_vectorized_fxt": fetch_20newsgroups_vectorized,
@@ -38,6 +63,9 @@
3863
"fetch_rcv1_fxt": fetch_rcv1,
3964
}
4065

66+
if scipy_datasets_require_network:
67+
dataset_fetchers["raccoon_face_fxt"] = raccoon_face_or_skip
68+
4169
_SKIP32_MARK = pytest.mark.skipif(
4270
environ.get("SKLEARN_RUN_FLOAT32_TESTS", "0") != "1",
4371
reason="Set SKLEARN_RUN_FLOAT32_TESTS=1 to run float32 dtype tests",
@@ -75,6 +103,7 @@ def wrapped(*args, **kwargs):
75103
fetch_kddcup99_fxt = _fetch_fixture(fetch_kddcup99)
76104
fetch_olivetti_faces_fxt = _fetch_fixture(fetch_olivetti_faces)
77105
fetch_rcv1_fxt = _fetch_fixture(fetch_rcv1)
106+
raccoon_face_fxt = pytest.fixture(raccoon_face_or_skip)
78107

79108

80109
def pytest_collection_modifyitems(config, items):
@@ -115,7 +144,8 @@ def pytest_collection_modifyitems(config, items):
115144
worker_id = environ.get("PYTEST_XDIST_WORKER", "gw0")
116145
if worker_id == "gw0" and run_network_tests:
117146
for name in datasets_to_download:
118-
dataset_fetchers[name]()
147+
with suppress(SkipTest):
148+
dataset_fetchers[name]()
119149

120150
for item in items:
121151
# Known failure on with GradientBoostingClassifier on ARM64

sklearn/feature_extraction/tests/test_image.py

Lines changed: 33 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
from scipy.sparse.csgraph import connected_components
88
import pytest
99

10-
from sklearn.utils.fixes import sp_version, parse_version
1110
from sklearn.feature_extraction.image import (
1211
img_to_graph,
1312
grid_to_graph,
@@ -18,17 +17,6 @@
1817
)
1918

2019

21-
@pytest.fixture(scope="module")
22-
def raccoon_face():
23-
if sp_version.release >= parse_version("1.10").release:
24-
pytest.importorskip("pooch")
25-
from scipy.datasets import face
26-
else:
27-
from scipy.misc import face
28-
29-
return face(gray=True)
30-
31-
3220
def test_img_to_graph():
3321
x, y = np.mgrid[:4, :4] - 10
3422
grad_x = img_to_graph(x)
@@ -93,8 +81,8 @@ def test_grid_to_graph():
9381
assert A.dtype == np.float64
9482

9583

96-
def test_connect_regions(raccoon_face):
97-
face = raccoon_face.copy()
84+
def test_connect_regions(raccoon_face_fxt):
85+
face = raccoon_face_fxt
9886
# subsample by 4 to reduce run time
9987
face = face[::4, ::4]
10088
for thr in (50, 150):
@@ -103,8 +91,8 @@ def test_connect_regions(raccoon_face):
10391
assert ndimage.label(mask)[1] == connected_components(graph)[0]
10492

10593

106-
def test_connect_regions_with_grid(raccoon_face):
107-
face = raccoon_face.copy()
94+
def test_connect_regions_with_grid(raccoon_face_fxt):
95+
face = raccoon_face_fxt
10896

10997
# subsample by 4 to reduce run time
11098
face = face[::4, ::4]
@@ -118,33 +106,27 @@ def test_connect_regions_with_grid(raccoon_face):
118106
assert ndimage.label(mask)[1] == connected_components(graph)[0]
119107

120108

121-
def _downsampled_face():
122-
if sp_version.release >= parse_version("1.10").release:
123-
pytest.importorskip("pooch")
124-
from scipy.datasets import face as raccoon_face
125-
else:
126-
from scipy.misc import face as raccoon_face
127-
128-
face = raccoon_face(gray=True)
129-
face = face.astype(np.float32)
109+
@pytest.fixture
110+
def downsampled_face(raccoon_face_fxt):
111+
face = raccoon_face_fxt
130112
face = face[::2, ::2] + face[1::2, ::2] + face[::2, 1::2] + face[1::2, 1::2]
131113
face = face[::2, ::2] + face[1::2, ::2] + face[::2, 1::2] + face[1::2, 1::2]
132114
face = face.astype(np.float32)
133115
face /= 16.0
134116
return face
135117

136118

137-
def _orange_face(face=None):
138-
face = _downsampled_face() if face is None else face
119+
@pytest.fixture
120+
def orange_face(downsampled_face):
121+
face = downsampled_face
139122
face_color = np.zeros(face.shape + (3,))
140123
face_color[:, :, 0] = 256 - face
141124
face_color[:, :, 1] = 256 - face / 2
142125
face_color[:, :, 2] = 256 - face / 4
143126
return face_color
144127

145128

146-
def _make_images(face=None):
147-
face = _downsampled_face() if face is None else face
129+
def _make_images(face):
148130
# make a collection of faces
149131
images = np.zeros((3,) + face.shape)
150132
images[0] = face
@@ -153,12 +135,12 @@ def _make_images(face=None):
153135
return images
154136

155137

156-
downsampled_face = _downsampled_face()
157-
orange_face = _orange_face(downsampled_face)
158-
face_collection = _make_images(downsampled_face)
138+
@pytest.fixture
139+
def downsampled_face_collection(downsampled_face):
140+
return _make_images(downsampled_face)
159141

160142

161-
def test_extract_patches_all():
143+
def test_extract_patches_all(downsampled_face):
162144
face = downsampled_face
163145
i_h, i_w = face.shape
164146
p_h, p_w = 16, 16
@@ -167,7 +149,7 @@ def test_extract_patches_all():
167149
assert patches.shape == (expected_n_patches, p_h, p_w)
168150

169151

170-
def test_extract_patches_all_color():
152+
def test_extract_patches_all_color(orange_face):
171153
face = orange_face
172154
i_h, i_w = face.shape[:2]
173155
p_h, p_w = 16, 16
@@ -176,7 +158,7 @@ def test_extract_patches_all_color():
176158
assert patches.shape == (expected_n_patches, p_h, p_w, 3)
177159

178160

179-
def test_extract_patches_all_rect():
161+
def test_extract_patches_all_rect(downsampled_face):
180162
face = downsampled_face
181163
face = face[:, 32:97]
182164
i_h, i_w = face.shape
@@ -187,7 +169,7 @@ def test_extract_patches_all_rect():
187169
assert patches.shape == (expected_n_patches, p_h, p_w)
188170

189171

190-
def test_extract_patches_max_patches():
172+
def test_extract_patches_max_patches(downsampled_face):
191173
face = downsampled_face
192174
i_h, i_w = face.shape
193175
p_h, p_w = 16, 16
@@ -205,15 +187,15 @@ def test_extract_patches_max_patches():
205187
extract_patches_2d(face, (p_h, p_w), max_patches=-1.0)
206188

207189

208-
def test_extract_patch_same_size_image():
190+
def test_extract_patch_same_size_image(downsampled_face):
209191
face = downsampled_face
210192
# Request patches of the same size as image
211193
# Should return just the single patch a.k.a. the image
212194
patches = extract_patches_2d(face, face.shape, max_patches=2)
213195
assert patches.shape[0] == 1
214196

215197

216-
def test_extract_patches_less_than_max_patches():
198+
def test_extract_patches_less_than_max_patches(downsampled_face):
217199
face = downsampled_face
218200
i_h, i_w = face.shape
219201
p_h, p_w = 3 * i_h // 4, 3 * i_w // 4
@@ -224,7 +206,7 @@ def test_extract_patches_less_than_max_patches():
224206
assert patches.shape == (expected_n_patches, p_h, p_w)
225207

226208

227-
def test_reconstruct_patches_perfect():
209+
def test_reconstruct_patches_perfect(downsampled_face):
228210
face = downsampled_face
229211
p_h, p_w = 16, 16
230212

@@ -233,7 +215,7 @@ def test_reconstruct_patches_perfect():
233215
np.testing.assert_array_almost_equal(face, face_reconstructed)
234216

235217

236-
def test_reconstruct_patches_perfect_color():
218+
def test_reconstruct_patches_perfect_color(orange_face):
237219
face = orange_face
238220
p_h, p_w = 16, 16
239221

@@ -242,14 +224,14 @@ def test_reconstruct_patches_perfect_color():
242224
np.testing.assert_array_almost_equal(face, face_reconstructed)
243225

244226

245-
def test_patch_extractor_fit():
246-
faces = face_collection
227+
def test_patch_extractor_fit(downsampled_face_collection):
228+
faces = downsampled_face_collection
247229
extr = PatchExtractor(patch_size=(8, 8), max_patches=100, random_state=0)
248230
assert extr == extr.fit(faces)
249231

250232

251-
def test_patch_extractor_max_patches():
252-
faces = face_collection
233+
def test_patch_extractor_max_patches(downsampled_face_collection):
234+
faces = downsampled_face_collection
253235
i_h, i_w = faces.shape[1:3]
254236
p_h, p_w = 8, 8
255237

@@ -272,15 +254,15 @@ def test_patch_extractor_max_patches():
272254
assert patches.shape == (expected_n_patches, p_h, p_w)
273255

274256

275-
def test_patch_extractor_max_patches_default():
276-
faces = face_collection
257+
def test_patch_extractor_max_patches_default(downsampled_face_collection):
258+
faces = downsampled_face_collection
277259
extr = PatchExtractor(max_patches=100, random_state=0)
278260
patches = extr.transform(faces)
279261
assert patches.shape == (len(faces) * 100, 19, 25)
280262

281263

282-
def test_patch_extractor_all_patches():
283-
faces = face_collection
264+
def test_patch_extractor_all_patches(downsampled_face_collection):
265+
faces = downsampled_face_collection
284266
i_h, i_w = faces.shape[1:3]
285267
p_h, p_w = 8, 8
286268
expected_n_patches = len(faces) * (i_h - p_h + 1) * (i_w - p_w + 1)
@@ -289,7 +271,7 @@ def test_patch_extractor_all_patches():
289271
assert patches.shape == (expected_n_patches, p_h, p_w)
290272

291273

292-
def test_patch_extractor_color():
274+
def test_patch_extractor_color(orange_face):
293275
faces = _make_images(orange_face)
294276
i_h, i_w = faces.shape[1:3]
295277
p_h, p_w = 8, 8
@@ -347,7 +329,7 @@ def test_extract_patches_strided():
347329
).all()
348330

349331

350-
def test_extract_patches_square():
332+
def test_extract_patches_square(downsampled_face):
351333
# test same patch size for all dimensions
352334
face = downsampled_face
353335
i_h, i_w = face.shape
@@ -366,7 +348,7 @@ def test_width_patch():
366348
extract_patches_2d(x, (1, 4))
367349

368350

369-
def test_patch_extractor_wrong_input():
351+
def test_patch_extractor_wrong_input(orange_face):
370352
"""Check that an informative error is raised if the patch_size is not valid."""
371353
faces = _make_images(orange_face)
372354
err_msg = "patch_size must be a tuple of two integers"

0 commit comments

Comments
 (0)
0