[Python-checkins] r80947 - in python/branches/py3k: Lib/unittest/loader.py Lib/unittest/test/test_discovery.py

michael.foord python-checkins at python.org
Sat May 8 01:42:40 CEST 2010


Author: michael.foord
Date: Sat May  8 01:42:40 2010
New Revision: 80947

Log:
Merged revisions 80946 via svnmerge from 
svn+ssh://pythondev@svn.python.org/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.
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Lib/unittest/loader.py
   python/branches/py3k/Lib/unittest/test/test_discovery.py

Modified: python/branches/py3k/Lib/unittest/loader.py
==============================================================================
--- python/branches/py3k/Lib/unittest/loader.py	(original)
+++ python/branches/py3k/Lib/unittest/loader.py	Sat May  8 01:42:40 2010
@@ -178,7 +178,10 @@
 
         if not top_level_dir in sys.path:
             # all test modules must be importable from the top level directory
-            sys.path.append(top_level_dir)
+            # should we *unconditionally* put the start directory in first
+            # in sys.path to minimise likelihood of conflicts between installed
+            # modules and development versions?
+            sys.path.insert(0, top_level_dir)
         self._top_level_dir = top_level_dir
 
         is_not_importable = False
@@ -251,6 +254,16 @@
                     except:
                         yield _make_failed_import_test(name, self.suiteClass)
                     else:
+                        mod_file = os.path.abspath(getattr(module, '__file__', full_path))
+                        realpath = os.path.splitext(mod_file)[0]
+                        fullpath_noext = os.path.splitext(full_path)[0]
+                        if realpath.lower() != fullpath_noext.lower():
+                            module_dir = os.path.dirname(realpath)
+                            mod_name = os.path.splitext(os.path.basename(full_path))[0]
+                            expected_dir = os.path.dirname(full_path)
+                            msg = ("%r module incorrectly imported from %r. Expected %r. "
+                                   "Is this module globally installed?")
+                            raise ImportError(msg % (mod_name, module_dir, expected_dir))
                         yield self.loadTestsFromModule(module)
             elif os.path.isdir(full_path):
                 if not os.path.isfile(os.path.join(full_path, '__init__.py')):

Modified: python/branches/py3k/Lib/unittest/test/test_discovery.py
==============================================================================
--- python/branches/py3k/Lib/unittest/test/test_discovery.py	(original)
+++ python/branches/py3k/Lib/unittest/test/test_discovery.py	Sat May  8 01:42:40 2010
@@ -1,4 +1,5 @@
 import os
+import re
 import sys
 
 import unittest
@@ -53,8 +54,9 @@
         loader._get_module_from_name = lambda path: path + ' module'
         loader.loadTestsFromModule = lambda module: module + ' tests'
 
-        loader._top_level_dir = '/foo'
-        suite = list(loader._find_tests('/foo', 'test*.py'))
+        top_level = os.path.abspath('/foo')
+        loader._top_level_dir = top_level
+        suite = list(loader._find_tests(top_level, 'test*.py'))
 
         expected = [name + ' module tests' for name in
                     ('test1', 'test2')]
@@ -294,6 +296,46 @@
         self.assertTrue(program.failfast)
         self.assertTrue(program.catchbreak)
 
+    def test_detect_module_clash(self):
+        class Module(object):
+            __file__ = 'bar/foo.py'
+        sys.modules['foo'] = Module
+        full_path = os.path.abspath('foo')
+        original_listdir = os.listdir
+        original_isfile = os.path.isfile
+        original_isdir = os.path.isdir
+
+        def cleanup():
+            os.listdir = original_listdir
+            os.path.isfile = original_isfile
+            os.path.isdir = original_isdir
+            del sys.modules['foo']
+            if full_path in sys.path:
+                sys.path.remove(full_path)
+        self.addCleanup(cleanup)
+
+        def listdir(_):
+            return ['foo.py']
+        def isfile(_):
+            return True
+        def isdir(_):
+            return True
+        os.listdir = listdir
+        os.path.isfile = isfile
+        os.path.isdir = isdir
+
+        loader = unittest.TestLoader()
+
+        mod_dir = os.path.abspath('bar')
+        expected_dir = os.path.abspath('foo')
+        msg = re.escape(r"'foo' module incorrectly imported from %r. Expected %r. "
+                "Is this module globally installed?" % (mod_dir, expected_dir))
+        self.assertRaisesRegexp(
+            ImportError, '^%s$' % msg, loader.discover,
+            start_dir='foo', pattern='foo.py'
+        )
+        self.assertEqual(sys.path[0], full_path)
+
 
 if __name__ == '__main__':
     unittest.main()


More information about the Python-checkins mailing list