osdir.com

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Import module from file path


Hi all,

I'm looking to import a module given a string representing the path to
the .py file defining the module. For example given this setup

mkdir -p a/b/c
touch a/__init__.py
touch a/b/__init__.py
touch a/b/c/__init__.py
touch a/b/c/stuff.py

I have a module a.b.c.stuff which is defined in the file
'/home/oscar/work/project/a/b/c/stuff.py'. Given that a.b.c.stuff is
importable and I have the (relative or absolute) path of stuff.py as a
string I would like to import that module.

I want this to work in 2.7 and 3.4+ and have come up with the
following which works for valid inputs:

import os.path

def import_submodule(filename, rootmodule):
    # Convert from path to module name
    rootdir = os.path.dirname(os.path.dirname(rootmodule.__path__[0]))
    filepath = os.path.relpath(filename, rootdir)
    basename, ext = os.path.splitext(filepath)
    modname = basename.replace('/', '.').replace('\\', '.')
    subattr = modname.split(rootmodule.__name__ + '.')[-1]
    modname = rootmodule.__name__ + '.' + subattr

    # Now import the module
    import importlib
    mod = importlib.import_module(modname)
    return mod

import a
mod = import_submodule('a/b/c/stuff.py', a)
print(dir(mod))

The first part of the above function is the bit that bothers me. I
think there are ways that it could import and run the wrong code if
accidentally given the wrong input (malevolent input is unimportant
here). Also it seems as if there should be a simpler way to get from
the path to the module name...

Cheers,
Oscar