Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ignore ImportError when exec source code

Tags:

python

I have an application that reads test scripts in python and sends them across the network for execution on a remote python instance. As the controlling program does not need to run these scripts I do not want to have all the modules the test scripts use installed on the controller's python environment. However the controller does need information from the test script to tell it how to run the test. Currently what I do to read and import test script data is something like

with open( 'test.py', 'r' ) as f:
    source = f.read()

m = types.ModuleType( "imported-temp", "Test module" )
co = compile( source, 'test.py', 'exec' )

exec co in m.__dict__

which yields a new module that contains the test. Unfortunately exec will raise ImportErrors if the test tries to import something the controller does not have. And worse, the module will not be fully imported.

If I can guarantee that the controller will not use the missing modules, is there someway I can ignore these exceptions? Or some other way to find out the names and classes defined in the test?

Examples test:

from controller import testUnit
import somethingThatTheControllerDoesNotHave

_testAttr = ['fast','foo','function']

class PartOne( testUnit ):
    def run( self ):
        pass

What the controller needs to know is the data in _testAttr and the name of all class definitions inheriting from testUnit.

like image 734
Charles Avatar asked May 20 '11 19:05

Charles


People also ask

How do I fix the ImportError No module named error in Python?

To get rid of this error “ImportError: No module named”, you just need to create __init__.py in the appropriate directory and everything will work fine.

What is ImportError?

In Python, ImportError occurs when the Python program tries to import module which does not exist in the private table. This exception can be avoided using exception handling using try and except blocks. We also saw examples of how the ImportError occurs and how it is handled.

Why I am getting module not found error in Python?

Python's ImportError ( ModuleNotFoundError ) indicates that you tried to import a module that Python doesn't find. It can usually be eliminated by adding a file named __init__.py to the directory and then adding this directory to $PYTHONPATH .


1 Answers

Write an import hook that catches the exception and returns a dummy module if the module doesn't exist.

import __builtin__
from types import ModuleType

class DummyModule(ModuleType):
    def __getattr__(self, key):
        return None
    __all__ = []   # support wildcard imports

def tryimport(name, globals={}, locals={}, fromlist=[], level=-1):
    try:
        return realimport(name, globals, locals, fromlist, level)
    except ImportError:
        return DummyModule(name)

realimport, __builtin__.__import__ = __builtin__.__import__, tryimport

import sys   # works as usual
import foo   # no error

from bar import baz     # also no error
from quux import *      # ditto

You could also write it to always return a dummy module, or to return a dummy module if the specified module hasn't already been loaded (hint: if it's in sys.modules, it has already been loaded).

like image 160
kindall Avatar answered Oct 22 '22 11:10

kindall