[BUG] mute stderr in QuickTester.run_tests, and fix np.all generator checks - #586
Conversation
…checks
Two fixes, both found while refactoring the sktime test framework to
inherit from skbase.
1. `run_tests` muted stdout only, so anything a test wrote to stderr still
reached the log at `verbose < 2`. It now mutes both streams, matching what
`sktime` does downstream. `StderrMute` already shipped in
`skbase.utils.stderr_mute` but was never used here.
2. Three checks passed a generator expression to `np.all` instead of a list.
`np.all` receives the generator object rather than an array of booleans, and
every generator object is truthy, so the checks always passed and their
bodies never ran.
- `_check_none_str_or_list_of_str` never rejected invalid input, so
`tests_to_run` and friends were unvalidated.
- the two checks in `test_create_test_instances_and_names` never ran.
The second of those also passed `names`, a list of str, as the second
argument to `isinstance`, which is not a type. Wrapping the comprehension
alone would raise TypeError, so it is corrected to `str`, which is what the
assert message already says it checks.
Verified: full test suite is 1609 passed, 23 skipped, identical to main. An
object returning non str names or non instances is now caught by
`test_create_test_instances_and_names`, and was not before. At `verbose=0`
stderr no longer leaks, and `verbose=2` still shows both streams.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #586 +/- ##
==========================================
- Coverage 85.07% 84.35% -0.72%
==========================================
Files 45 53 +8
Lines 3015 3995 +980
==========================================
+ Hits 2565 3370 +805
- Misses 450 625 +175 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
fkiraly
left a comment
There was a problem hiding this comment.
Thanks, and also for fixing the bugs in np.all.
Could you kindly add tests to prevent regressions? There should be fixtures that you can adapt. If it is too complex (e.g., resulting in 100s lines of code) we can omit it though.
|
Just added! I managed to keep it very concise (under 50 lines) by using |
Reference Issues/PRs
Spun out of the
sktimetest framework refactor (#10647), specifically PR #10862 which inheritsBaseFixtureGeneratorandQuickTesterfromskbase.testing. @fkiraly suggested upstreaming theStderrMutechange there.What does this implement/fix? Explain your changes.
This introduces two independent fixes in
skbase/testing/test_all_objects.py, both found while makingsktimeinherit this test framework.1.
run_testsonly muted stdoutCurrently,
run_testswraps each test inStdoutMute(active=verbose < 2), so anything a test writes to stderr still reaches the log atverbose=0.sktimehas been muting both streams since PR #8799, so inheritingrun_testsunchanged would have silently dropped the stderr half.StderrMutealready shipped inskbase.utils.stderr_mute, it was just never used here.Measured before and after:
verbose=0verbose=0verbose=2verbose=2still shows both streams, so the escape hatch is unchanged.2. Three checks passed a generator expression to
np.allFor example:
Without brackets, this is a generator expression.
np.allreceives a single generator object rather than an array of booleans. NumPy treats it as one scalar object and applies truthiness, and every generator object is truthy. The result is unconditionallyTrue, the generator is never consumed, and the check never fires.Affected areas:
QuickTester._check_none_str_or_list_of_str:tests_to_run,fixtures_to_run, and related args were effectively unvalidated.TestAllObjects.test_create_test_instances_and_names.There is a secondary bug in the last of these. It read:
Since
namesis a list of strings, not a type,isinstance(name, names)is invalid and raises aTypeError. The generator bug was masking it. Adding brackets alone would have converted a silently passing assert into a hardTypeErroron every object under test, so this is corrected toisinstance(name, str)to match the assertion message.Does your contribution introduce a new dependency? If yes, which one?
No
What should a reviewer concentrate their feedback on?
verbose < 2is the desired behavior, or whether it should be opt-in.namestostrcorrection intest_create_test_instances_and_names. It changes what that assert actually checks since it has never truly executed before.