def getPaths(roots, ignores=None):
paths, count, ignores = [], <NUM_LIT:0>, ignores or []<EOL>ignore_re = multiglob_compile(ignores, prefix=False)<EOL>for root in roots:<EOL><INDENT>root = os.path.realpath(root)<EOL>if os.path.isfile(root):<EOL><INDENT>paths.append(root)<EOL>continue<EOL><DEDENT>for fldr in os.walk(root):<EOL><INDENT>out.write("<STR_LIT>"<EOL>% count)<EOL>for subdir in fldr[<NUM_LIT:1>]:<EOL><INDENT>dirpath = os.path.join(fldr[<NUM_LIT:0>], subdir)<EOL>if ignore_re.match(dirpath):<EOL><INDENT>fldr[<NUM_LIT:1>].remove(subdir)<EOL><DEDENT><DEDENT>for filename in fldr[<NUM_LIT:2>]:<EOL><INDENT>filepath = os.path.join(fldr[<NUM_LIT:0>], filename)<EOL>if ignore_re.match(filepath):<EOL><INDENT>continue  <EOL><DEDENT>paths.append(filepath)<EOL>count += <NUM_LIT:1><EOL><DEDENT><DEDENT><DEDENT>out.write("<STR_LIT>" % (len(paths)),<EOL>newline=True)<EOL>return paths<EOL>
Recursively walk a set of paths and return a listing of contained files.

:param roots: Relative or absolute paths to files or folders.
:type roots: :class:`~__builtins__.list` of :class:`~__builtins__.str`

:param ignores: A list of :py:mod:`fnmatch` globs to avoid walking and
    omit from results
:type ignores: :class:`~__builtins__.list` of :class:`~__builtins__.str`

:returns: Absolute paths to only files.
:rtype: :class:`~__builtins__.list` of :class:`~__builtins__.str`

.. todo:: Try to optimize the ignores matching. Running a regex on every
   filename is a fairly significant percentage of the time taken according
   to the profiler.