[Zope3-checkins] SVN: Zope3/trunk/src/zope/importtool/ modify the zope.importtool.hook API so that the tests can run even when an

Fred L. Drake, Jr. fred at zope.com
Fri May 28 14:40:52 EDT 2004


Log message for revision 25094:
modify the zope.importtool.hook API so that the tests can run even when an
import hook from this package is already active



-=-
Modified: Zope3/trunk/src/zope/importtool/app.py
===================================================================
--- Zope3/trunk/src/zope/importtool/app.py	2004-05-28 17:40:40 UTC (rev 25093)
+++ Zope3/trunk/src/zope/importtool/app.py	2004-05-28 18:40:42 UTC (rev 25094)
@@ -34,7 +34,8 @@
 
 def run(options):
     reporter = FirstImportReporter()
-    hook.install_reporter(reporter)
+    h = hook.ReportingHook(reporter)
+    h.install()
     globals = {"__name__": "__main__",
                "__file__": options.argv[0]}
     old_argv = sys.argv[:]
@@ -42,7 +43,7 @@
     try:
         execfile(options.script, globals)
     finally:
-        hook.uninstall_reporter()
+        h.uninstall()
         sys.argv[:] = old_argv
     reporter.display_report()
 

Modified: Zope3/trunk/src/zope/importtool/hook.py
===================================================================
--- Zope3/trunk/src/zope/importtool/hook.py	2004-05-28 17:40:40 UTC (rev 25093)
+++ Zope3/trunk/src/zope/importtool/hook.py	2004-05-28 18:40:42 UTC (rev 25094)
@@ -31,53 +31,48 @@
 import __builtin__
 import sys
 
-__all__ = "install_reporter", "uninstall_reporter"
 
+class ReportingHook:
 
-previous__import__ = None
-current__import__ = None
+    def __init__(self, reporter):
+        self.reporter = reporter
+        self.active = False
+        self.previous = None
 
+    def install(self):
+        if self.active:
+            raise RuntimeError("import reporting hook already installed")
+        self.previous = __import__
+        __builtin__.__import__ = self.importhook
+        self.active = True
 
-def install_reporter(reporter):
-    global current__import__
-    global previous__import__
-    if previous__import__ is not None:
-        raise RuntimeError("import reporting hook already installed")
+    def uninstall(self):
+        if not self.active:
+            raise RuntimeError("import reporting hook not installed")
+        if __import__ != self.importhook:
+            raise RuntimeError("someone else is controlling imports: %r"
+                               % __import__)
+        __builtin__.__import__ = self.previous
+        self.active = False
+        self.previous = None
 
-    def importhook(name, globals=None, locals=None, fromlist=None):
+    def reset(self):
+        # reset as best we can; this is really for use from tests
+        if self.previous is not None:
+            __builtin__.__import__ = self.previous
+            self.previous = None
+        self.active = False
+
+    def importhook(self, name, globals=None, locals=None, fromlist=None):
         if globals is None:
             globals = sys._getframe(1).f_globals
         importer = globals.get("__name__")
-        reporter.request(importer, name, fromlist)
-        v = previous__import__(name, globals, locals, fromlist)
+        self.reporter.request(importer, name, fromlist)
+        v = self.previous(name, globals, locals, fromlist)
         if fromlist:
             imported = getattr(v, "__name__", None)
         else:
-            mod = previous__import__(name, globals, locals, ("foo",))
+            mod = self.previous(name, globals, locals, ("foo",))
             imported = getattr(mod, "__name__", None)
-        reporter.found(importer, imported, fromlist)
+        self.reporter.found(importer, imported, fromlist)
         return v
-
-    previous__import__ = __builtin__.__import__
-    __builtin__.__import__ = importhook
-    current__import__ = importhook
-
-
-def uninstall_reporter():
-    if __builtin__.__import__ is not current__import__:
-        raise RuntimeError("someone else is controlling imports")
-    reset()
-
-
-def active():
-    return current__import__ is not None
-
-
-def reset():
-    # reset as best we can; this is really for use from tests
-    global current__import__
-    global previous__import__
-    if previous__import__ is not None:
-        __builtin__.__import__ = previous__import__
-        previous__import__ = None
-    current__import__ = None

