[Zope3-checkins] SVN: Zope3/trunk/src/zope/importtool/ teaser for a runtime import analysis tool

Fred L. Drake, Jr. fred at zope.com
Thu May 27 18:32:10 EDT 2004


Log message for revision 25071:
teaser for a runtime import analysis tool


-=-
Added: Zope3/trunk/src/zope/importtool/__init__.py
===================================================================
--- Zope3/trunk/src/zope/importtool/__init__.py	2004-05-27 22:16:27 UTC (rev 25070)
+++ Zope3/trunk/src/zope/importtool/__init__.py	2004-05-27 22:32:09 UTC (rev 25071)
@@ -0,0 +1 @@
+# This directory is a Python package.


Property changes on: Zope3/trunk/src/zope/importtool/__init__.py
___________________________________________________________________
Name: svn:mime-type
   + text/x-python
Name: svn:eol-style
   + native

Added: Zope3/trunk/src/zope/importtool/hook.py
===================================================================
--- Zope3/trunk/src/zope/importtool/hook.py	2004-05-27 22:16:27 UTC (rev 25070)
+++ Zope3/trunk/src/zope/importtool/hook.py	2004-05-27 22:32:09 UTC (rev 25071)
@@ -0,0 +1,80 @@
+##############################################################################
+#
+# Copyright (c) 2004 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Low-level hook for __import__.
+
+This allows a 'reporter' function to be installed that can report what
+imports have occurred, possibly taking some action to block the import
+(by raising an exception).
+
+The reporter function is called with four arguments:
+
+- the full name of the module performing the import,
+- the full name of the module that was imported,
+- the name by which the importer referenced the imported module (this
+  may be a relative name rather than a full name), and
+- the 'fromlist' argument passed to __import__().
+
+$Id$
+"""
+
+import __builtin__
+
+__all__ = "install_reporter", "uninstall_reporter"
+
+
+
+previous__import__ = None
+current__import__ = None
+
+
+def install_reporter(report):
+    global current__import__
+    global previous__import__
+    if previous__import__ is not None:
+        raise RuntimeError("import reporting hook already installed")
+
+    def importhook(name, globals, locals, fromlist):
+        v = previous__import__(name, globals, locals, fromlist)
+        importer = globals.get("__name__")
+        if fromlist:
+            imported = getattr(v, "__name__", None)
+        else:
+            mod = previous__import__(name, globals, locals, ("foo",))
+            imported = getattr(mod, "__name__", None)
+        report(importer, imported, name, 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


Property changes on: Zope3/trunk/src/zope/importtool/hook.py
___________________________________________________________________
Name: svn:mime-type
   + text/x-python
Name: svn:eol-style
   + native

Added: Zope3/trunk/src/zope/importtool/tests/__init__.py
===================================================================
--- Zope3/trunk/src/zope/importtool/tests/__init__.py	2004-05-27 22:16:27 UTC (rev 25070)
+++ Zope3/trunk/src/zope/importtool/tests/__init__.py	2004-05-27 22:32:09 UTC (rev 25071)
@@ -0,0 +1 @@
+# This directory is a Python package.


Property changes on: Zope3/trunk/src/zope/importtool/tests/__init__.py
___________________________________________________________________
Name: svn:mime-type
   + text/x-python
Name: svn:eol-style
   + native

Added: Zope3/trunk/src/zope/importtool/tests/test_hook.py
===================================================================
--- Zope3/trunk/src/zope/importtool/tests/test_hook.py	2004-05-27 22:16:27 UTC (rev 25070)
+++ Zope3/trunk/src/zope/importtool/tests/test_hook.py	2004-05-27 22:32:09 UTC (rev 25071)
@@ -0,0 +1,104 @@
+##############################################################################
+#
+# Copyright (c) 2004 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Tests for zope.importtool.hook.
+
+$Id$
+"""
+import __builtin__
+import unittest
+
+from zope.importtool import hook
+
+
+real__import__ = __import__
+
+
+def alternate_hook(*args):
+    return real__import__(*args)
+
+
+class TestException(Exception):
+    """Exception raised in the tests."""
+
+
+class HookTestCase(unittest.TestCase):
+
+    def setUp(self):
+        self.reports = []
+
+    def tearDown(self):
+        hook.reset()
+
+    def report(self, *args):
+        self.reports.append(args)
+
+    def raise_error(self, *args):
+        self.reports.append(args)
+        raise TestException()
+
+    def test_normal_installation(self):
+        self.failIf(hook.active())
+        hook.install_reporter(self.report)
+        self.failIf(not hook.active())
+        hook.uninstall_reporter()
+        self.failIf(hook.active())
+        # now do it again, to make sure we really can re-install the hook
+        hook.install_reporter(self.report)
+        self.failIf(not hook.active())
+
+    def test_reinstall_fails_if_active(self):
+        hook.install_reporter(self.report)
+        self.assertRaises(RuntimeError, hook.install_reporter, self.report)
+
+    def test_uninstall_fails_if_never_active(self):
+        self.assertRaises(RuntimeError, hook.uninstall_reporter)
+
+    def test_uninstall_fails_if_no_longer_active(self):
+        hook.install_reporter(self.report)
+        hook.uninstall_reporter()
+        self.assertRaises(RuntimeError, hook.uninstall_reporter)
+
+    def test_wrap_other_hook(self):
+        __builtin__.__import__ = alternate_hook
+        hook.install_reporter(self.report)
+        self.failUnless(hook.active())
+        hook.uninstall_reporter()
+        self.failIf(hook.active())
+        self.failUnless(__builtin__.__import__ is alternate_hook)
+
+    def test_report_record(self):
+        hook.install_reporter(self.report)
+        import sys
+        import sys
+        from hook import install_reporter
+        self.assertEqual(
+            self.reports,
+            [(__name__, "sys", "sys", None),
+             (__name__, "sys", "sys", None),
+             (__name__, "zope.importtool.hook", "hook", ("install_reporter",)),
+             ])
+
+    def test_exception_from_reporter(self):
+        hook.install_reporter(self.raise_error)
+        try:
+            import sys
+        except TestException:
+            self.assertEqual(len(self.reports), 1)
+        else:
+            self.fail("expected TestException")
+
+
+def test_suite():
+    return unittest.makeSuite(HookTestCase)
+


Property changes on: Zope3/trunk/src/zope/importtool/tests/test_hook.py
___________________________________________________________________
Name: svn:mime-type
   + text/x-python
Name: svn:eol-style
   + native




More information about the Zope3-Checkins mailing list