[PEAK] Exceptions in lazy imported module not reported

Phillip J. Eby pje at telecommunity.com
Sat Dec 23 23:45:37 EST 2006


At 08:23 AM 12/23/2006 -0800, Vinj Vinj wrote:
>     reload(module)
>ImportError: No module named PriceDB
>------------------------
>
>This is usually caused by an exception which is raised
>in PriceDB (in the csae above) but the error that gets
>reported by the Lazy Importing modile is: "No module
>named PriceDB"
>
>I use Lazy Importing extensively and most of my
>modules are loaded through it. The startup time of my
>app has come down significantly. However, since I'm
>running a distributed app where multiple services get
>run on different servers, when I get this error, it is
>hard to debug.
>
>Is there any way that this error can get reported.

Not that I know of.  Although in my experience, the real problem is usually 
that the error is in a module that 'PriceDB' (or whatever) is importing, 
not in PriceDB itself.  I think that this is a side-effect of the "import 
rollback" support that was added in Python 2.4, and I don't know of any way 
to work around it.


>Nice to have feature:
>The autocomplete functionality does not work with
>IDE's like WINGIDE when you lazy import. It would be
>nice to have a script (which given a list of modules)
>will replace all occurances of those modules with Lazy
>Import loads or replace them back with regular loads.

You might have more luck by implementing a PEP 302 importer object that 
takes a list of module names that should be lazy, and adding it to 
sys.meta_path.  Then, *any* import of that module would be lazy.  Something 
like:

class LazyImporter:
     def __init__(self, names):
         self.names = dict.fromkeys(names)
     def find_module(self, fullname, path=None):
         if fullname in self.names:
             return self
     def load_module(self, fullname):
         self.names.pop(fullname)
         return lazyModule(fullname)

sys.meta_path.append(
     LazyImporter(
         ['pkg1.module1', 'pkg1.module2', ....]
     )
)

I'll probably add LazyImporter to a future version of Importing, but a 
quick bit of experimenting shows that the above works nicely, e.g.:

    >>> sys.meta_path.append(LazyImporter(['email']))
    >>> import email
    >>> type(email)
    <class 'peak.util.imports.LazyModule'>

Actually accessing attributes of the 'email' package then causes it to be 
loaded for real.

Unfortunately, you can't easily extend this approach to use wildcards.




More information about the PEAK mailing list