Import arbitrary python source file. (Python 3.3+)
python, python-3.3, python-3.x
Solution
Found a solution from `importlib` test code.
Using importlib.machinery.SourceFileLoader:
>>> import importlib.machinery
>>> loader = importlib.machinery.SourceFileLoader('a_b', '/tmp/a-b.txt')
>>> mod = loader.load_module()
>>> mod
<module 'a_b' from '/tmp/a-b.txt'>
NOTE: only works in Python 3.3+.
UPDATE `Loader.load_module` is deprecated since Python 3.4. Use `Loader.exec_module` instead:
>>> import types
>>> import importlib.machinery
>>> loader = importlib.machinery.SourceFileLoader('a_b', '/tmp/a-b.txt')
>>> mod = types.ModuleType(loader.name)
>>> loader.exec_module(mod)
>>> mod
<module 'a_b'>
>>> import importlib.machinery
>>> import importlib.util
>>> loader = importlib.machinery.SourceFileLoader('a_b', '/tmp/a-b.txt')
>>> spec = importlib.util.spec_from_loader(loader.name, loader)
>>> mod = importlib.util.module_from_spec(spec)
>>> loader.exec_module(mod)
>>> mod
<module 'a_b' from '/tmp/a-b.txt'>
Problem
How can I import an arbitrary python source file (whose filename could contain any characters, and does not always ends with `.py`) in Python 3.3+? I used `imp.load_module` as follows: ``` >>> import imp >>> path = '/tmp/a-b.txt' >>> with open(path, 'U') as f: ... mod = imp.load_module('a_b', f, path, ('.py', 'U', imp.PY_SOURCE)) ... >>> mod <module 'a_b' from '/tmp/a-b.txt'> ``` It still works in Python 3.3, but according to `imp.load_module` documentation, it is deprecated: Deprecated since version 3.3: Unneeded as loaders should be used to load modules and find_module() is deprecated. and `imp` module documentation recommends to use `importlib`: Note New programs should use importlib rather than this module. What is the proper way to load an arbitrary python source file in Python 3.3+ without using the deprecated `imp.load_module` function?