Modified: Zope3/trunk/src/zope/importtool/tests/test_hook.py
===================================================================
--- Zope3/trunk/src/zope/importtool/tests/test_hook.py	2004-05-28 17:40:40 UTC (rev 25093)
+++ Zope3/trunk/src/zope/importtool/tests/test_hook.py	2004-05-28 18:40:42 UTC (rev 25094)
@@ -51,10 +51,16 @@
 
     def setUp(self):
         self.reports = []
+        self.__import__ = __import__
 
     def tearDown(self):
-        hook.reset()
+        __builtin__.__import__ = self.__import__
 
+    def get_hook(self, reporter=None):
+        if reporter is None:
+            reporter = self
+        return hook.ReportingHook(reporter)
+
     def request(self, importer, name, fromlist):
         self.reports.append(name)
 
@@ -67,37 +73,43 @@
         raise TestException()
 
     def test_normal_installation(self):
-        self.failIf(hook.active())
-        hook.install_reporter(self)
-        self.failIf(not hook.active())
-        hook.uninstall_reporter()
-        self.failIf(hook.active())
+        h = self.get_hook()
+        self.failIf(h.active)
+        h.install()
+        self.failIf(not h.active)
+        h.uninstall()
+        self.failIf(h.active)
         # now do it again, to make sure we really can re-install the hook
-        hook.install_reporter(self)
-        self.failIf(not hook.active())
+        h.install()
+        self.failIf(not h.active)
 
     def test_reinstall_fails_if_active(self):
-        hook.install_reporter(self)
-        self.assertRaises(RuntimeError, hook.install_reporter, self)
+        h = self.get_hook()
+        h.install()
+        self.assertRaises(RuntimeError, h.install)
 
     def test_uninstall_fails_if_never_active(self):
-        self.assertRaises(RuntimeError, hook.uninstall_reporter)
+        h = self.get_hook()
+        self.assertRaises(RuntimeError, h.uninstall)
 
     def test_uninstall_fails_if_no_longer_active(self):
-        hook.install_reporter(self)
-        hook.uninstall_reporter()
-        self.assertRaises(RuntimeError, hook.uninstall_reporter)
+        h = self.get_hook()
+        h.install()
+        h.uninstall()
+        self.assertRaises(RuntimeError, h.uninstall)
 
     def test_wrap_other_hook(self):
+        h = self.get_hook()
         __builtin__.__import__ = alternate_hook
-        hook.install_reporter(self)
-        self.failUnless(hook.active())
-        hook.uninstall_reporter()
-        self.failIf(hook.active())
+        h.install()
+        self.failUnless(h.active)
+        h.uninstall()
+        self.failIf(h.active)
         self.failUnless(__builtin__.__import__ is alternate_hook)
 
     def test_report_record(self):
-        hook.install_reporter(self)
+        h = self.get_hook()
+        h.install()
         import sys
         import sys
         from sample import THE_ANSWER
@@ -110,7 +122,8 @@
              ])
 
     def test_exception_on_request(self):
-        hook.install_reporter(ReporterRaiseOnRequest())
+        h = self.get_hook(ReporterRaiseOnRequest())
+        h.install()
         try:
             import sys
         except TestException, e:
@@ -119,7 +132,8 @@
             self.fail("expected TestException")
 
     def test_exception_on_found(self):
-        hook.install_reporter(ReporterRaiseOnFound())
+        h = self.get_hook(ReporterRaiseOnFound())
+        h.install()
         try:
             import sys
         except TestException, e:
@@ -130,7 +144,8 @@
     def test_direct_calls(self):
         # make sure the hook function can be called directly as well,
         # and behave the way the default __import__() works
-        hook.install_reporter(self)
+        h = self.get_hook()
+        h.install()
         m = __import__("sys")
         self.assertEqual(self.reports[-1],
                          (__name__, "sys", "sys", None))




More information about the Zope3-Checkins mailing list