
    obUk                        d Z ddlmZ ddlZddlmZmZmZ ddlm	Z	 ddl
mZ ddlmZmZmZ ej                   r-dd	lmZmZmZmZmZmZmZmZmZmZ dd
lmZ ddlmZ eeege f   Z! ejD                  dd      Z# edd      Z$	  G d de%      Z& G d dejN                  e#         Z( e&       Z)e)jT                  Z*e)jV                  Z,e)j:                  Z-e)j\                  Z/y)zMachinery for walking a filesystem.

*Walking* a filesystem means recursively visiting a directory and
any sub-directories. It is a fairly common requirement for copying,
searching etc. See :ref:`walking` for details.
    )unicode_literalsN)defaultdictdeque
namedtuple   )	make_repr)FSError)abspathcombinenormpath)
AnyCallable
CollectionIteratorListMutableMappingOptionalTextTupleType)FS)Info_Fr   )boundStepzpath, dirs, filesc                        e Zd ZdZ	 	 	 	 	 	 	 	 d fd	Zed        Zed        Zed        Zed        Z	d Z
	 ddZd	 Zd
 Zd Zd Zd Z	 ddZ	 	 ddZddZddZ	 	 ddZ	 ddZ	 ddZ xZS )Walkerz>A walker object recursively lists directories in a filesystem.c	                 6   |dvrt        d      || _        |r|r%t        d      |r| j                  n| j                  }t	        |      st        d      || _        || _        || _        || _	        || _
        || _        || _        t        t        | ?          y)a-  Create a new `Walker` instance.

        Arguments:
            ignore_errors (bool): If `True`, any errors reading a
                directory will be ignored, otherwise exceptions will
                be raised.
            on_error (callable, optional): If ``ignore_errors`` is `False`,
                then this callable will be invoked for a path and the
                exception object. It should return `True` to ignore the error,
                or `False` to re-raise it.
            search (str): If ``"breadth"`` then the directory will be
                walked *top down*. Set to ``"depth"`` to walk *bottom up*.
            filter (list, optional): If supplied, this parameter should be
                a list of filename patterns, e.g. ``["*.py"]``. Files will
                only be returned if the final component matches one of the
                patterns.
            exclude (list, optional): If supplied, this parameter should be
                a list of filename patterns, e.g. ``["~*"]``. Files matching
                any of these patterns will be removed from the walk.
            filter_dirs (list, optional): A list of patterns that will be used
                to match directories paths. The walk will only open directories
                that match at least one of these patterns.
            exclude_dirs (list, optional): A list of patterns that will be
                used to filter out directories from the walk. e.g.
                ``['*.svn', '*.git']``.
            max_depth (int, optional): Maximum directory depth to walk.

        )breadthdepthz#search must be 'breadth' or 'depth'z,on_error is invalid when ignore_errors==Truezon_error must be callableN)
ValueErrorignore_errors_ignore_errors_raise_errorscallable	TypeErroron_errorsearchfilterexcludefilter_dirsexclude_dirs	max_depthsuperr   __init__)
selfr"   r'   r(   r)   r*   r+   r,   r-   	__class__s
            )/usr/lib/python3/dist-packages/fs/walk.pyr/   zWalker.__init__5   s    P --BCC* !OPP.;t**ASASH!788 &("fd$&    c                      y)z#Ignore dir scan errors when called.T clspatherrors      r2   r#   zWalker._ignore_errorsq   s     r3   c                      y)z%Re-raise dir scan errors when called.Fr5   r6   s      r2   r$   zWalker._raise_errorsw   s     r3   c                 T    |j                  d      }|r|j                  d      dz   S dS )zBCalculate the 'depth' of a directory path (i.e. count components)./r   r   )stripcount)r7   r8   _paths      r2   _calculate_depthzWalker._calculate_depth}   s,     

3',u{{3!#3!3r3   c                     t        |      S )a  Bind a `Walker` instance to a given filesystem.

        This *binds* in instance of the Walker to a given filesystem, so
        that you won't need to explicitly provide the filesystem as a
        parameter.

        Arguments:
            fs (FS): A filesystem object.

        Returns:
            ~fs.walk.BoundWalker: a bound walker.

        Examples:
            Use this method to explicitly bind a filesystem instance::

                >>> walker = Walker.bind(my_fs)
                >>> for path in walker.files(filter=['*.py']):
                ...     print(path)
                /foo.py
                /bar.py

            Unless you have written a customized walker class, you will
            be unlikely to need to call this explicitly, as filesystem
            objects already have a ``walk`` attribute which is a bound
            walker object::

                >>> for path in my_fs.walk.files(filter=['*.py']):
                ...     print(path)
                /foo.py
                /bar.py

        )BoundWalker)r7   fss     r2   bindzWalker.bind   s    F 2r3   c                    t        | j                  j                  | j                  df| j                  d f| j
                  df| j                  d f| j                  d f| j                  d f| j                  d f| j                  d f	      S )NFr   )r"   r'   r(   r)   r*   r+   r,   r-   )r   r1   __name__r"   r'   r(   r)   r*   r+   r,   r-   r0   s    r2   __repr__zWalker.__repr__   s    NN##--u5mmT*KK+KK&\\4())40++T2~~t,

 
	
