Comment 2 for bug 600259

Revision history for this message
Martijn Pieters (mjpieters) wrote :

I ran into this problem too, but not with uno. As a side-effect of z3c.autoinclude a completely unrelated package was imported (quodlibet) which installed a wrapper around __import__ in it's __init__ module to detect import errors on certain modules that had moved.

As soon as __import__ is wrapped (by uno or quodlibet or any other wrapper), the GenericSetup utils._resolveDottedName method will fail for any path passed to it, because of the way it tries to 'detect' an import error within a module.

The code in question:

    while parts_copy:
        try:
            module = __import__( '.'.join( parts_copy ) )
            break

        except ImportError:
            # Reraise if the import error was caused inside the imported file
            if sys.exc_info()[2].tb_next is not None: raise

            del parts_copy[ -1 ]

            if not parts_copy:
                return None

Note that is the traceback of the ImportError has a next frame, it is re-raised. With a dotted name like 'Products.CMFCore.exportimport.cachingpolicymgr.importCachingPolicyManager' the last entry is not a module, so the first time round there will *always* be an ImportError. With a wrapped __import__ function, there will always be a next frame in the traceback.

I won't argue about the rights or wrongs of wrapping the __import__ builtin, but I do think that the resolve method could be rethought to not rely on ImportErrors to detect what part of the path is a module and what part is an object inside a module.

In zope.configuration, it is at least assumed that if there is more than one part in the dotted name (part1.part2) the last part is an object name and not a module. If the same assumption was made in the GenericSetup resolver, this particular interaction with uno and other wrappers would at least go away.