Home | History | Annotate | Download | only in test
      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 imports readline which
     77         # initializes GNU readline which calls setlocale(LC_CTYPE, "")... :-(
     78         import locale
     79         locale_tuple = locale.getlocale(locale.LC_CTYPE)
     80         try:
     81             import rlcompleter
     82         except ImportError:
     83             pass
     84         finally:
     85             locale.setlocale(locale.LC_CTYPE, locale_tuple)
     86 
     87         ignored = []
     88         failed_imports = []
     89         lib_dir = os.path.dirname(os.path.dirname(__file__))
     90         for path, modname in self.walk_modules(lib_dir, ""):
     91             m = modname
     92             blacklisted = False
     93             while m:
     94                 if m in blacklist:
     95                     blacklisted = True
     96                     break
     97                 m = m.rpartition('.')[0]
     98             if blacklisted:
     99                 continue
    100             if support.verbose:
    101                 print(modname)
    102             try:
    103                 # This heuristic speeds up the process by removing, de facto,
    104                 # most test modules (and avoiding the auto-executing ones).
    105                 with open(path, "rb") as f:
    106                     if "__all__" not in f.read():
    107                         raise NoAll(modname)
    108                     self.check_all(modname)
    109             except NoAll:
    110                 ignored.append(modname)
    111             except FailedImport:
    112                 failed_imports.append(modname)
    113 
    114         if support.verbose:
    115             print('Following modules have no __all__ and have been ignored:',
    116                   ignored)
    117             print('Following modules failed to be imported:', failed_imports)
    118 
    119 
    120 def test_main():
    121     support.run_unittest(AllTest)
    122 
    123 if __name__ == "__main__":
    124     test_main()
    125