• Benjamin Peterson's avatar
    Merged revisions… · 886af966
    Benjamin Peterson yazdı
    Merged revisions 78966,78970,79018,79026-79027,79055,79156,79159,79163-79164,79173,79176,79194,79208,79212 via svnmerge from
    svn+ssh://pythondev@svn.python.org/python/trunk
    
    ........
      r78966 | florent.xicluna | 2010-03-14 10:20:59 -0500 (Sun, 14 Mar 2010) | 2 lines
    
      Do not hardcode Expat version.  It's possible to build Python with --with-system-expat option.
    ........
      r78970 | benjamin.peterson | 2010-03-14 21:58:24 -0500 (Sun, 14 Mar 2010) | 1 line
    
      this little exception dance is pointless
    ........
      r79018 | collin.winter | 2010-03-16 22:04:01 -0500 (Tue, 16 Mar 2010) | 1 line
    
      Delete unused import.
    ........
      r79026 | vinay.sajip | 2010-03-17 10:05:57 -0500 (Wed, 17 Mar 2010) | 1 line
    
      Issue #8162: logging: Clarified docstring and documentation for disable function.
    ........
      r79027 | collin.winter | 2010-03-17 12:36:16 -0500 (Wed, 17 Mar 2010) | 1 line
    
      Avoid hardcoding refcounts in tests.
    ........
      r79055 | benjamin.peterson | 2010-03-18 16:30:48 -0500 (Thu, 18 Mar 2010) | 1 line
    
      remove installation of deleted test/output dir
    ........
      r79156 | florent.xicluna | 2010-03-20 17:21:02 -0500 (Sat, 20 Mar 2010) | 2 lines
    
      Cleanup test_struct using check_warnings.
    ........
      r79159 | florent.xicluna | 2010-03-20 17:26:42 -0500 (Sat, 20 Mar 2010) | 2 lines
    
      Cleanup test_tarfile, and use check_warnings.
    ........
      r79163 | michael.foord | 2010-03-20 19:53:39 -0500 (Sat, 20 Mar 2010) | 1 line
    
      A faulty load_tests in a test module no longer halts test discovery. A placeholder test, that reports the failure, is created instead.
    ........
      r79164 | michael.foord | 2010-03-20 19:55:58 -0500 (Sat, 20 Mar 2010) | 1 line
    
      Change order of arguments in a unittest function.
    ........
      r79173 | georg.brandl | 2010-03-21 04:09:38 -0500 (Sun, 21 Mar 2010) | 1 line
    
      Document that GzipFile supports iteration.
    ........
      r79176 | georg.brandl | 2010-03-21 04:17:41 -0500 (Sun, 21 Mar 2010) | 1 line
    
      Introduce copy by slicing, used in later chapters.
    ........
      r79194 | florent.xicluna | 2010-03-21 06:58:11 -0500 (Sun, 21 Mar 2010) | 2 lines
    
      Use assertRaises and add a specific warning filter.
    ........
      r79208 | andrew.kuchling | 2010-03-21 13:47:12 -0500 (Sun, 21 Mar 2010) | 1 line
    
      Add items
    ........
      r79212 | georg.brandl | 2010-03-21 14:01:38 -0500 (Sun, 21 Mar 2010) | 1 line
    
      Fix plural.
    ........
    886af966
test_importhooks.py 7.76 KB
import sys
import imp
import os
import unittest
from test import support


test_src = """\
def get_name():
    return __name__
def get_file():
    return __file__
"""

absimp = "import sub\n"
relimp = "from . import sub\n"
deeprelimp = "from .... import sub\n"
futimp = "from __future__ import absolute_import\n"

reload_src = test_src+"""\
reloaded = True
"""

test_co = compile(test_src, "<???>", "exec")
reload_co = compile(reload_src, "<???>", "exec")

test2_oldabs_co = compile(absimp + test_src, "<???>", "exec")
test2_newabs_co = compile(futimp + absimp + test_src, "<???>", "exec")
test2_newrel_co = compile(relimp + test_src, "<???>", "exec")
test2_deeprel_co = compile(deeprelimp + test_src, "<???>", "exec")
test2_futrel_co = compile(futimp + relimp + test_src, "<???>", "exec")

test_path = "!!!_test_!!!"


class TestImporter:

    modules = {
        "hooktestmodule": (False, test_co),
        "hooktestpackage": (True, test_co),
        "hooktestpackage.sub": (True, test_co),
        "hooktestpackage.sub.subber": (True, test_co),
        "hooktestpackage.oldabs": (False, test2_oldabs_co),
        "hooktestpackage.newabs": (False, test2_newabs_co),
        "hooktestpackage.newrel": (False, test2_newrel_co),
        "hooktestpackage.sub.subber.subest": (True, test2_deeprel_co),
        "hooktestpackage.futrel": (False, test2_futrel_co),
        "sub": (False, test_co),
        "reloadmodule": (False, test_co),
    }

    def __init__(self, path=test_path):
        if path != test_path:
            # if out class is on sys.path_hooks, we must raise
            # ImportError for any path item that we can't handle.
            raise ImportError
        self.path = path

    def _get__path__(self):
        raise NotImplementedError

    def find_module(self, fullname, path=None):
        if fullname in self.modules:
            return self
        else:
            return None

    def load_module(self, fullname):
        ispkg, code = self.modules[fullname]
        mod = sys.modules.setdefault(fullname,imp.new_module(fullname))
        mod.__file__ = "<%s>" % self.__class__.__name__
        mod.__loader__ = self
        if ispkg:
            mod.__path__ = self._get__path__()
        exec(code, mod.__dict__)
        return mod


