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()
|
---|