Skip to content

Commit 1037e79

Browse files
committed
make the test suite green again (free of warnings)
* must_warn now accepts a num_expected argument to set the number of warnings we expect (instead of just checking there is only one) * mark all expected warnings as such * rename TestCheckedSession to CheckedSessionExample to avoid pytest trying to "test" it
1 parent 6dd745c commit 1037e79

File tree

5 files changed

+106
-53
lines changed

5 files changed

+106
-53
lines changed

larray/tests/common.py

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -154,23 +154,25 @@ def meta():
154154

155155

156156
@contextmanager
157-
def must_warn(warn_cls=None, msg=None, match=None, check_file=True, check_num=True):
158-
if msg is not None and match is not None:
159-
raise ValueError("bad test: can't use both msg and match arguments")
160-
elif msg is not None:
161-
match = re.escape(msg)
162-
163-
try:
164-
with pytest.warns(warn_cls, match=match) as caught_warnings:
165-
yield caught_warnings
166-
finally:
167-
if check_num:
168-
assert len(caught_warnings) == 1
169-
if check_file:
170-
caller_path = inspect.stack()[2].filename
171-
warning_path = caught_warnings[0].filename
172-
assert warning_path == caller_path, \
173-
f"{warning_path} != {caller_path}"
157+
def must_warn(warn_cls=None, msg=None, match=None, check_file=True, num_expected=1):
158+
if num_expected == 0:
159+
yield []
160+
else:
161+
if msg is not None and match is not None:
162+
raise ValueError("bad test: can't use both msg and match arguments")
163+
elif msg is not None:
164+
match = re.escape(msg)
165+
try:
166+
with pytest.warns(warn_cls, match=match) as caught_warnings:
167+
yield caught_warnings
168+
finally:
169+
if num_expected is not None:
170+
num_caught = len(caught_warnings)
171+
assert num_caught == num_expected, f"caught {num_caught} warnings instead of {num_expected}"
172+
if check_file:
173+
caller_path = inspect.stack()[2].filename
174+
warning_path = caught_warnings[0].filename
175+
assert warning_path == caller_path, f"{warning_path} != {caller_path}"
174176

175177

176178
@contextmanager

larray/tests/test_array.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5310,7 +5310,8 @@ def test_zip_array_items():
53105310

53115311
def test_growth_rate():
53125312
arr = Array([1, 2, 0, 0, 0, 4, 5], axes='time=2014..2020')
5313-
res = arr.growth_rate('time')
5313+
with must_warn(RuntimeWarning, "divide by zero encountered during operation"):
5314+
res = arr.growth_rate('time')
53145315
expected_res = Array([1.0, -1.0, 0.0, 0.0, inf, 0.25], axes='time=2015..2020')
53155316
assert_array_equal(res, expected_res)
53165317

larray/tests/test_checked_session.py

Lines changed: 65 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
meta = meta
2525

2626

27-
class TestCheckedSession(CheckedSession):
27+
class CheckedSessionExample(CheckedSession):
2828
b = b
2929
b024 = b024
3030
a: Axis
@@ -42,7 +42,7 @@ class TestCheckedSession(CheckedSession):
4242

4343
@pytest.fixture()
4444
def checkedsession():
45-
return TestCheckedSession(a=a, a2=a2, a01=a01, e=e, g=g, f=f, h=h)
45+
return CheckedSessionExample(a=a, a2=a2, a01=a01, e=e, g=g, f=f, h=h)
4646

4747

4848
def test_create_checkedsession_instance(meta):
@@ -53,7 +53,7 @@ def test_create_checkedsession_instance(meta):
5353
declared_variable_keys = ['a', 'a2', 'a01', 'c', 'e', 'g', 'f', 'h', 'b', 'b024', 'anonymous', 'ano01', 'd']
5454