class MetaImporter(TestImporter):
    def _get__path__(self):
        return []

class PathImporter(TestImporter):
    def _get__path__(self):
        return [self.path]


class ImportBlocker:
    """Place an ImportBlocker instance on sys.meta_path and you
    can be sure the modules you specified can't be imported, even
    if it's a builtin."""
    def __init__(self, *namestoblock):
        self.namestoblock = dict.fromkeys(namestoblock)
    def find_module(self, fullname, path=None):
        if fullname in self.namestoblock:
            return self
        return None
    def load_module(self, fullname):
        raise ImportError("I dare you")


class ImpWrapper:

    def __init__(self, path=None):
        if path is not None and not os.path.isdir(path):
            raise ImportError
        self.path = path

    def find_module(self, fullname, path=None):
        subname = fullname.split(".")[-1]
        if subname != fullname and self.path is None:
            return None
        if self.path is None:
            path = None
        else:
            path = [self.path]
        try:
            file, filename, stuff = imp.find_module(subname, path)
        except ImportError:
            return None
        return ImpLoader(file, filename, stuff)


class ImpLoader:

    def __init__(self, file, filename, stuff):
        self.file = file
        self.filename = filename
        self.stuff = stuff

    def load_module(self, fullname):
        mod = imp.load_module(fullname, self.file, self.filename, self.stuff)
        if self.file:
            self.file.close()
        mod.__loader__ = self  # for introspection
        return mod


class ImportHooksBaseTestCase(unittest.TestCase):

    def setUp(self):
        self.path = sys.path[:]
        self.meta_path = sys.meta_path[:]
        self.path_hooks = sys.path_hooks[:]
        sys.path_importer_cache.clear()
        self.modules_before = support.modules_setup()

    def tearDown(self):
        sys.path[:] = self.path
        sys.meta_path[:] = self.meta_path
        sys.path_hooks[:] = self.path_hooks
        sys.path_importer_cache.clear()
        support.modules_cleanup(*self.modules_before)


class ImportHooksTestCase(ImportHooksBaseTestCase):

    def doTestImports(self, importer=None):
        import hooktestmodule
        import hooktestpackage
        import hooktestpackage.sub
        import hooktestpackage.sub.subber
        self.assertEqual(hooktestmodule.get_name(),
                         "hooktestmodule")
        self.assertEqual(hooktestpackage.get_name(),
                         "hooktestpackage")
        self.assertEqual(hooktestpackage.sub.get_name(),
                         "hooktestpackage.sub")
        self.assertEqual(hooktestpackage.sub.subber.get_name(),
                         "hooktestpackage.sub.subber")
        if importer:
            self.assertEqual(hooktestmodule.__loader__, importer)
            self.assertEqual(hooktestpackage.__loader__, importer)
            self.assertEqual(hooktestpackage.sub.__loader__, importer)
            self.assertEqual(hooktestpackage.sub.subber.__loader__, importer)

        TestImporter.modules['reloadmodule'] = (False, test_co)
        import reloadmodule
        self.assertFalse(hasattr(reloadmodule,'reloaded'))

        import hooktestpackage.newrel
        self.assertEqual(hooktestpackage.newrel.get_name(),
                         "hooktestpackage.newrel")
        self.assertEqual(hooktestpackage.newrel.sub,
                         hooktestpackage.sub)

        import hooktestpackage.sub.subber.subest as subest
        self.assertEqual(subest.get_name(),
                         "hooktestpackage.sub.subber.subest")
        self.assertEqual(subest.sub,
                         hooktestpackage.sub)

        import hooktestpackage.futrel
        self.assertEqual(hooktestpackage.futrel.get_name(),
                         "hooktestpackage.futrel")
        self.assertEqual(hooktestpackage.futrel.sub,
                         hooktestpackage.sub)

        import sub
        self.assertEqual(sub.get_name(), "sub")

        import hooktestpackage.oldabs
        self.assertEqual(hooktestpackage.oldabs.get_name(),
                         "hooktestpackage.oldabs")
        self.assertEqual(hooktestpackage.oldabs.sub, sub)

        import hooktestpackage.newabs
        self.assertEqual(hooktestpackage.newabs.get_name(),
                         "hooktestpackage.newabs")
        self.assertEqual(hooktestpackage.newabs.sub, sub)

    def testMetaPath(self):
        i = MetaImporter()
        sys.meta_path.append(i)
        self.doTestImports(i)

    def testPathHook(self):
        sys.path_hooks.append(PathImporter)
        sys.path.append(test_path)
        self.doTestImports()

    def testBlocker(self):
        mname = "exceptions"  # an arbitrary harmless builtin module
        support.unload(mname)
        sys.meta_path.append(ImportBlocker(mname))
        self.assertRaises(ImportError, __import__, mname)

    def testImpWrapper(self):
        i = ImpWrapper()
        sys.meta_path.append(i)
        sys.path_hooks.append(ImpWrapper)
        mnames = ("colorsys", "urllib.parse", "distutils.core")
        for mname in mnames:
            parent = mname.split(".")[0]
            for n in list(sys.modules):
                if n.startswith(parent):
                    del sys.modules[n]
        for mname in mnames:
            m = __import__(mname, globals(), locals(), ["__dummy__"])
            m.__loader__  # to make sure we actually handled the import


def test_main():
    support.run_unittest(ImportHooksTestCase)

if __name__ == "__main__":
    test_main()