Python exec and __name__

exec, python, scope

Solution

You could use `imp.load_module` instead:

import imp

with open(mainfile) as src:
    imp.load_module('__main__', src, mainfile, (".py", "r", imp.PY_SOURCE))

This imports the file as the `__main__` module, executing it.

Note that it takes an actual file object when the type is set to `imp.PY_SOURCE`, so you'd need to create a temporary file for this to work if your source code comes from somewhere other than a file.

Otherwise, can always set `__name__` manually:

>>> src = '''\
... if __name__ == '__main__': print('Main!')
... else: print('Damn', __name__)
... '''
>>> exec(src)
Main!
>>> exec(src, {})
Damn builtins
>>> exec(src, {'__name__':'__main__'})
Main!

Problem

When I run: ``` exec("print(__name__)") ``` it prints `__main__`. But when I run: ``` exec("print __name__", {}) ``` it prints `builtins`. How to make the second example to also print `__main__`? What I try to achieve is to run a piece of code with `exec()` so that from the perspective of the it looks like it was run from command line. I would like to tun the code with clean scope but the second example breaks the code relying on `if __name__ == "__main__"`. How to fix this?

Original source