[Zope3-checkins] SVN: zope.testing/trunk/src/zope/testing/testrunner/ Add another option (--indirect-source) to show only warnings originating

Christian Theune ct at gocept.com
Thu Jan 29 15:18:38 EST 2009


Log message for revision 95526:
  Add another option (--indirect-source) to show only warnings originating
  from select modules (and their sub-modules).
  

Changed:
  U   zope.testing/trunk/src/zope/testing/testrunner/importcheck.py
  U   zope.testing/trunk/src/zope/testing/testrunner/options.py

-=-
Modified: zope.testing/trunk/src/zope/testing/testrunner/importcheck.py
===================================================================
--- zope.testing/trunk/src/zope/testing/testrunner/importcheck.py	2009-01-29 20:07:06 UTC (rev 95525)
+++ zope.testing/trunk/src/zope/testing/testrunner/importcheck.py	2009-01-29 20:18:38 UTC (rev 95526)
@@ -16,10 +16,12 @@
 wrapper_cache = {}
 seen = set()
 
+
 class IndirectAttributeAccessChecker(types.ModuleType):
 
-    def __init__(self, module):
+    def __init__(self, module, options):
         self.__import_checker_module = module
+        self.__import_checker_options = options
 
     def __setattr__(self, name, value):
         if name.startswith('_IndirectAttributeAccessChecker__import_checker_'):
@@ -35,66 +37,83 @@
         attr = getattr(module, name)
         if getattr(attr, '__module__', None) is None:
             return attr
-        if attr.__module__ != module.__name__:
-            import_mod, real_mod = module.__name__, attr.__module__
-            if (import_mod, name, real_mod) in WHITELIST:
-                # No warning for things on the whitelist.
-                pass
-            elif real_mod in ['doctest', 'zope.testing.doctest']:
-                # doctest regularly sticks stuff somewhere else. We
-                # ignore those.
-                pass
-            elif import_mod == 'sys' and name in ['stdin', 'stdout']:
-                # Those are redirected regularly.
-                pass
-            elif import_mod == 'os' and real_mod == 'posix':
-                pass
-            elif name == '__class__' and real_mod == '__builtin__':
-                pass
-            elif (import_mod == 'types' or
-                  import_mod.startswith('xml.dom')) and real_mod == '__builtin__':
-                # No warning for the types from the type module that
-                # really originate from builtins
-                pass
-            elif import_mod.split('.') == real_mod.split('.')[:-1]:
-                # Don't warn if the package of a module re-exports a
-                # symbol.
-                pass
-            elif real_mod in sys.modules and hasattr(sys.modules[real_mod], '__file__') and not sys.modules[real_mod].__file__.endswith('.py'):
-                # The real module seems to be a C-Module which is
-                # regularly masked using another Python module in front
-                # of it.
-                pass
-            elif real_mod.split('.')[-1] == '_' + import_mod.split('.')[-1]:
-                # Looks like an internal module, prefixed with _ was
-                # exported to the same module name without an _
-                pass
-            elif real_mod.startswith('_') and real_mod == import_mod.split('.')[-1]:
-                # Looks like a C-module which doesn't declare its
-                # package path correctly.
-                pass
+        if attr.__module__ == module.__name__:
+            return attr
+
+        frame = sys._getframe(1)
+        show_only_from = self.__import_checker_options.indirect_source
+        if show_only_from:
+            for include in show_only_from:
+                if frame.f_globals['__name__'].startswith(include):
+                    break
             else:
-                attr_type = type(attr).__name__
-                frame = sys._getframe(1)
-                file = frame.f_code.co_filename
-                line = frame.f_lineno
-                signature = (import_mod, name, real_mod, file, line)
-                if signature not in seen:
-                    print ("WARNING: indirect import of %s `%s.%s` (originally defined at `%s`)"
-                            % (attr_type, import_mod, name, real_mod))
-                    print "caused at %s:%s" % (file, line)
-                    seen.add(signature)
+                # This warning was caused in a module not under the
+                # `indirect source` parameter.
+                return attr
+
+        import_mod, real_mod = module.__name__, attr.__module__
+        if (import_mod, name, real_mod) in WHITELIST:
+            # No warning for things on the whitelist.
+            pass
+        elif real_mod in ['doctest', 'zope.testing.doctest']:
+            # doctest regularly sticks stuff somewhere else. We
+            # ignore those.
+            pass
+        elif import_mod == 'sys' and name in ['stdin', 'stdout']:
+            # Those are redirected regularly.
+            pass
+        elif import_mod == 'os' and real_mod == 'posix':
+            pass
+        elif name == '__class__' and real_mod == '__builtin__':
+            pass
+        elif (import_mod == 'types' or
+              import_mod.startswith('xml.dom')) and real_mod == '__builtin__':
+            # No warning for the types from the type module that
+            # really originate from builtins
+            pass
+        elif import_mod.split('.') == real_mod.split('.')[:-1]:
+            # Don't warn if the package of a module re-exports a
+            # symbol.
+            pass
+        elif real_mod in sys.modules and hasattr(sys.modules[real_mod], '__file__') and not sys.modules[real_mod].__file__.endswith('.py'):
+            # The real module seems to be a C-Module which is
+            # regularly masked using another Python module in front
+            # of it.
+            pass
+        elif real_mod.split('.')[-1] == '_' + import_mod.split('.')[-1]:
+            # Looks like an internal module, prefixed with _ was
+            # exported to the same module name without an _
+            pass
+        elif real_mod.startswith('_') and real_mod == import_mod.split('.')[-1]:
+            # Looks like a C-module which doesn't declare its
+            # package path correctly.
+            pass
+        else:
+            attr_type = type(attr).__name__
+            file = frame.f_code.co_filename
+            line = frame.f_lineno
+            signature = (import_mod, name, real_mod, file, line)
+            if signature not in seen:
+                print ("WARNING: indirect import of %s `%s.%s` (originally defined at `%s`)"
+                        % (attr_type, import_mod, name, real_mod))
+                print "caused at %s:%s" % (file, line)
+                seen.add(signature)
         return attr
 
 
 class IndirectImportWarner(ihooks.ModuleImporter):
 
+    def __init__(self, options):
+        ihooks.ModuleImporter.__init__(self)
+        self.options = options
+
     def import_module(self, name, globals=None, locals=None,
             fromlist=None):
         result = ihooks.ModuleImporter.import_module(
             self, name, globals=globals, locals=locals, fromlist=fromlist)
         if id(result) not in wrapper_cache:
-            checker = IndirectAttributeAccessChecker(result)
+            checker = IndirectAttributeAccessChecker(
+                result, self.options)
             if not hasattr(result, '__all__'):
                 # Support * imports
                 checker.__all__ = [x for x in dir(result) if not
@@ -137,7 +156,9 @@
     active = True
 
     def global_setup(self):
-        ihooks.install(IndirectImportWarner())
+        if self.runner.options.indirect_imports:
+            ihooks.install(IndirectImportWarner(self.runner.options))
 
     def global_teardown(self):
-        ihooks.uninstall()
+        if self.runner.options.indirect_imports:
+            ihooks.uninstall()

Modified: zope.testing/trunk/src/zope/testing/testrunner/options.py
===================================================================
--- zope.testing/trunk/src/zope/testing/testrunner/options.py	2009-01-29 20:07:06 UTC (rev 95525)
+++ zope.testing/trunk/src/zope/testing/testrunner/options.py	2009-01-29 20:18:38 UTC (rev 95526)
@@ -314,6 +314,20 @@
 Run the tests under pychecker
 """)
 
+analysis.add_option(
+    '--indirect-imports', '-i', action="store_true", dest='indirect_imports',
+    help="""\
+Inject an import hook and report usage of indirectly imported classes
+and functions.
+""")
+
+analysis.add_option(
+    '--indirect-source', action="append", dest='indirect_source',
+    help="""\
+Only report indirect imports that originated in the given package or
+module (or one of its sub-packages or sub-modules).
+""")
+
 parser.add_option_group(analysis)
 
 ######################################################################



More information about the Zope3-Checkins mailing list