5555
# setting variables without default values
56-
cs = TestCheckedSession(a, a01, a2=a2, e=e, f=f, g=g, h=h)
56+
cs = CheckedSessionExample(a, a01, a2=a2, e=e, f=f, g=g, h=h)
5757
assert list(cs.keys()) == declared_variable_keys
5858
assert cs.b.equals(b)
5959
assert cs.b024.equals(b024)
@@ -70,18 +70,19 @@ def test_create_checkedsession_instance(meta):
7070
assert cs.h.equals(h)
7171

7272
# metadata
73-
cs = TestCheckedSession(a, a01, a2=a2, e=e, f=f, g=g, h=h, meta=meta)
73+
cs = CheckedSessionExample(a, a01, a2=a2, e=e, f=f, g=g, h=h, meta=meta)
7474
assert cs.meta == meta
7575

7676
# override default value
7777
b_alt = Axis('b=b0..b4')
78-
cs = TestCheckedSession(a, a01, b=b_alt, a2=a2, e=e, f=f, g=g, h=h)
78+
cs = CheckedSessionExample(a, a01, b=b_alt, a2=a2, e=e, f=f, g=g, h=h)
7979
assert cs.b is b_alt
8080

8181
# test for "NOT_LOADED" variables
82-
with must_warn(UserWarning, msg="No value passed for the declared variable 'a'", check_file=False):
83-
TestCheckedSession(a01=a01, a2=a2, e=e, f=f, g=g, h=h)
84-
cs = TestCheckedSession()
82+
with must_warn(UserWarning, msg="No value passed for the declared variable 'a'"):
83+
CheckedSessionExample(a01=a01, a2=a2, e=e, f=f, g=g, h=h)
84+
with must_warn(UserWarning, match=r"No value passed for the declared variable '\w+'", num_expected=7):
85+
cs = CheckedSessionExample()
8586
assert list(cs.keys()) == declared_variable_keys
8687
# --- variables with default values ---
8788
assert cs.b.equals(b)
@@ -100,17 +101,17 @@ def test_create_checkedsession_instance(meta):
100101
assert isinstance(cs.h, NotLoaded)
101102

102103
# passing a scalar to set all elements a CheckedArray
103-
cs = TestCheckedSession(a, a01, a2=a2, e=e, f=f, g=g, h=5)
104+
cs = CheckedSessionExample(a, a01, a2=a2, e=e, f=f, g=g, h=5)
104105
assert cs.h.axes == AxisCollection((a3, b2))
105106
assert cs.h.equals(full(axes=(a3, b2), fill_value=5))
106107

107108
# add the undeclared variable 'i'
108-
with must_warn(UserWarning, f"'i' is not declared in '{cs.__class__.__name__}'", check_file=False):
109-
cs = TestCheckedSession(a, a01, a2=a2, i=5, e=e, f=f, g=g, h=h)
109+
with must_warn(UserWarning, f"'i' is not declared in '{cs.__class__.__name__}'"):
110+
cs = CheckedSessionExample(a, a01, a2=a2, i=5, e=e, f=f, g=g, h=h)
110111
assert list(cs.keys()) == declared_variable_keys + ['i']
111112

112113
# test inheritance between checked sessions
113-
class TestInheritance(TestCheckedSession):
114+
class TestInheritance(CheckedSessionExample):
114115
# override variables
115116
b = b2
116117
c: int = 5
@@ -145,7 +146,7 @@ class TestInheritance(TestCheckedSession):
145146

146147
@needs_pytables
147148
def test_init_checkedsession_hdf():
148-
cs = TestCheckedSession(inputpath('test_session.h5'))
149+
cs = CheckedSessionExample(inputpath('test_session.h5'))
149150
assert set(cs.keys()) == {'b', 'b024', 'a', 'a2', 'anonymous', 'a01', 'ano01', 'c', 'd', 'e', 'g', 'f', 'h'}
150151

151152

@@ -260,7 +261,7 @@ def test_add_cs(checkedsession):
260261
test_add(cs)
261262

