annotate DEPENDENCIES/mingw32/Python27/Lib/site-packages/numpy/testing/nosetester.py @ 118:770eb830ec19 emscripten

Typo fix
author Chris Cannam
date Wed, 18 May 2016 16:14:08 +0100
parents 2a2c65a20a8b
children
rev   line source
Chris@87 1 """
Chris@87 2 Nose test running.
Chris@87 3
Chris@87 4 This module implements ``test()`` and ``bench()`` functions for NumPy modules.
Chris@87 5
Chris@87 6 """
Chris@87 7 from __future__ import division, absolute_import, print_function
Chris@87 8
Chris@87 9 import os
Chris@87 10 import sys
Chris@87 11 import warnings
Chris@87 12 from numpy.compat import basestring
Chris@87 13 from numpy import ModuleDeprecationWarning
Chris@87 14
Chris@87 15
Chris@87 16 def get_package_name(filepath):
Chris@87 17 """
Chris@87 18 Given a path where a package is installed, determine its name.
Chris@87 19
Chris@87 20 Parameters
Chris@87 21 ----------
Chris@87 22 filepath : str
Chris@87 23 Path to a file. If the determination fails, "numpy" is returned.
Chris@87 24
Chris@87 25 Examples
Chris@87 26 --------
Chris@87 27 >>> np.testing.nosetester.get_package_name('nonsense')
Chris@87 28 'numpy'
Chris@87 29
Chris@87 30 """
Chris@87 31
Chris@87 32 fullpath = filepath[:]
Chris@87 33 pkg_name = []
Chris@87 34 while 'site-packages' in filepath or 'dist-packages' in filepath:
Chris@87 35 filepath, p2 = os.path.split(filepath)
Chris@87 36 if p2 in ('site-packages', 'dist-packages'):
Chris@87 37 break
Chris@87 38 pkg_name.append(p2)
Chris@87 39
Chris@87 40 # if package name determination failed, just default to numpy/scipy
Chris@87 41 if not pkg_name:
Chris@87 42 if 'scipy' in fullpath:
Chris@87 43 return 'scipy'
Chris@87 44 else:
Chris@87 45 return 'numpy'
Chris@87 46
Chris@87 47 # otherwise, reverse to get correct order and return
Chris@87 48 pkg_name.reverse()
Chris@87 49
Chris@87 50 # don't include the outer egg directory
Chris@87 51 if pkg_name[0].endswith('.egg'):
Chris@87 52 pkg_name.pop(0)
Chris@87 53
Chris@87 54 return '.'.join(pkg_name)
Chris@87 55
Chris@87 56 def import_nose():
Chris@87 57 """ Import nose only when needed.
Chris@87 58 """
Chris@87 59 fine_nose = True
Chris@87 60 minimum_nose_version = (0, 10, 0)
Chris@87 61 try:
Chris@87 62 import nose
Chris@87 63 except ImportError:
Chris@87 64 fine_nose = False
Chris@87 65 else:
Chris@87 66 if nose.__versioninfo__ < minimum_nose_version:
Chris@87 67 fine_nose = False
Chris@87 68
Chris@87 69 if not fine_nose:
Chris@87 70 msg = 'Need nose >= %d.%d.%d for tests - see ' \
Chris@87 71 'http://somethingaboutorange.com/mrl/projects/nose' % \
Chris@87 72 minimum_nose_version
Chris@87 73
Chris@87 74 raise ImportError(msg)
Chris@87 75
Chris@87 76 return nose
Chris@87 77
Chris@87 78 def run_module_suite(file_to_run=None, argv=None):
Chris@87 79 """
Chris@87 80 Run a test module.
Chris@87 81
Chris@87 82 Equivalent to calling ``$ nosetests <argv> <file_to_run>`` from
Chris@87 83 the command line
Chris@87 84
Chris@87 85 Parameters
Chris@87 86 ----------
Chris@87 87 file_to_run: str, optional
Chris@87 88 Path to test module, or None.
Chris@87 89 By default, run the module from which this function is called.
Chris@87 90 argv: list of strings
Chris@87 91 Arguments to be passed to the nose test runner. ``argv[0]`` is
Chris@87 92 ignored. All command line arguments accepted by ``nosetests``
Chris@87 93 will work.
Chris@87 94
Chris@87 95 .. versionadded:: 1.9.0
Chris@87 96
Chris@87 97 Examples
Chris@87 98 --------
Chris@87 99 Adding the following::
Chris@87 100
Chris@87 101 if __name__ == "__main__" :
Chris@87 102 run_module_suite(argv=sys.argv)
Chris@87 103
Chris@87 104 at the end of a test module will run the tests when that module is
Chris@87 105 called in the python interpreter.
Chris@87 106
Chris@87 107 Alternatively, calling::
Chris@87 108
Chris@87 109 >>> run_module_suite(file_to_run="numpy/tests/test_matlib.py")
Chris@87 110
Chris@87 111 from an interpreter will run all the test routine in 'test_matlib.py'.
Chris@87 112 """
Chris@87 113 if file_to_run is None:
Chris@87 114 f = sys._getframe(1)
Chris@87 115 file_to_run = f.f_locals.get('__file__', None)
Chris@87 116 if file_to_run is None:
Chris@87 117 raise AssertionError
Chris@87 118
Chris@87 119 if argv is None:
Chris@87 120 argv = ['', file_to_run]
Chris@87 121 else:
Chris@87 122 argv = argv + [file_to_run]
Chris@87 123
Chris@87 124 nose = import_nose()
Chris@87 125 from .noseclasses import KnownFailure
Chris@87 126 nose.run(argv=argv, addplugins=[KnownFailure()])
Chris@87 127
Chris@87 128
Chris@87 129 class NoseTester(object):
Chris@87 130 """
Chris@87 131 Nose test runner.
Chris@87 132
Chris@87 133 This class is made available as numpy.testing.Tester, and a test function
Chris@87 134 is typically added to a package's __init__.py like so::
Chris@87 135
Chris@87 136 from numpy.testing import Tester
Chris@87 137 test = Tester().test
Chris@87 138
Chris@87 139 Calling this test function finds and runs all tests associated with the
Chris@87 140 package and all its sub-packages.
Chris@87 141
Chris@87 142 Attributes
Chris@87 143 ----------
Chris@87 144 package_path : str
Chris@87 145 Full path to the package to test.
Chris@87 146 package_name : str
Chris@87 147 Name of the package to test.
Chris@87 148
Chris@87 149 Parameters
Chris@87 150 ----------
Chris@87 151 package : module, str or None, optional
Chris@87 152 The package to test. If a string, this should be the full path to
Chris@87 153 the package. If None (default), `package` is set to the module from
Chris@87 154 which `NoseTester` is initialized.
Chris@87 155 raise_warnings : str or sequence of warnings, optional
Chris@87 156 This specifies which warnings to configure as 'raise' instead
Chris@87 157 of 'warn' during the test execution. Valid strings are:
Chris@87 158
Chris@87 159 - "develop" : equals ``(DeprecationWarning, RuntimeWarning)``
Chris@87 160 - "release" : equals ``()``, don't raise on any warnings.
Chris@87 161
Chris@87 162 See Notes for more details.
Chris@87 163
Chris@87 164 Notes
Chris@87 165 -----
Chris@87 166 The default for `raise_warnings` is
Chris@87 167 ``(DeprecationWarning, RuntimeWarning)`` for the master branch of NumPy,
Chris@87 168 and ``()`` for maintenance branches and released versions. The purpose
Chris@87 169 of this switching behavior is to catch as many warnings as possible
Chris@87 170 during development, but not give problems for packaging of released
Chris@87 171 versions.
Chris@87 172
Chris@87 173 """
Chris@87 174 # Stuff to exclude from tests. These are from numpy.distutils
Chris@87 175 excludes = ['f2py_ext',
Chris@87 176 'f2py_f90_ext',
Chris@87 177 'gen_ext',
Chris@87 178 'pyrex_ext',
Chris@87 179 'swig_ext']
Chris@87 180
Chris@87 181 def __init__(self, package=None, raise_warnings="release"):
Chris@87 182 package_name = None
Chris@87 183 if package is None:
Chris@87 184 f = sys._getframe(1)
Chris@87 185 package_path = f.f_locals.get('__file__', None)
Chris@87 186 if package_path is None:
Chris@87 187 raise AssertionError
Chris@87 188 package_path = os.path.dirname(package_path)
Chris@87 189 package_name = f.f_locals.get('__name__', None)
Chris@87 190 elif isinstance(package, type(os)):
Chris@87 191 package_path = os.path.dirname(package.__file__)
Chris@87 192 package_name = getattr(package, '__name__', None)
Chris@87 193 else:
Chris@87 194 package_path = str(package)
Chris@87 195
Chris@87 196 self.package_path = package_path
Chris@87 197
Chris@87 198 # Find the package name under test; this name is used to limit coverage
Chris@87 199 # reporting (if enabled).
Chris@87 200 if package_name is None:
Chris@87 201 package_name = get_package_name(package_path)
Chris@87 202 self.package_name = package_name
Chris@87 203
Chris@87 204 # Set to "release" in constructor in maintenance branches.
Chris@87 205 self.raise_warnings = raise_warnings
Chris@87 206
Chris@87 207 def _test_argv(self, label, verbose, extra_argv):
Chris@87 208 ''' Generate argv for nosetest command
Chris@87 209
Chris@87 210 Parameters
Chris@87 211 ----------
Chris@87 212 label : {'fast', 'full', '', attribute identifier}, optional
Chris@87 213 see ``test`` docstring
Chris@87 214 verbose : int, optional
Chris@87 215 Verbosity value for test outputs, in the range 1-10. Default is 1.
Chris@87 216 extra_argv : list, optional
Chris@87 217 List with any extra arguments to pass to nosetests.
Chris@87 218
Chris@87 219 Returns
Chris@87 220 -------
Chris@87 221 argv : list
Chris@87 222 command line arguments that will be passed to nose
Chris@87 223 '''
Chris@87 224 argv = [__file__, self.package_path, '-s']
Chris@87 225 if label and label != 'full':
Chris@87 226 if not isinstance(label, basestring):
Chris@87 227 raise TypeError('Selection label should be a string')
Chris@87 228 if label == 'fast':
Chris@87 229 label = 'not slow'
Chris@87 230 argv += ['-A', label]
Chris@87 231 argv += ['--verbosity', str(verbose)]
Chris@87 232
Chris@87 233 # When installing with setuptools, and also in some other cases, the
Chris@87 234 # test_*.py files end up marked +x executable. Nose, by default, does
Chris@87 235 # not run files marked with +x as they might be scripts. However, in
Chris@87 236 # our case nose only looks for test_*.py files under the package
Chris@87 237 # directory, which should be safe.
Chris@87 238 argv += ['--exe']
Chris@87 239
Chris@87 240 if extra_argv:
Chris@87 241 argv += extra_argv
Chris@87 242 return argv
Chris@87 243
Chris@87 244 def _show_system_info(self):
Chris@87 245 nose = import_nose()
Chris@87 246
Chris@87 247 import numpy
Chris@87 248 print("NumPy version %s" % numpy.__version__)
Chris@87 249 npdir = os.path.dirname(numpy.__file__)
Chris@87 250 print("NumPy is installed in %s" % npdir)
Chris@87 251
Chris@87 252 if 'scipy' in self.package_name:
Chris@87 253 import scipy
Chris@87 254 print("SciPy version %s" % scipy.__version__)
Chris@87 255 spdir = os.path.dirname(scipy.__file__)
Chris@87 256 print("SciPy is installed in %s" % spdir)
Chris@87 257
Chris@87 258 pyversion = sys.version.replace('\n', '')
Chris@87 259 print("Python version %s" % pyversion)
Chris@87 260 print("nose version %d.%d.%d" % nose.__versioninfo__)
Chris@87 261
Chris@87 262 def _get_custom_doctester(self):
Chris@87 263 """ Return instantiated plugin for doctests
Chris@87 264
Chris@87 265 Allows subclassing of this class to override doctester
Chris@87 266
Chris@87 267 A return value of None means use the nose builtin doctest plugin
Chris@87 268 """
Chris@87 269 from .noseclasses import NumpyDoctest
Chris@87 270 return NumpyDoctest()
Chris@87 271
Chris@87 272 def prepare_test_args(self, label='fast', verbose=1, extra_argv=None,
Chris@87 273 doctests=False, coverage=False):
Chris@87 274 """
Chris@87 275 Run tests for module using nose.
Chris@87 276
Chris@87 277 This method does the heavy lifting for the `test` method. It takes all
Chris@87 278 the same arguments, for details see `test`.
Chris@87 279
Chris@87 280 See Also
Chris@87 281 --------
Chris@87 282 test
Chris@87 283
Chris@87 284 """
Chris@87 285 # fail with nice error message if nose is not present
Chris@87 286 import_nose()
Chris@87 287 # compile argv
Chris@87 288 argv = self._test_argv(label, verbose, extra_argv)
Chris@87 289 # bypass tests noted for exclude
Chris@87 290 for ename in self.excludes:
Chris@87 291 argv += ['--exclude', ename]
Chris@87 292 # our way of doing coverage
Chris@87 293 if coverage:
Chris@87 294 argv+=['--cover-package=%s' % self.package_name, '--with-coverage',
Chris@87 295 '--cover-tests', '--cover-erase']
Chris@87 296 # construct list of plugins
Chris@87 297 import nose.plugins.builtin
Chris@87 298 from .noseclasses import KnownFailure, Unplugger
Chris@87 299 plugins = [KnownFailure()]
Chris@87 300 plugins += [p() for p in nose.plugins.builtin.plugins]
Chris@87 301 # add doctesting if required
Chris@87 302 doctest_argv = '--with-doctest' in argv
Chris@87 303 if doctests == False and doctest_argv:
Chris@87 304 doctests = True
Chris@87 305 plug = self._get_custom_doctester()
Chris@87 306 if plug is None:
Chris@87 307 # use standard doctesting
Chris@87 308 if doctests and not doctest_argv:
Chris@87 309 argv += ['--with-doctest']
Chris@87 310 else: # custom doctesting
Chris@87 311 if doctest_argv: # in fact the unplugger would take care of this
Chris@87 312 argv.remove('--with-doctest')
Chris@87 313 plugins += [Unplugger('doctest'), plug]
Chris@87 314 if doctests:
Chris@87 315 argv += ['--with-' + plug.name]
Chris@87 316 return argv, plugins
Chris@87 317
Chris@87 318 def test(self, label='fast', verbose=1, extra_argv=None,
Chris@87 319 doctests=False, coverage=False,
Chris@87 320 raise_warnings=None):
Chris@87 321 """
Chris@87 322 Run tests for module using nose.
Chris@87 323
Chris@87 324 Parameters
Chris@87 325 ----------
Chris@87 326 label : {'fast', 'full', '', attribute identifier}, optional
Chris@87 327 Identifies the tests to run. This can be a string to pass to
Chris@87 328 the nosetests executable with the '-A' option, or one of several
Chris@87 329 special values. Special values are:
Chris@87 330 * 'fast' - the default - which corresponds to the ``nosetests -A``
Chris@87 331 option of 'not slow'.
Chris@87 332 * 'full' - fast (as above) and slow tests as in the
Chris@87 333 'no -A' option to nosetests - this is the same as ''.
Chris@87 334 * None or '' - run all tests.
Chris@87 335 attribute_identifier - string passed directly to nosetests as '-A'.
Chris@87 336 verbose : int, optional
Chris@87 337 Verbosity value for test outputs, in the range 1-10. Default is 1.
Chris@87 338 extra_argv : list, optional
Chris@87 339 List with any extra arguments to pass to nosetests.
Chris@87 340 doctests : bool, optional
Chris@87 341 If True, run doctests in module. Default is False.
Chris@87 342 coverage : bool, optional
Chris@87 343 If True, report coverage of NumPy code. Default is False.
Chris@87 344 (This requires the `coverage module:
Chris@87 345 <http://nedbatchelder.com/code/modules/coverage.html>`_).
Chris@87 346 raise_warnings : str or sequence of warnings, optional
Chris@87 347 This specifies which warnings to configure as 'raise' instead
Chris@87 348 of 'warn' during the test execution. Valid strings are:
Chris@87 349
Chris@87 350 - "develop" : equals ``(DeprecationWarning, RuntimeWarning)``
Chris@87 351 - "release" : equals ``()``, don't raise on any warnings.
Chris@87 352
Chris@87 353 Returns
Chris@87 354 -------
Chris@87 355 result : object
Chris@87 356 Returns the result of running the tests as a
Chris@87 357 ``nose.result.TextTestResult`` object.
Chris@87 358
Chris@87 359 Notes
Chris@87 360 -----
Chris@87 361 Each NumPy module exposes `test` in its namespace to run all tests for it.
Chris@87 362 For example, to run all tests for numpy.lib:
Chris@87 363
Chris@87 364 >>> np.lib.test() #doctest: +SKIP
Chris@87 365
Chris@87 366 Examples
Chris@87 367 --------
Chris@87 368 >>> result = np.lib.test() #doctest: +SKIP
Chris@87 369 Running unit tests for numpy.lib
Chris@87 370 ...
Chris@87 371 Ran 976 tests in 3.933s
Chris@87 372
Chris@87 373 OK
Chris@87 374
Chris@87 375 >>> result.errors #doctest: +SKIP
Chris@87 376 []
Chris@87 377 >>> result.knownfail #doctest: +SKIP
Chris@87 378 []
Chris@87 379 """
Chris@87 380
Chris@87 381 # cap verbosity at 3 because nose becomes *very* verbose beyond that
Chris@87 382 verbose = min(verbose, 3)
Chris@87 383
Chris@87 384 from . import utils
Chris@87 385 utils.verbose = verbose
Chris@87 386
Chris@87 387 if doctests:
Chris@87 388 print("Running unit tests and doctests for %s" % self.package_name)
Chris@87 389 else:
Chris@87 390 print("Running unit tests for %s" % self.package_name)
Chris@87 391
Chris@87 392 self._show_system_info()
Chris@87 393
Chris@87 394 # reset doctest state on every run
Chris@87 395 import doctest
Chris@87 396 doctest.master = None
Chris@87 397
Chris@87 398 if raise_warnings is None:
Chris@87 399 raise_warnings = self.raise_warnings
Chris@87 400
Chris@87 401 _warn_opts = dict(develop=(DeprecationWarning, RuntimeWarning),
Chris@87 402 release=())
Chris@87 403 if raise_warnings in _warn_opts.keys():
Chris@87 404 raise_warnings = _warn_opts[raise_warnings]
Chris@87 405
Chris@87 406 with warnings.catch_warnings():
Chris@87 407 # Reset the warning filters to the default state,
Chris@87 408 # so that running the tests is more repeatable.
Chris@87 409 warnings.resetwarnings()
Chris@87 410 # If deprecation warnings are not set to 'error' below,
Chris@87 411 # at least set them to 'warn'.
Chris@87 412 warnings.filterwarnings('always', category=DeprecationWarning)
Chris@87 413 # Force the requested warnings to raise
Chris@87 414 for warningtype in raise_warnings:
Chris@87 415 warnings.filterwarnings('error', category=warningtype)
Chris@87 416 # Filter out annoying import messages.
Chris@87 417 warnings.filterwarnings('ignore', message='Not importing directory')
Chris@87 418 warnings.filterwarnings("ignore", message="numpy.dtype size changed")
Chris@87 419 warnings.filterwarnings("ignore", message="numpy.ufunc size changed")
Chris@87 420 warnings.filterwarnings("ignore", category=ModuleDeprecationWarning)
Chris@87 421 warnings.filterwarnings("ignore", category=FutureWarning)
Chris@87 422 # Filter out boolean '-' deprecation messages. This allows
Chris@87 423 # older versions of scipy to test without a flood of messages.
Chris@87 424 warnings.filterwarnings("ignore", message=".*boolean negative.*")
Chris@87 425 warnings.filterwarnings("ignore", message=".*boolean subtract.*")
Chris@87 426
Chris@87 427 from .noseclasses import NumpyTestProgram
Chris@87 428
Chris@87 429 argv, plugins = self.prepare_test_args(
Chris@87 430 label, verbose, extra_argv, doctests, coverage)
Chris@87 431 t = NumpyTestProgram(argv=argv, exit=False, plugins=plugins)
Chris@87 432
Chris@87 433 return t.result
Chris@87 434
Chris@87 435 def bench(self, label='fast', verbose=1, extra_argv=None):
Chris@87 436 """
Chris@87 437 Run benchmarks for module using nose.
Chris@87 438
Chris@87 439 Parameters
Chris@87 440 ----------
Chris@87 441 label : {'fast', 'full', '', attribute identifier}, optional
Chris@87 442 Identifies the benchmarks to run. This can be a string to pass to
Chris@87 443 the nosetests executable with the '-A' option, or one of several
Chris@87 444 special values. Special values are:
Chris@87 445 * 'fast' - the default - which corresponds to the ``nosetests -A``
Chris@87 446 option of 'not slow'.
Chris@87 447 * 'full' - fast (as above) and slow benchmarks as in the
Chris@87 448 'no -A' option to nosetests - this is the same as ''.
Chris@87 449 * None or '' - run all tests.
Chris@87 450 attribute_identifier - string passed directly to nosetests as '-A'.
Chris@87 451 verbose : int, optional
Chris@87 452 Verbosity value for benchmark outputs, in the range 1-10. Default is 1.
Chris@87 453 extra_argv : list, optional
Chris@87 454 List with any extra arguments to pass to nosetests.
Chris@87 455
Chris@87 456 Returns
Chris@87 457 -------
Chris@87 458 success : bool
Chris@87 459 Returns True if running the benchmarks works, False if an error
Chris@87 460 occurred.
Chris@87 461
Chris@87 462 Notes
Chris@87 463 -----
Chris@87 464 Benchmarks are like tests, but have names starting with "bench" instead
Chris@87 465 of "test", and can be found under the "benchmarks" sub-directory of the
Chris@87 466 module.
Chris@87 467
Chris@87 468 Each NumPy module exposes `bench` in its namespace to run all benchmarks
Chris@87 469 for it.
Chris@87 470
Chris@87 471 Examples
Chris@87 472 --------
Chris@87 473 >>> success = np.lib.bench() #doctest: +SKIP
Chris@87 474 Running benchmarks for numpy.lib
Chris@87 475 ...
Chris@87 476 using 562341 items:
Chris@87 477 unique:
Chris@87 478 0.11
Chris@87 479 unique1d:
Chris@87 480 0.11
Chris@87 481 ratio: 1.0
Chris@87 482 nUnique: 56230 == 56230
Chris@87 483 ...
Chris@87 484 OK
Chris@87 485
Chris@87 486 >>> success #doctest: +SKIP
Chris@87 487 True
Chris@87 488
Chris@87 489 """
Chris@87 490
Chris@87 491 print("Running benchmarks for %s" % self.package_name)
Chris@87 492 self._show_system_info()
Chris@87 493
Chris@87 494 argv = self._test_argv(label, verbose, extra_argv)
Chris@87 495 argv += ['--match', r'(?:^|[\\b_\\.%s-])[Bb]ench' % os.sep]
Chris@87 496
Chris@87 497 # import nose or make informative error
Chris@87 498 nose = import_nose()
Chris@87 499
Chris@87 500 # get plugin to disable doctests
Chris@87 501 from .noseclasses import Unplugger
Chris@87 502 add_plugins = [Unplugger('doctest')]
Chris@87 503
Chris@87 504 return nose.run(argv=argv, addplugins=add_plugins)