diff options
-rw-r--r-- | numpy/testing/noseclasses.py | 66 | ||||
-rw-r--r-- | numpy/testing/nosetester.py | 95 |
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) ######################################################################## |