262263
u = Axis('u=u0..u2')
263-
with must_warn(UserWarning, msg=f"'u' is not declared in '{cs.__class__.__name__}'", check_file=False):
264+
with must_warn(UserWarning, msg=f"'u' is not declared in '{cs.__class__.__name__}'"):
264265
cs.add(u)
265266

266267

@@ -276,7 +277,8 @@ def test_iter_cs(checkedsession):
276277
def test_filter_cs(checkedsession):
277278
# see comment in test_iter_cs() about fields ordering
278279
cs = checkedsession
279-
cs.ax = 'ax'
280+
with must_warn(UserWarning, msg="'ax' is not declared in 'CheckedSessionExample'"):
281+
cs.ax = 'ax'
280282
assert_seq_equal(cs.filter(), [a, a2, a01, c, e, g, f, h, b, b024, anonymous, ano01, d, 'ax'])
281283
assert_seq_equal(cs.filter('a*'), [a, a2, a01, anonymous, ano01, 'ax'])
282284
assert list(cs.filter('a*', dict)) == []
@@ -306,9 +308,10 @@ def _test_io_cs(tmpdir, meta, engine, ext):
306308

307309
# a) - all typed variables have a defined value
308310
# - no extra variables are added
309-
csession = TestCheckedSession(a=a, a2=a2, a01=a01, d=d, e=e, g=g, f=f, h=h, meta=meta)
311+
csession = CheckedSessionExample(a=a, a2=a2, a01=a01, d=d, e=e, g=g, f=f, h=h, meta=meta)
310312
csession.save(fpath, engine=engine)
311-
cs = TestCheckedSession()
313+
with must_warn(UserWarning, match=r"No value passed for the declared variable '\w+'", num_expected=7):
314+
cs = CheckedSessionExample()
312315
cs.load(fpath, engine=engine)
313316
# --- keys ---
314317
assert list(cs.keys()) == list(csession.keys())
@@ -343,12 +346,14 @@ def _test_io_cs(tmpdir, meta, engine, ext):
343346

344347
# b) - not all typed variables have a defined value
345348
# - no extra variables are added
346-
csession = TestCheckedSession(a=a, d=d, e=e, h=h, meta=meta)
349+
with must_warn(UserWarning, match=r"No value passed for the declared variable '\w+'", num_expected=4):
350+
csession = CheckedSessionExample(a=a, d=d, e=e, h=h, meta=meta)
347351
if 'csv' in engine:
348352
import shutil
349353
shutil.rmtree(fpath)
350354
csession.save(fpath, engine=engine)
351-
cs = TestCheckedSession()
355+
with must_warn(UserWarning, match=r"No value passed for the declared variable '\w+'", num_expected=7):
356+
cs = CheckedSessionExample()
352357
cs.load(fpath, engine=engine)
353358
# --- keys ---
354359
assert list(cs.keys()) == list(csession.keys())
@@ -379,10 +384,27 @@ def _test_io_cs(tmpdir, meta, engine, ext):
379384
i = ndtest(6)
380385
j = ndtest((3, 3))
381386
k = ndtest((2, 2))
382-
csession = TestCheckedSession(a=a, a2=a2, a01=a01, d=d, e=e, g=g, f=f, h=h, k=k, j=j, i=i, meta=meta)
387+
with must_warn(UserWarning, match=r"'\w' is not declared in 'CheckedSessionExample'", num_expected=3):
388+
csession = CheckedSessionExample(a=a, a2=a2, a01=a01, d=d, e=e, g=g, f=f, h=h, k=k, j=j, i=i, meta=meta)
383389
csession.save(fpath, engine=engine)
384-
cs = TestCheckedSession()
385-
cs.load(fpath, engine=engine)
390+
with must_warn(UserWarning, match=r"No value passed for the declared variable '\w+'", num_expected=7):
391+
cs = CheckedSessionExample()
392+
393+
# number of expected warnings is different depending on engine
394+
expected_warnings = {
395+
'pandas_excel': 3,
396+
'xlwings_excel': 3,
397+
'pandas_csv': 3,
398+
'pandas_hdf': 47, # FIXME: there is something fishy here
399+
'pickle': 3,
400+
}
401+
num_expected = expected_warnings[engine]
402+
# FIXME: we should try to fix the bad warning line instead of ignoring it
403+
check_file = engine != 'pandas_hdf'
404+
with must_warn(UserWarning, match=r"'\w' is not declared in 'CheckedSessionExample'",
405+
check_file=check_file, num_expected=num_expected):
406+
cs.load(fpath, engine=engine)
407+
386408
# --- names ---
387409
# we do not use keys() since order of undeclared variables
388410
# may not be preserved (at least for the HDF format)
@@ -394,15 +416,29 @@ def _test_io_cs(tmpdir, meta, engine, ext):
394416

