blob: 2c5dbefb3a037df4b7b837207150c5aefab00c07 [file] [log] [blame]
Josh Gaoc62e49a2016-04-29 18:11:04 -07001from __future__ import print_function
2
3import unittest
4from test import test_support as support
5import os
6import sys
7
8# Setup bsddb warnings
9try:
10 bsddb = support.import_module('bsddb', deprecated=True)
11except unittest.SkipTest:
12 pass
13
14
15class NoAll(RuntimeError):
16 pass
17
18class FailedImport(RuntimeError):
19 pass
20
21
22class 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
119def test_main():
120 support.run_unittest(AllTest)
121
122if __name__ == "__main__":
123 test_main()