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

Christian Theune <[email protected]>
Newsgroups gmane.comp.web.zope.zope3.cvs
Message-ID <[email protected]>
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)
 
 ######################################################################
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.