Hacking the scope to pieces

H

Hugh Macdonald

We're starting to version a number of our python modules here, and I've
written a small function that assists with loading the versioned
modules...

A module would be called something like: myModule_1_0.py

In anything that uses it, though, we want to be able to refer to it
simply as 'myModule', with an environment variable ("MYMODULE_VERSION"
- set to "1.0") that defines the version.

I've written a module called 'moduleLoader' with the follwing function
in:

def loadModule(module, version, v = globals()):
import compiler
loadStr = "import %s_%s as %s" % (module, version.replace(".", "_"),
module)
eval(compiler.compile(loadStr, "/tmp/%s_%s_errors.txt" % (module,
version.replace(".", "_")), "single"))
v[module] = vars()[module]


The ideal situation with this would be to be able, in whatever script,
to have:

import moduleLoader
moduleLoader.loadModule("myModule", os.getenv("MODULE_VERSION"))


However, this doesn't work. The two options that do work are:

import moduleLoader
moduleLoader.loadModule("myModule", os.getenv("MODULE_VERSION"),
globals())


import moduleLoader
moduleLoader.loadModule("myModule", os.getenv("MODULE_VERSION"))
from moduleLoader import myModule


What I'm after is a way of moduleLoader.loadModule working back up the
scope and placing the imported module in the main global scope. Any
idea how to do this?
 
S

Skip Montanaro

Hugh> What I'm after is a way of moduleLoader.loadModule working back up
Hugh> the scope and placing the imported module in the main global
Hugh> scope. Any idea how to do this?

You want to write an import hook I think. I'd start with the docs for the
__import__ builtin. Also, Google for "python import hook".

Skip
 
H

Hugh Macdonald

Maybe I misunderstood what you meant, but I couldn't quite manage to
get this one working....

My initial hopes about __import__() were that I could define it inside
my new module (moduleLoader) and, when the module is imported, it could
do stuff (like try to hold onto the vars() and globals() from the
importing scope). However, I couldn't get it to import...

The route I've ended up going (which is just about as simple) is just
to return the new module from moduleLoader.loadModule, so my loading
code is:

import moduleLoader
myModule = moduleLoader.loadModule("myModule",
os.getenv("MODULE_VERSION"))

I've also switched over to using 'inp' for this, rather than creating a
compiler string - much nicer....

Anyway, thanks Skip
 
G

gry

Hugh said:
We're starting to version a number of our python modules here, and I've
written a small function that assists with loading the versioned
modules...

A module would be called something like: myModule_1_0.py

In anything that uses it, though, we want to be able to refer to it
simply as 'myModule', with an environment variable ("MYMODULE_VERSION"
- set to "1.0") that defines the version.

Another technique that you might want to consider, is to have an
explicit
"require" call in the code, instead of an external environment
variable.
The python gtk interface, "pygtk", is used like so:

import pygtk
pygtk.require('1.5')
import gtk

-- or

import pygtk
pygtk.require('2.0')
import gtk

I imagine you could eliminate the extra "import gtk" step, by clever
coding of the import hook. You can find pygtk at:

http://ftp.gnome.org/pub/GNOME/sources/pygtk/2.4/pygtk-2.4.1.tar.gz

I've written a module called 'moduleLoader' with the follwing function
in:

def loadModule(module, version, v = globals()):
import compiler
loadStr = "import %s_%s as %s" % (module, version.replace(".", "_"),
module)
eval(compiler.compile(loadStr, "/tmp/%s_%s_errors.txt" % (module,
version.replace(".", "_")), "single"))
v[module] = vars()[module]


The ideal situation with this would be to be able, in whatever script,
to have:

import moduleLoader
moduleLoader.loadModule("myModule", os.getenv("MODULE_VERSION"))


However, this doesn't work. The two options that do work are:

import moduleLoader
moduleLoader.loadModule("myModule", os.getenv("MODULE_VERSION"),
globals())


import moduleLoader
moduleLoader.loadModule("myModule", os.getenv("MODULE_VERSION"))
from moduleLoader import myModule


What I'm after is a way of moduleLoader.loadModule working back up the
scope and placing the imported module in the main global scope. Any
idea how to do this?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top