395417
# Update a Group + an Axis + an array (overwrite=False)
396418
# -----------------------------------------------------
397-
csession = TestCheckedSession(a=a, a2=a2, a01=a01, d=d, e=e, g=g, f=f, h=h, meta=meta)
419+
csession = CheckedSessionExample(a=a, a2=a2, a01=a01, d=d, e=e, g=g, f=f, h=h, meta=meta)
398420
csession.save(fpath, engine=engine)
399421
a4 = Axis('a=0..3')
400422
a4_01 = a3['0,1'] >> 'a01'
401423
e2 = ndtest((a4, 'b=b0..b2'))
402424
h2 = full_like(h, fill_value=10)
403-
TestCheckedSession(a=a4, a01=a4_01, e=e2, h=h2).save(fpath, overwrite=False, engine=engine)
404-
cs = TestCheckedSession()
405-
cs.load(fpath, engine=engine)
425+
with must_warn(UserWarning, match=r"No value passed for the declared variable '\w+'", num_expected=3):
426+
CheckedSessionExample(a=a4, a01=a4_01, e=e2, h=h2).save(fpath, overwrite=False, engine=engine)
427+
with must_warn(UserWarning, match=r"No value passed for the declared variable '\w+'", num_expected=7):
428+
cs = CheckedSessionExample()
429+
430+
# number of expected warnings is different depending on engine
431+
expected_warnings = {
432+
'pandas_excel': 0,
433+
'xlwings_excel': 0,
434+
'pandas_hdf': 0,
435+
'pandas_csv': 3,
436+
'pickle': 0,
437+
}
438+
num_expected = expected_warnings[engine]
439+
with must_warn(UserWarning, match=r"'\w' is not declared in 'CheckedSessionExample'",
440+
num_expected=num_expected):
441+
cs.load(fpath, engine=engine)
406442
# --- variables with default values ---
407443
assert cs.b.equals(b)
408444
assert cs.b024.equals(b024)
@@ -440,9 +476,10 @@ def _test_io_cs(tmpdir, meta, engine, ext):
440476

441477
# Load only some objects
442478
# ----------------------
443-
csession = TestCheckedSession(a=a, a2=a2, a01=a01, d=d, e=e, g=g, f=f, h=h, meta=meta)
479+
csession = CheckedSessionExample(a=a, a2=a2, a01=a01, d=d, e=e, g=g, f=f, h=h, meta=meta)
444480
csession.save(fpath, engine=engine)
445-
cs = TestCheckedSession()
481+
with must_warn(UserWarning, match=r"No value passed for the declared variable '\w+'", num_expected=7):
482+
cs = CheckedSessionExample()
446483
names_to_load = ['e', 'h'] if is_excel_or_csv else ['a', 'a01', 'a2', 'e', 'h']
447484
cs.load(fpath, names=names_to_load, engine=engine)
448485
# --- keys ---

