Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3b2494f

Browse files
author
Michael Foord
committed
Merged revisions 80946 via svnmerge from
svn+ssh://[email protected]/python/trunk ........ r80946 | michael.foord | 2010-05-08 01:39:38 +0200 (Sat, 08 May 2010) | 1 line Issue 8547 - detecting and reporting that modules have been imported from the wrong location under test discovery. ........
1 parent 135d87c commit 3b2494f

2 files changed

Lines changed: 58 additions & 3 deletions

File tree

Lib/unittest/loader.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,10 @@ def discover(self, start_dir, pattern='test*.py', top_level_dir=None):
178178

179179
if not top_level_dir in sys.path:
180180
# all test modules must be importable from the top level directory
181-
sys.path.append(top_level_dir)
181+
# should we *unconditionally* put the start directory in first
182+
# in sys.path to minimise likelihood of conflicts between installed
183+
# modules and development versions?
184+
sys.path.insert(0, top_level_dir)
182185
self._top_level_dir = top_level_dir
183186

184187
is_not_importable = False
@@ -251,6 +254,16 @@ def _find_tests(self, start_dir, pattern):
251254
except:
252255
yield _make_failed_import_test(name, self.suiteClass)
253256
else:
257+
mod_file = os.path.abspath(getattr(module, '__file__', full_path))
258+
realpath = os.path.splitext(mod_file)[0]
259+
fullpath_noext = os.path.splitext(full_path)[0]
260+
if realpath.lower() != fullpath_noext.lower():
261+
module_dir = os.path.dirname(realpath)
262+
mod_name = os.path.splitext(os.path.basename(full_path))[0]
263+
expected_dir = os.path.dirname(full_path)
264+
msg = ("%r module incorrectly imported from %r. Expected %r. "
265+
"Is this module globally installed?")
266+
raise ImportError(msg % (mod_name, module_dir, expected_dir))
254267
yield self.loadTestsFromModule(module)
255268
elif os.path.isdir(full_path):
256269
if not os.path.isfile(os.path.join(full_path, '__init__.py')):

Lib/unittest/test/test_discovery.py

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import os
2+
import re
23
import sys
34

45
import unittest
@@ -53,8 +54,9 @@ def isfile(path):
5354
loader._get_module_from_name = lambda path: path + ' module'
5455
loader.loadTestsFromModule = lambda module: module + ' tests'
5556

56-
loader._top_level_dir = '/foo'
57-
suite = list(loader._find_tests('/foo', 'test*.py'))
57+
top_level = os.path.abspath('/foo')
58+
loader._top_level_dir = top_level
59+
suite = list(loader._find_tests(top_level, 'test*.py'))
5860

5961
expected = [name + ' module tests' for name in
6062
('test1', 'test2')]
@@ -294,6 +296,46 @@ def discover(self, start_dir, pattern, top_level_dir):
294296
self.assertTrue(program.failfast)
295297
self.assertTrue(program.catchbreak)
296298

299+
def test_detect_module_clash(self):
300+
class Module(object):
301+
__file__ = 'bar/foo.py'
302+
sys.modules['foo'] = Module
303+
full_path = os.path.abspath('foo')
304+
original_listdir = os.listdir
305+
original_isfile = os.path.isfile
306+
original_isdir = os.path.isdir
307+
308+
def cleanup():
309+
os.listdir = original_listdir
310+
os.path.isfile = original_isfile
311+
os.path.isdir = original_isdir
312+
del sys.modules['foo']
313+
if full_path in sys.path:
314+
sys.path.remove(full_path)
315+
self.addCleanup(cleanup)
316+
317+
def listdir(_):
318+
return ['foo.py']
319+
def isfile(_):
320+
return True
321+
def isdir(_):
322+
return True
323+
os.listdir = listdir
324+
os.path.isfile = isfile
325+
os.path.isdir = isdir
326+
327+
loader = unittest.TestLoader()
328+
329+
mod_dir = os.path.abspath('bar')
330+
expected_dir = os.path.abspath('foo')
331+
msg = re.escape(r"'foo' module incorrectly imported from %r. Expected %r. "
332+
"Is this module globally installed?" % (mod_dir, expected_dir))
333+
self.assertRaisesRegexp(
334+
ImportError, '^%s$' % msg, loader.discover,
335+
start_dir='foo', pattern='foo.py'
336+
)
337+
self.assertEqual(sys.path[0], full_path)
338+
297339

298340
if __name__ == '__main__':
299341
unittest.main()

0 commit comments

Comments
 (0)