["python","python-3.x","python-3.3"]
Import arbitrary python source file. (Python 3.3+)

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?
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'>