summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--numpy/testing/noseclasses.py66
-rw-r--r--numpy/testing/nosetester.py95
2 files changed, 71 insertions, 90 deletions
diff --git a/numpy/testing/noseclasses.py b/numpy/testing/noseclasses.py
index f97ea9126..25f6662b7 100644
--- a/numpy/testing/noseclasses.py
+++ b/numpy/testing/noseclasses.py
@@ -185,16 +185,24 @@ print_state = numpy.get_printoptions()
class NumpyDoctest(npd.Doctest):
name = 'numpydoctest' # call nosetests with --with-numpydoctest
- enabled = True
+ score = 1000 # load late, after doctest builtin
def options(self, parser, env=os.environ):
Plugin.options(self, parser, env)
def configure(self, options, config):
+ # parent method sets enabled flag from command line --with-numpydoctest
Plugin.configure(self, options, config)
self.doctest_tests = True
self.finder = NumpyDocTestFinder()
self.parser = doctest.DocTestParser()
+ if self.enabled:
+ # Pull standard doctest out of plugin list; there's no reason to run
+ # both. In practice the Unplugger plugin above would cover us when
+ # run from a standard numpy.test() call; this is just in case
+ # someone wants to run our plugin outside the numpy.test() machinery
+ config.plugins.plugins = [p for p in config.plugins.plugins
+ if p.name != 'doctest']
# Turn on whitespace normalization, set a minimal execution context
# for doctests, implement a "#random" directive to allow executing a
@@ -263,6 +271,27 @@ class NumpyDoctest(npd.Doctest):
return npd.Doctest.wantFile(self, file)
+class Unplugger(object):
+ """ Nose plugin to remove named plugin late in loading
+
+ By default it removes the "doctest" plugin.
+ """
+ name = 'unplugger'
+ enabled = True # always enabled
+ score = 4000 # load late in order to be after builtins
+
+ def __init__(self, to_unplug='doctest'):
+ self.to_unplug = to_unplug
+
+ def options(self, parser, env):
+ pass
+
+ def configure(self, options, config):
+ # Pull named plugin out of plugins list
+ config.plugins.plugins = [p for p in config.plugins.plugins
+ if p.name != self.to_unplug]
+
+
class KnownFailureTest(Exception):
'''Raise this exception to mark a test as a known failing test.'''
pass
@@ -295,41 +324,9 @@ class KnownFailure(ErrorClassPlugin):
self.enabled = False
-class NpConfig(nose.core.Config):
- ''' Class to pull out nose doctest plugin after configuration
-
- This allows the user to set doctest related settings in their
- configuration. For example, without this fix, a setting of
- 'with-doctest=1' in the user's .noserc file would cause an error, if
- we remove the doctest extension before this stage. Our configure
- uses the plugin to parse any settings, but then removed the doctest
- plugin because the numpy doctester should be used for doctests
- instead.
- '''
- def __init__(self, config):
- self.__dict__ = config.__dict__
-
- def configure(self, *args, **kwargs):
- super(NpConfig, self).configure(*args, **kwargs)
- self.plugins.plugins = [p for p in self.plugins.plugins
- if p.name != 'doctest']
-
-
-# Our class has two uses. First, to allow us to use NpConfig above to
-# remove the doctest plugin after it has parsed the configuration.
-# Second we save the results of the tests in runTests - see runTests
+# Class allows us to save the results of the tests in runTests - see runTests
# method docstring for details
class NumpyTestProgram(nose.core.TestProgram):
- def makeConfig(self, *args, **kwargs):
- """Load a Config, pre-filled with user config files if any are
- found.
-
- We override this method only to allow us to return a NpConfig
- object instead of a Config object.
- """
- config = super(NumpyTestProgram, self).makeConfig(*args, **kwargs)
- return NpConfig(config)
-
def runTests(self):
"""Run Tests. Returns true on success, false on failure, and
sets self.success to the same value.
@@ -345,7 +342,6 @@ class NumpyTestProgram(nose.core.TestProgram):
plug_runner = self.config.plugins.prepareTestRunner(self.testRunner)
if plug_runner is not None:
self.testRunner = plug_runner
-
self.result = self.testRunner.run(self.test)
self.success = self.result.wasSuccessful()
return self.success
diff --git a/numpy/testing/nosetester.py b/numpy/testing/nosetester.py
index 90e09f880..9e27352ab 100644
--- a/numpy/testing/nosetester.py
+++ b/numpy/testing/nosetester.py
@@ -79,33 +79,6 @@ def run_module_suite(file_to_run = None):
import_nose().run(argv=['',file_to_run])
-# contructs NoseTester method docstrings
-def _docmethod(meth, testtype):
- if not meth.__doc__:
- return
-
- test_header = \
- '''Parameters
- ----------
- label : {'fast', 'full', '', attribute identifer}
- Identifies the %(testtype)ss to run. This can be a string to
- pass to the nosetests executable with the '-A' option, or one of
- several special values.
- Special values are:
- 'fast' - the default - which corresponds to nosetests -A option
- of 'not slow'.
- 'full' - fast (as above) and slow %(testtype)ss as in the
- no -A option to nosetests - same as ''
- None or '' - run all %(testtype)ss
- attribute_identifier - string passed directly to nosetests as '-A'
- verbose : integer
- verbosity value for test outputs, 1-10
- extra_argv : list
- List with any extra args to pass to nosetests''' \
- % {'testtype': testtype}
-
- meth.__doc__ = meth.__doc__ % {'test_header':test_header}
-
class NoseTester(object):
"""
@@ -171,7 +144,19 @@ class NoseTester(object):
def _test_argv(self, label, verbose, extra_argv):
''' Generate argv for nosetest command
- %(test_header)s
+ Parameters
+ ----------
+ label : {'fast', 'full', '', attribute identifier}, optional
+ see ``test`` docstring
+ verbose : int, optional
+ Verbosity value for test outputs, in the range 1-10. Default is 1.
+ extra_argv : list, optional
+ List with any extra arguments to pass to nosetests.
+
+ Returns
+ -------
+ argv : list
+ command line arguments that will be passed to nose
'''
argv = [__file__, self.package_path, '-s']
if label and label != 'full':
@@ -239,12 +224,13 @@ class NoseTester(object):
argv += ['--exclude','pyrex_ext']
argv += ['--exclude','swig_ext']
- nose = import_nose()
+ # fail with nice error message if nose is not present
+ import_nose()
# construct list of plugins
import nose.plugins.builtin
- from noseclasses import NumpyDoctest, KnownFailure
- plugins = [NumpyDoctest(), KnownFailure()]
+ from noseclasses import NumpyDoctest, KnownFailure, Unplugger
+ plugins = [NumpyDoctest(), KnownFailure(), Unplugger()]
plugins += [p() for p in nose.plugins.builtin.plugins]
return argv, plugins
@@ -256,15 +242,14 @@ class NoseTester(object):
Parameters
----------
label : {'fast', 'full', '', attribute identifier}, optional
- Identifies the tests to run. This can be a string to pass to the
- nosetests executable with the '-A' option, or one of
- several special values.
- Special values are:
- 'fast' - the default - which corresponds to the ``nosetests -A``
- option of 'not slow'.
- 'full' - fast (as above) and slow tests as in the
- 'no -A' option to nosetests - this is the same as ''.
- None or '' - run all tests.
+ Identifies the tests to run. This can be a string to pass to
+ the nosetests executable with the '-A' option, or one of several
+ special values. Special values are:
+ * 'fast' - the default - which corresponds to the ``nosetests -A``
+ option of 'not slow'.
+ * 'full' - fast (as above) and slow tests as in the
+ 'no -A' option to nosetests - this is the same as ''.
+ * None or '' - run all tests.
attribute_identifier - string passed directly to nosetests as '-A'.
verbose : int, optional
Verbosity value for test outputs, in the range 1-10. Default is 1.
@@ -336,18 +321,17 @@ class NoseTester(object):
Parameters
----------
label : {'fast', 'full', '', attribute identifier}, optional
- Identifies the tests to run. This can be a string to pass to the
- nosetests executable with the '-A' option, or one of
- several special values.
- Special values are:
- 'fast' - the default - which corresponds to the ``nosetests -A``
- option of 'not slow'.
- 'full' - fast (as above) and slow tests as in the
- 'no -A' option to nosetests - this is the same as ''.
- None or '' - run all tests.
+ Identifies the benchmarks to run. This can be a string to pass to
+ the nosetests executable with the '-A' option, or one of several
+ special values. Special values are:
+ * 'fast' - the default - which corresponds to the ``nosetests -A``
+ option of 'not slow'.
+ * 'full' - fast (as above) and slow benchmarks as in the
+ 'no -A' option to nosetests - this is the same as ''.
+ * None or '' - run all tests.
attribute_identifier - string passed directly to nosetests as '-A'.
verbose : int, optional
- Verbosity value for test outputs, in the range 1-10. Default is 1.
+ Verbosity value for benchmark outputs, in the range 1-10. Default is 1.
extra_argv : list, optional
List with any extra arguments to pass to nosetests.
@@ -392,13 +376,14 @@ class NoseTester(object):
argv = self._test_argv(label, verbose, extra_argv)
argv += ['--match', r'(?:^|[\\b_\\.%s-])[Bb]ench' % os.sep]
+ # import nose or make informative error
nose = import_nose()
- return nose.run(argv=argv)
- # generate method docstrings
- _docmethod(_test_argv, '(testtype)')
- _docmethod(test, 'test')
- _docmethod(bench, 'benchmark')
+ # get plugin to disable doctests
+ from noseclasses import Unplugger
+ add_plugins = [Unplugger('doctest')]
+
+ return nose.run(argv=argv, addplugins=add_plugins)
########################################################################