0

I'm very new to python. Here is the problem Im having. I have hooked the builtin._import_ with my custom hook which loads a module from a string.

def import_hook(name, globals=None, locals=None, fromlist=None):
    if name in sys.modules:
            obj = sys.modules[name]
            return obj
    #Make sure we hook only for modules which start with ajay    
    if name.startswith("ajay"):
        statement = '''
print 'inside the ajay module'
def ajay_func():
    print 'inside the func'
'''
        mod = imp.new_module(name)
        mod.__file__ = name
        compiled = compile(statement, '<string>', 'exec')
        exec compiled in mod.__dict__
        sys.modules[name] = mod
        return mod

    return original_import(name, globals, locals, fromlist)

Then I use this hook in function which is loading a module and calling its function in exec statement.

original_import = __builtin__.__import__
def test(request):
    statement = '''
import sys
import ajay
def ILessons_1(request):
    ajay.ajay_func()
'''
    try:
        __builtin__.__import__ = import_hook
        compiled = compile(statement, '<string>', 'exec')
        exec (compiled, globals(), locals())  #in statement_module.__dict__
        ajay.ajay_func()
        return ILessons_1(request);
    finally:
        __builtin__.__import__ = original_import 
        pass 

When I run this code I get error "global name 'ajay' is not defined"in line "return ILessons_1(request);". Interesting thing is python is able to resolve ajay in line just above this line. Im pretty sure Im making some mistake in exec statement but have not been able to figure out.

Can some please help me solve this problem. Thanks

ajay singh
  • 135
  • 1
  • 7

1 Answers1

0

Noted few issues here:

1) globals and locals are built-in function names, You should not use them as variable names.

2) Possibly a bug? (tested with python 2.7.1 under ubuntu)

Consider following code (note the exec statement):

def outer_function():
    foo = "foobar"
    statement = '''
def inner_function():
    print foo
'''
    #exec statement in globals(), locals()
    exec statement in globals().update(locals())
    inner_function()

outer_function()

Here commented string (exec with 2 arguments after in) will not work as described at in the documentation and result in:

NameError: global name 'foo' is not defined

But one may manually combine globals+locals an pass them to exec (next string after comment in my example). Looks like a workaround to me.

Michael Dillon
  • 1,037
  • 6
  • 16
yan
  • 196
  • 1
  • 9