larray/tests/test_session.py

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
needs_xlwings, needs_pytables, needs_openpyxl, must_warn)
1414
from larray.inout.common import _supported_scalars_types
1515
from larray import (Session, Axis, Array, Group, isnan, zeros_like, ndtest, ones_like,
16-
ones, full, full_like, stack, local_arrays, global_arrays, arrays)
16+
ones, full, full_like, stack, local_arrays, global_arrays, arrays, CheckedSession)
1717

1818

1919
# avoid flake8 errors
@@ -152,7 +152,10 @@ def test_setattr(session):
152152
def test_add(session):
153153
i = Axis('i=i0..i2')
154154
i01 = i['i0,i1'] >> 'i01'
155-
session.add(i, i01, j='j')
155+
expected_warnings = 3 if isinstance(session, CheckedSession) else 0
156+
with must_warn(UserWarning, match=r"'\w+' is not declared in 'CheckedSessionExample'",
157+
num_expected=expected_warnings):
158+
session.add(i, i01, j='j')
156159
assert i.equals(session.i)
157160
assert i01 == session.i01
158161
assert session.j == 'j'
@@ -371,7 +374,10 @@ def test_element_equals(session):
371374
del other_session[deleted_key]
372375
expected_res[deleted_key] = False
373376
# add one item
374-
other_session['k'] = k
377+
expected_warnings = 1 if isinstance(other_session, CheckedSession) else 0
378+
with must_warn(UserWarning, match=r"'k' is not declared in 'CheckedSessionExample'",
379+
num_expected=expected_warnings):
380+
other_session['k'] = k
375381
expected_res = expected_res.append('name', False, label='k')
376382

377383
res = session.element_equals(other_session)
@@ -408,7 +414,10 @@ def test_eq(session):
408414
# ====== session with missing/extra items ======
409415
del other_session['g']
410416
expected_res['g'] = False
411-
other_session['k'] = k
417+
expected_warnings = 1 if isinstance(other_session, CheckedSession) else 0
418+
with must_warn(UserWarning, match=r"'k' is not declared in 'CheckedSessionExample'",
419+
num_expected=expected_warnings):
420+
other_session['k'] = k
412421
expected_res = expected_res.append('name', False, label='k')
413422

414423
res = session == other_session
@@ -448,7 +457,10 @@ def test_ne(session):
448457
# ====== session with missing/extra items ======
449458
del other_session['g']
450459
expected_res['g'] = True
451-
other_session['k'] = k
460+
expected_warnings = 1 if isinstance(other_session, CheckedSession) else 0
461+
with must_warn(UserWarning, match=r"'k' is not declared in 'CheckedSessionExample'",
462+
num_expected=expected_warnings):
463+
other_session['k'] = k
452464
expected_res = expected_res.append('name', True, label='k')
453465

454466
res = session != other_session
@@ -563,7 +575,7 @@ def test_rdiv(session):
563575
sess = session
564576

565577
# scalar / session
566-
with must_warn(RuntimeWarning, msg="divide by zero encountered during operation", check_num=False):
578+
with must_warn(RuntimeWarning, msg="divide by zero encountered during operation", num_expected=4):
567579
res = 2 / sess
568580
with np.errstate(divide='ignore'):
569581
expected_e = 2 / e
@@ -580,7 +592,7 @@ def test_rdiv(session):
580592
other = {'e': e, 'f': f}
581593
with must_warn(RuntimeWarning,
582594
msg="invalid value (NaN) encountered during operation (this is typically caused by a 0 / 0)",
583-
check_num=False):
595+
num_expected=2):
584596
res = other / sess
585597
with np.errstate(invalid='ignore'):
586598
expected_e = e / e

setup.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ addopts = -v --doctest-modules
3131
#--cov
3232

3333
filterwarnings =
34+
ignore::DeprecationWarning:flake8.*:
3435
ignore::DeprecationWarning:pyreadline.*:
3536
ignore::DeprecationWarning:pywintypes.*:
3637
ignore::DeprecationWarning:tables.*:

0 commit comments

Comments
 (0)