1 from __future__ import print_function 2 3 import unittest 4 from test import test_support as support 5 import os 6 import sys 7 8 # Setup bsddb warnings 9 try: 10 bsddb = support.import_module('bsddb', deprecated=True) 11 except unittest.SkipTest: 12 pass 13 14 15 class NoAll(RuntimeError): 16 pass 17 18 class FailedImport(RuntimeError): 19 pass 20 21 22 class AllTest(unittest.TestCase): 23 24 def check_all(self, modname): 25 names = {} 26 with support.check_warnings((".* (module|package)", 27 DeprecationWarning), quiet=True): 28 try: 29 exec "import %s" % modname in names 30 except: 31 # Silent fail here seems the best route since some modules 32 # may not be available or not initialize properly in all 33 # environments. 34 raise FailedImport(modname) 35 if not hasattr(sys.modules[modname], "__all__"): 36 raise NoAll(modname) 37 names = {} 38 try: 39 exec "from %s import *" % modname in names 40 except Exception as e: 41 # Include the module name in the exception string 42 self.fail("__all__ failure in {}: {}: {}".format( 43 modname, e.__class__.__name__, e)) 44 if "__builtins__" in names: 45 del names["__builtins__"] 46 keys = set(names) 47 all = set(sys.modules[modname].__all__) 48 self.assertEqual(keys, all) 49 50 def walk_modules(self, basedir, modpath): 51 for fn in sorted(os.listdir(basedir)): 52 path = os.path.join(basedir, fn) 53 if os.path.isdir(path): 54 pkg_init = os.path.join(path, '__init__.py') 55 if os.path.exists(pkg_init): 56 yield pkg_init, modpath + fn 57 for p, m in self.walk_modules(path, modpath + fn + "."): 58 yield p, m 59 continue 60 if not fn.endswith('.py') or fn == '__init__.py': 61 continue 62 yield path, modpath + fn[:-3] 63 64 def test_all(self): 65 # Blacklisted modules and packages 66 blacklist = set([ 67 # Will raise a SyntaxError when compiling the exec statement 68 '__future__', 69 ]) 70 71 if not sys.platform.startswith('java'): 72 # In case _socket fails to build, make this test fail more gracefully 73 # than an AttributeError somewhere deep in CGIHTTPServer. 74 import _socket 75 76 # rlcompleter needs special consideration; it import readline which 77 # initializes GNU readline which calls setlocale(LC_CTYPE, "")... :-( 78 try: 79 import rlcompleter 80 import locale 81 except ImportError: 82 pass 83 else: 84 locale.setlocale(locale.LC_CTYPE, 'C') 85 86 ignored = [] 87 failed_imports = [] 88 lib_dir = os.path.dirname(os.path.dirname(__file__)) 89 for path, modname in self.walk_modules(lib_dir, ""): 90 m = modname 91 blacklisted = False 92 while m: 93 if m in blacklist: 94 blacklisted = True 95 break 96 m = m.rpartition('.')[0] 97 if blacklisted: 98 continue 99 if support.verbose: 100 print(modname) 101 try: 102 # This heuristic speeds up the process by removing, de facto, 103 # most test modules (and avoiding the auto-executing ones). 104 with open(path, "rb") as f: 105 if "__all__" not in f.read(): 106 raise NoAll(modname) 107 self.check_all(modname) 108 except NoAll: 109 ignored.append(modname) 110 except FailedImport: 111 failed_imports.append(modname) 112 113 if support.verbose: 114 print('Following modules have no __all__ and have been ignored:', 115 ignored) 116 print('Following modules failed to be imported:', failed_imports) 117 118 119 def test_main(): 120 support.run_unittest(AllTest) 121 122 if __name__ == "__main__": 123 test_main() 124