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