Example #1
0
def parse_submodule_definition(modpath):
    """
    Statically determine the submodules that should be auto-imported
    """
    # the __init__ file may have a variable describing the correct imports
    # should imports specify the name of this variable or should it always
    # be __submodules__?
    imports = None
    init_fpath = join(modpath, '__init__.py')
    if exists(init_fpath):
        with open(init_fpath, 'r') as file:
            source = file.read()
        try:
            imports = static.parse_static_value('__submodules__', source)
        except NameError:
            try:
                imports = static.parse_static_value('__SUBMODULES__', source)
            except NameError:
                pass
    return imports
Example #2
0
def parse_user_declarations(modpath):
    """
    Statically determine special file-specific user options and declarations
    """
    # the __init__ file may have a variable describing the correct imports
    # should imports specify the name of this variable or should it always be
    # __submodules__?
    user_decl = {}

    init_fpath = join(modpath, '__init__.py')
    if exists(init_fpath):
        with open(init_fpath, 'r') as file:
            source = file.read()
        try:
            # Include only these submodules
            user_decl['__submodules__'] = static.parse_static_value('__submodules__', source)
        except NameError:
            try:
                user_decl['__submodules__'] = static.parse_static_value('__SUBMODULES__', source)
            except NameError:
                pass
            else:
                warnings.warn(
                    'Use __submodules__, __SUBMODULES__ is depricated',
                    DeprecationWarning)

        try:
            user_decl['__explicit__'] = static.parse_static_value('__extra_all__', source)
        except NameError:
            pass

        try:
            user_decl['__external__'] = static.parse_static_value('__external__', source)
        except NameError:
            pass

        try:
            # Add custom explicitly defined names to this, and they will be
            # automatically added to the __all__ variable.
            user_decl['__explicit__'] = static.parse_static_value('__explicit__', source)
        except NameError:
            pass

        try:
            # Procted items are exposed, but their attributes are not
            user_decl['__protected__'] = static.parse_static_value('__protected__', source)
        except NameError:
            pass

        try:
            # Private items and their attributes are not exposed
            user_decl['__private__'] = static.parse_static_value('__private__', source)
        except NameError:
            pass
    return user_decl
Example #3
0
def _extract_attributes(modpath, respect_all=True):
    """
    This is the function that basically simulates import *

    Example:
        >>> modpath = static.modname_to_modpath('mkinit', hide_init=False)
        >>> modpath = static.modname_to_modpath('ubelt.util_path', hide_init=False)
        >>> _extract_attributes(modpath)
    """
    try:
        if six.PY2:
            with open(modpath, 'r') as file:
                source = file.read()
        else:
            with open(modpath, 'r', encoding='utf8') as file:
                source = file.read()
    except Exception as ex:  # nocover
        raise IOError('Error reading {}, caused by {}'.format(
            modpath, repr(ex)))
    valid_attrs = None
    if respect_all:  # pragma: nobranch
        try:
            valid_attrs = static.parse_static_value('__all__', source)
        except NameError:
            pass
    if valid_attrs is None:
        # The __all__ variable is not specified or we dont care
        try:
            top_level = TopLevelVisitor.parse(source)
        except SyntaxError as ex:
            msg = 'modpath={} has bad syntax: {}'.format(modpath, ex)
            raise SyntaxError(msg)
        attrnames = top_level.attrnames
        # list of names we wont export by default
        invalid_callnames = dir(builtins)
        valid_attrs = []
        for attr in attrnames:
            if attr.startswith('_'):
                continue
            if attr in invalid_callnames:  # nocover
                continue
            valid_attrs.append(attr)
    return valid_attrs
Example #4
0
def _static_parse_imports(modpath, imports=None, use_all=True):
    """
    Args:
        modpath (str): base path to a package (with an __init__)
        imports (list): list of submodules to look at in the base package

    CommandLine:
        python -m mkinit.static_autogen _static_parse_imports

    Example:
        >>> modpath = static.modname_to_modpath('mkinit')
        >>> tup = _static_parse_imports(modpath, None, True)
        >>> modname, imports, from_imports = tup
        >>> # assert 'autogen_init' in imports
    """
    # FIXME: handle the case where the __init__.py file doesn't exist yet
    modname = static.modpath_to_modname(modpath, check=False)
    if imports is not None:
        if modname is None:
            raise AssertionError('modname is None')
        import_paths = {
            m: static.modname_to_modpath(modname + '.' + m, hide_init=False)
            for m in imports
        }
    else:
        import_paths = dict(_find_local_submodules(modpath))
        imports = sorted(import_paths.keys())

    from_imports = []
    for rel_modname in imports:
        sub_modpath = import_paths[rel_modname]
        if sub_modpath is None:
            raise Exception('Failed to lookup {!r}'.format(rel_modname))
        try:
            if six.PY2:
                with open(sub_modpath, 'r') as file:
                    source = file.read()
            else:
                with open(sub_modpath, 'r', encoding='utf8') as file:
                    source = file.read()
        except Exception as ex:  # nocover
            raise IOError('Error reading {}, caused by {}'.format(
                sub_modpath, repr(ex)))
        valid_attrs = None
        if use_all:  # pragma: nobranch
            try:
                valid_attrs = static.parse_static_value('__all__', source)
            except NameError:
                pass
        if valid_attrs is None:
            # The __all__ variable is not specified or we dont care
            top_level = TopLevelVisitor.parse(source)
            attrnames = top_level.attrnames
            # list of names we wont export by default
            invalid_callnames = dir(builtins)
            valid_attrs = []
            for attr in attrnames:
                if attr.startswith('_'):
                    continue
                if attr in invalid_callnames:  # nocover
                    continue
                valid_attrs.append(attr)
        from_imports.append((rel_modname, sorted(valid_attrs)))
    return modname, imports, from_imports