How to generate a module object from a code object in Python

bytecode, python

Solution

As a comment already indicates, in today's Python the preferred way to instantiate types that don't have built-in names is to call the type obtained via the types module from the standard library:

>>> import types
>>> m = types.ModuleType('m', 'The m module')

note that this does not automatically insert the new module in `sys.modules`:

>>> import sys
>>> sys.modules['m']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'm'

That's a task you must perform by hand:

>>> sys.modules['m'] = m
>>> sys.modules['m']
<module 'm' (built-in)>

This can be important, since a module's code object normally executes after the module's added to `sys.modules` -- for example, it's perfectly correct for such code to refer to `sys.modules[__name__]`, and that would fail (`KeyError`) if you forgot this step. After this step, and setting `m.__file__` as you already have in your edit,

>>> code = compile("a=23", "m.py", "exec")
>>> exec code in m.__dict__
>>> m.a
23

(or the Python 3 equivalent where `exec` is a function, if Python 3 is what you're using, of course;-) is correct (of course, you'll normally have obtained the code object by subtler means than compiling a string, but that's not material to your question;-).

In older versions of Python you would have used the `new` module instead of the `types` module to make a new module object at the start, but `new` is deprecated since Python 2.6 and removed in Python 3.

Problem

Given that I have the code object for a module, how do I get the corresponding module object? It looks like `moduleNames = {}; exec code in moduleNames` does something very close to what I want. It returns the globals declared in the module into a dictionary. But if I want the actual module object, how do I get it? EDIT: It looks like you can roll your own module object. The module type isn't conveniently documented, but you can do something like this: ``` import sys module = sys.__class__ del sys foo = module('foo', 'Doc string') foo.__file__ = 'foo.pyc' exec code in foo.__dict__ ```

Original source