diff --git a/IPython/utils/module_paths.py b/IPython/utils/module_paths.py index f984580..d50df80 100644 --- a/IPython/utils/module_paths.py +++ b/IPython/utils/module_paths.py @@ -2,14 +2,7 @@ Utility functions for finding modules on sys.path. -`find_mod` finds named module on sys.path. - -`get_init` helper function that finds __init__ file in a directory. - -`find_module` variant of imp.find_module in std_lib that only returns -path to module and not an open file object as well. - - +`find_module` returns a path to module or None, given certain conditions. """ #----------------------------------------------------------------------------- @@ -25,7 +18,7 @@ path to module and not an open file object as well. #----------------------------------------------------------------------------- # Stdlib imports -import imp +import importlib import os # Third-party imports @@ -44,81 +37,34 @@ import os #----------------------------------------------------------------------------- # Classes and functions #----------------------------------------------------------------------------- -def find_module(name, path=None): - """imp.find_module variant that only return path of module. - - The `imp.find_module` returns a filehandle that we are not interested in. - Also we ignore any bytecode files that `imp.find_module` finds. - - Parameters - ---------- - name : str - name of module to locate - path : list of str - list of paths to search for `name`. If path=None then search sys.path - Returns - ------- - filename : str - Return full path of module or None if module is missing or does not have - .py or .pyw extension - """ - if name is None: - return None - try: - file, filename, _ = imp.find_module(name, path) - except ImportError: - return None - if file is None: - return filename - else: - file.close() - if os.path.splitext(filename)[1] in [".py", ".pyc"]: - return filename - else: - return None - -def get_init(dirname): - """Get __init__ file path for module directory - - Parameters - ---------- - dirname : str - Find the __init__ file in directory `dirname` - - Returns - ------- - init_path : str - Path to __init__ file +def find_mod(module_name): """ - fbase = os.path.join(dirname, "__init__") - for ext in [".py", ".pyw"]: - fname = fbase + ext - if os.path.isfile(fname): - return fname + Find module `module_name` on sys.path, and return the path to module `module_name`. + - If `module_name` refers to a module directory, then return path to __init__ file. + - If `module_name` is a directory without an __init__file, return None. + - If module is missing or does not have a `.py` or `.pyw` extension, return None. + - Note that we are not interested in running bytecode. + - Otherwise, return the fill path of the module. -def find_mod(module_name): - """Find module `module_name` on sys.path - - Return the path to module `module_name`. If `module_name` refers to - a module directory then return path to __init__ file. Return full - path of module or None if module is missing or does not have .py or .pyw - extension. We are not interested in running bytecode. - Parameters ---------- module_name : str Returns ------- - modulepath : str - Path to module `module_name`. + module_path : str + Path to module `module_name`, its __init__.py, or None, + depending on above conditions. """ - parts = module_name.split(".") - basepath = find_module(parts[0]) - for submodname in parts[1:]: - basepath = find_module(submodname, [basepath]) - if basepath and os.path.isdir(basepath): - basepath = get_init(basepath) - return basepath + loader = importlib.util.find_spec(module_name) + module_path = loader.origin + if module_path is None: + return None + else: + split_path = module_path.split(".") + if split_path[1] in ["py", "pyw"]: + return module_path + else: + return None diff --git a/IPython/utils/tests/test_module_paths.py b/IPython/utils/tests/test_module_paths.py index 5b24647..b315c69 100644 --- a/IPython/utils/tests/test_module_paths.py +++ b/IPython/utils/tests/test_module_paths.py @@ -66,62 +66,42 @@ def teardown(): shutil.rmtree(TMP_TEST_DIR) sys.path = old_syspath - -def test_get_init_1(): - """See if get_init can find __init__.py in this testdir""" - with make_tempfile(join(TMP_TEST_DIR, "__init__.py")): - assert mp.get_init(TMP_TEST_DIR) - -def test_get_init_2(): - """See if get_init can find __init__.pyw in this testdir""" - with make_tempfile(join(TMP_TEST_DIR, "__init__.pyw")): - assert mp.get_init(TMP_TEST_DIR) - -def test_get_init_3(): - """get_init can't find __init__.pyc in this testdir""" - with make_tempfile(join(TMP_TEST_DIR, "__init__.pyc")): - nt.assert_is_none(mp.get_init(TMP_TEST_DIR)) - -def test_get_init_4(): - """get_init can't find __init__ in empty testdir""" - nt.assert_is_none(mp.get_init(TMP_TEST_DIR)) - - def test_find_mod_1(): + """ + Search for a directory's file path. + Expected output: a path to that directory's __init__.py file. + """ modpath = join(TMP_TEST_DIR, "xmod", "__init__.py") nt.assert_equal(mp.find_mod("xmod"), modpath) def test_find_mod_2(): + """ + Search for a directory's file path. + Expected output: a path to that directory's __init__.py file. + TODO: Confirm why this is a duplicate test. + """ modpath = join(TMP_TEST_DIR, "xmod", "__init__.py") nt.assert_equal(mp.find_mod("xmod"), modpath) def test_find_mod_3(): + """ + Search for a directory + a filename without its .py extension + Expected output: full path with .py extension. + """ modpath = join(TMP_TEST_DIR, "xmod", "sub.py") nt.assert_equal(mp.find_mod("xmod.sub"), modpath) def test_find_mod_4(): + """ + Search for a filename without its .py extension + Expected output: full path with .py extension + """ modpath = join(TMP_TEST_DIR, "pack.py") nt.assert_equal(mp.find_mod("pack"), modpath) def test_find_mod_5(): - modpath = join(TMP_TEST_DIR, "packpyc.pyc") - nt.assert_equal(mp.find_mod("packpyc"), modpath) - -def test_find_module_1(): - modpath = join(TMP_TEST_DIR, "xmod") - nt.assert_equal(mp.find_module("xmod"), modpath) - -def test_find_module_2(): - """Testing sys.path that is empty""" - nt.assert_is_none(mp.find_module("xmod", [])) - -def test_find_module_3(): - """Testing sys.path that is empty""" - nt.assert_is_none(mp.find_module(None, None)) - -def test_find_module_4(): - """Testing sys.path that is empty""" - nt.assert_is_none(mp.find_module(None)) - -def test_find_module_5(): - nt.assert_is_none(mp.find_module("xmod.nopack")) + """ + Search for a filename with a .pyc extension + Expected output: TODO: do we exclude or include .pyc files? + """ + nt.assert_equal(mp.find_mod("packpyc"), None)