from __future__ import print_function

import unittest
from test import test_support as support
import os
import sys

# Setup bsddb warnings
try:
    bsddb = support.import_module('bsddb', deprecated=True)
except unittest.SkipTest:
    pass


class NoAll(RuntimeError):
    pass

class FailedImport(RuntimeError):
    pass


class AllTest(unittest.TestCase):

    def check_all(self, modname):
        names = {}
        with support.check_warnings((".* (module|package)",
                                     DeprecationWarning), quiet=True):
            try:
                exec "import %s" % modname in names
            except:
                # Silent fail here seems the best route since some modules
                # may not be available or not initialize properly in all
                # environments.
                raise FailedImport(modname)
        if not hasattr(sys.modules[modname], "__all__"):
            raise NoAll(modname)
        names = {}
        try:
            exec "from %s import *" % modname in names
        except Exception as e:
            # Include the module name in the exception string
            self.fail("__all__ failure in {}: {}: {}".format(
                      modname, e.__class__.__name__, e))
        if "__builtins__" in names:
            del names["__builtins__"]
        keys = set(names)
        all = set(sys.modules[modname].__all__)
        self.assertEqual(keys, all)

    def walk_modules(self, basedir, modpath):
        for fn in sorted(os.listdir(basedir)):
            path = os.path.join(basedir, fn)
            if os.path.isdir(path):
                pkg_init = os.path.join(path, '__init__.py')
                if os.path.exists(pkg_init):
                    yield pkg_init, modpath + fn
                    for p, m in self.walk_modules(path, modpath + fn + "."):
                        yield p, m
                continue
            if not fn.endswith('.py') or fn == '__init__.py':
                continue
            yield path, modpath + fn[:-3]

    def test_all(self):
        # Blacklisted modules and packages
        blacklist = set([
            # Will raise a SyntaxError when compiling the exec statement
            '__future__',
        ])

        if not sys.platform.startswith('java'):
            # In case _socket fails to build, make this test fail more gracefully
            # than an AttributeError somewhere deep in CGIHTTPServer.
            import _socket

        # rlcompleter needs special consideration; it import readline which
        # initializes GNU readline which calls setlocale(LC_CTYPE, "")... :-(
        try:
            import rlcompleter
            import locale
        except ImportError:
            pass
        else:
            locale.setlocale(locale.LC_CTYPE, 'C')

        ignored = []
        failed_imports = []
        lib_dir = os.path.dirname(os.path.dirname(__file__))
        for path, modname in self.walk_modules(lib_dir, ""):
            m = modname
            blacklisted = False
            while m:
                if m in blacklist:
                    blacklisted = True
                    break
                m = m.rpartition('.')[0]
            if blacklisted:
                continue
            if support.verbose:
                print(modname)
            try:
                # This heuristic speeds up the process by removing, de facto,
                # most test modules (and avoiding the auto-executing ones).
                with open(path, "rb") as f:
                    if "__all__" not in f.read():
                        raise NoAll(modname)
                    self.check_all(modname)
            except NoAll:
                ignored.append(modname)
            except FailedImport:
                failed_imports.append(modname)

        if support.verbose:
            print('Following modules have no __all__ and have been ignored:',
                  ignored)
            print('Following modules failed to be imported:', failed_imports)


def test_main():
    support.run_unittest(AllTest)

if __name__ == "__main__":
    test_main()
