Skip to content

Instantly share code, notes, and snippets.

@tgarc
Created February 2, 2017 21:06
Show Gist options
  • Select an option

  • Save tgarc/45fcdee4597dc1fc724b135f76fea3ba to your computer and use it in GitHub Desktop.

Select an option

Save tgarc/45fcdee4597dc1fc724b135f76fea3ba to your computer and use it in GitHub Desktop.

Revisions

  1. tgarc created this gist Feb 2, 2017.
    54 changes: 54 additions & 0 deletions findfile.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,54 @@
    import os
    import glob
    import errno
    try:
    from itertools import ifilter as filter
    except ImportError:
    pass

    def findfile(filepath, find_all, search_path='', recursive=False, allowglob=False, rel_path='.', follow_links=False):
    filelist = []

    # first expand user; we want user relative paths to be considered
    # same as absolute paths
    filepath = os.path.expanduser(filepath)

    # For absolute paths, add any existing matches
    if os.path.isabs(filepath):
    if allowglob:
    filelist.extend(glob.iglob(filepath))
    else:
    filelist.append(filepath)
    # This is an 'explicity' relative path, consider it relative to rel_path
    elif os.path.dirname(filepath) != '':
    filepath = os.path.join(os.path.abspath(rel_path), filepath)
    if allowglob:
    filelist.extend(glob.iglob(filepath))
    else:
    filelist.append(filepath)
    # This has no explicit relative path component, so we can search
    # for this on the search_path
    elif search_path:
    for pathcmp in search_path.split(os.path.pathsep):
    for root, dirs, files in os.walk(pathcmp, followlinks=follow_links):
    root = os.path.abspath(root)
    if allowglob:
    filelist.extend(glob.iglob(os.path.join(root, filepath)))
    else:
    pathmatch = os.path.join(root, filepath)
    if not find_all and os.path.isfile(pathmatch):
    return pathmatch # for speed's sake, return here
    filelist.append(pathmatch)
    if not recursive: break

    # filter out non-existent and non-file matches
    filelist = list(filter(os.path.isfile, filelist))

    # For convenience, we have the somewhat odd behavior that when
    # searching for a single match (find_all=False) we raise an error
    # when no match is found. OTOH, we stay silent if we're returning
    # a list of matches
    if not (find_all or filelist):
    raise IOError(errno.ENOENT, "No match found for expression: '%s'" % filepath)

    return filelist if find_all else filelist[0]