[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