| from __future__ import print_function |
| |
| import unittest |
| from test import test_support as support |
| import os |
| import sys |
| |
| # Setup bsddb warnings |
| try: |
| bsddb = support.import_module('bsddb', deprecated=True) |
| except unittest.SkipTest: |
| pass |
| |
| |
| class NoAll(RuntimeError): |
| pass |
| |
| class FailedImport(RuntimeError): |
| pass |
| |
| |
| class AllTest(unittest.TestCase): |
| |
| def check_all(self, modname): |
| names = {} |
| with support.check_warnings((".* (module|package)", |
| DeprecationWarning), quiet=True): |
| try: |
| exec "import %s" % modname in names |
| except: |
| # Silent fail here seems the best route since some modules |
| # may not be available or not initialize properly in all |
| # environments. |
| raise FailedImport(modname) |
| if not hasattr(sys.modules[modname], "__all__"): |
| raise NoAll(modname) |
| names = {} |
| try: |
| exec "from %s import *" % modname in names |
| except Exception as e: |
| # Include the module name in the exception string |
| self.fail("__all__ failure in {}: {}: {}".format( |
| modname, e.__class__.__name__, e)) |
| if "__builtins__" in names: |
| del names["__builtins__"] |
| keys = set(names) |
| all = set(sys.modules[modname].__all__) |
| self.assertEqual(keys, all) |
| |
| def walk_modules(self, basedir, modpath): |
| for fn in sorted(os.listdir(basedir)): |
| path = os.path.join(basedir, fn) |
| if os.path.isdir(path): |
| pkg_init = os.path.join(path, '__init__.py') |
| if os.path.exists(pkg_init): |
| yield pkg_init, modpath + fn |
| for p, m in self.walk_modules(path, modpath + fn + "."): |
| yield p, m |
| continue |
| if not fn.endswith('.py') or fn == '__init__.py': |
| continue |
| yield path, modpath + fn[:-3] |
| |
| def test_all(self): |
| # Blacklisted modules and packages |
| blacklist = set([ |
| # Will raise a SyntaxError when compiling the exec statement |
| '__future__', |
| ]) |
| |
| if not sys.platform.startswith('java'): |
| # In case _socket fails to build, make this test fail more gracefully |
| # than an AttributeError somewhere deep in CGIHTTPServer. |
| import _socket |
| |
| # rlcompleter needs special consideration; it import readline which |
| # initializes GNU readline which calls setlocale(LC_CTYPE, "")... :-( |
| try: |
| import rlcompleter |
| import locale |
| except ImportError: |
| pass |
| else: |
| locale.setlocale(locale.LC_CTYPE, 'C') |
| |
| ignored = [] |
| failed_imports = [] |
| lib_dir = os.path.dirname(os.path.dirname(__file__)) |
| for path, modname in self.walk_modules(lib_dir, ""): |
| m = modname |
| blacklisted = False |
| while m: |
| if m in blacklist: |
| blacklisted = True |
| break |
| m = m.rpartition('.')[0] |
| if blacklisted: |
| continue |
| if support.verbose: |
| print(modname) |
| try: |
| # This heuristic speeds up the process by removing, de facto, |
| # most test modules (and avoiding the auto-executing ones). |
| with open(path, "rb") as f: |
| if "__all__" not in f.read(): |
| raise NoAll(modname) |
| self.check_all(modname) |
| except NoAll: |
| ignored.append(modname) |
| except FailedImport: |
| failed_imports.append(modname) |
| |
| if support.verbose: |
| print('Following modules have no __all__ and have been ignored:', |
| ignored) |
| print('Following modules failed to be imported:', failed_imports) |
| |
| |
| def test_main(): |
| support.run_unittest(AllTest) |
| |
| if __name__ == "__main__": |
| test_main() |