[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