Args:
        modname (str): module name

    Tutorial:
        Replacement for
        from modname import *

        Usage is like this
        globals().update(ut.import_star('<module>'))
        OR
        ut.import_star('<module>', __name__)

    Ignore:
        >>> from utool.util_import import *  # NOQA
        modname = 'opengm'
        submod = None
        parent = __name__

def import_star(modname, parent=None):
    """
    Args:
        modname (str): module name

    Tutorial:
        Replacement for
        from modname import *

        Usage is like this
        globals().update(ut.import_star('<module>'))
        OR
        ut.import_star('<module>', __name__)

    Ignore:
        >>> from utool.util_import import *  # NOQA
        modname = 'opengm'
        submod = None
        parent = __name__
    """
    import six
    from os.path import dirname
    if parent is None:
        parent_module = None
    else:
        parent_module = sys.modules[parent]
        if isinstance(parent, six.string_types):
            parent_module = sys.modules[parent]
        else:
            raise ValueError('parent must be the module __name__ attribute')

    try:
        module = sys.modules[modname]
    except KeyError:
        try:
            module = __import__(modname, {}, {}, fromlist=[], level=0)
        except ImportError:
            if parent_module is None:
                print('Maybe try specifying parent?')
                raise
            # Inject into the parent if given
            # Temporilly put this module dir in the pythonpath to simulate
            # relative imports
            relative_to = dirname(parent_module.__file__)
            sys.path.append(relative_to)
            try:
                module = __import__(modname, {}, {}, fromlist=[], level=0)
            except Exception:
                raise
            finally:
                sys.path.pop()
    # get public attributes
    module_attrs = [attr for attr in dir(module) if not attr.startswith('_')]
    module_vars = {attr: getattr(module, attr) for attr in module_attrs}
    if parent is not None:
        # Inject into the parent if given
        if isinstance(parent, six.string_types):
            parent_module = sys.modules[parent]
            for attr, var in module_vars.items():
                setattr(parent_module, attr, var)
        else:
            raise ValueError('parent must be the module __name__ attribute')
    # return the module dictionary
    return module_vars