def ast_scan_file(filename, re_fallback=True):
    '''Scans a file for imports using AST.

    In addition to normal imports, try to get imports via `__import__`
    or `import_module` calls. The AST parser should be able to resolve
    simple variable assignments in cases where these functions are called
    with variables instead of strings.
    '''
    try:
        with io.open(filename, 'rb') as fp:
            try:
                root = ast.parse(fp.read(), filename=filename)
            except (SyntaxError, IndentationError):
                if re_fallback:
                    log.debug('Falling back to regex scanner')
                    return _ast_scan_file_re(filename)
                else:
                    log.error('Could not parse file: %s', filename)
                    log.info('Exception:', exc_info=True)
                return None, None
            log.debug('Starting AST Scan: %s', filename)
            ast_visitor.reset(filename)
            ast_visitor.visit(root)
            log.debug('Project path: %s', ast_visitor.import_root)
            return ast_visitor.scope, ast_visitor.imports
    except IOError:
        log.warn('Could not open file: %s', filename)

    return None, None
Scans a file for imports using AST.

    In addition to normal imports, try to get imports via `__import__`
    or `import_module` calls. The AST parser should be able to resolve
    simple variable assignments in cases where these functions are called
    with variables instead of strings.