|
|
# IPython: modified copy of numpy.testing.utils, so numpy.testing.decorators
|
|
|
# works without numpy being installed.
|
|
|
"""
|
|
|
Utility function to facilitate testing.
|
|
|
"""
|
|
|
|
|
|
import os
|
|
|
import sys
|
|
|
import re
|
|
|
import operator
|
|
|
import types
|
|
|
import warnings
|
|
|
|
|
|
# The following two classes are copied from python 2.6 warnings module (context
|
|
|
# manager)
|
|
|
class WarningMessage(object):
|
|
|
|
|
|
"""
|
|
|
Holds the result of a single showwarning() call.
|
|
|
|
|
|
Notes
|
|
|
-----
|
|
|
`WarningMessage` is copied from the Python 2.6 warnings module,
|
|
|
so it can be used in NumPy with older Python versions.
|
|
|
|
|
|
"""
|
|
|
|
|
|
_WARNING_DETAILS = ("message", "category", "filename", "lineno", "file",
|
|
|
"line")
|
|
|
|
|
|
def __init__(self, message, category, filename, lineno, file=None,
|
|
|
line=None):
|
|
|
local_values = locals()
|
|
|
for attr in self._WARNING_DETAILS:
|
|
|
setattr(self, attr, local_values[attr])
|
|
|
if category:
|
|
|
self._category_name = category.__name__
|
|
|
else:
|
|
|
self._category_name = None
|
|
|
|
|
|
def __str__(self):
|
|
|
return ("{message : %r, category : %r, filename : %r, lineno : %s, "
|
|
|
"line : %r}" % (self.message, self._category_name,
|
|
|
self.filename, self.lineno, self.line))
|
|
|
|
|
|
class WarningManager:
|
|
|
"""
|
|
|
A context manager that copies and restores the warnings filter upon
|
|
|
exiting the context.
|
|
|
|
|
|
The 'record' argument specifies whether warnings should be captured by a
|
|
|
custom implementation of ``warnings.showwarning()`` and be appended to a
|
|
|
list returned by the context manager. Otherwise None is returned by the
|
|
|
context manager. The objects appended to the list are arguments whose
|
|
|
attributes mirror the arguments to ``showwarning()``.
|
|
|
|
|
|
The 'module' argument is to specify an alternative module to the module
|
|
|
named 'warnings' and imported under that name. This argument is only useful
|
|
|
when testing the warnings module itself.
|
|
|
|
|
|
Notes
|
|
|
-----
|
|
|
`WarningManager` is a copy of the ``catch_warnings`` context manager
|
|
|
from the Python 2.6 warnings module, with slight modifications.
|
|
|
It is copied so it can be used in NumPy with older Python versions.
|
|
|
|
|
|
"""
|
|
|
def __init__(self, record=False, module=None):
|
|
|
self._record = record
|
|
|
if module is None:
|
|
|
self._module = sys.modules['warnings']
|
|
|
else:
|
|
|
self._module = module
|
|
|
self._entered = False
|
|
|
|
|
|
def __enter__(self):
|
|
|
if self._entered:
|
|
|
raise RuntimeError("Cannot enter %r twice" % self)
|
|
|
self._entered = True
|
|
|
self._filters = self._module.filters
|
|
|
self._module.filters = self._filters[:]
|
|
|
self._showwarning = self._module.showwarning
|
|
|
if self._record:
|
|
|
log = []
|
|
|
def showwarning(*args, **kwargs):
|
|
|
log.append(WarningMessage(*args, **kwargs))
|
|
|
self._module.showwarning = showwarning
|
|
|
return log
|
|
|
else:
|
|
|
return None
|
|
|
|
|
|
def __exit__(self):
|
|
|
if not self._entered:
|
|
|
raise RuntimeError("Cannot exit %r without entering first" % self)
|
|
|
self._module.filters = self._filters
|
|
|
self._module.showwarning = self._showwarning
|
|
|
|
|
|
def assert_warns(warning_class, func, *args, **kw):
|
|
|
"""Fail unless a warning of class warning_class is thrown by callable when
|
|
|
invoked with arguments args and keyword arguments kwargs.
|
|
|
|
|
|
If a different type of warning is thrown, it will not be caught, and the
|
|
|
test case will be deemed to have suffered an error.
|
|
|
"""
|
|
|
|
|
|
# XXX: once we may depend on python >= 2.6, this can be replaced by the
|
|
|
# warnings module context manager.
|
|
|
ctx = WarningManager(record=True)
|
|
|
l = ctx.__enter__()
|
|
|
warnings.simplefilter('always')
|
|
|
try:
|
|
|
func(*args, **kw)
|
|
|
if not len(l) > 0:
|
|
|
raise AssertionError("No warning raised when calling %s"
|
|
|
% func.__name__)
|
|
|
if not l[0].category is warning_class:
|
|
|
raise AssertionError("First warning for %s is not a " \
|
|
|
"%s( is %s)" % (func.__name__, warning_class, l[0]))
|
|
|
finally:
|
|
|
ctx.__exit__()
|
|
|
|