r3   c                 p    | j                   dk(  r| j                  |||      S | j                  |||      S )zGet the walk generator.r   
namespaces)r(   _walk_breadth_walk_depth)r0   rC   r8   rK   s       r2   
_iter_walkzWalker._iter_walk   s@     ;;)#%%b$:%FF##B#DDr3   c                     | j                   '|j                  | j                   |j                        ry| j                  '|j                  | j                  |j                        sy| j	                  |||      S )z6Check if a directory should be considered in the walk.F)r,   matchnamer+   check_open_dirr0   rC   r8   infos       r2   _check_open_dirzWalker._check_open_dir   se     (RXXd6G6G-S'9I9I4990U""2tT22r3   c                      y)ad  Check if a directory should be opened.

        Override to exclude directories from the walk.

        Arguments:
            fs (FS): A filesystem instance.
            path (str): Path to directory.
            info (Info): A resource info object for the directory.

        Returns:
            bool: `True` if the directory should be opened.

        Tr5   rS   s       r2   rR   zWalker.check_open_dir   s     r3   c                 `    | j                   || j                   k\  ry| j                  |||      S )z0Check if a directory contents should be scanned.F)r-   check_scan_dir)r0   rC   r8   rT   r    s        r2   _check_scan_dirzWalker._check_scan_dir   s1     >>%%4>>*A""2tT22r3   c                      y)a  Check if a directory should be scanned.

        Override to omit scanning of certain directories. If a directory
        is omitted, it will appear in the walk but its files and
        sub-directories will not.

        Arguments:
            fs (FS): A filesystem instance.
            path (str): Path to directory.
            info (Info): A resource info object for the directory.

        Returns:
            bool: `True` if the directory should be scanned.

        Tr5   rS   s       r2   rX   zWalker.check_scan_dir   s    " r3   c                     | j                   '|j                  | j                   |j                        ry|j                  | j                  |j                        S )a  Check if a filename should be included.

        Override to exclude files from the walk.

        Arguments:
            fs (FS): A filesystem instance.
            info (Info): A resource info object.

        Returns:
            bool: `True` if the file should be included.

        F)r*   rP   rQ   r)   )r0   rC   rT   s      r2   
check_filezWalker.check_file   s?     <<#tyy(IxxTYY//r3   c              #      K   	 |j                  ||      D ]  }|  y# t        $ r}| j                  ||      s Y d}~yd}~ww xY ww)a  Get an iterator of `Info` objects for a directory path.

        Arguments:
            fs (FS): A filesystem instance.
            dir_path (str): A path to a directory on the filesystem.
            namespaces (list): A list of additional namespaces to
                include in the `Info` objects.

        Returns:
            ~collections.Iterator: iterator of `Info` objects for
            resources within the given path.

        rJ   N)scandirr	   r'   )r0   rC   dir_pathrK   rT   r9   s         r2   _scanzWalker._scan
  sQ     (	

8

C 
 	==51 2	s)   A
! A
	AAA
AA
c              #   :  K   t        t        |            }t        t              }| j	                  |||      }|D ][  \  }}|@g }	g }
||   D ]!  }|j
                  r|	n|
j                  |       # t        ||	|
       ||= H||   j                  |       ] yw)ab  Walk the directory structure of a filesystem.

        Arguments:
            fs (FS): A filesystem instance.
            path (str): A path to a directory on the filesystem.
            namespaces (list, optional): A list of additional namespaces
                to add to the `Info` objects.

        Returns:
            collections.Iterator: an iterator of `~fs.walk.Step` instances.

        The return value is an iterator of ``(<path>, <dirs>, <files>)``
        named tuples,  where ``<path>`` is an absolute path to a
        directory, and ``<dirs>`` and ``<files>`` are a list of
        `~fs.info.Info` objects for directories and files in ``<path>``.

        Example:
            >>> walker = Walker(filter=['*.py'])
            >>> for path, dirs, files in walker.walk(my_fs, namespaces=["details"]):
            ...    print("[{}]".format(path))
            ...    print("{} directories".format(len(dirs)))
            ...    total = sum(info.size for info in files)
            ...    print("{} bytes".format(total))
            [/]
            2 directories
            55 bytes
            ...

        rJ   N)r
   r   r   listrN   is_dirappendr   )r0   rC   r8   rK   r?   dir_info_walkr_   rT   dirsfiles_infos               r2   walkzWalker.walk%  s     H 't$EjA# 		0NHd|%h/ DE"\\Tu<<UCD8T511X&"))$/		0s   BBc              #      K   t         }| j                  ||      D ]*  \  }}|	|j                  r |||j                         , yw)aD  Walk a filesystem, yielding absolute paths to files.

        Arguments:
            fs (FS): A filesystem instance.
            path (str): A path to a directory on the filesystem.

        Yields:
            str: absolute path to files on the filesystem found
            recursively within the given directory.

        r8   Nr   rN   rc   rQ   r0   rC   r8   _combiner?   rT   s         r2   rh   zWalker.filesW  sJ      ??2D?9 	1KE4udii00	1   "A
A
A
c              #      K   t         }| j                  ||      D ]*  \  }}|	|j                  s |||j                         , yw)aP  Walk a filesystem, yielding absolute paths to directories.

        Arguments:
            fs (FS): A filesystem instance.
            path (str): A path to a directory on the filesystem.

        Yields:
            str: absolute path to directories on the filesystem found
            recursively within the given directory.

        rl   Nrm   rn   s         r2   rg   zWalker.dirsi  sJ      ??2D?9 	1KE4DKKudii00	1rp   c              #      K   t         }| j                  |||      }|D ]  \  }}|	 |||j                        |f ! yw)a  Walk a filesystem, yielding tuples of ``(<path>, <info>)``.

        Arguments:
            fs (FS): A filesystem instance.
            path (str): A path to a directory on the filesystem.
            namespaces (list, optional): A list of additional namespaces
                to add to the `Info` objects.

        Yields:
            (str, Info): a tuple of ``(<absolute path>, <resource info>)``.

        r8   rK   N)r   rN   rQ   )r0   rC   r8   rK   ro   rf   r?   rT   s           r2   rT   zWalker.info{  sP     & *E  	7KE4udii0$66	7s
   %AAc              #     K   t        |g      }|j                  }|j                  }t        }| j                  }| j
                  }	| j                  }
| j                  }| j                  } |	|      }|r |       } ||||      D ]c  }|j                  rE |	|      |z
  dz   } |
|||      s(||f  |||||      s: | |||j                               T |||      s^||f e |df |ryyw)z*Walk files using a *breadth first* search.rJ   r   N)r   
appendleftpopr   r`   r@   rU   rY   r\   rc   rQ   )r0   rC   r8   rK   queuepushrv   ro   r`   r@   rU   rY   _check_filer    r_   rT   _depths                    r2   rL   zWalker._walk_breadth  s     tfii

00....oo &uHb(zB 	-;;-h7%?!CF&r8T:&n,*2xvF (DII!>?"2t,&n,	- D.  s   B*C6-C6?#C6#C64C6c              #     K   t         }| j                  }| j                  }| j                  }| j                  }| j
                  }	 ||      }
| ||||      dfg}|j                  }|r|d   \  }}}t        |d      }||| |df |d= no|j                  rT ||      |
z
  dz   } ||||      rK |||||      r* |||j                        } || ||||      ||ff       n||f n |	||      r||f |ryyw)z(Walk files using a *depth first* search.rJ   Nr   )
r   r`   r@   rU   rY   r\   rd   nextrc   rQ   )r0   rC   r8   rK   ro   r`   r@   rU   rY   ry   r    stackrx   r_   
iter_filesparentrT   rz   r?   s                      r2   rM   zWalker._walk_depth  s@     

00....oo & 5Tj94@
 ||+09(Hj&
D)D|% Ln$"I)(3e;a?"2x6&r8T6B (499 = % %b%J G!)4 0 'n,r4("D.(1 s   D DD)FNr   NNNNN)Nr<   Nr<   )rF   
__module____qualname____doc__r/   classmethodr#   r$   r@   rD   rH   rN   rU   rR   rY   rX   r\   r`   rj   rh   rg   rT   rL   rM   __classcell__)r1   s   @r2   r   r   2   s    H :'x  
  
 4 4 " "H
