special case loading modules with imp

Irmen de Jong irmen at -NOSPAM-REMOVETHIS-xs4all.nl
Thu Jul 31 00:41:15 CEST 2003


Steven Taschuk wrote:

> I was going to suggest StringIO, but it turns out imp.load_module
> wants a real file, not merely something file-like.
> 
> However, you can always do it by hand:
> 
>     >>> import imp  
>     >>> sourcecode = 'def foo(x): return 11*x' 
>     >>> mod = imp.new_module('foo')
>     >>> exec sourcecode in mod.__dict__
>     >>> mod.foo(16)
>     176

Heh, that's cool.
That looks like what I'm doing in Pyro to load (and import)
'mobile code' that is sent from one computer to another.

However I do it a bit different, partly because it's not always
the *source* that gets loaded: if the .pyc bytecodes are available,
those are loaded instead. Also, I stuff the modules into sys.modules
because they have to be found by regular import statements after
they're loaded.

So I'm doing:

--------- code snippet from Pyro ------------
name="not.yet.existing.module"
module=<received module source or .pyc bytecode>

import imp,marshal,new
name=name.split('.')
path=''
mod=new.module("pyro-agent-context")

for m in name:
	path+='.'+m
	# use already loaded modules instead of overwriting them
	real_path = path[1:]
	if sys.modules.has_key(real_path):
		mod = sys.modules[real_path]
	else:
		setattr(mod,m,new.module(path[1:]))
		mod=getattr(mod,m)
		sys.modules[path[1:]]=mod
	
if module[0:4]!=imp.get_magic():
	# compile source code
	code=compile(module,'<downloaded>','exec')
else:
	# read bytecode from the client
	code=marshal.loads(module[8:])
# finally, execute the module code in the right module.
exec code in mod.__dict__
--------- end code snippet from Pyro ------------


It works, but I'm not too fond of the bytecode 'tricks'...

--Irmen





More information about the Python-list mailing list