blob: 608ec01f14017b60c79db608066bb2771313c3e5 [file] [log] [blame]
Walter Dörwaldb1ded1e2003-04-15 11:10:33 +00001import unittest
Antoine Pitrou4de39cd2009-10-10 21:08:31 +00002from test import support
3import os
Skip Montanaroe99d5ea2001-01-20 19:54:20 +00004import sys
Tim Petersb05cd492002-04-11 20:04:12 +00005
Skip Montanaroe99d5ea2001-01-20 19:54:20 +00006
Antoine Pitrou4de39cd2009-10-10 21:08:31 +00007class NoAll(RuntimeError):
8 pass
9
10class FailedImport(RuntimeError):
11 pass
12
13
Walter Dörwaldb1ded1e2003-04-15 11:10:33 +000014class AllTest(unittest.TestCase):
15
16 def check_all(self, modname):
17 names = {}
Antoine Pitroua0d2f4d2010-10-29 11:53:34 +000018 with support.check_warnings(
19 (".* (module|package)", DeprecationWarning),
20 ("", ResourceWarning),
21 quiet=True):
Christian Heimes75ca4ea2008-05-06 23:48:04 +000022 try:
23 exec("import %s" % modname, names)
Antoine Pitrou4de39cd2009-10-10 21:08:31 +000024 except:
Christian Heimes75ca4ea2008-05-06 23:48:04 +000025 # Silent fail here seems the best route since some modules
Antoine Pitrou4de39cd2009-10-10 21:08:31 +000026 # may not be available or not initialize properly in all
27 # environments.
28 raise FailedImport(modname)
29 if not hasattr(sys.modules[modname], "__all__"):
30 raise NoAll(modname)
Walter Dörwaldb1ded1e2003-04-15 11:10:33 +000031 names = {}
Antoine Pitrou4de39cd2009-10-10 21:08:31 +000032 try:
33 exec("from %s import *" % modname, names)
34 except Exception as e:
35 # Include the module name in the exception string
36 self.fail("__all__ failure in {}: {}: {}".format(
37 modname, e.__class__.__name__, e))
Guido van Rossume2b70bc2006-08-18 22:13:04 +000038 if "__builtins__" in names:
Walter Dörwaldb1ded1e2003-04-15 11:10:33 +000039 del names["__builtins__"]
Raymond Hettingera690a992003-11-16 16:17:49 +000040 keys = set(names)
41 all = set(sys.modules[modname].__all__)
Guido van Rossumd8faa362007-04-27 19:54:29 +000042 self.assertEqual(keys, all)
Skip Montanaroe99d5ea2001-01-20 19:54:20 +000043
Antoine Pitrou4de39cd2009-10-10 21:08:31 +000044 def walk_modules(self, basedir, modpath):
45 for fn in sorted(os.listdir(basedir)):
46 path = os.path.join(basedir, fn)
47 if os.path.isdir(path):
48 pkg_init = os.path.join(path, '__init__.py')
49 if os.path.exists(pkg_init):
50 yield pkg_init, modpath + fn
51 for p, m in self.walk_modules(path, modpath + fn + "."):
52 yield p, m
53 continue
54 if not fn.endswith('.py') or fn == '__init__.py':
55 continue
56 yield path, modpath + fn[:-3]
57
Walter Dörwaldb1ded1e2003-04-15 11:10:33 +000058 def test_all(self):
Antoine Pitrou4de39cd2009-10-10 21:08:31 +000059 # Blacklisted modules and packages
60 blacklist = set([
61 # Will raise a SyntaxError when compiling the exec statement
62 '__future__',
63 ])
64
Walter Dörwaldb1ded1e2003-04-15 11:10:33 +000065 if not sys.platform.startswith('java'):
66 # In case _socket fails to build, make this test fail more gracefully
67 # than an AttributeError somewhere deep in CGIHTTPServer.
68 import _socket
Tim Petersab9ba272001-08-09 21:40:30 +000069
Walter Dörwaldb1ded1e2003-04-15 11:10:33 +000070 # rlcompleter needs special consideration; it import readline which
71 # initializes GNU readline which calls setlocale(LC_CTYPE, "")... :-(
72 try:
Antoine Pitrou4de39cd2009-10-10 21:08:31 +000073 import rlcompleter
74 import locale
75 except ImportError:
76 pass
77 else:
78 locale.setlocale(locale.LC_CTYPE, 'C')
79
80 ignored = []
81 failed_imports = []
82 lib_dir = os.path.dirname(os.path.dirname(__file__))
83 for path, modname in self.walk_modules(lib_dir, ""):
84 m = modname
85 blacklisted = False
86 while m:
87 if m in blacklist:
88 blacklisted = True
89 break
90 m = m.rpartition('.')[0]
91 if blacklisted:
92 continue
93 if support.verbose:
94 print(modname)
Walter Dörwaldb1ded1e2003-04-15 11:10:33 +000095 try:
Antoine Pitrou4de39cd2009-10-10 21:08:31 +000096 # This heuristic speeds up the process by removing, de facto,
97 # most test modules (and avoiding the auto-executing ones).
98 with open(path, "rb") as f:
99 if b"__all__" not in f.read():
100 raise NoAll(modname)
101 self.check_all(modname)
102 except NoAll:
103 ignored.append(modname)
104 except FailedImport:
105 failed_imports.append(modname)
106
107 if support.verbose:
108 print('Following modules have no __all__ and have been ignored:',
109 ignored)
110 print('Following modules failed to be imported:', failed_imports)
Walter Dörwaldb1ded1e2003-04-15 11:10:33 +0000111
112
113def test_main():
Antoine Pitrou4de39cd2009-10-10 21:08:31 +0000114 support.run_unittest(AllTest)
Walter Dörwaldb1ded1e2003-04-15 11:10:33 +0000115
116if __name__ == "__main__":
117 test_main()