$ 	E3"3&0, 	< 	00d1$1* 	7: 	!!N 	0)r3   r   c                   R    e Zd ZdZefdZd Zd Z	 	 d
dZeZ	ddZ
ddZ	 	 d
d	Zy)rB   a  A class that binds a `Walker` instance to a `FS` instance.

    You will typically not need to create instances of this class
    explicitly. Filesystems have a `~FS.walk` property which returns a
    `BoundWalker` object.

    Example:
        >>> tmp_fs = fs.tempfs.TempFS()
        >>> tmp_fs.walk
        BoundWalker(TempFS())

    A `BoundWalker` is callable. Calling it is an alias for the
    `~fs.walk.BoundWalker.walk` method.

    c                      || _         || _        y)zCreate a new walker bound to the given filesystem.

        Arguments:
            fs (FS): A filesystem instance.
            walker_class (type): A `~fs.walk.WalkerBase`
                sub-class. The default uses `~fs.walk.Walker`.

        N)rC   walker_class)r0   rC   r   s      r2   r/   zBoundWalker.__init__  s     (r3   c                 8    dj                  | j                        S )NzBoundWalker({!r}))formatrC   rG   s    r2   rH   zBoundWalker.__repr__  s    "))$''22r3   c                 *     | j                   |i |}|S )zCreate a walker instance.)r   )r0   argskwargswalkers       r2   _make_walkerzBoundWalker._make_walker  s      #""D3F3r3   Nc                 b     | j                   di |}|j                  | j                  ||      S )aY
  Walk the directory structure of a filesystem.

        Arguments:
            path (str):
            namespaces (list, optional): A list of namespaces to include
                in the resource information, e.g. ``['basic', 'access']``
                (defaults to ``['basic']``).

        Keyword Arguments:
            ignore_errors (bool): If `True`, any errors reading a
                directory will be ignored, otherwise exceptions will be
                raised.
            on_error (callable): If ``ignore_errors`` is `False`, then
                this callable will be invoked with a path and the exception
                object. It should return `True` to ignore the error, or
                `False` to re-raise it.
            search (str): If ``'breadth'`` then the directory will be
                walked *top down*. Set to ``'depth'`` to walk *bottom up*.
            filter (list): If supplied, this parameter should be a list
                of file name patterns, e.g. ``['*.py']``. Files will only be
                returned if the final component matches one of the
                patterns.
            exclude (list, optional): If supplied, this parameter should be
                a list of filename patterns, e.g. ``['~*', '.*']``. Files matching
                any of these patterns will be removed from the walk.
            filter_dirs (list, optional): A list of patterns that will be used
                to match directories paths. The walk will only open directories
                that match at least one of these patterns.
            exclude_dirs (list): A list of patterns that will be used
                to filter out directories from the walk, e.g. ``['*.svn',
                '*.git']``.
            max_depth (int, optional): Maximum directory depth to walk.

        Returns:
            ~collections.Iterator: an iterator of ``(<path>, <dirs>, <files>)``
            named tuples,  where ``<path>`` is an absolute path to a
            directory, and ``<dirs>`` and ``<files>`` are a list of
            `~fs.info.Info` objects for directories and files in ``<path>``.

        Example:
            >>> walker = Walker(filter=['*.py'])
            >>> for path, dirs, files in walker.walk(my_fs, namespaces=['details']):
            ...     print("[{}]".format(path))
            ...     print("{} directories".format(len(dirs)))
            ...     total = sum(info.size for info in files)
            ...     print("{} bytes".format(total))
            [/]
            2 directories
            55 bytes
            ...

        This method invokes `Walker.walk` with bound `FS` object.

        rs   r5   )r   rj   rC   r0   r8   rK   r   r   s        r2   rj   zBoundWalker.walk  s3    z #"",V,{{477*{EEr3   c                 `     | j                   di |}|j                  | j                  |      S )aA  Walk a filesystem, yielding absolute paths to files.

        Arguments:
            path (str): A path to a directory.

        Keyword Arguments:
            ignore_errors (bool): If `True`, any errors reading a
                directory will be ignored, otherwise exceptions will be
                raised.
            on_error (callable): If ``ignore_errors`` is `False`, then
                this callable will be invoked with a path and the exception
                object. It should return `True` to ignore the error, or
                `False` to re-raise it.
            search (str): If ``'breadth'`` then the directory will be
                walked *top down*. Set to ``'depth'`` to walk *bottom up*.
            filter (list): If supplied, this parameter should be a list
                of file name patterns, e.g. ``['*.py']``. Files will only be
                returned if the final component matches one of the
                patterns.
            exclude (list, optional): If supplied, this parameter should be
                a list of filename patterns, e.g. ``['~*', '.*']``. Files matching
                any of these patterns will be removed from the walk.
            filter_dirs (list, optional): A list of patterns that will be used
                to match directories paths. The walk will only open directories
                that match at least one of these patterns.
            exclude_dirs (list): A list of patterns that will be used
                to filter out directories from the walk, e.g. ``['*.svn',
                '*.git']``.
            max_depth (int, optional): Maximum directory depth to walk.

        Returns:
            ~collections.Iterator: An iterator over file paths (absolute
            from the filesystem root).

        This method invokes `Walker.files` with the bound `FS` object.

        rl   r5   )r   rh   rC   r0   r8   r   r   s       r2   rh   zBoundWalker.filesT  s1    N #"",V,||DGG$|//r3   c                 `     | j                   di |}|j                  | j                  |      S )au  Walk a filesystem, yielding absolute paths to directories.

        Arguments:
            path (str): A path to a directory.

        Keyword Arguments:
            ignore_errors (bool): If `True`, any errors reading a
                directory will be ignored, otherwise exceptions will be
                raised.
            on_error (callable): If ``ignore_errors`` is `False`, then
                this callable will be invoked with a path and the exception
                object. It should return `True` to ignore the error, or
                `False` to re-raise it.
            search (str): If ``'breadth'`` then the directory will be
                walked *top down*. Set to ``'depth'`` to walk *bottom up*.
            filter_dirs (list, optional): A list of patterns that will be used
                to match directories paths. The walk will only open directories
                that match at least one of these patterns.
            exclude_dirs (list): A list of patterns that will be used
                to filter out directories from the walk, e.g. ``['*.svn',
                '*.git']``.
            max_depth (int, optional): Maximum directory depth to walk.

        Returns:
            ~collections.Iterator: an iterator over directory paths
            (absolute from the filesystem root).

        This method invokes `Walker.dirs` with the bound `FS` object.

        rl   r5   )r   rg   rC   r   s       r2   rg   zBoundWalker.dirs~  s1    @ #"",V,{{477{..r3   c                 b     | j                   di |}|j                  | j                  ||      S )a  Walk a filesystem, yielding path and `Info` of resources.

        Arguments:
            path (str): A path to a directory.
            namespaces (list, optional): A list of namespaces to include
                in the resource information, e.g. ``['basic', 'access']``
                (defaults to ``['basic']``).

        Keyword Arguments:
            ignore_errors (bool): If `True`, any errors reading a
                directory will be ignored, otherwise exceptions will be
                raised.
            on_error (callable): If ``ignore_errors`` is `False`, then
                this callable will be invoked with a path and the exception
                object. It should return `True` to ignore the error, or
                `False` to re-raise it.
            search (str): If ``'breadth'`` then the directory will be
                walked *top down*. Set to ``'depth'`` to walk *bottom up*.
            filter (list): If supplied, this parameter should be a list
                of file name patterns, e.g. ``['*.py']``. Files will only be
                returned if the final component matches one of the
                patterns.
            exclude (list, optional): If supplied, this parameter should be
                a list of filename patterns, e.g. ``['~*', '.*']``. Files matching
                any of these patterns will be removed from the walk.
            filter_dirs (list, optional): A list of patterns that will be used
                to match directories paths. The walk will only open directories
                that match at least one of these patterns.
            exclude_dirs (list): A list of patterns that will be used
                to filter out directories from the walk, e.g. ``['*.svn',
                '*.git']``.
            max_depth (int, optional): Maximum directory depth to walk.

        Returns:
            ~collections.Iterable: an iterable yielding tuples of
            ``(<absolute path>, <resource info>)``.

        This method invokes `Walker.info` with the bound `FS` object.

        rs   r5   )r   rT   rC   r   s        r2   rT   zBoundWalker.info  s3    ^ #"",V,{{477*{EEr3   r   r   )rF   r   r   r   r   r/   rH   r   rj   __call__rh   rg   rT   r5   r3   r2   rB   rB     sK      )/ )3 >F@ H(0T!/J 0Fr3   rB   )0r   
__future__r   typingcollectionsr   r   r   _reprr   errorsr	   r8   r
   r   r   TYPE_CHECKINGr   r   r   r   r   r   r   r   r   r   baser   rT   r   	ExceptionboolOnErrorTypeVarr   r   objectr   GenericrB   default_walkerrj   rh   
walk_files	walk_inforg   	walk_dirsr5   r3   r2   <module>r      s    (  6 6   , ,	   i($./G V^^D% &-.u)V u)pgF&..$ gF\ !!
		r3   