This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author gagern
Recipients docs@python, gagern
Date 2011-02-15.08:33:26
SpamBayes Score 7.049916e-14
Marked as misclassified No
Message-id <1297758807.39.0.713611114484.issue11218@psf.upfronthosting.co.za>
In-reply-to
Content
If I follow the documentation at http://docs.python.org/library/unittest.html#unittest.main by putting the following two snippets of code in my module file:

def load_tests(loader, standard_tests, pattern='test*.py'):
    # top level directory cached on loader instance
    this_dir = os.path.dirname(__file__)
    package_tests = loader.discover(start_dir=this_dir, pattern=pattern)
    standard_tests.addTests(package_tests)
    return standard_tests

if __name__ == "__main__":
    unittest.main()

then the application will fail with an obscure error message:

======================================================================
ERROR: __main__ (unittest.loader.LoadTestsFailure)
----------------------------------------------------------------------
TypeError: object of type 'NoneType' has no len()

----------------------------------------------------------------------
Ran 1 test in 0.000s

Monkeypatching unittest.loader._make_failed_load_tests to display a stack trace, I got this:

Traceback (most recent call last):
  File "/usr/lib64/python2.7/unittest/loader.py", line 71, in loadTestsFromModule
    return load_tests(self, tests, None)
  File "tester.py", line 15, in load_tests
    package_tests = loader.discover(start_dir=this_dir, pattern=pattern)
  File "/usr/lib64/python2.7/unittest/loader.py", line 204, in discover
    tests = list(self._find_tests(start_dir, pattern))
  File "/usr/lib64/python2.7/unittest/loader.py", line 247, in _find_tests
    if not self._match_path(path, full_path, pattern):
  File "/usr/lib64/python2.7/unittest/loader.py", line 235, in _match_path
    return fnmatch(path, pattern)
  File "/usr/lib64/python2.7/fnmatch.py", line 43, in fnmatch
    return fnmatchcase(name, pat)
  File "/usr/lib64/python2.7/fnmatch.py", line 75, in fnmatchcase
    res = translate(pat)
  File "/usr/lib64/python2.7/fnmatch.py", line 87, in translate
    i, n = 0, len(pat)
TypeError: object of type 'NoneType' has no len()

The error is due to the fact that pattern is passed as None to load_tests, but apparently loader.discover doesn't loke a None pattern.

I would suggest that
a) discover internally translates None to the default of 'test*.py' or
b) the documentation is changed to cater for this common use case, i.e. by including a "pattern is None" case distinction in its load_tests snippet.

In case b) is implemented but not a), it would be nice to have a more expressive error message by catching the error somewhat sooner.
History
Date User Action Args
2011-02-15 08:33:27gagernsetrecipients: + gagern, docs@python
2011-02-15 08:33:27gagernsetmessageid: <1297758807.39.0.713611114484.issue11218@psf.upfronthosting.co.za>
2011-02-15 08:33:26gagernlinkissue11218 messages
2011-02-15 08:33:26gagerncreate