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