1
+ from contextlib import contextmanager
2
+
1
3
import dask
2
4
import numpy as np
3
5
import pytest
@@ -12,11 +14,11 @@ def xp():
12
14
return array_namespace (da .empty (0 ))
13
15
14
16
15
- @pytest . fixture
16
- def no_compute ():
17
+ @contextmanager
18
+ def assert_no_compute ():
17
19
"""
18
- Cause the test to raise if at any point anything calls compute() or persist(),
19
- e.g. as it can be triggered implicitly by __bool__, __array__, etc.
20
+ Context manager that raises if at any point inside it anything calls compute()
21
+ or persist(), e.g. as it can be triggered implicitly by __bool__, __array__, etc.
20
22
"""
21
23
def get (dsk , * args , ** kwargs ):
22
24
raise AssertionError ("Called compute() or persist()" )
@@ -25,72 +27,82 @@ def get(dsk, *args, **kwargs):
25
27
yield
26
28
27
29
28
- def test_no_compute (no_compute ):
29
- """Test the no_compute fixture """
30
+ def test_no_compute ():
31
+ """Test the no_compute context manager """
30
32
a = da .asarray (True )
31
33
with pytest .raises (AssertionError , match = "Called compute" ):
32
- bool (a )
34
+ with assert_no_compute ():
35
+ bool (a )
36
+
37
+ # Exiting the context manager restores the original scheduler
38
+ assert bool (a ) is True
33
39
34
40
35
41
# Test no_compute for functions that use generic _aliases with xp=np
36
42
37
- def test_unary_ops_no_compute (xp , no_compute ):
38
- a = xp .asarray ([1.5 , - 1.5 ])
39
- xp .ceil (a )
40
- xp .floor (a )
41
- xp .trunc (a )
42
- xp .sign (a )
43
+ def test_unary_ops_no_compute (xp ):
44
+ with assert_no_compute ():
45
+ a = xp .asarray ([1.5 , - 1.5 ])
46
+ xp .ceil (a )
47
+ xp .floor (a )
48
+ xp .trunc (a )
49
+ xp .sign (a )
43
50
44
51
45
- def test_matmul_tensordot_no_compute (xp , no_compute ):
52
+ def test_matmul_tensordot_no_compute (xp ):
46
53
A = da .ones ((4 , 4 ), chunks = 2 )
47
54
B = da .zeros ((4 , 4 ), chunks = 2 )
48
- xp .matmul (A , B )
49
- xp .tensordot (A , B )
55
+ with assert_no_compute ():
56
+ xp .matmul (A , B )
57
+ xp .tensordot (A , B )
50
58
51
59
52
60
# Test no_compute for functions that are fully bespoke for dask
53
61
54
- def test_asarray_no_compute (xp , no_compute ):
55
- a = xp .arange (10 )
56
- xp .asarray (a )
57
- xp .asarray (a , dtype = np .int16 )
58
- xp .asarray (a , dtype = a .dtype )
59
- xp .asarray (a , copy = True )
60
- xp .asarray (a , copy = True , dtype = np .int16 )
61
- xp .asarray (a , copy = True , dtype = a .dtype )
62
- xp .asarray (a , copy = False )
63
- xp .asarray (a , copy = False , dtype = a .dtype )
62
+ def test_asarray_no_compute (xp ):
63
+ with assert_no_compute ():
64
+ a = xp .arange (10 )
65
+ xp .asarray (a )
66
+ xp .asarray (a , dtype = np .int16 )
67
+ xp .asarray (a , dtype = a .dtype )
68
+ xp .asarray (a , copy = True )
69
+ xp .asarray (a , copy = True , dtype = np .int16 )
70
+ xp .asarray (a , copy = True , dtype = a .dtype )
71
+ xp .asarray (a , copy = False )
72
+ xp .asarray (a , copy = False , dtype = a .dtype )
64
73
65
74
66
75
@pytest .mark .parametrize ("copy" , [True , False ])
67
- def test_astype_no_compute (xp , no_compute , copy ):
68
- a = xp .arange (10 )
69
- xp .astype (a , np .int16 , copy = copy )
70
- xp .astype (a , a .dtype , copy = copy )
76
+ def test_astype_no_compute (xp , copy ):
77
+ with assert_no_compute ():
78
+ a = xp .arange (10 )
79
+ xp .astype (a , np .int16 , copy = copy )
80
+ xp .astype (a , a .dtype , copy = copy )
71
81
72
82
73
- def test_clip_no_compute (xp , no_compute ):
74
- a = xp .arange (10 )
75
- xp .clip (a )
76
- xp .clip (a , 1 )
77
- xp .clip (a , 1 , 8 )
83
+ def test_clip_no_compute (xp ):
84
+ with assert_no_compute ():
85
+ a = xp .arange (10 )
86
+ xp .clip (a )
87
+ xp .clip (a , 1 )
88
+ xp .clip (a , 1 , 8 )
78
89
79
90
80
- def test_generators_are_lazy (xp , no_compute ):
91
+ def test_generators_are_lazy (xp ):
81
92
"""
82
93
Test that generator functions are fully lazy, e.g. that
83
94
da.ones(n) is not implemented as da.asarray(np.ones(n))
84
95
"""
85
96
size = 100_000_000_000 # 800 GB
86
97
chunks = size // 10 # 10x 80 GB chunks
87
98
88
- xp .zeros (size , chunks = chunks )
89
- xp .ones (size , chunks = chunks )
90
- xp .empty (size , chunks = chunks )
91
- xp .full (size , fill_value = 123 , chunks = chunks )
92
- a = xp .arange (size , chunks = chunks )
93
- xp .zeros_like (a )
94
- xp .ones_like (a )
95
- xp .empty_like (a )
96
- xp .full_like (a , fill_value = 123 )
99
+ with assert_no_compute ():
100
+ xp .zeros (size , chunks = chunks )
101
+ xp .ones (size , chunks = chunks )
102
+ xp .empty (size , chunks = chunks )
103
+ xp .full (size , fill_value = 123 , chunks = chunks )
104
+ a = xp .arange (size , chunks = chunks )
105
+ xp .zeros_like (a )
106
+ xp .ones_like (a )
107
+ xp .empty_like (a )
108
+ xp .full_like (a , fill_value = 123 )
0 commit comments