How can I mimic Python's "import .. as" with code from a text string

Question:

I have a text string, code, containing the complete code for a python module. I know I could write the code to a local file and import it as cm with the following:

with open("codemod.py","w") as f:
    f.write(code)
import codemod as cm

Is there a way do this directly from the code string without creating a local file? Perhaps using importlib or __import()__ or exec()?

I know that exec(code) has the same effect as import codemod, but how do I mimic the import as cm option?

Asked By: holistone

||

Answers:

You can use exec to execute the code in the string:

# Read file
with open('codemod.py', 'r') as f: 
    code = f.read()

# Execute code
exec(code)

However, as you’ve already noticed, this will be running the code in the current namespace and not import it as a module but simply execute it.
If you want to have the code to be imported as a module, you need to create the module by hand and add it to the current namespace yourself:

# Read file
with open('codemod.py', 'r') as f: 
    code = f.read()

import importlib.util as importutil

# Name of module

# Create a new spec for our module
codemod_spec = importutil.spec_from_loader("codemod", loader=None)

# Create a new module codemod
codemod_module = importlib.utils.module_from_spec(codemod_spec)

# Execute the code in the codemod's namespace
exec(code, codemod_module)

# Add module to namespace as 'cm' instead of 'codemod'
globals()['cm'] = codemod_module

# And from now  on out you should be all set
Answered By: lstuma

I can suggest you to first replace the name "codemod" and then apply exec:

exec(code.replace("codemod","cm"))

But it may rename other functions or variables with "codemod" in their name.

Answered By: nicod
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.