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

Skip to content

Commit 01984e9

Browse files
author
Michael Foord
committed
Merged revisions 80932 via svnmerge from
svn+ssh://[email protected]/python/trunk ........ r80932 | michael.foord | 2010-05-07 20:16:19 +0200 (Fri, 07 May 2010) | 1 line Issue 8547 - detecting and reporting that modules have been imported from the wrong location under test discovery. ........
1 parent 8956271 commit 01984e9

2 files changed

Lines changed: 53 additions & 1 deletion

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: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,45 @@ def discover(self, start_dir, pattern, top_level_dir):
294294
self.assertTrue(program.failfast)
295295
self.assertTrue(program.catchbreak)
296296

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

298337
if __name__ == '__main__':
299338
unittest.main()

0 commit comments

Comments
 (0)