Turn path with opt. globbing into valid list of files respecting
    include and exclude patterns.
    
    Parameters
    ----------
    path : str
        Path to process. Can be location of a file, folder or glob.
        Can be in uri-notation, can be relative or absolute or start with ~.
    include : list, optional
        Globbing patterns to require in result, defaults to ['*', '.*'].
    exclude : list, optional
        Globbing patterns to exclude from result, defaults to ['.*', '_*'].
    
    Returns
    -------
    objs : list
        List of valid files
    
    Notes
    -----
    - Doesn't show hidden files starting with '.' by default. To enable hidden files, make sure '.*' is in `include` and '.*' is not in `exclude`.
    - Doesn't show files starting with '_' by default. To enable these files, make sure '_*' is not in `exclude`.

def _path_to_objs(path, include=['*', '.*'], exclude=['.*', '_*']):
    """Turn path with opt. globbing into valid list of files respecting
    include and exclude patterns.
    
    Parameters
    ----------
    path : str
        Path to process. Can be location of a file, folder or glob.
        Can be in uri-notation, can be relative or absolute or start with ~.
    include : list, optional
        Globbing patterns to require in result, defaults to ['*', '.*'].
    exclude : list, optional
        Globbing patterns to exclude from result, defaults to ['.*', '_*'].
    
    Returns
    -------
    objs : list
        List of valid files
    
    Notes
    -----
    - Doesn't show hidden files starting with '.' by default. To enable hidden files, make sure '.*' is in `include` and '.*' is not in `exclude`.
    - Doesn't show files starting with '_' by default. To enable these files, make sure '_*' is not in `exclude`.
    """
    
    if '://' in path:
        # don't modify when path is in uri-notation, except for local files
        if path.startswith('file://'):
            path = path[7:]
        else:
            return [path]
    
    path = os.path.abspath(os.path.expanduser(path))
    
    if os.path.isfile(path):
        if not path.lower().endswith(('.xlsx', '.xls')) and zipfile.is_zipfile(path):
            # zipfile misidentifies xlsx as archive of xml files
            with zipfile.ZipFile(path) as myzip:
                zipped = []
                for z in myzip.namelist():
                    z_fn = os.path.basename(z)
                    if z_fn != '' and any([fnmatch(z_fn, i) for i in include]) and \
                        not any([fnmatch(z_fn, e) for e in exclude]):
                        zipped.append(z)
                return [myzip.open(z) for z in zipped]
        else:
            return [path]
    elif os.path.isdir(path):
        cands = [os.path.abspath(os.path.join(path, p)) for p in os.listdir(path)]
        dirname = path
    else:
        cands = []
        dirname = os.path.dirname(path)
    
    include = list(chain.from_iterable(glob(os.path.join(dirname, i)) for i in include))
    exclude = list(chain.from_iterable(glob(os.path.join(dirname, e)) for e in exclude))
    
    objs = []
    if cands == []:
        cands = glob(path)
    for p in cands:
        if os.path.isfile(p) and p in include and not p in exclude:
            objs.append(p)
    
    zipped = [zipfile.is_zipfile(o) and not o.lower().endswith(('.xlsx', '.xls')) \
        for o in objs]
    toappend = []
    todelete = []
    
    for ix, o in enumerate(objs):
        # if zipfile in objs replace zipfile with its contents
        if zipped[ix]:
            for new_o in _path_to_objs(o):
                toappend.append(new_o)
            todelete.append(ix)
    
    shiftindex = 0
    for d in todelete:
        del objs[d - shiftindex]
        shiftindex += 1
    
    for new_o in toappend:
        objs.append(new_o)
    
    return objs