8000 BUG: Add a lock to assert_equal and other testing functions by seberg · Pull Request #8427 · numpy/numpy · GitHub
[go: up one dir, main page]

Skip to content

BUG: Add a lock to assert_equal and other testing functions #8427

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 31, 2016
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 26 additions & 3 deletions numpy/testing/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@
else:
from StringIO import StringIO

try:
from threading import Lock
except ImportError:
from dummy_threading import Lock


__all__ = [
'assert_equal', 'assert_almost_equal', 'assert_approx_equal',
'assert_array_equal', 'assert_array_less', 'assert_string_equal',
Expand All @@ -42,6 +48,20 @@ class KnownFailureException(Exception):
pass


# Warning filtering is generally not threadsafe in python, this is also
# true for `catch_warnings` or `suppress_warinings`. In NumPy 1.12
# however, `assert_equal` and the array comparison asserts, use this
# to filter out some comparison warnings. Since removing this filter
# may also affect downstream projects and skimage (and possibly more)
# do parallel manual parallel testing using `assert_equal`, a quick fix
# seems to be to lock the less obvious threading trap. Ideally (in
# master this is the case), there should simply not be warning filter
# logic in the assert functions themself.
# While probably not perfectly safe in principle, it is sufficient
# in the case of skimage and probably most testing scenarios and the
# chance of deadlocks seems very unlikely.
_assert_comparison_lock = Lock()

KnownFailureTest = KnownFailureException # backwards compat
verbose = 0

Expand Down Expand Up @@ -395,15 +415,17 @@ def assert_equal(actual,desired,err_msg='',verbose=True):
except (TypeError, ValueError, NotImplementedError):
pass

# Explicitly use __eq__ for comparison, ticket #2552
with suppress_warnings() as sup:
# Put lock around the warning filter, see comment at lock definition
with _assert_comparison_lock, suppress_warnings() as sup:
# TODO: Better handling will to needed when change happens!
sup.filter(DeprecationWarning, ".*NAT ==")
sup.filter(FutureWarning, ".*NAT ==")
# Explicitly use __eq__ for comparison, ticket #2552
if not (desired == actual):
raise AssertionError(msg)



def print_assert_equal(test_string, actual, desired):
"""
Test if two objects are equal, and print an error message if test fails.
Expand Down Expand Up @@ -691,7 +713,8 @@ def safe_comparison(*args, **kwargs):
# pass (or maybe eventually catch the errors and return False, I
# dunno, that's a little trickier and we can figure that out when the
# time comes).
with suppress_warnings() as sup:
# Note: Put a lock around warning filter (comment at lock definition)
with _assert_comparison_lock, suppress_warnings() as sup:
sup.filter(DeprecationWarning, ".*==")
sup.filter(FutureWarning, ".*==")
return comparison(*args, **kwargs)
Expand Down
0