def test_alwaysPreferPy(self): """ Verify that .py files will always be preferred to .pyc files, regardless of directory listing order. """ mypath = FilePath(self.mktemp()) mypath.createDirectory() pp = modules.PythonPath(sysPath=[mypath.path]) originalSmartPath = pp._smartPath def _evilSmartPath(pathName): o = originalSmartPath(pathName) originalChildren = o.children def evilChildren(): # normally this order is random; let's make sure it always # comes up .pyc-first. x = originalChildren() x.sort() x.reverse() return x o.children = evilChildren return o mypath.child("abcd.py").setContent('\n') compileall.compile_dir(mypath.path, quiet=True) # sanity check self.assertEquals(len(mypath.children()), 2) pp._smartPath = _evilSmartPath self.assertEquals(pp['abcd'].filePath, mypath.child('abcd.py'))
def _underUnderPathTest(self, doImport=True): moddir2 = self.mktemp() fpmd = FilePath(moddir2) fpmd.createDirectory() fpmd.child("foozle.py").setContent("x = 123\n") self.packagePath.child("__init__.py").setContent( "__path__.append(%r)\n" % (moddir2,)) # Cut here self._setupSysPath() modinfo = modules.getModule(self.packageName) self.assertEquals( self.findByIteration(self.packageName+".foozle", modinfo, importPackages=doImport), modinfo['foozle']) self.assertEquals(modinfo['foozle'].load().x, 123)
def _underUnderPathTest(self, doImport=True): moddir2 = self.mktemp() fpmd = FilePath(moddir2) fpmd.createDirectory() fpmd.child("foozle.py").setContent("x = 123\n") self.packagePath.child("__init__.py").setContent( "__path__.append(%r)\n" % (moddir2, )) # Cut here self._setupSysPath() modinfo = modules.getModule(self.packageName) self.assertEquals( self.findByIteration(self.packageName + ".foozle", modinfo, importPackages=doImport), modinfo['foozle']) self.assertEquals(modinfo['foozle'].load().x, 123)
def pathEntryWithOnePackage(self, pkgname="test_package"): """ Generate a L{FilePath} with one package, named C{pkgname}, on it, and return the L{FilePath} of the path entry. """ entry = FilePath(self.mktemp()) pkg = entry.child("test_package") pkg.makedirs() pkg.child("__init__.py").setContent("") return entry
def test_packageMissingPath(self): """ A package can delete its __path__ for some reasons, C{modules.PythonPath} should be able to deal with it. """ mypath = FilePath(self.mktemp()) mypath.createDirectory() pp = modules.PythonPath(sysPath=[mypath.path]) subpath = mypath.child("abcd") subpath.createDirectory() subpath.child("__init__.py").setContent('del __path__\n') sys.path.append(mypath.path) import abcd try: l = list(pp.walkModules()) self.assertEquals(len(l), 1) self.assertEquals(l[0].name, 'abcd') finally: del abcd del sys.modules['abcd'] sys.path.remove(mypath.path)
class PathModificationTest(PySpaceTestCase): """ These tests share setup/cleanup behavior of creating a dummy package and stuffing some code in it. """ _serialnum = itertools.count().next # used to generate serial numbers for # package names. def setUp(self): self.pathExtensionName = self.mktemp() self.pathExtension = FilePath(self.pathExtensionName) self.pathExtension.createDirectory() self.packageName = "pyspacetests%d" % (self._serialnum(),) self.packagePath = self.pathExtension.child(self.packageName) self.packagePath.createDirectory() self.packagePath.child("__init__.py").setContent("") self.packagePath.child("a.py").setContent(sampleModuleContents) self.packagePath.child("b.py").setContent(sampleModuleWithExportsContents) self.packagePath.child("c__init__.py").setContent("") self.packagePath.child("d.py").setContent(sampleModuleWithExportedImportsContents) self.pathSetUp = False def _setupSysPath(self): assert not self.pathSetUp self.pathSetUp = True sys.path.append(self.pathExtensionName) def _underUnderPathTest(self, doImport=True): moddir2 = self.mktemp() fpmd = FilePath(moddir2) fpmd.createDirectory() fpmd.child("foozle.py").setContent("x = 123\n") self.packagePath.child("__init__.py").setContent( "__path__.append(%r)\n" % (moddir2,)) # Cut here self._setupSysPath() modinfo = modules.getModule(self.packageName) self.assertEquals( self.findByIteration(self.packageName+".foozle", modinfo, importPackages=doImport), modinfo['foozle']) self.assertEquals(modinfo['foozle'].load().x, 123) def test_underUnderPathAlreadyImported(self): """ Verify that iterModules will honor the __path__ of already-loaded packages. """ self._underUnderPathTest() def test_underUnderPathNotAlreadyImported(self): """ Verify that iterModules will honor the __path__ of already-loaded packages. """ self._underUnderPathTest(False) test_underUnderPathNotAlreadyImported.todo = ( "This may be impossible but it sure would be nice.") def _listModules(self): pkginfo = modules.getModule(self.packageName) nfni = [modinfo.name.split(".")[-1] for modinfo in pkginfo.iterModules()] nfni.sort() self.failUnlessEqual(nfni, ['a', 'b', 'c__init__', 'd']) def test_listingModules(self): """ Make sure the module list comes back as we expect from iterModules on a package, whether zipped or not. """ self._setupSysPath() self._listModules() def test_listingModulesAlreadyImported(self): """ Make sure the module list comes back as we expect from iterModules on a package, whether zipped or not, even if the package has already been imported. """ self._setupSysPath() namedAny(self.packageName) self._listModules() def test_moduleAttributes(self): """ Module attributes can be iterated over without executing the code. """ self._setupSysPath() modinfo = modules.getModule(self.packageName + ".a") attrs = sorted(modinfo.iterAttributes(), key=lambda a: a.name) names = sorted(["foo", "doFoo", "Foo"]) for attr, name in zip(attrs, names): self.assertEquals(attr.onObject, modinfo) self.assertFalse(attr.isLoaded()) self.assertEquals(attr.name, modinfo.name + '.' + name) self.assertRaises(NotImplementedError, lambda: list(attr.iterAttributes())) def test_loadedModuleAttributes(self): """ Module attributes can be iterated over after the module has been loaded. """ self._setupSysPath() modinfo = modules.getModule(self.packageName + ".a") modinfo.load() attrs = sorted([a for a in modinfo.iterAttributes() if '_' not in a.name], key=lambda a: a.name) names = sorted(["foo", "doFoo", "Foo"]) for attr, name in zip(attrs, names): self.assertEquals(attr.onObject, modinfo) self.assertTrue(attr.isLoaded()) self.assertEquals(attr.name, modinfo.name + '.' + name) if name == "Foo": classattrs = [a.name for a in attr.iterAttributes()] self.assertIn(modinfo.name + '.Foo.x', classattrs) def test_attributeLoading(self): """ Calling .load() on a L{PythonAttribute} loads the module it's a part of and returns the attribute value. """ self._setupSysPath() modinfo = modules.getModule(self.packageName + ".a") attr = [x for x in modinfo.iterAttributes() if x.name.endswith('foo')][0] mod = attr.onObject self.assertFalse(attr.isLoaded()) self.assertFalse(mod.isLoaded()) val = attr.load() self.assertTrue(attr.isLoaded()) self.assertTrue(mod.isLoaded()) self.assertEquals(val, 123) self.assertEquals(attr.pythonValue, 123) self.assertEquals(attr.load(), 123) def test_moduleImportNames(self): """ The fully qualified names imported by a module can be inspected. """ self._setupSysPath() modinfo = modules.getModule(self.packageName + ".a") self.assertEquals(sorted(modinfo.iterImportNames()), sorted(["sys", "os", "datetime", "twisted.python.reflect", "twisted.python.filepath", "twisted.python.components.registerAdapter"])) def test_moduleExportDefinedNames(self): """ The exports of a module with no __all__ are all its defined names. """ self._setupSysPath() modinfo = modules.getModule(self.packageName + ".a") self.assertEqual(sorted(modinfo.iterExportNames()), sorted(["foo", "doFoo", "Foo"])) def test_moduleExportAll(self): """ If __all__ is defined as a list of string literals, the names in it are used as the list of the module's exports. """ self._setupSysPath() modinfo = modules.getModule(self.packageName + ".b") self.assertEqual(sorted(modinfo.iterExportNames()), sorted(["foo"])) def test_exportedImports(self): """ If __all__ mentions imports, they're included in the collection of defined names. """ self._setupSysPath() modinfo = modules.getModule(self.packageName + ".d") self.assertEqual(sorted([x.name.rsplit('.', 1)[1] for x in modinfo.iterAttributes()]), sorted(["foo", "registerAdapter", "reflect"])) def test_moduleExportProblems(self): """ C{SyntaxError} is raised when doing inspection of module exports if __all__ is not a single list of string literals. """ self.packagePath.child("e.py").setContent("__all__ = ['a' + 'b']") self.packagePath.child("f.py").setContent("__all__ = ['a']\n__all__ = ['a', 'b']") self._setupSysPath() modinfo1 = modules.getModule(self.packageName + ".e") modinfo2 = modules.getModule(self.packageName + ".f") self.assertRaises(SyntaxError, lambda: list(modinfo1.iterExportNames())) self.assertRaises(SyntaxError, lambda: list(modinfo2.iterExportNames())) if ast is None: astMsg = ("Examining unloaded module attributes requires the 'ast'" " module from Python 2.6.") test_moduleAttributes.skip = astMsg test_moduleImportNames.skip = astMsg test_moduleExportAll.skip = astMsg test_moduleExportDefinedNames.skip = astMsg test_moduleExportProblems.skip = astMsg def tearDown(self): # Intentionally using 'assert' here, this is not a test assertion, this # is just an "oh f**k what is going ON" assertion. -glyph if self.pathSetUp: HORK = "path cleanup failed: don't be surprised if other tests break" assert sys.path.pop() is self.pathExtensionName, HORK+", 1" assert self.pathExtensionName not in sys.path, HORK+", 2"
class PathModificationTest(PySpaceTestCase): """ These tests share setup/cleanup behavior of creating a dummy package and stuffing some code in it. """ _serialnum = itertools.count().next # used to generate serial numbers for # package names. def setUp(self): self.pathExtensionName = self.mktemp() self.pathExtension = FilePath(self.pathExtensionName) self.pathExtension.createDirectory() self.packageName = "pyspacetests%d" % (self._serialnum(), ) self.packagePath = self.pathExtension.child(self.packageName) self.packagePath.createDirectory() self.packagePath.child("__init__.py").setContent("") self.packagePath.child("a.py").setContent(sampleModuleContents) self.packagePath.child("b.py").setContent( sampleModuleWithExportsContents) self.packagePath.child("c__init__.py").setContent("") self.packagePath.child("d.py").setContent( sampleModuleWithExportedImportsContents) self.pathSetUp = False def _setupSysPath(self): assert not self.pathSetUp self.pathSetUp = True sys.path.append(self.pathExtensionName) def _underUnderPathTest(self, doImport=True): moddir2 = self.mktemp() fpmd = FilePath(moddir2) fpmd.createDirectory() fpmd.child("foozle.py").setContent("x = 123\n") self.packagePath.child("__init__.py").setContent( "__path__.append(%r)\n" % (moddir2, )) # Cut here self._setupSysPath() modinfo = modules.getModule(self.packageName) self.assertEquals( self.findByIteration(self.packageName + ".foozle", modinfo, importPackages=doImport), modinfo['foozle']) self.assertEquals(modinfo['foozle'].load().x, 123) def test_underUnderPathAlreadyImported(self): """ Verify that iterModules will honor the __path__ of already-loaded packages. """ self._underUnderPathTest() def test_underUnderPathNotAlreadyImported(self): """ Verify that iterModules will honor the __path__ of already-loaded packages. """ self._underUnderPathTest(False) test_underUnderPathNotAlreadyImported.todo = ( "This may be impossible but it sure would be nice.") def _listModules(self): pkginfo = modules.getModule(self.packageName) nfni = [ modinfo.name.split(".")[-1] for modinfo in pkginfo.iterModules() ] nfni.sort() self.failUnlessEqual(nfni, ['a', 'b', 'c__init__', 'd']) def test_listingModules(self): """ Make sure the module list comes back as we expect from iterModules on a package, whether zipped or not. """ self._setupSysPath() self._listModules() def test_listingModulesAlreadyImported(self): """ Make sure the module list comes back as we expect from iterModules on a package, whether zipped or not, even if the package has already been imported. """ self._setupSysPath() namedAny(self.packageName) self._listModules() def test_moduleAttributes(self): """ Module attributes can be iterated over without executing the code. """ self._setupSysPath() modinfo = modules.getModule(self.packageName + ".a") attrs = sorted(modinfo.iterAttributes(), key=lambda a: a.name) names = sorted(["foo", "doFoo", "Foo"]) for attr, name in zip(attrs, names): self.assertEquals(attr.onObject, modinfo) self.assertFalse(attr.isLoaded()) self.assertEquals(attr.name, modinfo.name + '.' + name) self.assertRaises(NotImplementedError, lambda: list(attr.iterAttributes())) def test_loadedModuleAttributes(self): """ Module attributes can be iterated over after the module has been loaded. """ self._setupSysPath() modinfo = modules.getModule(self.packageName + ".a") modinfo.load() attrs = sorted( [a for a in modinfo.iterAttributes() if '_' not in a.name], key=lambda a: a.name) names = sorted(["foo", "doFoo", "Foo"]) for attr, name in zip(attrs, names): self.assertEquals(attr.onObject, modinfo) self.assertTrue(attr.isLoaded()) self.assertEquals(attr.name, modinfo.name + '.' + name) if name == "Foo": classattrs = [a.name for a in attr.iterAttributes()] self.assertIn(modinfo.name + '.Foo.x', classattrs) def test_attributeLoading(self): """ Calling .load() on a L{PythonAttribute} loads the module it's a part of and returns the attribute value. """ self._setupSysPath() modinfo = modules.getModule(self.packageName + ".a") attr = [x for x in modinfo.iterAttributes() if x.name.endswith('foo')][0] mod = attr.onObject self.assertFalse(attr.isLoaded()) self.assertFalse(mod.isLoaded()) val = attr.load() self.assertTrue(attr.isLoaded()) self.assertTrue(mod.isLoaded()) self.assertEquals(val, 123) self.assertEquals(attr.pythonValue, 123) self.assertEquals(attr.load(), 123) def test_moduleImportNames(self): """ The fully qualified names imported by a module can be inspected. """ self._setupSysPath() modinfo = modules.getModule(self.packageName + ".a") self.assertEquals( sorted(modinfo.iterImportNames()), sorted([ "sys", "os", "datetime", "twisted.python.reflect", "twisted.python.filepath", "twisted.python.components.registerAdapter" ])) def test_moduleExportDefinedNames(self): """ The exports of a module with no __all__ are all its defined names. """ self._setupSysPath() modinfo = modules.getModule(self.packageName + ".a") self.assertEqual(sorted(modinfo.iterExportNames()), sorted(["foo", "doFoo", "Foo"])) def test_moduleExportAll(self): """ If __all__ is defined as a list of string literals, the names in it are used as the list of the module's exports. """ self._setupSysPath() modinfo = modules.getModule(self.packageName + ".b") self.assertEqual(sorted(modinfo.iterExportNames()), sorted(["foo"])) def test_exportedImports(self): """ If __all__ mentions imports, they're included in the collection of defined names. """ self._setupSysPath() modinfo = modules.getModule(self.packageName + ".d") self.assertEqual( sorted( [x.name.rsplit('.', 1)[1] for x in modinfo.iterAttributes()]), sorted(["foo", "registerAdapter", "reflect"])) def test_moduleExportProblems(self): """ C{SyntaxError} is raised when doing inspection of module exports if __all__ is not a single list of string literals. """ self.packagePath.child("e.py").setContent("__all__ = ['a' + 'b']") self.packagePath.child("f.py").setContent( "__all__ = ['a']\n__all__ = ['a', 'b']") self._setupSysPath() modinfo1 = modules.getModule(self.packageName + ".e") modinfo2 = modules.getModule(self.packageName + ".f") self.assertRaises(SyntaxError, lambda: list(modinfo1.iterExportNames())) self.assertRaises(SyntaxError, lambda: list(modinfo2.iterExportNames())) if ast is None: astMsg = ("Examining unloaded module attributes requires the 'ast'" " module from Python 2.6.") test_moduleAttributes.skip = astMsg test_moduleImportNames.skip = astMsg test_moduleExportAll.skip = astMsg test_moduleExportDefinedNames.skip = astMsg test_moduleExportProblems.skip = astMsg def tearDown(self): # Intentionally using 'assert' here, this is not a test assertion, this # is just an "oh f**k what is going ON" assertion. -glyph if self.pathSetUp: HORK = "path cleanup failed: don't be surprised if other tests break" assert sys.path.pop() is self.pathExtensionName, HORK + ", 1" assert self.pathExtensionName not in sys.path, HORK + ", 2"