While trying to use zope.app.modul.ZopePersistentModuleImporter, I ran across an interaction with code that uses the following hack to try and discern where an exception was raised.
>>> if sys.exc_info()[2].tb_next is not None: >>> raise The problem is occurs when an application provides an __import__ function written in python. In that case then there is a tb_next for all ImportError exceptions and this hack no longer indicates when the error was deeper. The same problem would occur if the hack were used while catching AttributeError and there was a python implementation for attribute access involved. This hack counts on the fact that C code which raises an error doesn't get included in the stack. It counts on this fact, however, at points where Python specifically allows application specific implementations written in Python. See the first paragraph of the __import__ documentation. http://docs.python.org/lib/built-in-funcs.html#l2h-6 Here's a grep of the Zope 2.10 branch. These first two are catching TypeError: ./Zope/lib/python/zope/component/_api.py:73: if sys.exc_info()[2].tb_next is not None: ./Zope/lib/python/zope/interface/interface.py:644: if sys.exc_info()[2].tb_next is not None: And these are catching ImportError: ./Zope/lib/python/zope/configuration/config.py:186: if sys.exc_info()[2].tb_next is not None: ./Zope/lib/python/zope/configuration/config.py:208: if sys.exc_info()[2].tb_next is not None: For zope.configuration.config.ConfigurationContext.resolve, this hack makes the difference between an ImportError being raised or a ConfigurationError. This inturn interacts with zope.app.component.back35.LayerField.fromUnicode which only catches ConfigurationError and doesn't catch ImportError. And here's the GenericSetup 1.3 branch, it is also catching ImportError: ./Products/GenericSetup/utils.py:89: if sys.exc_info()[2].tb_next is not None: raise Products.GenericSetup.utils._resolveDottedName is particularly troublesome since the except ImportError is inside a while loop so when __import__ is a python function and it raises ImportError, _resolveDottedName ends up not continuing with the while loop as it should. It seems like the root of the problem is that Python doesn't provide a way to distinguish between an error and a deeper error of the same type. This hack is trying to make that distinction but it interferes with places that Python specifically allows application specific implementations written in Python. Does that mean that code using this hack is broken? Also, zope.dottedname.resolve.resolve, zope.app.introspector.resolve, zope.app.component.site.resolve, zope.app.module.resolve, zope.configuration.name.resolve, zope.configuration.config.ConfigurationContext.resolve, Products.GenericSetup.utils._resolveDottedName. How many versions of this wheel do we need? :) Thoughts? Corrections? Suggested solutions. Ross _______________________________________________ Zope-Dev maillist - Zope-Dev@zope.org http://mail.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope )