resolves issue #59
resolves issue #48 Have the path.pyimport() helper raise an EnvironmentError if an import of a given file returns a module that does not appear to be coming from the actual path. E.g. for a directory layout like this: a / test_whatever.py b / test_whatever.py calling py.path.local("b/test_whatever.py").pyimport() will fail if the other globally scoped test_whatever module was loaded already. --HG-- branch : trunk
This commit is contained in:
		
							parent
							
								
									1f01fafec7
								
							
						
					
					
						commit
						86fc12dd15
					
				|  | @ -516,7 +516,16 @@ class LocalPath(FSBase): | ||||||
|                     self._prependsyspath(self.dirpath()) |                     self._prependsyspath(self.dirpath()) | ||||||
|                 modname = self.purebasename |                 modname = self.purebasename | ||||||
|             mod = __import__(modname, None, None, ['__doc__']) |             mod = __import__(modname, None, None, ['__doc__']) | ||||||
|             #self._module = mod |             modfile = mod.__file__ | ||||||
|  |             if modfile[-4:] in ('.pyc', '.pyo'): | ||||||
|  |                 modfile = modfile[:-1] | ||||||
|  |             elif modfile.endswith('$py.class'): | ||||||
|  |                 modfile = modfile[:-9] + '.py' | ||||||
|  |             if not self.samefile(modfile): | ||||||
|  |                 raise EnvironmentError("mismatch:\n" | ||||||
|  |                 "imported module %r\n" | ||||||
|  |                 "does not stem from %r\n"  | ||||||
|  |                 "maybe __init__.py files are missing?" % (mod, str(self))) | ||||||
|             return mod |             return mod | ||||||
|         else: |         else: | ||||||
|             try: |             try: | ||||||
|  |  | ||||||
|  | @ -70,6 +70,12 @@ class TmpTestdir: | ||||||
|             py.std.sys.path.remove(p) |             py.std.sys.path.remove(p) | ||||||
|         if hasattr(self, '_olddir'): |         if hasattr(self, '_olddir'): | ||||||
|             self._olddir.chdir() |             self._olddir.chdir() | ||||||
|  |         # delete modules that have been loaded from tmpdir | ||||||
|  |         for name, mod in list(sys.modules.items()): | ||||||
|  |             if mod: | ||||||
|  |                 fn = getattr(mod, '__file__', None) | ||||||
|  |                 if fn and fn.startswith(str(self.tmpdir)): | ||||||
|  |                     del sys.modules[name] | ||||||
| 
 | 
 | ||||||
|     def getreportrecorder(self, obj): |     def getreportrecorder(self, obj): | ||||||
|         if isinstance(obj, py._com.Registry): |         if isinstance(obj, py._com.Registry): | ||||||
|  |  | ||||||
|  | @ -1,6 +1,11 @@ | ||||||
| Changes between 1.0.2 and '1.1.0b1' | Changes between 1.0.2 and '1.1.0b1' | ||||||
| ===================================== | ===================================== | ||||||
| 
 | 
 | ||||||
|  | * fix issue48 and issue59: raise an Error if the module | ||||||
|  |   from an imported test file does not seem to come from  | ||||||
|  |   the filepath - avoids "same-name" confusion that has | ||||||
|  |   been reported repeatedly | ||||||
|  | 
 | ||||||
| * merged Ronny's nose-compatibility hacks: now | * merged Ronny's nose-compatibility hacks: now | ||||||
|   nose-style setup_module() and setup() functions are  |   nose-style setup_module() and setup() functions are  | ||||||
|   supported |   supported | ||||||
|  |  | ||||||
|  | @ -336,6 +336,27 @@ class TestImport: | ||||||
|         from xxxpackage import module1  |         from xxxpackage import module1  | ||||||
|         assert module1 is mod1 |         assert module1 is mod1 | ||||||
| 
 | 
 | ||||||
|  |     def test_pyimport_check_filepath_consistency(self, monkeypatch, tmpdir): | ||||||
|  |         name = 'pointsback123' | ||||||
|  |         ModuleType = type(py.std.sys) | ||||||
|  |         p = tmpdir.ensure(name + '.py') | ||||||
|  |         for ending in ('.pyc', '$py.class', '.pyo'): | ||||||
|  |             mod = ModuleType(name) | ||||||
|  |             pseudopath = tmpdir.ensure(name+ending) | ||||||
|  |             mod.__file__ = str(pseudopath) | ||||||
|  |             monkeypatch.setitem(sys.modules, name, mod) | ||||||
|  |             newmod = p.pyimport() | ||||||
|  |             assert mod == newmod | ||||||
|  |         monkeypatch.undo() | ||||||
|  |         mod = ModuleType(name) | ||||||
|  |         pseudopath = tmpdir.ensure(name+"123.py") | ||||||
|  |         mod.__file__ = str(pseudopath) | ||||||
|  |         monkeypatch.setitem(sys.modules, name, mod) | ||||||
|  |         excinfo = py.test.raises(EnvironmentError, "p.pyimport()") | ||||||
|  |         s = str(excinfo.value) | ||||||
|  |         assert "mismatch" in s  | ||||||
|  |         assert name+"123" in s  | ||||||
|  | 
 | ||||||
| def test_pypkgdir(tmpdir): | def test_pypkgdir(tmpdir): | ||||||
|     pkg = tmpdir.ensure('pkg1', dir=1) |     pkg = tmpdir.ensure('pkg1', dir=1) | ||||||
|     pkg.ensure("__init__.py") |     pkg.ensure("__init__.py") | ||||||
|  |  | ||||||
|  | @ -16,6 +16,18 @@ class TestModule: | ||||||
|         py.test.raises(ImportError, modcol.collect) |         py.test.raises(ImportError, modcol.collect) | ||||||
|         py.test.raises(ImportError, modcol.run) |         py.test.raises(ImportError, modcol.run) | ||||||
| 
 | 
 | ||||||
|  |     def test_import_duplicate(self, testdir): | ||||||
|  |         a = testdir.mkdir("a") | ||||||
|  |         b = testdir.mkdir("b") | ||||||
|  |         p = a.ensure("test_whatever.py") | ||||||
|  |         p.pyimport() | ||||||
|  |         del py.std.sys.modules['test_whatever'] | ||||||
|  |         b.ensure("test_whatever.py") | ||||||
|  |         result = testdir.runpytest() | ||||||
|  |         s = result.stdout.str() | ||||||
|  |         assert 'mismatch' in s | ||||||
|  |         assert 'test_whatever' in s | ||||||
|  | 
 | ||||||
|     def test_syntax_error_in_module(self, testdir): |     def test_syntax_error_in_module(self, testdir): | ||||||
|         modcol = testdir.getmodulecol("this is a syntax error")  |         modcol = testdir.getmodulecol("this is a syntax error")  | ||||||
|         py.test.raises(SyntaxError, modcol.collect) |         py.test.raises(SyntaxError, modcol.collect) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue