4

A solution for this problem is available for Python 2, but it uses the imp module which is deprecated in Python 3.

imp has been replaced by importlib which works well for file based imports. Specifically, importlib.import_module requires a file name - not a string or a file handler.

I made a workaround by dumping the contents of the URL to a file and importing it

def initlog():
    modulename = '_mylogging'
    try:
        import _mylogging
    except ImportError:
        r = requests.get('http://(...)/mylogging.py')
        with open(modulename+'.py', "w") as f:
            f.write(r.text)
    finally:
        import _mylogging

    return _mylogging.MYLogging().getlogger()

but I would like to avoid the intermediate file.

Putting the security, network performance and availability issues aside - is there a way to feed a string to importlib? (or from a file handler, in which case I would use io.StringIO)

0

1 Answer 1

4

You can adapt exactly the same answer to 3.x, using the replacement for imp.new_module:

from types import ModuleType

foo = ModuleType('foo')

and the replacement for the exec statement:

foo_code = """
class Foo:
    pass
"""

exec(foo_code, globals(), foo.__dict__)

After which everything works as expected:

>>> dir(foo)
['Foo', '__doc__', '__loader__', '__name__', '__package__', '__spec__']
>>> foo.Foo()
<__main__.Foo object at 0x110546ba8>
Sign up to request clarification or add additional context in comments.

1 Comment

But, the recipe didn't work for me until I changed <pre><code> exec(foo_code, foo.__dict__, foo.__dict__) </code></pre>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.