Your IP : 216.73.216.213


Current Path : /opt/alt/python37/lib/python3.7/site-packages/pyfakefs/__pycache__/
Upload File :
Current File : //opt/alt/python37/lib/python3.7/site-packages/pyfakefs/__pycache__/fake_filesystem.cpython-37.pyc

B

��\�&�@s�dZddlZddlZddlZddlZddlZddlZddlZddlZddl	Z	ddl
mZddlm
Z
mZmZmZmZmZmZddlmZddlmZmZddlmZddlmZmZmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%d	Z&d
Z'dZ(dZ)d
Z*dZ+dZ,dZ-edd�Z.ddddddd�Z/ej0ddk�r4ejdk�r4de/d<ej0dk�rPde/d<d e/d!<ej�1d"��rdd#Z2nd$Z2d%Z3dZ4e%�rzd&ne�5�a6e%�r�d&ne�7�a8d'd(�Z9d)d*�Z:d+d,�Z;Gd-d.�d.e<�Z=d/d0�Z>Gd1d2�d2e?�Z@Gd3d4�d4e@�ZAe�Be@e@jCd5�e�Be@e@jDd6�e�Be@e@jEd7�Gd8d9�d9e@�ZFGd:d;�d;e@�ZGe�BeGeGjHd<�e�BeGeGjId=�e�BeGeGjDd6�e�BeGeGjJd>�Gd?d@�d@eG�ZKGdAdB�dBe?�ZLe�BeLeLjMdC�e�BeLeLjNdD�e�BeLeLjOdE�e�BeLeLjPdF�e�BeLeLjdG�e�BeLeLjQdH�e�BeLeLjRdI�e�BeLeLjSdJ�e�BeLeLjTdK�e�BeLeLjUdL�e�BeLeLjVdM�e�BeLeLjWdN�e�BeLeLjXdO�e�BeLeLjYdP�e�BeLeLjZdQ�e�BeLeLj[dR�e�BeLeLj\dS�e�BeLeLj]dT�e�BeLeLj^dU�e�BeLeLj_dV�e�BeLeLj`dW�e�BeLeLjadX�e�BeLeLjbdY�e�BeLeLjcdZ�e�BeLeLjdd[�e�BeLeLjed\�e�BeLeLjfd]�e�BeLeLjgd^�e�BeLeLjhd_�e�BeLeLjid`�e�BeLeLjjda�e�BeLeLjkdb�e�BeLeLjldc�e�BeLeLjmdd�e�BeLeLjnde�e�BeLeLjodf�e�BeLeLjpdg�e�BeLeLjqdh�e�BeLeLjrdi�e�BeLeLjsdj�e�BeLeLjtdk�e�BeLeLjudl�e�BeLeLjvdm�Gdndo�doe?�ZwGdpdq�dqe?�ZxGdrds�dse?�ZyGdtdu�due?�ZzGdvdw�dwe?�Z{Gdxdy�dye?�Z|e�BezezjcdZ�e�Bezezj}dz�Gd{d|�d|e?�Z~d}d~�Ze�dk�r�e�dS)�a�	A fake filesystem implementation for unit testing.

:Includes:
  * :py:class:`FakeFile`: Provides the appearance of a real file.
  * :py:class:`FakeDirectory`: Provides the appearance of a real directory.
  * :py:class:`FakeFilesystem`: Provides the appearance of a real directory
    hierarchy.
  * :py:class:`FakeOsModule`: Uses :py:class:`FakeFilesystem` to provide a
    fake :py:mod:`os` module replacement.
  * :py:class:`FakeIoModule`: Uses :py:class:`FakeFilesystem` to provide a
    fake ``io`` module replacement.
  * :py:class:`FakePathModule`:  Faked ``os.path`` module replacement.
  * :py:class:`FakeFileOpen`:  Faked ``file()`` and ``open()`` function
    replacements.

:Usage:

>>> from pyfakefs import fake_filesystem
>>> filesystem = fake_filesystem.FakeFilesystem()
>>> os_module = fake_filesystem.FakeOsModule(filesystem)
>>> pathname = '/a/new/dir/new-file'

Create a new file object, creating parent directory objects as needed:

>>> os_module.path.exists(pathname)
False
>>> new_file = filesystem.create_file(pathname)

File objects can't be overwritten:

>>> os_module.path.exists(pathname)
True
>>> try:
...   filesystem.create_file(pathname)
... except IOError as e:
...   assert e.errno == errno.EEXIST, 'unexpected errno: %d' % e.errno
...   assert e.strerror == 'File exists in the fake filesystem'

Remove a file object:

>>> filesystem.remove_object(pathname)
>>> os_module.path.exists(pathname)
False

Create a new file object at the previous path:

>>> beatles_file = filesystem.create_file(pathname,
...     contents='Dear Prudence\nWon\'t you come out to play?\n')
>>> os_module.path.exists(pathname)
True

Use the FakeFileOpen class to read fake file objects:

>>> file_module = fake_filesystem.FakeFileOpen(filesystem)
>>> for line in file_module(pathname):
...     print(line.rstrip())
...
Dear Prudence
Won't you come out to play?

File objects cannot be treated like directory objects:

>>> try:
...   os_module.listdir(pathname)
... except OSError as e:
...   assert e.errno == errno.ENOTDIR, 'unexpected errno: %d' % e.errno
...   assert e.strerror == 'Not a directory in the fake filesystem'

The FakeOsModule can list fake directory objects:

>>> os_module.listdir(os_module.path.dirname(pathname))
['new-file']

The FakeOsModule also supports stat operations:

>>> import stat
>>> stat.S_ISREG(os_module.stat(pathname).st_mode)
True
>>> stat.S_ISDIR(os_module.stat(os_module.path.dirname(pathname)).st_mode)
True
�N)�
namedtuple)�S_IFREG�S_IFDIR�S_ISLNK�S_IFMT�S_ISDIR�S_IFLNK�S_ISREG)�
Deprecator)�scandir�walk)�use_scandir)
�FakeStatResult�FileBufferIO�IS_PY2�NullFileBufferIO�is_int_type�is_byte_string�is_unicode_string�make_string_path�	text_type�IS_WINzno-reimportselfz3.5.8���@i�i�i��
open_modesz<must_exist can_read can_write truncate append must_not_exist)TTFFFF)FFTTFF)FFTFTF)TTTFFF)FTTTFF)FTTFTF)�r�w�azr+zw+za+��win32�rw)rr)FFTFFT�x)FTTFFTzx+�linux�(� z{Do not instantiate a FakePathModule directly; let FakeOsModule instantiate it.  See the FakeOsModule docstring for details.�cCs|adS)a%Set the global user id. This is used as st_uid for new files
    and to differentiate between a normal user and the root user (uid 0).
    For the root user, some permission restrictions are ignored.

    Args:
        uid: (int) the user ID of the user calling the file system functions.
    N)�USER_ID)�uid�r)�I/opt/alt/python37/lib/python3.7/site-packages/pyfakefs/fake_filesystem.py�set_uid�s	r+cCs|adS)z�Set the global group id. This is only used to set st_gid for new files,
    no permision checks are performed.

    Args:
        gid: (int) the group ID of the user calling the file system functions.
    N)�GROUP_ID)�gidr)r)r*�set_gid�sr.cCstdkS)z1Return True if the current user is the root user.r)r'r)r)r)r*�is_root�sr/cs eZdZdZ�fdd�Z�ZS)�FakeLargeFileIoExceptionz|Exception thrown on unsupported operations for fake large files.
    Fake large files have a size with no real content.
    cstt|��d|�dS)Nz?Read and write operations not supported for fake large file: %s)�superr0�__init__)�self�	file_path)�	__class__r)r*r2�s
z!FakeLargeFileIoException.__init__)�__name__�
__module__�__qualname__�__doc__r2�
__classcell__r)r))r5r*r0�sr0cCs*tj�|jd�}t|j�}|tj|j<|S)z)Recompiles and creates new module object.N)�sys�modules�popr6�
__import__)�old�saved�newr)r)r*�_copy_module�s
rBcs�eZdZdZdZeeBdddddfdd�Zedd��Z	edd	��Z
ed
d��Zedd
��Zedd��Z
ejdd��Zejdd
��Ze
jdd��Z
dd�Zdd�Zdd�Zdd�Zdd�Zd>dd�Zedd ��Zed!d"��Zed#�d$d%��Zed&�d'd(��Zejd)d ��Zed&�d*d+��Zed,�d-d.��Zed/�d0d1��Zed2�d3d4��Z�fd5d6�Z�fd7d8�Zd9d:�Z ed;�d<d=��Z!�Z"S)?�FakeFilea�Provides the appearance of a real file.

    Attributes currently faked out:
      * `st_mode`: user-specified, otherwise S_IFREG
      * `st_ctime`: the time.time() timestamp of the file change time (updated
        each time a file's attributes is modified).
      * `st_atime`: the time.time() timestamp when the file was last accessed.
      * `st_mtime`: the time.time() timestamp when the file was last modified.
      * `st_size`: the size of the file
      * `st_nlink`: the number of hard links to the file
      * `st_ino`: the inode number - a unique number identifying the file
      * `st_dev`: a unique number identifying the (fake) file system device
        the file belongs to
      * `st_uid`: always set to USER_ID, which can be changed globally using
            `set_uid`
      * `st_gid`: always set to GROUP_ID, which can be changed globally using
            `set_gid`

    .. note:: The resolution for `st_ctime`, `st_mtime` and `st_atime` in the
        real file system depends on the used file system (for example it is
        only 1s for HFS+ and older Linux file systems, but much higher for
        ext4 and NTFS). This is currently ignored by pyfakefs, which uses
        the resolution of `time.time()`.

        Under Windows, `st_atime` is not updated for performance reasons by
        default. pyfakefs never updates `st_atime` under Windows, assuming
        the default setting.
    )
�st_mode�st_ino�st_dev�st_nlink�st_uid�st_gid�st_size�st_atime�st_mtime�st_ctime�st_atime_ns�st_mtime_ns�st_ctime_nsNcCs�|dkrtd��||_||_||_t|jttt���|_	||j	_
||_|pLd|_|�
|�|_|jdk	rpt|j�nd|j	_d|_d|_i|_dS)aF
        Args:
            name: Name of the file/directory, without parent path information
            st_mode: The stat.S_IF* constant representing the file type (i.e.
                stat.S_IFREG, stat.S_IFDIR)
            contents: The contents of the filesystem object; should be a string
                or byte object for regular files, and a list of other
                FakeFile or FakeDirectory objects for FakeDirectory objects
            filesystem: The fake filesystem where the file is created.
            encoding: If contents is a unicode string, the encoding used
                for serialization.
            errors: The error mode used for encoding/decoding errors.
            side_effect: function handle that is executed when file is written,
                must accept the file object as an argument.
        Nzfilesystem shall not be None�strictr)�
ValueError�
filesystem�_side_effect�namer�
is_windows_fsr'r,�time�stat_resultrD�encoding�errors�_encode_contents�_byte_contents�lenrJ�epoch�
parent_dir�xattr)r3rUrD�contentsrSrYrZ�side_effectr)r)r*r2�s
zFakeFile.__init__cCs|jS)z&Return the contents as raw byte array.)r\)r3r)r)r*�
byte_contents!szFakeFile.byte_contentscCs4ts.t|jt�r.|jj|jp$t�d�|jd�S|jS)z9Return the contents as string with the original encoding.F)rZ)	r�
isinstancerc�bytes�decoderY�locale�getpreferredencodingrZ)r3r)r)r*ra&s

zFakeFile.contentscCs|jjS)z*Return the creation time of the fake file.)rXrM)r3r)r)r*rM/szFakeFile.st_ctimecCs|jjS)z(Return the access time of the fake file.)rXrK)r3r)r)r*rK4szFakeFile.st_atimecCs|jjS)z.Return the modification time of the fake file.)rXrL)r3r)r)r*rL9szFakeFile.st_mtimecCs||j_dS)z'Set the creation time of the fake file.N)rXrM)r3�valr)r)r*rM>scCs||j_dS)z%Set the access time of the fake file.N)rXrK)r3rir)r)r*rKCscCs||j_dS)z+Set the modification time of the fake file.N)rXrL)r3rir)r)r*rLHscCs@|�|�|jrd|_|jr0|j�||j|j�||_d|_dS)aSets the self.st_size attribute and replaces self.content with None.

        Provided specifically to simulate very large files without regards
        to their content (which wouldn't fit in memory).
        Note that read/write operations with such a file raise
            :py:class:`FakeLargeFileIoException`.

        Args:
          st_size: (int) The desired file size

        Raises:
          IOError: if the st_size is not a non-negative integer,
                   or if st_size exceeds the available file system space
        rN)�_check_positive_intrJ�sizerS�change_disk_usagerUrFr\)r3rJr)r)r*�set_large_file_sizeMs
zFakeFile.set_large_file_sizecCs&t|�r|dkr"|j�tj|j�dS)Nr)rrS�raise_io_error�errno�ENOSPCrU)r3rkr)r)r*rjdszFakeFile._check_positive_intcCs
|jdkS)zNReturn `True` if this file was initialized with size but no contents.
        N)r\)r3r)r)r*�
is_large_fileiszFakeFile.is_large_filecCsFt|�rBtr(|�|jpt�d�|j�}nt||jp:t�d�|j�}|S)NF)rr�encoderYrgrhrZre)r3rar)r)r*r[ns
zFakeFile._encode_contentscCsh|�|�}|j|k}t|�}|jr(d|_|jp0d}|j�|||j|j�||_||_|j	d7_	|S)a�Sets the file contents and size.
           Called internally after initial file creation.

        Args:
            contents: string, new content of file.

        Returns:
            True if the contents have been changed.

        Raises:
              IOError: if the st_size is not a non-negative integer,
                   or if st_size exceeds the available file system space
        rr&)
r[r\r]rkrJrSrlrUrFr^)r3ra�changedrJ�current_sizer)r)r*�_set_initial_contents{s


zFakeFile._set_initial_contentscCs(||_|�|�}|jdk	r$|�|�|S)a+Sets the file contents and size and increases the modification time.
        Also executes the side_effects if available.

        Args:
          contents: (str, bytes, unicode) new content of file.
          encoding: (str) the encoding to be used for writing the contents
                    if they are a unicode string.
                    If not given, the locale preferred encoding is used.

        Raises:
          IOError: if `st_size` is not a non-negative integer,
                   or if it exceeds the available file system space.
        N)rYrurT)r3rarYrsr)r)r*�set_contents�s



zFakeFile.set_contentscCs|jS)z7Return the size in bytes of the file contents.
        )rJ)r3r)r)r*rk�sz
FakeFile.sizecCs�g}|}x|r$|�d|j�|j}q
W|j�|j�}|d|kr�|�d�|�|�}|ovt|d�dkov|dddk}|s�||}n
|�|�}|j�|�}|S)z+Return the full path of the current object.r�r&�:)	�insertrUr_rS�_path_separatorr=�joinr]�absnormpath)r3�names�obj�sep�dir_path�is_driver)r)r*�path�s


$

z
FakeFile.pathz
property pathcCs|jS)N)r�)r3r)r)r*�GetPath�szFakeFile.GetPathz
property sizecCs|jS)N)rk)r3r)r)r*�GetSize�szFakeFile.GetSizecCs�|�|�|jpd}|j�|||j|j�|jr�||krL|jd|�|_n4trjd|jd||f|_n|jd||7_||_|jd7_dS)a:Resizes file content, padding with nulls if new size exceeds the
        old size.

        Args:
          st_size: The desired size for the file.

        Raises:
          IOError: if the st_size arg is not a non-negative integer
                   or if st_size exceeds the available file system space
        rNz%s%s��r&)	rjrJrSrlrUrFr\rr^)r3rJrtr)r)r*rk�s

cCs
||_dS)N)rk)r3�valuer)r)r*�SetSize�szFakeFile.SetSizezproperty st_atimecCs
||_dS)zeSet the self.st_atime attribute.

        Args:
          st_atime: The desired access time.
        N)rK)r3rKr)r)r*�SetATime�szFakeFile.SetATimezproperty st_mtimecCs
||_dS)zkSet the self.st_mtime attribute.

        Args:
          st_mtime: The desired modification time.
        N)rL)r3rLr)r)r*�SetMTime�szFakeFile.SetMTimezproperty st_ctimecCs
||_dS)zgSet the self.st_ctime attribute.

        Args:
          st_ctime: The desired creation time.
        N)rM)r3rMr)r)r*�SetCTimeszFakeFile.SetCTimecs&||jkrt|j|�Stt|��|�S)z'Forward some properties to stat_result.)�
stat_types�getattrrXr1rC�__getattr__)r3�item)r5r)r*r�s
zFakeFile.__getattr__cs*||jkrt|j||�Stt|��||�S)z'Forward some properties to stat_result.)r��setattrrXr1rC�__setattr__)r3�keyr�)r5r)r*r�s
zFakeFile.__setattr__cCsd|j|jfS)Nz%s(%o))rUrD)r3r)r)r*�__str__szFakeFile.__str__rEcCs
||_dS)a
Set the self.st_ino attribute.
        Note that a unique inode is assigned automatically to a new fake file.
        This function does not guarantee uniqueness and should be used with
        caution.

        Args:
          st_ino: (int) The desired inode.
        N)rE)r3rEr)r)r*�SetInos
zFakeFile.SetIno)N)#r6r7r8r9r�r�
PERM_DEF_FILEr2�propertyrcrarMrKrL�setterrmrjrqr[rurvrkr�r
r�r�r�r�r�r�r�r�r�r�r:r)r))r5r*rC�s@#	

			rCcs0eZdZ�fdd�Zedd��Zdd�Z�ZS)�FakeNullFilecs(|jr
dnd}tt|�j||dd�dS)Nz/dev/nul�)rSra)rVr1r�r2)r3rS�devnull)r5r)r*r2(s
zFakeNullFile.__init__cCsdS)Nr�r))r3r)r)r*rc-szFakeNullFile.byte_contentscCsdS)Nr))r3rar)r)r*ru1sz"FakeNullFile._set_initial_contents)r6r7r8r2r�rcrur:r)r))r5r*r�'sr��SetLargeFileSize�SetContents�IsLargeFilecsDeZdZdZd�fdd�	Zedd��Zd�fdd�	Zd	d
�Z�Z	S)
�FakeFileFromRealFileztRepresents a fake file copied from the real file system.

    The contents of the file are read on demand only.
    Ncs(tt|�jtj�|�||d�d|_dS)a3
        Args:
            file_path: Path to the existing file.
            filesystem: The fake filesystem where the file is created.

        Raises:
            OSError: if the file does not exist in the real file system.
            OSError: if the file already exists in the fake file system.
        )rUrSrbFN)r1r�r2�osr��basename�
contents_read)r3r4rSrb)r5r)r*r2@s

zFakeFileFromRealFile.__init__c	CsF|js0d|_t�|jd��}|��|_WdQRXt�|j�j|_|jS)NT�rb)	r��io�openr4�readr\r��statrK)r3�fr)r)r*rcOsz"FakeFileFromRealFile.byte_contentscsd|_tt|��||�dS)NT)r�r1r�rv)r3rarY)r5r)r*rvYsz!FakeFileFromRealFile.set_contentscCsdS)zThe contents are never faked.Fr))r3r)r)r*rq]sz"FakeFileFromRealFile.is_large_file)N)N)
r6r7r8r9r2r�rcrvrqr:r)r))r5r*r�:s

r�cs�eZdZdZedfdd�Zddd�Zedd��Zed	d
��Z	dd�Z
d
d�Zdd�Zddd�Z
edd��Zed�dd��Zdd�Z�fdd�Z�ZS)�
FakeDirectoryz,Provides the appearance of a real directory.NcCs*tj||t|Bi|d�|jd7_dS)a
        Args:
            name:  name of the file/directory, without parent path information
            perm_bits: permission bits. defaults to 0o777.
            filesystem: if set, the fake filesystem where the directory
                is created
        )rSr&N)rCr2rrG)r3rU�	perm_bitsrSr)r)r*r2eszFakeDirectory.__init__cCs0|jjrts|jj}n|jj}|tj|j��dS)N)rSrVr�raise_os_errorrnro�EISDIRr�)r3rarY�	error_fctr)r)r*rvss
zFakeDirectory.set_contentscCs|jS)z/Return the list of contained directory entries.)rc)r3r)r)r*razszFakeDirectory.contentscCs dd�t|j��dd�d�D�S)z^Return the list of contained directory entry names ordered by
        creation order.
        cSsg|]}|d�qS)rr))�.0r�r)r)r*�
<listcomp>�sz.FakeDirectory.ordered_dirs.<locals>.<listcomp>cSs
|djS)Nr&)rE)�entryr)r)r*�<lambda>�r�z,FakeDirectory.ordered_dirs.<locals>.<lambda>)r�)�sortedrc�items)r3r)r)r*�ordered_dirsszFakeDirectory.ordered_dirscCs�t�s4|jt@s4|jjs4tr tnt}|tj	d|j
��|j|jkrR|j�
tj|j
�||j|j<||_|jd7_|jd7_|j|_|jdkr�|j�|j|j|j�dS)a5Adds a child FakeFile to this directory.

        Args:
            path_object: FakeFile instance to add as a child of this directory.

        Raises:
            OSError: if the directory has no write permission (Posix only)
            OSError: if the file or directory to be added already exists
        zPermission Deniedr&N)r/rD�
PERM_WRITErSrVr�IOError�OSErrorro�EACCESr�rUrar��EEXISTr_rGrFrlrk)r3�path_object�	exceptionr)r)r*�	add_entry�s

zFakeDirectory.add_entrycCs|�|�}|j|S)a)Retrieves the specified child file or directory entry.

        Args:
            pathname_name: The basename of the child object to retrieve.

        Returns:
            The fake file or directory object.

        Raises:
            KeyError: if no child exists by the specified name.
        )�_normalized_entrynamera)r3�
pathname_namer)r)r*�	get_entry�s
zFakeDirectory.get_entrycs,|jjs(�fdd�|jD�}|r(|d��S)Ncs g|]}|�����kr|�qSr))�lower)r�rU)r�r)r*r��sz7FakeDirectory._normalized_entryname.<locals>.<listcomp>r)rS�is_case_sensitivera)r3r��matching_namesr))r�r*r��s
z#FakeDirectory._normalized_entrynameTcCs
|�|�}|�|�}|jjrX|jt@dkr:|j�tj|�|j�	|�r�|j�tj|�n,t
�s�|jttB@ttBkr�|j�tj|�|r�t|t
�r�x@|jr�|�t|j�d�q�Wn |jdkr�|j�|j||j�|jd8_|jd8_|jdks�t�|j|=dS)a&Removes the specified child file or directory.

        Args:
            pathname_name: Basename of the child object to remove.
            recursive: If True (default), the entries in contained directories
                are deleted first. Used to propagate removal errors
                (e.g. permission problems) from contained entries.

        Raises:
            KeyError: if no child exists by the specified name.
            OSError: if user lacks permission to delete the file,
                or (Windows only) the file is open.
        rr&N)r�r�rSrVrDr�r�ror��
has_open_filer/�PERM_EXErdr�ra�remove_entry�listrGrlrkrF�AssertionError)r3r��	recursiver�r)r)r*r��s(



zFakeDirectory.remove_entrycCstdd�|j��D��S)zMReturn the total size of all files contained in this directory tree.
        cSsg|]}|dj�qS)r&)rk)r�r�r)r)r*r��sz&FakeDirectory.size.<locals>.<listcomp>)�sumrar�)r3r)r)r*rk�szFakeDirectory.sizez
property sizecCs|jS)N)rk)r3r)r)r*r��szFakeDirectory.GetSizecCs$|}x|r||krdS|j}qWdS)zmReturn `True` if dir_object is a direct or indirect parent
        directory, or if both are the same object.TF)r_)r3�
dir_objectr~r)r)r*�has_parent_object�s
zFakeDirectory.has_parent_objectcs\tt|���d}xD|jD]:}|j|��}x&|�d�D]}|r8|d|d}q8WqW|S)Nz:
�
z  )r1r�r�ra�split)r3�descriptionr��	item_desc�line)r5r)r*r��szFakeDirectory.__str__)N)T)r6r7r8r9�PERM_DEFr2rvr�rar�r�r�r�r�rkr
r�r�r�r:r)r))r5r*r�bs

'
r��AddEntry�GetEntry�RemoveEntrycs>eZdZdZd	�fdd�	Zedd��Ze�fdd��Z�ZS)
�FakeDirectoryFromRealDirectoryz~Represents a fake directory copied from the real file system.

    The contents of the directory are read on demand only.
    Ncst|p|}t�|�}tt|�jtj�|�d|j|d�|j|_|j	|_	|j
|_
|j|_|j|_||_
||_d|_dS)ao
        Args:
            source_path: Full directory path.
            filesystem: The fake filesystem where the directory is created.
            read_only: If set, all files under the directory are treated
                as read-only, e.g. a write access raises an exception;
                otherwise, writing to the files changes the fake files
                only as usually.
            target_path: If given, the target path of the directory,
                otherwise the target is the same as `source_path`.

        Raises:
            OSError: if the directory does not exist in the real file system
        r&)rUr�rSFN)r�r�r1r�r2r�r�rDrMrKrLrIrH�source_path�	read_onlyr�)r3r�rSr��target_path�	real_stat)r5r)r*r2
s

z'FakeDirectoryFromRealDirectory.__init__cCs�|js|d|_|j}xht�|j�D]X}tj�|j|�}tj�||�}tj�|�rd|jj||j	|d�q |jj
||j	|d�q W|jS)z[Return the list of contained directory entries, loading them
        if not already loaded.T)r�)r�r�r��listdirr�r{�isdirrS�add_real_directoryr��
add_real_filerc)r3�baser�r�r�r)r)r*ra*sz'FakeDirectoryFromRealDirectory.contentscs|js
dStt|�jS)Nr)r�r1r�rk)r3)r5r)r*rk<sz#FakeDirectoryFromRealDirectory.size)N)	r6r7r8r9r2r�rarkr:r)r))r5r*r�sr�c
@sbeZdZdZejjddfdd�Zedd��Z	d�dd�Z
d	d
�Zdd�Zd
d�Z
dd�Zd�dd�Zd�dd�Zedd��Zdd�Zdd�Zdd�Zd�dd�Zd�d d!�Zd"d#�Zd$d%�Zd�d&d'�Zd�d(d)�Zd*d+�Zd�d-d.�Zd�d/d0�Zd�d1d2�Zd�d3d4�Z d5d6�Z!e"d7d8��Z#d9d:�Z$d;d<�Z%d=d>�Z&d?d@�Z'dAdB�Z(dCdD�Z)dEdF�Z*dGdH�Z+dIdJ�Z,dKdL�Z-dMdN�Z.dOdP�Z/dQdR�Z0dSdT�Z1dUdV�Z2dWdX�Z3dYdZ�Z4d[d\�Z5d]d^�Z6d_d`�Z7d�dadb�Z8edcdd��Z9d�dedf�Z:dgdh�Z;didj�Z<dkdl�Z=dmdn�Z>dodp�Z?dqdr�Z@d�dsdt�ZAdudv�ZBd�dwdx�ZCd�dydz�ZDd{d|�ZEd}d~�ZFdd��ZGd�d��ZHd�d��ZId�d��ZJd�d��ZKeLfd�d��ZMeNeOBd�dd,ddddfd�d��ZPd�d�d��ZQd�d�d��ZRd�d�d��ZSeNeOBd�dd,ddddddf
d�d��ZTd�d�d��ZUd�d��ZVd�d��ZWd�d��ZXeLfd�d��ZYd�d��ZZeLdfd�d��Z[d�d�d��Z\d�d�d��Z]d�d�d��Z^d�d��Z_d�d��Z`d�d��Zad�d�d��Zbd�d��Zcd�d��Zdd�d��ZedS)��FakeFilesystemaProvides the appearance of a real directory tree for unit testing.

    Attributes:
        path_separator: The path separator, corresponds to `os.path.sep`.
        alternative_path_separator: Corresponds to `os.path.altsep`.
        is_windows_fs: `True` in a real or faked Windows file system.
        is_macos: `True` under MacOS, or if we are faking it.
        is_case_sensitive: `True` if a case-sensitive file system is assumed.
        root: The root :py:class:`FakeDirectory` entry of the file system.
        cwd: The current working directory path.
        umask: The umask used for newly created files, see `os.umask`.
        patcher: Holds the Patcher object if created from it. Allows access
        to the patcher object if using the pytest fs fixture.
    NcCs�||_tjj|_||_|tjkr&d|_tjdk|_	tjdk|_
|j	pH|j
|_t|j|d�|_
|j
j|_t�d�|_t�|j�g|_g|_d|_d|_i|_|�|j
j|�|��t|�|_dS)a^
        Args:
            path_separator:  optional substitute for os.path.sep
            total_size: if not None, the total size in bytes of the
                root filesystem.

        Example usage to emulate real file systems:

        >>> filesystem = FakeFilesystem(
        ...     alt_path_separator='/' if _is_windows else None)

        Nr �darwin)rS�r)�path_separatorr�r��altsep�alternative_path_separator�patcherrr;�platformrV�is_macosr�r��rootrU�cwd�umask�
open_files�
_free_fd_heap�	_last_ino�	_last_dev�mount_points�add_mount_point�_add_standard_streamsr��dev_null)r3r��
total_sizer�r)r)r*r2Ts(


zFakeFilesystem.__init__cCs|jo|jS)N)rVr�)r3r)r)r*�is_linux�szFakeFilesystem.is_linuxcCsTt|j|d�|_|jj|_g|_g|_d|_d|_i|_	|�
|jj|�|��dS)z3Remove all file system contents and reset the root.)rSrN)r�r�r�rUr�r�r�r�r�r�r�r�)r3r�r)r)r*�reset�s
zFakeFilesystem.resetcCs |jdkrtd��|j��dS)a�Pause the patching of the file system modules until `resume` is
        called. After that call, all file system calls are executed in the
        real file system.
        Calling pause() twice is silently ignored.
        Only allowed if the file system object was created by a
        Patcher object. This is also the case for the pytest `fs` fixture.

        Raises:
            RuntimeError: if the file system was not created by a Patcher.
        NzUpause() can only be called from a fake file system object created by a Patcher object)r��RuntimeError�pause)r3r)r)r*r��s
zFakeFilesystem.pausecCs |jdkrtd��|j��dS)aGResume the patching of the file system modules if `pause` has
        been called before. After that call, all file system calls are
        executed in the fake file system.
        Does nothing if patching is not paused.
        Raises:
            RuntimeError: if the file system has not been created by `Patcher`.
        NzVresume() can only be called from a fake file system object created by a Patcher object)r�r��resume)r3r)r)r*r��s
zFakeFilesystem.resumecCs|jr
dSdS)Nz
r�)rV)r3r)r)r*�line_separator�szFakeFilesystem.line_separatorcCst�|�dS)Nz in the fake filesystem)r��strerror)r3ror)r)r*�_error_message�szFakeFilesystem._error_messagecCsP|�|�}|dk	r@tjdkr@|jr@tr2t|||��t||||��t|||��dS)a*Raises OSError.
        The error message is constructed from the given error code and shall
        start with the error string issued in the real system.
        Note: this is not true under Windows if winerror is given - in this
        case a localized message specific to winerror will be shown in the
        real file system.

        Args:
            errno: A numeric error code from the C variable errno.
            filename: The name of the affected file, if any.
            winerror: Windows only - the specific Windows error code.
        Nr )r�r;r�rVr�WindowsErrorr�)r3ro�filename�winerror�messager)r)r*r��s
zFakeFilesystem.raise_os_errorcCst||�|�|��dS)a%Raises IOError.
        The error message is constructed from the given error code and shall
        start with the error in the real system.

        Args:
            errno: A numeric error code from the C variable errno.
            filename: The name of the affected file, if any.
        N)r�r�)r3ror�r)r)r*rn�s	zFakeFilesystem.raise_io_errorcCsL|dkr|Str$t|t�rHt|�Sn$t|t�rHt|t�rH|�t�d��S|S)z{Return the string as byte or unicode depending
        on the type of matched, assuming string is an ASCII string.
        NF)rrdrre�strrrrgrh)�matched�stringr)r)r*�_matching_string�s

zFakeFilesystem._matching_stringcCs|�||j�S)z2Return the path separator as the same type as path)rr�)r3r�r)r)r*rz�szFakeFilesystem._path_separatorcCs|�||j�S)z>Return the alternative path separator as the same type as path)rr�)r3r�r)r)r*�_alternative_path_separator�sz*FakeFilesystem._alternative_path_separatorcCs|jptjdkS)N)rrw)rVr;�version_info)r3r)r)r*�_is_link_supported�sz!FakeFilesystem._is_link_supportedcCsr|�|�}||jkr"|�tj|�|jd7_|j|dd�|j|<||jjkrV|jn|�|�}|j|_	|j|S)a�Add a new mount point for a filesystem device.
        The mount point gets a new unique device number.

        Args:
            path: The root path for the new mount path.

            total_size: The new total size of the added filesystem device
                in bytes. Defaults to infinite size.

        Returns:
            The newly created mount point dict.

        Raises:
            OSError: if trying to mount an existing mount point again.
        r&r)�idevr��	used_size)
r|r�r�ror�r�r�rU�
create_dirrF)r3r�r��root_dirr)r)r*r��s


zFakeFilesystem.add_mount_pointFcCs6|jr2|s|�|�s2|�|�d}|r2|j|d�SdS)Nr)r�)rV�_mount_point_for_path�
splitdriver�)r3r��force�driver)r)r*�_auto_mount_drive_if_neededs
z*FakeFilesystem._auto_mount_drive_if_neededcCs�dd�}|�|�|��}||jkr,|j|S|�|d�}|�|�dd�}xH|jD]>}|�||�}|rr|�|�srqR|�|�rRt|�t|�krR|}qRW|r�|j||�S|j|dd�}|s�t�|S)NcSs>|dkst|t�r|Str*|�t�d��S|�t�d��SdS)zXConvert the str, unicode or byte object to a str
            using the default encoding.NF)rdr�rrrrgrhrf)rr)r)r*�to_strs
z4FakeFilesystem._mount_point_for_path.<locals>.to_str�r&T)r)	r|�_original_pathr�rr�
startswithr]rr�)r3r�r�
mount_pathr
�	root_path�mount_pointr)r)r*r
s"


z$FakeFilesystem._mount_point_for_pathcCs(x"|j��D]}|d|kr|SqWdS)Nr)r��values)r3rrr)r)r*�_mount_point_for_device9sz&FakeFilesystem._mount_point_for_devicecCshtdd�}|dkr"|j|jj}n
|�|�}|r\|ddk	r\||d|d|d|d�S|ddd�S)a�Return the total, used and free disk space in bytes as named tuple,
        or placeholder values simulating unlimited space if not set.

        .. note:: This matches the return value of shutil.disk_usage().

        Args:
            path: The disk space is returned for the file system device where
                `path` resides.
                Defaults to the root path (e.g. '/' on Unix systems).
        �usageztotal, used, freeNr�rlr)rr�r�rUr
)r3r��	DiskUsagerr)r)r*�get_disk_usage>s

zFakeFilesystem.get_disk_usagecCsL|dkr|jj}|�|�}|ddk	r@|d|kr@|�tj|�||d<dS)a�Changes the total size of the file system, preserving the used space.
        Example usage: set the size of an auto-mounted Windows drive.

        Args:
            total_size: The new total size of the filesystem in bytes.

            path: The disk space is changed for the file system device where
                `path` resides.
                Defaults to the root path (e.g. '/' on Unix systems).

        Raises:
            IOError: if the new space is smaller than the used size.
        Nr�r)r�rUr
rnrorp)r3r�r�rr)r)r*�set_disk_usageVs
zFakeFilesystem.set_disk_usagecCsP|�|�}|rL|d}|dk	r<||d|kr<|�tj|�|d|7<dS)a�Change the used disk space by the given amount.

        Args:
            usage_change: Number of bytes added to the used space.
                If negative, the used space will be decreased.

            file_path: The path of the object needing the disk space.

            st_dev: The device ID for the respective file system.

        Raises:
            IOError: if usage_change exceeds the free file system space
        r�Nr)rrnrorp)r3�usage_changer4rFrr�r)r)r*rlls
z FakeFilesystem.change_disk_usageTc
Csxy(|j||dd�}|�|||�|j��Stk
rr}z,t|d�rJ|jn|j}|j|j||d�Wdd}~XYnXdS)a�Return the os.stat-like tuple for the FakeFile object of entry_path.

        Args:
            entry_path:  Path to filesystem object to retrieve.
            follow_symlinks: If False and entry_path points to a symlink,
                the link itself is inspected instead of the linked object.

        Returns:
            The FakeStatResult object corresponding to entry_path.

        Raises:
            OSError: if the filesystem object doesn't exist.
        T)�allow_fdr�)r�N)	�resolve�(raise_for_filepath_ending_with_separatorrX�copyr��hasattrr�ror�)r3�
entry_path�follow_symlinks�file_object�io_errorr�r)r)r*r��s

zFakeFilesystem.statc	
Cs�|�|�r�t|j�r�y|�|�}WnRttfk
rt}z0|jrN|jtjkrNdS|j	rb|�
tj|��Wdd}~XYnX|r�|j	s�|jr�|}|j	r�t|j�}n$|jr�|r�t|j�}nt
|j�}|r�|j	r�tjntj}|�
||�dS)N)�ends_with_path_separatorrrDrr�r�r�ro�ENOENTrVr��EINVALr	r�ENOTDIR)	r3r"r$r#�macos_handling�link_object�exc�is_error�error_nrr)r)r*r�s*


z7FakeFilesystem.raise_for_filepath_ending_with_separatorc
Cs�y|j||dd�}Wn>tk
rR}z |jtjkr@|�tj|��Wdd}~XYnX|jr~|t@rp|jdB|_q�|jd@|_n|jt@|t@B|_t	�	�|_
dS)a5Change the permissions of a file as encoded in integer mode.

        Args:
            path: (str) Path to the file.
            mode: (int) Permissions.
            follow_symlinks: If `False` and `path` points to a symlink,
                the link itself is affected instead of the linked object.
        T)rN�im�)rr�ror'r�rVr�rD�PERM_ALLrWrM)r3r��moder#r$r%r)r)r*�chmod�s	
zFakeFilesystem.chmodc	
Cs�|�||�y|j||dd�}Wn>tk
r^}z |jtjkrL|�tj|��Wdd}~XYnX|dk	r�x"|D]}t|ttf�snt	d��qnW|d|_
|d|_nR|dk	r�x|D]}t|t�s�t	d��q�W|d|_|d|_
nt��}||_
||_dS)a#Change the access and modified times of a file.

        Args:
            path: (str) Path to the file.
            times: 2-tuple of int or float numbers, of the form (atime, mtime)
                which is used to set the access and modified times in seconds.
                If None, both times are set to the current time.
            ns: 2-tuple of int numbers, of the form (atime, mtime)  which is
                used to set the access and modified times in nanoseconds.
                If `None`, both times are set to the current time.
                New in Python 3.3.
            follow_symlinks: If `False` and entry_path points to a symlink,
                the link itself is queried instead of the linked object.
                New in Python 3.3.

            Raises:
                TypeError: If anything other than the expected types is
                    specified in the passed `times` or `ns` tuple,
                    or if the tuple length is not equal to 2.
                ValueError: If both times and ns are specified.
        T)rNzatime and mtime must be numbersrr&zatime and mtime must be ints)�_handle_utime_arg_errorsrr�ror'r�rd�int�float�	TypeErrorrKrLrNrOrW)	r3r��times�nsr#r$r%�	file_time�current_timer)r)r*�utime�s,




zFakeFilesystem.utimecCsT|dk	r|dk	rtd��|dk	r4t|�dkr4td��|dk	rPt|�dkrPtd��dS)Nz:utime: you may specify either 'times' or 'ns' but not bothrwz9utime: 'times' must be either a tuple of two ints or Nonez'utime: 'ns' must be a tuple of two ints)rRr]r6)r3r8r7r)r)r*r3sz'FakeFilesystem._handle_utime_arg_errorscCs||�|�_dS)a>Set the self.st_ino attribute of file at 'path'.
        Note that a unique inode is assigned automatically to a new fake file.
        Using this function does not guarantee uniqueness and should used
        with caution.

        Args:
            path: Path to file.
            st_ino: The desired inode.
        N)�
get_objectrE)r3r�rEr)r)r*r�szFakeFilesystem.SetInocCs>|jr"t�|j�}|g|j|<|S|j�|g�t|j�dS)aXAdd file_obj to the list of open files on the filesystem.
        Used internally to manage open files.

        The position in the open_files array is the file descriptor number.

        Args:
            file_obj: File object to be added to open files list.

        Returns:
            File descriptor number for the file object.
        r&)r��heapq�heappopr��appendr])r3�file_obj�open_fdr)r)r*�_add_open_fileszFakeFilesystem._add_open_filecCsd|j|<t�|j|�dS)z�Remove file object with given descriptor from the list
        of open files.

        Sets the entry in open_files to None.

        Args:
            file_des: Descriptor of file object to be removed from
            open files list.
        N)r�r=�heappushr�)r3�file_desr)r)r*�_close_open_file-s

zFakeFilesystem._close_open_filecCsLt|�std��|t|j�ks,|j|dkr>|�tjt|��|j|dS)aReturn an open file.

        Args:
            file_des: File descriptor of the open file.

        Raises:
            OSError: an invalid file descriptor.
            TypeError: filedes is not an integer.

        Returns:
            Open file object.
        zan integer is requiredNr)rr6r]r�r�ro�EBADFr�)r3rDr)r)r*�
get_open_file:s
zFakeFilesystem.get_open_filecCs|dd�|jD�kS)z�Return True if the given file object is in the list of open files.

        Args:
            file_object: The FakeFile object to be checked.

        Returns:
            `True` if the file is open.
        cSsg|]}|r|d���qS)r)r<)r��wrappersr)r)r*r�Wsz0FakeFilesystem.has_open_file.<locals>.<listcomp>)r�)r3r$r)r)r*r�Ns	zFakeFilesystem.has_open_filecCs*|jdks|s|S|�|�|�|�|��S)N)r��replacerrz)r3r�r)r)r*�_normalize_path_sepZsz"FakeFilesystem._normalize_path_sepcCst|�}|�|�S)aReplace all appearances of alternative path separator
        with path separator.

        Do nothing if no alternative separator is set.

        Args:
            path: The path to be normalized.

        Returns:
            The normalized path that will be used internally.
        )rrJ)r3r�r)r)r*�normcase`szFakeFilesystem.normcasecCs�|�|�}|�|�\}}|�|�}|�|�}|�|�}g}|�|d�}|�|d�}xN|D]F}	|	rX|	|krjqX|	|kr�|r�|d|kr�|��qXn|r�qX|�|	�qXW|�|�}
|r�||
}
||
p�|S)a�Mimic os.path.normpath using the specified path_separator.

        Mimics os.path.normpath using the path_separator that was specified
        for this FakeFilesystem. Normalizes the path, but unlike the method
        absnormpath, does not make it absolute.  Eliminates dot components
        (. and ..) and combines repeated path separators (//).  Initial ..
        components are left in place for relative paths.
        If the result is an empty path, '.' is returned instead.

        This also replaces alternative path separator with path separator.
        That is, it behaves like the real os.path.normpath on Windows if
        initialized with '\' as path separator and  '/' as alternative
        separator.

        Args:
            path:  (str) The path to normalize.

        Returns:
            (str) A copy of path with empty components and dot components
            removed.
        �.z..���)	rKrrzrr�rr=r?r{)r3r�r
r�is_absolute_path�path_components�collapsed_path_components�dot�dotdot�	component�collapsed_pathr)r)r*�normpathos.





zFakeFilesystem.normpathcs�����fdd�}�js�s �S�����g��j}xb�D]Z}t|t�sN|�S��||�\}}|dks�t|t�r�|jdkr�|jdkr�|�S��|�q:W|�S)aDReturn a normalized case version of the given path for
        case-insensitive file systems. For case-sensitive file systems,
        return path unchanged.

        Args:
            path: the file path to be transformed

        Returns:
            A version of path matching the case of existing path elements.
        csZt��t��kr&���t��d������}|���}��|�rV|�|�sV||}|S)N)r]�extendrzr{r)r�normalized_path)�normalized_componentsr�rOr3r)r*�components_to_path�s

z9FakeFilesystem._original_path.<locals>.components_to_pathNr)	r��_path_componentsr�rdr��_directory_contentr\rJr?)r3r�rY�current_dirrS�dir_namer))rXr�rOr3r*r�s$







zFakeFilesystem._original_pathcCs�|�|�}|�||j�}|s$|j}nF|�|�sj|�||jj�}|�|d�}|�|��||kr`|pb||f�}||�|d�kr~|}|�	|�S)arAbsolutize and minimalize the given path.

        Forces all relative paths to be absolute, and normalizes the path to
        eliminate dot and empty components.

        Args:
            path:  Path to normalize.

        Returns:
            The normalized path relative to the current working directory,
            or the root directory if path is empty.
        rrL)
rKrr�r��_starts_with_root_pathr�rUrzr{rU)r3r�r��	root_name�emptyr)r)r*r|�s


zFakeFilesystem.absnormpathc	Cs|�|�}|�|�}|�|�}|s&dS|�|�}|��}|�|d�}|sr|rj|�|�}|d||dfSd|fSx�|D]|}|rxx|ds�|��q�W|r�|s�|�|�}|d||dfSt|�dkr�|d�|�r�|d||fS|�|�|fSqxW||fS)a�Mimic os.path.splitpath using the specified path_separator.

        Mimics os.path.splitpath using the path_separator that was specified
        for this FakeFilesystem.

        Args:
            path:  (str) The path to split.

        Returns:
            (str) A duple (pathname, basename) for which pathname does not
            end with a slash, and basename does not contain a slash.
        )rrrxrr&rrM)	rKrzr��_starts_with_drive_letterr=rr]�endswithr{)	r3r�rrO�starts_with_driver��colon�
componentsrSr)r)r*�	splitpath�s4







zFakeFilesystem.splitpathcCst|�}|j�r
t|�dk�r
|�|�}|�|�}tjdkr�|dd�|dkr�|dd�|kr�|�|d�}|dkr�|dd�|fS|�||d�}||dkr�|dd�|fS|dkr�t|�}|d|�||d�fS|dd�|�|d�k�r
|dd�|dd�fS|dd�|fS)	a�Splits the path into the drive part and the rest of the path.

        Taken from Windows specific implementation in Python 3.5
        and slightly adapted.

        Args:
            path: the full path to be splitpath.

        Returns:
            A tuple of the drive part and the rest of the path, or of
            an empty string and the full path if drive letters are
            not supported or no drive is present.
        rw)rw��rrrMNr&rx)	rrVr]rKrzr;r�findr)r3r�r�	sep_index�
sep_index2r)r)r*rs(


zFakeFilesystem.splitdrivecGs"|d}|dd�}|�|�}||�|�g}|�|�\}}x�|D]�}|�|�\}	}
|
rz|
dd�|krz|	sn|sr|	}|
}q@n0|	r�|	|kr�|js�|	��|��kr�|	}|
}q@|	}|r�|dd�|kr�||}||
}q@W|�|d�}|�r|dd�|k�r|�r|dd�|k�r|||S||S)zSTaken from Python 3.5 os.path.join() code in ntpath.py
        and slightly adaptedrr&NrMrx)rzrrr�r�r)r3�	all_paths�	base_path�paths_to_addr�seps�result_drive�result_pathr��
drive_part�	path_partrdr)r)r*�_join_paths_with_drive_support6s6

z-FakeFilesystem._join_paths_with_drive_supportcGs�tjdkrdd�|D�}t|�dkr,|dS|jr<|j|�Sg}|�|d�}xH|D]@}|�|�rj|g}qT|r�|d�|�s�|�|�|rT|�|�qTW|�	|dd��
|�S)aMimic os.path.join using the specified path_separator.

        Args:
            *paths:  (str) Zero or more paths to join.

        Returns:
            (str) The paths joined by the path separator, starting with
            the last absolute path in paths.
        )r�cSsg|]}t�|��qSr))r��fspath)r�r�r)r)r*r�esz,FakeFilesystem.joinpaths.<locals>.<listcomp>r&rrMr)r;rr]rVrtrzr^rbr?rr{)r3�paths�joined_path_segmentsr�path_segmentr)r)r*�	joinpathsZs"





zFakeFilesystem.joinpathscCs�|r||�|�krgS|�|�\}}|�|�|��}|s@|s@t�|dsnt|�dkrb|dsbg}n|dd�}|r~|�d|�|S)a7Breaks the path into a list of component names.

        Does not include the root directory as a component, as all paths
        are considered relative to the root directory for the FakeFilesystem.
        Callers should basically follow this pattern:

        .. code:: python

            file_path = self.absnormpath(file_path)
            path_components = self._path_components(file_path)
            current_dir = self.root
            for component in path_components:
                if component not in current_dir.contents:
                    raise IOError
                _do_stuff_with_component(current_dir, component)
                current_dir = current_dir.get_entry(component)

        Args:
            path:  Path to tokenize.

        Returns:
            The list of names split from path.
        rr&N)rzrr�r�r]ry)r3r�r
rOr)r)r*rZxszFakeFilesystem._path_componentscCs<|�|d�}|jo:t|�dko:|dd�jo:|dd�|kS)aReturn True if file_path starts with a drive letter.

        Args:
            file_path: the full path to be examined.

        Returns:
            `True` if drive letter support is enabled in the filesystem and
            the path starts with a drive letter.
        rxrwNr&)rrVr]�isalpha)r3r4rdr)r)r*ra�s
z(FakeFilesystem._starts_with_drive_lettercCsH|�||jj�}|�|�}|�|�pF|jr>|���|���pF|�|�S)N)rr�rUrJrr�r�ra)r3r4r_r)r)r*r^�s


z%FakeFilesystem._starts_with_root_pathcCsV|�||jj�}||kpT|jr0|��|��kpTdt|�koFdknoT|�|�S)Nrwr)rr�rUr�r�r]ra)r3r4r_r)r)r*�
_is_root_path�s
zFakeFilesystem._is_root_pathcCsRt|�rdSt|�}|oP||j|jfkoP|�|�|��pP|jdk	oP|�|�|��S)z>Return True if ``file_path`` ends with a valid path separator.FN)rrr�r�rbrzr)r3r4r)r)r*r&�s

z'FakeFilesystem.ends_with_path_separatorcCs|�|�sdS|�|�|��S)NF)r&�isfile�!_path_without_trailing_separators)r3r�r)r)r*�!is_filepath_ending_with_separator�s
z0FakeFilesystem.is_filepath_ending_with_separatorcsRt�t�sdS��jkr&��j�fS|jsN��fdd��jD�}|rN|dSdS)N)NNcs*g|]"}|�����kr|�j|f�qSr))r�ra)r��subdir)rS�	directoryr)r*r��sz5FakeFilesystem._directory_content.<locals>.<listcomp>r)rdr�rar�)r3r�rS�matching_contentr))rSr�r*r[�s


z!FakeFilesystem._directory_contentc	Cs�|r|�|�rdSt|�}|dkr&t�|s.dS||jjkrB|jSy|�|�rRdS|�|�}Wntt	fk
rvdSX||j
jkr�dS|�|�}|j
}x$|D]}|�||�d}|s�dSq�WdS)aReturn true if a path points to an existing file system object.

        Args:
            file_path:  The path to examine.

        Returns:
            (bool) True if the corresponding object exists.

        Raises:
            TypeError: if file_path is None.
        TNFr&)
�islinkrr6r�rUrVr�resolve_pathr�r�r�rZr[)r3r4�
check_linkrOr\rSr)r)r*�exists�s0


zFakeFilesystem.existscCs"tst|t�r|�t�d��}|S)NF)rrdrerfrgrh)r�r)r)r*�
_to_stringszFakeFilesystem._to_stringcCs�|r(tjdkr(t|t�r(|�|���jSt|�}|dkr@td��|�	|�}|rX|�
|�sf|�tj
|�|�|�|��}|�|�r�|S||jjkr�|S|�|�}|�||�}|�|�S)a9Follow a path, resolving symlinks.

        ResolvePath traverses the filesystem along the specified file path,
        resolving file names and symbolic links until all elements of the path
        are exhausted, or we reach a file which does not exist.
        If all the elements are not consumed, they just get appended to the
        path resolved so far.
        This gives us the path which is as resolved as it can be, even if the
        file does not exist.

        This behavior mimics Unix semantics, and is best shown by example.
        Given a file system that looks like this:

              /a/b/
              /a/b/c -> /a/b2          c is a symlink to /a/b2
              /a/b2/x
              /a/c   -> ../d
              /a/x   -> y

         Then:
              /a/b/x      =>  /a/b/x
              /a/c        =>  /a/d
              /a/x        =>  /a/y
              /a/b/c/d/e  =>  /a/b2/d/e

        Args:
            file_path: The path to examine.
            allow_fd: If `True`, `file_path` may be open file descriptor.
            raw_io: `True` if called from low-level I/O functions.

        Returns:
            The resolved_path (string) or None.

        Raises:
            TypeError: if `file_path` is `None`.
            IOError: if `file_path` is '' or a part of the path doesn't exist.
        )rrNz/Expected file system path string, received None)r;rrdr4rGr<r�rr6r��_valid_relative_pathrnror'r|rr|r�rUrZ�_resolve_components�_components_to_path)r3r4r�raw_iorO�resolved_componentsr)r)r*r�s"'



zFakeFilesystem.resolve_pathcCs8|r|�|d�n|j}|�|�}|�|�s4||}|S)Nr)rzr�r{r^)r3�component_foldersrr�r)r)r*r�Ds


z"FakeFilesystem._components_to_pathc
Cs�|j}d}g}x�|r�|�d�}|�|�|�||�d}|dkrL|�|�Pt|j�r|tkr�|rh|jn|j	}|t
j|�|��|�
||�}|�|�}	|	|}g}|j}|d7}qW|S)Nrr&)r�r=r?r[rVrrD�_MAX_LINK_DEPTHr�rnro�ELOOPr��_follow_linkrZ)
r3rOr�r\�
link_depthr�rSr��	link_path�target_componentsr)r)r*r�Ls.





z"FakeFilesystem._resolve_componentscCsX|jr
dS|�||jd�}x6|rR||krR|d|�|��}|�|�|��sdSqWdS)NTz..F)rVrr��rfindr�r|)r3r4�slash_dotdotr)r)r*r�ssz#FakeFilesystem._valid_relative_pathcCsD|j}|�|�}|�|�s:|dd�}|�|�|�|�}|�|�S)a9Follow a link w.r.t. a path resolved so far.

        The component is either a real file, which is a no-op, or a
        symlink. In the case of a symlink, we have to modify the path
        as built up so far
          /a/b => ../c  should yield /a/../c (which will normalize to /a/c)
          /a/b => x     should yield /a/x
          /a/b => /x/y/z should yield /x/y/z
        The modified path may land us in a new spot which is itself a
        link, so we may repeat the process.

        Args:
            link_path_components: The resolved path built up to the link
                so far.
            link: The link object itself.

        Returns:
            (string) The updated path resolved after following the link.

        Raises:
            IOError: if there are too many levels of symbolic link
        NrM)rarzr^r?r{rU)r3�link_path_components�linkr�rrer)r)r*r�~s



zFakeFilesystem._follow_linkcCs�t|�}||jjkr|jS||jjkr,|jS|�|�}|�|�}|j}y^xX|D]P}t|j�rh|�|j	�}t
|j�s�|js�|�t
j|�|�t
j|�|�|�}qNWWn"tk
r�|�t
j|�YnX|S)a�Search for the specified filesystem object within the fake
        filesystem.

        Args:
            file_path: Specifies target FakeFile object to retrieve, with a
                path that has already been normalized/resolved.

        Returns:
            The FakeFile object corresponding to file_path.

        Raises:
            IOError: if the object is not found.
        )rr�rUr�rrZrrDrrarrVrnror)r'r��KeyError)r3r4rO�
target_objectrSr)r)r*�get_object_from_normpath�s(




z'FakeFilesystem.get_object_from_normpathcCs"t|�}|�|�|��}|�|�S)aASearch for the specified filesystem object within the fake
        filesystem.

        Args:
            file_path: Specifies the target FakeFile object to retrieve.

        Returns:
            The FakeFile object corresponding to `file_path`.

        Raises:
            IOError: if the object is not found.
        )rr|rr�)r3r4r)r)r*r<�s
zFakeFilesystem.get_objectcCsTt|t�r.|r&tjdkr&|�|���Std��|rJt|�}|�|�	|��S|�
|�S)a�Search for the specified filesystem object, resolving all links.

        Args:
            file_path: Specifies the target FakeFile object to retrieve.
            follow_symlinks: If `False`, the link itself is resolved,
                otherwise the object linked to.
            allow_fd: If `True`, `file_path` may be an open file descriptor

        Returns:
          The FakeFile object corresponding to `file_path`.

        Raises:
            IOError: if the object is not found.
        )rrzCpath should be string, bytes or os.PathLike (if supported), not int)rdr4r;rrGr<r6rr�r��lresolve)r3r4r#rr)r)r*r�s
zFakeFilesystem.resolvecCs�t|�}||jjkr|jS|�|�}|�|�}|�|�\}}|sF|j}yR|�|�}|sZt�t	|t
�s�|js�t	|t�r�|�
tj|�|�
tj|�|�|�Stk
r�|�
tj|�YnXdS)a�Search for the specified object, resolving only parent links.

        This is analogous to the stat/lstat difference.  This resolves links
        *to* the object but not of the final object itself.

        Args:
            path: Specifies target FakeFile object to retrieve.

        Returns:
            The FakeFile object corresponding to path.

        Raises:
            IOError: if the object is not found.
        N)rr�rUr~rrfr�rr�rdr�rVrCrnror)r'r�r�)r3r��parent_directory�
child_name�
parent_objr)r)r*r��s$




zFakeFilesystem.lresolvecCsT|p|j}|s|j}n0|�|�}t|j�sF|jr6tjntj}|||�|�	|�dS)a�Add a fake file or directory into the filesystem at file_path.

        Args:
            file_path: The path to the file to be added relative to self.
            file_object: File or directory to add.
            error_class: The error class to be thrown if file_path does
                not correspond to a directory (used internally(

        Raises:
            IOError or OSError: if file_path does not correspond to a
                directory.
        N)
r�r�rrrDrVror'r)r�)r3r4r$r��target_directory�errorr)r)r*�
add_objects



zFakeFilesystem.add_objectc
Cs�|�|�}|�|�}|�|�}|j|dd�s<|�tj|d�|rJ|�|�|�|�}|jsh|�	|||�|j|dd�r�|�
|||||�}|s�dS|�|�\}}|�|�\}}	|�|�s�|�tj|�|�|�}
|�|�}|
j
|j
kr�|�tj|�t|j��s|�|j�rtjntj|�|�|��r4|�tj|�|
�|�}|
j|dd�|	|_|�|	�}	|	|jk�rr|�|	�|�|�dS)a�Renames a FakeFile object at old_file_path to new_file_path,
        preserving all properties.

        Args:
            old_file_path: Path to filesystem object to rename.
            new_file_path: Path to where the filesystem object will live
                after this call.
            force_replace: If set and destination is an existing file, it
                will be replaced even under Windows if the user has
                permissions, otherwise replacement happens under Unix only.

        Raises:
            OSError: if old_file_path does not exist.
            OSError: if new_file_path is an existing directory
                (Windows, or Posix if old_file_path points to a regular file)
            OSError: if old_file_path is a directory and new_file_path a file
            OSError: if new_file_path is an existing file and force_replace
                not set (Windows only).
            OSError: if new_file_path is an existing file and could not be
                removed (Posix, or Windows with force_replace set).
            OSError: if dirname(new_file_path) does not exist.
            OSError: if the file would be moved to another filesystem
                (e.g. mount point).
        T)r�rwNF)r�)r&r|r�r�ror'�%_handle_broken_link_with_trailing_sepr�rV�_handle_posix_dir_link_errors�_rename_to_existing_pathrfrrF�EXDEVrrDr�r)r�r(r�r�rUr�rar�)
r3�
old_file_path�
new_file_path�
force_replace�
ends_with_sep�
old_object�old_dir�old_name�new_dir�new_name�old_dir_object�new_dir_object�object_to_renamer)r)r*�rename3sL











zFakeFilesystem.renamecCsB|�|�r>|�|�s>|jr tjn|jr,tjntj}|�||�dS)N)	r�r�r�ror'rVr(r)r�)r3r�r�r)r)r*r�ys


z4FakeFilesystem._handle_broken_link_with_trailing_sepcCs�|j|dd�r&|�|�r&|�tj|�|j|dd�rh|�|�rh|rL|jrLdS|rVtjntj}|�||�|r�|�|�r�||kr�|js�|�tj|�dS)NF)r#)r�r�r�ror)r�r�rV)r3r�r�r�r�r)r)r*r��s


z,FakeFilesystem._handle_posix_dir_link_errorsc	
Cs|�|�}||krBt|j�s>|r>|jr,tjntj}|�||�dS||krX|�||�}n�t	|j�slt|j�r�|�
|||||�n�t	|j�r�|jr�tjntj}|�||�n^|jr�|s�|�tj|�nDy|�|�Wn4t
k
�r}z|�|j|j�Wdd}~XYnX|S)N)r<rrDrVror(r)r��_rename_same_objectr�$_handle_rename_error_for_dir_or_linkr��
remove_objectr�r�)	r3r�r�r�r�r��
new_objectr�r,r)r)r*r��s.



"z'FakeFilesystem._rename_to_existing_pathcCsv|jr(|r|�tj|�n|�tj|�t|j�sr|jrZt|j�rL|rL|jsZ|�tj	|�t
|j�rr|�tj|�dS)N)rVr�ror�r�rrDrar��	ENOTEMPTYr	r�)r3r�r�r�r�r�r)r)r*r��s



z3FakeFilesystem._handle_rename_error_for_dir_or_linkc
	Cs�|��|��k}|s�y�|�|�}|�|�}|�|�}||kr~||k|��|��kkr~|j|dd�}tj�|�|jkpz|j}n|��|��k}|r�|�	|�\}}	|�
|�|�|	�}Wnttfk
r�YnX|s�d}|S)NF)r#)
r�r�rrr�r�r�rUr�rfrzr�r�)
r3r�r��	do_rename�
real_old_path�original_old_path�
real_new_path�real_object�parent�	file_namer)r)r*r��s2




z"FakeFilesystem._rename_same_objectcCs�|�|�|��}|�|�r(|�tj|�y&|�|�\}}|�|�}|�|�WnBt	k
rp|�
tj|�Yn"tk
r�|�
tj
|�YnXdS)anRemove an existing file or directory.

        Args:
            file_path: The path to the file relative to self.

        Raises:
            IOError: if file_path does not correspond to an existing file, or
                if part of the path refers to something other than a directory.
            OSError: if the directory is in use (eg, if it is '/').
        N)r|rr|r�ro�EBUSYrfrr�r�rnr'�AttributeErrorr))r3r4�dirnamer�r�r)r)r*r��s

zFakeFilesystem.remove_objectcCs0t|�}|�|tj�}|�||j�}|�||�S)N)rrr�rr�rI)r3r��os_sep�fake_sepr)r)r*r�szFakeFilesystem.make_string_pathc	Cs|�|�}|�|�}|�|�|j|dd�r:|�tj|�|�|�}|j}g}x~|D]v}|�	||�d}|s�t
||d�}|�|�|�|�|}qTt
|j�r�|�|j�}|}|jt@tkrT|�tj|j�qTWx|D]}t|B|_q�W|jd7_|j|_|S)a�Create `directory_path`, and all the parent directories.

        Helper method to set up your test faster.

        Args:
            directory_path: The full directory path to create.
            perm_bits: The permission bits as set by `chmod`.

        Returns:
            The newly created FakeDirectory object.

        Raises:
            OSError: if the directory already exists.
        T)r�r&)rS)rr|rr�r�ror�rZr�r[r�r?r�rrDrrarr)r�r�rE)	r3�directory_pathr�rOr\�new_dirsrSr�r�r)r)r*r�s2








zFakeFilesystem.create_dirrc

Cs|j|||||||||	d�	S)aGCreate `file_path`, including all the parent directories along
        the way.

        This helper method can be used to set up tests more easily.

        Args:
            file_path: The path to the file to create.
            st_mode: The stat constant representing the file type.
            contents: the contents of the file. If not given and st_size is
                None, an empty file is assumed.
            st_size: file size; only valid if contents not given. If given,
                the file is considered to be in "large file mode" and trying
                to read from or write to the file will result in an exception.
            create_missing_dirs: If `True`, auto create missing directories.
            apply_umask: `True` if the current umask must be applied
                on `st_mode`.
            encoding: If `contents` is a unicode string, the encoding used
                for serialization.
            errors: The error mode used for encoding/decoding errors.
            side_effect: function handle that is executed when file is written,
                must accept the file object as an argument.

        Returns:
            The newly created FakeFile object.

        Raises:
            IOError: if the file already exists.
            IOError: if the containing directory is required and missing.
        )rb)�create_file_internally)
r3r4rDrarJ�create_missing_dirs�apply_umaskrYrZrbr)r)r*�create_file*	s!
zFakeFilesystem.create_filecCsn|p|}t|�}|�|�}t�|�}|j|dd�}|j�|�|rP|jdM_||_|�|j	|j
|j�|S)aDCreate `file_path`, including all the parent directories along the
        way, for an existing real file. The contents of the real file are read
        only on demand.

        Args:
            source_path: Path to an existing file in the real file system
            read_only: If `True` (the default), writing to the fake file
                raises an exception.  Otherwise, writing to the file changes
                the fake file only.
            target_path: If given, the path of the target direction,
                otherwise it is equal to `source_path`.

        Returns:
            the newly created FakeFile object.

        Raises:
            OSError: if the file does not exist in the real file system.
            IOError: if the file already exists in the fake file system.

        .. note:: On most systems, accessing the fake file's contents may
            update both the real and fake files' `atime` (access time).
            In this particular case, `add_real_file()` violates the rule
            that `pyfakefs` must not modify the real file system.
        T)�read_from_real_fsi$�)rr�r�r�rX�set_from_stat_resultrDr4rlrkrUrF)r3r�r�r�r��	fake_filer)r)r*r�O	s

zFakeFilesystem.add_real_filec

Cs|�|�}tj�|�s$|�tj|�|p*|}|r�tj�|�d}|�|�rV|�|�}n
|�	|�}t
||||�}|�|�|jd7_|j|_
nn|�	|�}xbt�|�D]T\}}	}
tj�|jtj�||��}x.|
D]&}|�tj�||�|tj�||��q�Wq�W|S)a"Create a fake directory corresponding to the real directory at the
        specified path.  Add entries in the fake directory corresponding to
        the entries in the real directory.

        Args:
            source_path: The path to the existing directory.
            read_only: If set, all files under the directory are treated as
                read-only, e.g. a write access raises an exception;
                otherwise, writing to the files changes the fake files only
                as usually.
            lazy_read: If set (default), directory contents are only read when
                accessed, and only until the needed subdirectory level.

                .. note:: This means that the file system size is only updated
                  at the time the directory contents are read; set this to
                  `False` only if you are dependent on accurate file system
                  size in your test
            target_path: If given, the target directory, otherwise,
                the target directory is the same as `source_path`.

        Returns:
            the newly created FakeDirectory object.

        Raises:
            OSError: if the directory does not exist in the real file system.
            IOError: if the directory already exists in the fake file system.
        rr&)r~r�r�r�rnror'r�r<rr�r�r�rErr{�relpathr�)
r3r�r��	lazy_readr��parent_pathr_r�r��_�files�new_base�	fileEntryr)r)r*r�x	s.







z!FakeFilesystem.add_real_directorycCs:x4|D],}tj�|�r&|�|||�q|�||�qWdS)a�This convenience method adds multiple files and/or directories from
        the real file system to the fake file system. See `add_real_file()` and
        `add_real_directory()`.

        Args:
            path_list: List of file and directory paths in the real file
                system.
            read_only: If set, all files and files under under the directories
                are treated as read-only, e.g. a write access raises an
                exception; otherwise, writing to the files changes the fake
                files only as usually.
            lazy_dir_read: Uses lazy reading of directory contents if set
                (see `add_real_directory`)

        Raises:
            OSError: if any of the files and directories in the list
                does not exist in the real file system.
            OSError: if any of the files and directories in the list
                already exists in the fake file system.
        N)r�r�r�r�r�)r3�	path_listr��
lazy_dir_readr�r)r)r*�add_real_paths�	s
zFakeFilesystem.add_real_pathscCs||
r
|jn|j}|�|�}|�|�}t|�s4td��|j|dd�rP|�tj|�|�	|�\}
}|
sh|j
}
|�|
�|�|
�s�|s�|tj|
�|�
|
�n
|�|
�}
|r�||jM}|	r�t|||d�}nt||||||d�}|jd7_|j|_|�|
||�|dk�r|dk�rd}|	�sx|dk	�s0|dk	�rxy$|dk	�rH|�|�n
|�|�Wn"tk
�rv|�|��YnX|S)	aInternal fake file creator that supports both normal fake files
        and fake files based on real files.

        Args:
            file_path: path to the file to create.
            st_mode: the stat.S_IF constant representing the file type.
            contents: the contents of the file. If not given and st_size is
                None, an empty file is assumed.
            st_size: file size; only valid if contents not given. If given,
                the file is considered to be in "large file mode" and trying
                to read from or write to the file will result in an exception.
            create_missing_dirs: if True, auto create missing directories.
            apply_umask: whether or not the current umask must be applied
                on st_mode.
            encoding: if contents is a unicode string, the encoding used for
                serialization.
            errors: the error mode used for encoding/decoding errors
            read_from_real_fs: if True, the contents are read from the real
                file system on demand.
            raw_io: `True` if called from low-level API (`os.open`)
            side_effect: function handle that is executed when file is written,
                must accept the file object as an argument.
        z;st_mode must be of int type - did you mean to set contents?T)r�)rSrb)rSrYrZrbr&Nr)r�rnrr|rr6r�ror�rfr�rr'rrr�r�rCr�rEr�rmrur�r�)r3r4rDrarJr�r�rYrZr�r�rbr�r��new_filer$r)r)r*r��	sP







z%FakeFilesystem.create_file_internallycCs|��std��|�|�}|�|�}|�|�}|�|�r�|�|�rP|�tj|�|�|�rp|j	s�|�tj
|�nd|j	r�|�tj|�|j|�|�dd�s�|�tj
|�|j
r�|j|dd�r�|�|�n|�tj|�|�|�s�|�|�}t|�}|j|ttB||dd�S)a,Create the specified symlink, pointed at the specified link target.

        Args:
            file_path:  path to the symlink to create
            link_target:  the target of the symlink
            create_missing_dirs: If `True`, any missing parent directories of
                file_path will be created

        Returns:
            The newly created FakeFile object.

        Raises:
            OSError: if the symlink could not be created
                (see :py:meth:`create_file`).
            OSError: if on Windows before Python 3.2.
        z=Symbolic links are not supported on Windows before Python 3.2T)r�)rDrar�r�)rr�rrKr&r�r�ror�rVr'r(r~r�r�r�r�r�rr�)r3r4�link_targetr�r)r)r*�create_symlink
s:







zFakeFilesystem.create_symlinkcCs|��std��|�|�}|j|dd�r6|�tj|�|�|�\}}|sN|j}|�|�sf|�tj	|�|�
|�r�|jr|tjntj
}|�||�|js�|�
|�r�|�tj	|�y|�|�}Wn"tk
r�|�tj	|�YnX|jt@�r|�|jr�tjntj|�||_|�||�|S)a
Create a hard link at new_path, pointing at old_path.

        Args:
            old_path: An existing link to the target file.
            new_path: The destination path to create a new link at.

        Returns:
            The FakeFile object referred to by old_path.

        Raises:
            OSError:  if something already exists at new_path.
            OSError:  if old_path is a directory.
            OSError:  if the parent directory doesn't exist.
            OSError:  if on Windows before Python 3.2.
        z4Links are not supported on Windows before Python 3.2T)r�)rr�r|r�r�ror�rfr�r'r&rVr(r)rr�rDrr��EPERMrUr�)r3�old_path�new_path�new_path_normalized�new_parent_directory�new_basenamer��old_filer)r)r*r�Q
s6



zFakeFilesystem.linkc
CsDy|�|j�Wn.ttfk
r>}z|jtjkSd}~XYnXdS)NF)r�rar�r�ror�)r3�link_objr,r)r)r*�_is_circular_link�
s
z FakeFilesystem._is_circular_linkc
Cs�|dkrt�y|�|�}Wn0tk
rJ}z|�|j|�Wdd}~XYnXt|j�tkrh|�tj|�|�	|�r�|j
s�|�|�r�|�tj|�|�|j�s�|j
r�tj}n$|�
|�r�|jr�|jStj}ntj}|�||j�|jS)a�Read the target of a symlink.

        Args:
            path:  symlink to read the target of.

        Returns:
            the string representing the path to which the symbolic link points.

        Raises:
            TypeError: if path is None
            OSError: (with errno=ENOENT) if path is not a valid path, or
                (with errno=EINVAL) if path is valid, but is not a symlink,
                or if the path ends with a path separator (Posix only)
        N)r6r�r�r�rorrDrr(r&rVr�r�r�r�r�r'ra)r3r�r�r,r�r)r)r*�readlink�
s* 

zFakeFilesystem.readlinkcCs8t|�}|�|�}|�|�}|s.|�tjd�|jr>|�|�}|�|�\}}|r�|�	|�}|�
||jd�}|�|�r�|js�|�
|�\}}}|�|�s�|�tj|�|�|�}|j|dd��r|jr�||jkr�tj}	ntj}	|r�|jr�|�|�s�|�|�n|�|	|�|�|�\}
}|�|
t|||j@|d��dS)a�Create a leaf Fake directory.

        Args:
            dir_name: (str) Name of directory to create.
                Relative paths are assumed to be relative to '/'.
            mode: (int) Mode to create directory with.  This argument defaults
                to 0o777. The umask is applied to this mode.

        Raises:
            OSError: if the directory name is invalid or parent directory is
                read only or as per :py:meth:`add_object`.
        rz..T)r�)rSN)rr&r~r�ror'rVr|rfrUrr�rb�	partitionr�r�r�r�r�r�r�r�)r3r]r1r�r_r��base_dir�ellipsis�dummy_dotdotr.�head�tailr)r)r*�makedir�
s6






zFakeFilesystem.makedircCs x|�|�r|dd�}qW|S)NrM)r&)r3r�r)r)r*r~�
sz0FakeFilesystem._path_without_trailing_separatorsc	
Cs|�|�}|�|�}|r@|jr@|j|dd�r@|�|�s@|�|�|�|�}|j}x0|D](}||jkspt|jt	�stPqV|j|}qVWy|�
|||j@�Wndtt
fk
r�}zB|r�t|�|�t�s�|jr�|jtjkr�tj|_|�|j|j�Wdd}~XYnXdS)a�Create a leaf Fake directory and create any non-existent
        parent dirs.

        Args:
            dir_name: (str) Name of directory to create.
            mode: (int) Mode to create directory (and any necessary parent
                directories) with. This argument defaults to 0o777.
                The umask is applied to this mode.
          exist_ok: (boolean) If exist_ok is False (the default), an OSError is
                raised if the target directory already exists.
                New in Python 3.2.

        Raises:
            OSError: if the directory already exists and exist_ok=False,
                or as per :py:meth:`create_dir`.
        T)r�N)r&r|r�r�r�rZr�rard�dictrr�r�r�rr�rVror)r'r�r�)	r3r]r1�exist_okr�rOr\rS�er)r)r*�makedirs�
s*







zFakeFilesystem.makedirsc	Csft|�}|dkrt�y4|�||�}|rF|j|||d�t|j�|kSWnttfk
r`dSXdS)a�Helper function to implement isdir(), islink(), etc.

        See the stat(2) man page for valid stat.S_I* flag values

        Args:
            path: Path to file to stat and test
            st_flag: The stat.S_I* flag checked for the file's st_mode

        Returns:
            (boolean) `True` if the st_flag is set in path's st_mode.

        Raises:
          TypeError: if path is None
        N)r*F)rr6rrrrDr�r�)r3r��st_flagr#r~r)r)r*�_is_of_typeszFakeFilesystem._is_of_typecCs|�|t|�S)aDetermine if path identifies a directory.

        Args:
            path: Path to filesystem object.

        Returns:
            `True` if path points to a directory (following symlinks).

        Raises:
            TypeError: if path is None.
        )r�r)r3r�r#r)r)r*r�3szFakeFilesystem.isdircCs|�|t|�S)aDetermine if path identifies a regular file.

        Args:
            path: Path to filesystem object.

        Returns:
            `True` if path points to a regular file (following symlinks).

        Raises:
            TypeError: if path is None.
        )r�r)r3r�r#r)r)r*r}AszFakeFilesystem.isfilecCs|j|tdd�S)aDetermine if path identifies a symbolic link.

        Args:
            path: Path to filesystem object.

        Returns:
            `True` if path points to a symlink (S_IFLNK set in st_mode)

        Raises:
            TypeError: if path is None.
        F)r#)r�r)r3r�r)r)r*r�OszFakeFilesystem.islinkc
Csty|�|�}Wn0tk
r>}z|�|j|�Wdd}~XYnX|jt@sp|jr\tr\tj}ntj	}|�||d�|S)anTest that the target is actually a directory, raising OSError
        if not.

        Args:
            target_directory: Path to the target directory within the fake
                filesystem.

        Returns:
            The FakeDirectory object corresponding to target_directory.

        Raises:
            OSError: if the target is not a directory.
        Ni)
rr�r�rorDrrVrr(r))r3r�r�r,r.r)r)r*�
confirmdir]s 

zFakeFilesystem.confirmdirc
Cs|�|�}|�|�r|�|�|�|�r�|�|�}t|j�tkr�|�|�}t|j�t	kr�|j
rftj}n|j
rttj}ntj}|�||�t|�}|�|j�r�|j
r�tj}n|j
r�tj}ntj}|�||�n|�||�y|�|�Wn4tk
�r}z|�|j|j�Wdd}~XYnXdS)aRemove the FakeFile object at the specified file path.

        Args:
            path: Path to file to be removed.

        Raises:
            OSError: if path points to a directory.
            OSError: if path does not exist.
            OSError: if removal failed.
        N)r|r&r�r�rrrDrr�rrVror�r�r�r�r�rrbr�r)rr�r�r�)r3r��	norm_pathr~r�r�r,r)r)r*�removews6





zFakeFilesystem.removec
Cs�|dkr&|jrtjntj}|�||�|�|�}|�|�}|�|�r�|jst|�|�rt|r\dS|rf|j	st|�tj
|�|�|�}|jr�|�tj
|�y|�|�Wn2tk
r�}z|�|j|j�Wdd}~XYnXdS)aRemove a leaf Fake directory.

        Args:
            target_directory: (str) Name of directory to remove.
            allow_symlink: (bool) if `target_directory` is a symlink,
                the function just returns, otherwise it raises (Posix only)

        Raises:
            OSError: if target_directory does not exist.
            OSError: if target_directory does not point to a directory.
            OSError: if removal failed per FakeFilesystem.RemoveObject.
                Cannot remove '.'.
        )�.rLN)rVror�r(r�r&r|r�r�r�r)rrar�r�r�r�)r3r��
allow_symlinkr.r�r�r,r)r)r*�rmdir�s$




zFakeFilesystem.rmdircCs*|j|dd�}|�|�}|j}t|���S)afReturn a list of file names in target_directory.

        Args:
            target_directory: Path to the target directory within the
                fake filesystem.

        Returns:
            A list of file names within the target directory in arbitrary
            order.

        Raises:
            OSError: if the target is not a directory.
        T)r)r�r�rar��keys)r3r�r��directory_contentsr)r)r*r��s
zFakeFilesystem.listdircCs
t|j�S)N)r�r�)r3r)r)r*r��szFakeFilesystem.__str__cCs4|�ttj��|�ttj��|�ttj��dS)N)rB�StandardStreamWrapperr;�stdin�stdout�stderr)r3r)r)r*r��sz$FakeFilesystem._add_standard_streams)N)NN)N)N)F)N)N)T)TF)T)NNT)F)FT)TF)N)F)TN)TTN)TT)T)T)T)T)F)fr6r7r8r9r�r�rr2r�r�r�r�r�r�r�r�rn�staticmethodrrzrrr�rr
rrrrlr�rr2r;r3r
r�rBrErGr�rJrKrUrr|rfrrtrzrZrar^r|r&rr[r�r�r�r�r�r�r�r�r<rr�r�r�r�r�r�r�r�r�rr�rrr�r�r�r�r�r�r�r�r�r�r�r~r�r�r�r}r�r�r�r�r�r�r�r)r)r)r*r�Ds�4












1


1(,'$'

&
<')$
&

F"/"
)
6
I
86(/-


,
"r��GetDiskUsage�SetDiskUsage�ChangeDiskUsage�
AddMountPoint�GetStat�
ChangeMode�
UpdateTime�AddOpenFile�
CloseOpenFile�HasOpenFile�GetOpenFile�NormalizePathSeparator�CollapsePath�
NormalizeCase�
NormalizePath�	SplitPath�
SplitDrive�	JoinPaths�GetPathComponents�StartsWithDriveLetter�Exists�ResolvePath�GetObjectFromNormalizedPath�	GetObject�
ResolveObject�LResolveObject�	AddObject�RemoveObject�RenameObject�CreateDirectory�
CreateFile�
CreateLink�CreateHardLink�ReadLink�
MakeDirectory�MakeDirectories�IsDir�IsFile�IsLink�
ConfirmDir�
RemoveFile�RemoveDirectory�ListDirc@seZdZdZeej�Zedd��Z	d;dd�Z
dd�Zd	d
�Zdd�Z
d
d�Zdd�Zdd�Zdd�Zdd�Zdd�Zdd�Zdd�Zdd�Zdd �Zd!d"�Zd#d$�Zd%d&�Zd<d'd(�Zd)d*�Zejd+ks�ejd,kr�d-d.�Z d/d0�Z!d1d2�Z"d3d4�Z#d5d6�Z$e%�rd7d8�Z&d9d:�Z'dS)=�FakePathModulez�Faked os.path module replacement.

    FakePathModule should *only* be instantiated by FakeOsModule.  See the
    FakeOsModule docstring for details.
    cCsXddddddddd	d
ddd
ddddddddg}tr<|�d�tjdksJtsT|�d�|S)zqReturn the list of patched function names. Used for patching
        functions imported from the module.
        �abspathr�r��
expanduser�getatime�getctime�getmtime�getsize�isabsr�r}r��ismountr{�lexistsrKrU�realpathr�r�rrr �samefile)rr?r;r�)�dirr)r)r*r5s


zFakePathModule.dirNcCsL||_|j|_|dkr&tjttdd�||j_|_|jj|_	|jj
|_dS)z�Init.

        Args:
            filesystem: FakeFilesystem used to provide file system information
            os_module: (deprecated) FakeOsModule to assign to self.os
        Nrw)�
stacklevel)rS�
_OS_PATH_COPY�_os_path�warnings�warn�FAKE_PATH_MODULE_DEPRECATION�DeprecationWarningr�r�rr�r�)r3rS�	os_moduler)r)r*r2-s
zFakePathModule.__init__cCs|j�|�S)z�Determine whether the file object exists within the fake filesystem.

        Args:
            path: The path to the file object.

        Returns:
            (bool) `True` if the file exists.
        )rSr�)r3r�r)r)r*r�=s	zFakePathModule.existscCs|jj|dd�S)z�Test whether a path exists.  Returns True for broken symbolic links.

        Args:
          path:  path to the symlink object.

        Returns:
          bool (if file exists).
        T)r�)rSr�)r3r�r)r)r*r2Hs	zFakePathModule.lexistsc
Cs�yN|j�|�}|j�|�rJt|j�tkrJ|jjr6tjntj	}|j�
||�|jStk
r�}zt
�|j|j��Wdd}~XYnXdS)z�Return the file object size in bytes.

        Args:
          path:  path to the file object.

        Returns:
          file size in bytes.
        N)rSrr&rrDrrVror(r)r�rJr�r�r�r�)r3r�r@r.r,r)r)r*r/Ss	zFakePathModule.getsizecCs~|jjr|�|�d}t|�}|j�|�}|j�|�}|jjr^t|�dko\|dd�||fkS|�|�px|dk	ox|�|�SdS)z,Return True if path is an absolute pathname.r&rN)rSrVrrrzrr]r)r3r�rr�r)r)r*r0gs 
zFakePathModule.isabscCs|j�|�S)z)Determine if path identifies a directory.)rSr�)r3r�r)r)r*r�tszFakePathModule.isdircCs|j�|�S)z,Determine if path identifies a regular file.)rSr})r3r�r)r)r*r}xszFakePathModule.isfilecCs|j�|�S)z�Determine if path identifies a symbolic link.

        Args:
            path: Path to filesystem object.

        Returns:
            `True` if path points to a symbolic link.

        Raises:
            TypeError: if path is None.
        )rSr�)r3r�r)r)r*r�|szFakePathModule.islinkcCs>y|j�|�}|jStk
r8|jjtjdd�YnXdS)aCReturns the modification time of the fake file.

        Args:
            path: the path to fake file.

        Returns:
            (int, float) the modification time of the fake file
                         in number of seconds since the epoch.

        Raises:
            OSError: if the file does not exist.
        r)r�N)rSrrLr�r�ror')r3r�r@r)r)r*r.�s

zFakePathModule.getmtimecCs:y|j�|�}Wn"tk
r2|j�tj�YnX|jS)a�Returns the last access time of the fake file.

        Note: Access time is not set automatically in fake filesystem
            on access.

        Args:
            path: the path to fake file.

        Returns:
            (int, float) the access time of the fake file in number of seconds
                since the epoch.

        Raises:
            OSError: if the file does not exist.
        )rSrr�r�ror'rK)r3r�r@r)r)r*r,�s
zFakePathModule.getatimecCs:y|j�|�}Wn"tk
r2|j�tj�YnX|jS)a2Returns the creation time of the fake file.

        Args:
            path: the path to fake file.

        Returns:
            (int, float) the creation time of the fake file in number of
                seconds since the epoch.

        Raises:
            OSError: if the file does not exist.
        )rSrr�r�ror'rM)r3r�r@r)r)r*r-�s

zFakePathModule.getctimecs���fdd�}t����j���}�j���}����sH��|����nJ�jjrZ��|�sl|dk	r���|�r�|�}�j�|�r���|dd������	��S)z&Return the absolute version of a path.cs>trt�t�r�j��Sts0t�t�r0�j��S�j��SdS)z%Return the current working directory.N)rrdrr��getcwdure�getcwdb�getcwdr))r�r3r)r*r@�s


z&FakePathModule.abspath.<locals>.getcwdNrw)
rrSrzrr0r{rVrrarU)r3r�r@rr�r�r))r�r3r*r*�s


zFakePathModule.abspathcGs|jj|�S)z8Return the completed path with a separator of the parts.)rSrz)r3�pr)r)r*r{�szFakePathModule.joincCs|j�|�S)zHSplit the path into the directory and the filename of the path.
        )rSrf)r3r�r)r)r*r��szFakePathModule.splitcCs|j�|�S)zRSplit the path into the drive part and the rest of the path, if
        supported.)rSr)r3r�r)r)r*r�szFakePathModule.splitdrivecCs|j�|�S)z0Normalize path, eliminating double slashes, etc.)rSrU)r3r�r)r)r*rU�szFakePathModule.normpathcCs |j�|�}|jjr|��}|S)zPConvert to lower case under windows, replaces additional path
        separator.)rSrKrVr�)r3r�r)r)r*rK�szFakePathModule.normcasecCs�|std��t|�}|dk	r&t|�}n|jj}|jjdk	rb|�|jj|jj�}|�|jj|jj�}|�|jj|jj�}|�|jj|jj�}|j�	||�}|�|jj|jj�S)zQWe mostly rely on the native implementation and adapt the
        path separator.zno path specifiedN)
rRrrSr�r�rIr8rr�r�)r3r��startr)r)r*r��s 




zFakePathModule.relpathcCs>|jjr|�|�St|�}|�|dd�|i�\}}|�|�S)z}Return the canonical path of the specified filename, eliminating any
        symbolic links encountered in the path.
        Nr)rSrVr*r�
_joinrealpath)r3r�r��okr)r)r*r3
s

zFakePathModule.realpathr )rrwcCs0|j�|�}|j�|�}|j|jko.|j|jkS)a�Return whether path1 and path2 point to the same file.
            Windows support new in Python 3.2.

            Args:
                path1: first file path or path object (Python >=3.6)
                path2: second file path or path object (Python >=3.6)

            Raises:
                OSError: if one of the paths does not point to an existing
                    file system object.
            )rSr�rErF)r3�path1�path2�stat1�stat2r)r)r*r4
szFakePathModule.samefilecCs>|j�|d�}|j�|d�}|j�|�}|�|�rB|dd�}|}x�|�r4|�|�\}}}|rD||krhqD||kr�|r�|j�|�\}}||kr�|j�|||�}qD|}qD|j�||�}	|j�|	�s�|	}qD|	|kr�||	}|dk	r�qD|j�|	|�dfSd||	<|�||j�	|	�|�\}}
|
�s*|j�||�dfS|||	<qDW|dfS)z�Join two paths, normalizing and eliminating any symbolic links
        encountered in the second path.
        Taken from Python source and adapted.
        rLz..r&NFT)
rSrrzr0r�rfrzr�rCr�)r3r��rest�seen�curdir�pardirrrUr��newpathrDr)r)r*rC+
sB
zFakePathModule._joinrealpathcCs|�|�dS)z2Returns the first part of the result of `split()`.r)r�)r3r�r)r)r*r�\
szFakePathModule.dirnamecCs|j�|��|jj|j�S)ztReturn the argument with an initial component of ~ or ~user
        replaced by that user's home directory.
        )r8r+rIr)r3r�r)r)r*r+`
szFakePathModule.expandusercCs�t|�}|sdS|j�|�}|j�|�}|jjr�|jjdk	rN||j�|�f}n|f}|j�|�\}}|r�|dd�|kr�|p�||kS||kr�dSx(|jjD]}|�	|�|�	|�kr�dSq�WdS)aPReturn true if the given path is a mount point.

        Args:
            path: Path to filesystem object to be checked

        Returns:
            `True` if path is a mount point added to the fake file system.
            Under Windows also returns True for drive and UNC roots
            (independent of their existence).
        FNr&T)
rrSr|rzrVr�rrr��rstrip)r3r��normed_pathr�	path_sepsr
rIrr)r)r*r1g
s$zFakePathModule.ismountc	Cs�y|j�|�}Wntjk
r&dSX||||�x�|D]|}|j�||�}|jjrp|j�|�r�|�|||�q:y|jj|dd�}Wntjk
r�w:YnXt	|j
�r:|�|||�q:WdS)a~Directory tree walk with callback function.

            Args:
                top: Root path to traverse. The root itself is not included
                    in the called elements.
                func: Function to be called for each visited path node.
                arg: First argument to be called with func (apart from
                    dirname and filenames).
            NF)r#)rSr�r�r�rzrVr�rr�rrD)r3�top�func�argr}rU�str)r)r*r�
s 


zFakePathModule.walkcCst|j|�S)z1Forwards any non-faked calls to the real os.path.)r�r8)r3rUr)r)r*r��
szFakePathModule.__getattr__)N)N)(r6r7r8r9rBr�r�r7r�r5r2r�r2r/r0r�r}r�r.r,r-r*r{r�rrUrKr�r3r;r�rr4rCr�r+r1rrr�r)r)r)r*r)s>




1!r)c@s�eZdZdZdZedd��Zdgdd�Zdd�Zdhd
d�Z	dd
�Z
didd�Zdd�Zdd�Z
dd�Zedjdd��Zdd�Zdd�Zdd�Zdd�Zer�d d!�Znd"d#�Zd$d%�Zejd&k�r�d'Zd(Zdkd*d+�Zdld,d-�Zdmd.d/�Zdnd1d2�Ze �r�dod4d5�Z!dpd7d8�Z"dqd9d:�Z#drd;d<�Z$dsd=d>�Z%dtd?d@�Z&dudAdB�Z'dvdCdD�Z(ejd&k�rTdEdF�Z)dwdGdH�Z*dIdJ�Z+e,dfdKdL�Z-e,dfdMdN�Z.dOdP�Z/dxdQdR�Z0dydSdT�Z1dUdV�Z2dzdWdX�Z3d{dYdZ�Z4d|d[d\�Z5d}d]d^�Z6d~d_d`�Z7dadb�Z8dcdd�Z9dedf�Z:dS)�FakeOsModulea�Uses FakeFilesystem to provide a fake os module replacement.

    Do not create os.path separately from os, as there is a necessary circular
    dependency between os and os.path to replicate the behavior of the standard
    Python modules.  What you want to do is to just let FakeOsModule take care
    of `os.path` setup itself.

    # You always want to do this.
    filesystem = fake_filesystem.FakeFilesystem()
    my_os_module = fake_filesystem.FakeOsModule(filesystem)
    NcCs�ddddddddd	d
ddd
ddddddddddddddddg}trN|dg7}n*|dd g7}tj�d!�rx|d"d#d$d%d&g7}tr�|d'g7}|S)(zqReturn the list of patched function names. Used for patching
        functions imported from the module.
        �access�chdirr2�chown�close�fstat�fsyncr@�lchmodr�r��lstatr��mkdir�mknodr�r�r�r��
removedirsr�r�r��symlinkr��unlinkr;r�writer>r?rIr#�	fdatasync�getxattr�	listxattr�removexattr�setxattrr)rr;r�rr
)r5r)r)r*r5�
s

zFakeOsModule.dircCs�||_|j|_|j|_|��|_t|_|dkr>t	|j|�|_
ntjt
tdd�||_
trb|j|_n|j|_|jrtdnd|j_dS)z�Also exposes self.path (to fake os.path).

        Args:
            filesystem: FakeFilesystem used to provide file system information
            os_path_module: (deprecated) Optional FakePathModule instance
        Nrw)r6z/dev/nul)rSr�rr�r�r��linesepr��
_os_moduler)r�r9r:r;r<r�_fdopen_ver2�fdopen�_fdopenrVr5r�)r3rS�os_path_moduler)r)r*r2�
s


zFakeOsModule.__init__cOs$t|d�std��t|j�||�S)a"Redirector to open() builtin function.

        Args:
            *args: Pass through args.
            **kwargs: Pass through kwargs.

        Returns:
            File object corresponding to file_des.

        Raises:
            TypeError: if file descriptor is not an integer.
        rzan integer is required)rr6�FakeFileOpenrS)r3�args�kwargsr)r)r*rm�
s
zFakeOsModule._fdopenrc
Cs^t|�std��yt|j�j||d�Stk
rX}z|j�|j|j�Wdd}~XYnXdS)a�Returns an open file object connected to the file descriptor
        file_des.

        Args:
            file_des: An integer file descriptor for the file object requested.
            mode: Additional file flags. Currently checks to see if the mode
                matches the mode of the requested file object.
            bufsize: ignored. (Used for signature compliance with
                __builtin__.fdopen)

        Returns:
            File object corresponding to file_des.

        Raises:
            OSError: if bad file descriptor or incompatible mode is given.
            TypeError: if file descriptor is not an integer.
        zan integer is required)r1N)	rr6rorS�callr�r�ror�)r3rDr1�bufsizer,r)r)r*rk�
szFakeOsModule._fdopen_ver2cCs6|jjrdStjdkrdSt�d�}t�|�|SdS)zReturn the current umask.rr rwN)rSrVr;r�r�r�)r3�maskr)r)r*�_umasks


zFakeOsModule._umaskcCs^|�||j|�}|dkr4|jjr&d}nd|��@}t|tj@|tj@|tj	tjB@|tj
@|tj@|tj@d�}|j
r�|jr�td��|jjs�|j�|�r�|j�|�}t|t�r�|js�|jjr�|jr�|j�tj|�t|||j�}|j�|�}||_|Sd}	d}
ttd��r |tj@tjk}
t|j|
d	d
�||	|d�}|j|jj k�rV|�!||�|�"�S)a�Return the file descriptor for a FakeFile.

        Args:
            file_path: the path to the file
            flags: low-level bits to indicate io operation
            mode: bits to define default permissions
                Note: only basic modes are supported, OS-specific modes are
                ignored
            dir_fd: If not `None`, the file descriptor of a directory,
                with `file_path` being relative to this directory.
                New in Python 3.3.

        Returns:
            A file descriptor.

        Raises:
            IOError: if the path cannot be found
            ValueError: if invalid mode is given
            NotImplementedError: if `os.O_EXCL` is used without `os.O_CREAT`
        Ni�i�)�
must_exist�can_read�	can_write�truncater?�must_not_existz,O_EXCL without O_CREAT mode is not supported�bF�O_TEMPORARYT)�delete_on_closer�)r)#�_path_with_dir_fdr�rSrVru�
_OpenModesr��O_CREAT�O_WRONLY�O_RDWR�O_TRUNC�O_APPEND�O_EXCLrzrv�NotImplementedErrorr�rrdr�r�rxr�ror��FakeDirWrapperrB�filedesr!r|ror$r�r2�fileno)r3r4�flagsr1�dir_fdrr~�dir_wrapperrD�	str_flagsr}r�r)r)r*r�'sJ


zFakeOsModule.opencCs|j�|�}|��dS)z�Close a file descriptor.

        Args:
            file_des: An integer file descriptor for the file object requested.

        Raises:
            OSError: bad file descriptor.
            TypeError: if file descriptor is not an integer.
        N)rSrGrY)r3rD�file_handler)r)r*rYjs
zFakeOsModule.closecCs|j�|�}d|_|�|�S)a�Read number of bytes from a file descriptor, returns bytes read.

        Args:
            file_des: An integer file descriptor for the file object requested.
            num_bytes: Number of bytes to read from file.

        Returns:
            Bytes read from file.

        Raises:
            OSError: bad file descriptor.
            TypeError: if file descriptor is not an integer.
        T)rSrGr�r�)r3rD�	num_bytesr�r)r)r*r�wszFakeOsModule.readcCsX|j�|�}t|t�r(|j�tj|j�d|_|�	�|�
�|�|�|��t
|�S)a�Write string to file descriptor, returns number of bytes written.

        Args:
            file_des: An integer file descriptor for the file object requested.
            contents: String of bytes to write to file.

        Returns:
            Number of bytes written.

        Raises:
            OSError: bad file descriptor.
            TypeError: if file descriptor is not an integer.
        T)rSrGrdr�r�rorFr4r��_sync_io�update_flush_posrc�flushr])r3rDrar�r)r)r*rc�s

zFakeOsModule.writecCs
t�|�S)auDetermine whether a file's time stamps are reported as floats
        or ints.

        Calling without arguments returns the current value. The value is
        shared by all instances of FakeOsModule.

        Args:
            newvalue: If `True`, mtime, ctime, atime are reported as floats.
                Otherwise, they are returned as ints (rounding down).
        )r�stat_float_times)�newvaluer)r)r*r��szFakeOsModule.stat_float_timescCs|j�|���}|j��S)aIReturn the os.stat-like tuple for the FakeFile object of file_des.

        Args:
            file_des: The file descriptor of filesystem object to retrieve.

        Returns:
            The FakeStatResult object corresponding to entry_path.

        Raises:
            OSError: if the filesystem object doesn't exist.
        )rSrGr<rXr )r3rDr$r)r)r*rZ�s
zFakeOsModule.fstatcCs$t|�std��|jj}||j_|S)z�Change the current umask.

        Args:
            new_mask: (int) The new umask value.

        Returns:
            The old umask.

        Raises:
            TypeError: if new_mask is of an invalid type.
        zan integer is required)rr6rSr�)r3�new_mask�	old_umaskr)r)r*r��s
zFakeOsModule.umaskcCsT|jj|dd�}|j�|�|j�|�}t�sH|jtBsH|j�tj	|�||j_
dS)a*Change current working directory to target directory.

        Args:
            target_directory: The path to new current working directory.

        Raises:
            OSError: if user lacks permission to enter the argument directory
                or if the target is not a directory.
        T)rN)rSr�r�rr/rDr�r�ror�r�)r3r�r�r)r)r*rW�s

zFakeOsModule.chdircCs|jjS)z!Return current working directory.)rSr�)r3r)r)r*r@�szFakeOsModule.getcwdcCst|jj�S)z;Return current working directory as unicode. Python 2 only.)rrSr�)r3r)r)r*r>�szFakeOsModule.getcwducCst|jjt�d��S)z9Return current working directory as bytes. Python 3 only.F)rerSr�rgrh)r3r)r)r*r?�szFakeOsModule.getcwdbcCs|j�|�S)aiReturn a list of file names in target_directory.

        Args:
            target_directory: Path to the target directory within the fake
                filesystem.

        Returns:
            A list of file names within the target directory in arbitrary
                order.

        Raises:
          OSError:  if the target is not a directory.
        )rSr�)r3r�r)r)r*r��szFakeOsModule.listdir)rrr&rwTcCsF|jjstd��t|t�r(|�t���}|jj||dd�}|j	�
|�S)aoReturn the value of the given extended filesystem attribute for
            `path`.

            Args:
                path: File path, file descriptor or path-like object (for
                    Python >= 3.6).
                attribute: (str or bytes) The attribute name.
                follow_symlinks: (bool) If True (the default), symlinks in the
                    path are traversed.

            Returns:
                The contents of the extended attribute as bytes or None if
                the attribute does not exist.

            Raises:
                OSError: if the path does not exist.
            z'module 'os' has no attribute 'getxattr'T)r)rSr�r�rdrerfr;�getfilesystemencodingrr`�get)r3r��	attributer#r@r)r)r*res

zFakeOsModule.getxattrcCs@|jjstd��|dkr |��}|jj||dd�}t|j���S)aReturn a list of the extended filesystem attributes on `path`.

            Args:
                path: File path, file descriptor or path-like object (for
                    Python >= 3.6). If None, the current directory is used.
                follow_symlinks: (bool) If True (the default), symlinks in the
                    path are traversed.

            Returns:
                A list of all attribute names for the given path as str.

            Raises:
                OSError: if the path does not exist.
            z(module 'os' has no attribute 'listxattr'NT)r)rSr�r�r@rr�r`r�)r3r�r#r@r)r)r*rf$s
zFakeOsModule.listxattrcCsP|jjstd��t|t�r(|�t���}|jj||dd�}||j	krL|j	|=dS)a�Removes the extended filesystem attribute attribute from `path`.

            Args:
                path: File path, file descriptor or path-like object (for
                    Python >= 3.6).
                attribute: (str or bytes) The attribute name.
                follow_symlinks: (bool) If True (the default), symlinks in the
                    path are traversed.

            Raises:
                OSError: if the path does not exist.
            z*module 'os' has no attribute 'removexattr'T)rN)
rSr�r�rdrerfr;r�rr`)r3r�r�r#r@r)r)r*rg=s



zFakeOsModule.removexattrrcCs�|jjstd��t|t�r(|�t���}t|�s8t	d��|jj
||dd�}||jk}|rt||jkrt|j�
tj|j�|s�||jkr�|j�
tj|j�||j|<dS)aWSets the value of the given extended filesystem attribute for
            `path`.

            Args:
                path: File path, file descriptor or path-like object (for
                    Python >= 3.6).
                attribute: The attribute name (str or bytes).
                value: (byte-like) The value to be set.
                follow_symlinks: (bool) If True (the default), symlinks in the
                    path are traversed.

            Raises:
                OSError: if the path does not exist.
                TypeError: if `value` is not a byte-like object.
            z'module 'os' has no attribute 'setxattr'za bytes-like object is requiredT)rN)rSr�r�rdrerfr;r�rr6rr`�XATTR_CREATEr�ro�ENODATAr��
XATTR_REPLACEr�)r3r�r�r�r�r#r@r�r)r)r*rhUs


zFakeOsModule.setxattrrcCst|j|�S)a�Return an iterator of DirEntry objects corresponding to the
            entries in the directory given by path.

            Args:
                path: Path to the target directory within the fake filesystem.

            Returns:
                An iterator to an unsorted list of os.DirEntry objects for
                each entry in path.

            Raises:
                OSError: if the target is not a directory.
            )rrS)r3r�r)r)r*rxszFakeOsModule.scandirFcCst|j||||�S)a�Perform an os.walk operation over the fake filesystem.

        Args:
            top: The root directory from which to begin walk.
            topdown: Determines whether to return the tuples with the root as
                the first entry (`True`) or as the last, after all the child
                directory tuples (`False`).
          onerror: If not `None`, function which will be called to handle the
                `os.error` instance provided when `os.listdir()` fails.
          followlinks: If `True`, symbolic links are followed.

        Yields:
            (path, directories, nondirectories) for top and each of its
            subdirectories.  See the documentation for the builtin os module
            for further details.
        )rrS)r3rQ�topdown�onerror�followlinksr)r)r*r�szFakeOsModule.walkcCs|�||j|�}|j�|�S)aDRead the target of a symlink.

        Args:
            path:  Symlink to read the target of.
            dir_fd: If not `None`, the file descriptor of a directory,
                with `path` being relative to this directory.
                New in Python 3.3.

        Returns:
            the string representing the path to which the symbolic link points.

        Raises:
            TypeError: if `path` is None
            OSError: (with errno=ENOENT) if path is not a valid path, or
                     (with errno=EINVAL) if path is valid, but is not a symlink
        )r~r�rS)r3r�r�r)r)r*r��szFakeOsModule.readlinkcCs>|dkrd}ntjdkr td��|�||j|�}|j�||�S)a�Return the os.stat-like tuple for the FakeFile object of entry_path.

        Args:
            entry_path:  path to filesystem object to retrieve.
            dir_fd: (int) If not `None`, the file descriptor of a directory,
                with `entry_path` being relative to this directory.
                New in Python 3.3.
            follow_symlinks: (bool) If `False` and `entry_path` points to a
                symlink, the link itself is changed instead of the linked
                object.
                New in Python 3.3.

        Returns:
            The FakeStatResult object corresponding to entry_path.

        Raises:
            OSError: if the filesystem object doesn't exist.
        NT)rrz;stat() got an unexpected keyword argument 'follow_symlinks')r;rr6r~r�rS)r3r"r�r#r)r)r*r��s
zFakeOsModule.statcCs |�||j|�}|jj|dd�S)a�Return the os.stat-like tuple for entry_path, not following symlinks.

        Args:
            entry_path:  path to filesystem object to retrieve.
            dir_fd: If not `None`, the file descriptor of a directory, with
                `entry_path` being relative to this directory.
                New in Python 3.3.

        Returns:
            the FakeStatResult object corresponding to `entry_path`.

        Raises:
            OSError: if the filesystem object doesn't exist.
        F)r#)r~r]rSr�)r3r"r�r)r)r*r]�szFakeOsModule.lstatcCs |�||j|�}|j�|�dS)a�Remove the FakeFile object at the specified file path.

        Args:
            path: Path to file to be removed.
            dir_fd: If not `None`, the file descriptor of a directory,
                with `path` being relative to this directory.
                New in Python 3.3.

        Raises:
            OSError: if path points to a directory.
            OSError: if path does not exist.
            OSError: if removal failed.
        N)r~r�rS)r3r�r�r)r)r*r��szFakeOsModule.removecCs |�||j|�}|j�|�dS)a�Remove the FakeFile object at the specified file path.

        Args:
            path: Path to file to be removed.
            dir_fd: If not `None`, the file descriptor of a directory,
                with `path` being relative to this directory.
                New in Python 3.3.

        Raises:
            OSError: if path points to a directory.
            OSError: if path does not exist.
            OSError: if removal failed.
        N)r~rbrSr�)r3r�r�r)r)r*rb�szFakeOsModule.unlinkcCs"|�||j|�}|j�||�dS)aRename a FakeFile object at old_file_path to new_file_path,
        preserving all properties.
        Also replaces existing new_file_path object, if one existed
        (Unix only).

        Args:
            old_file_path: Path to filesystem object to rename.
            new_file_path: Path to where the filesystem object will live
                after this call.
            dir_fd: If not `None`, the file descriptor of a directory,
                with `old_file_path` being relative to this directory.
                New in Python 3.3.

        Raises:
            OSError: if old_file_path does not exist.
            OSError: if new_file_path is an existing directory.
            OSError: if new_file_path is an existing file (Windows only)
            OSError: if new_file_path is an existing file and could not
                be removed (Unix)
            OSError: if `dirname(new_file)` does not exist
            OSError: if the file would be moved to another filesystem
                (e.g. mount point)
        N)r~r�rS)r3r�r�r�r)r)r*r��szFakeOsModule.renamecCs|jj||dd�dS)a0Renames a FakeFile object at old_file_path to new_file_path,
            preserving all properties.
            Also replaces existing new_file_path object, if one existed.

            Args:
                old_file_path: Path to filesystem object to rename.
                new_file_path: Path to where the filesystem object will live
                    after this call.

            Raises:
                OSError: if old_file_path does not exist.
                OSError: if new_file_path is an existing directory.
                OSError: if new_file_path is an existing file and could
                    not be removed
                OSError: if `dirname(new_file)` does not exist
                OSError: if the file would be moved to another filesystem
                    (e.g. mount point)
            T)r�N)rSr�)r3r�r�r)r)r*rIszFakeOsModule.replacecCs |�||j|�}|j�|�dS)a�Remove a leaf Fake directory.

        Args:
            target_directory: (str) Name of directory to remove.
            dir_fd: If not `None`, the file descriptor of a directory,
                with `target_directory` being relative to this directory.
                New in Python 3.3.

        Raises:
            OSError: if target_directory does not exist or is not a directory,
            or as per FakeFilesystem.remove_object. Cannot remove '.'.
        N)r~r�rS)r3r�r�r)r)r*r�2s
zFakeOsModule.rmdircCs�|j�|�}|j�|�}|jr8|j�tj|j�|��n
|�	|�|j�
|�\}}|sf|j�
|�\}}x@|r�|r�|j�|�}|jr�P|jj	|dd�|j�
|�\}}qhWdS)a'Remove a leaf fake directory and all empty intermediate ones.

        Args:
            target_directory: the directory to be removed.

        Raises:
            OSError: if target_directory does not exist or is not a directory.
            OSError: if target_directory is not empty.
        T)r�N)rSr|r�rar�ror�r�r�r�r�)r3r�r�r�r��head_dirr)r)r*r`Cs


zFakeOsModule.removedirsc
Csh|�||j|�}y|j�||�Wn@tk
rb}z"|jtjkrP|j�|j|��Wdd}~XYnXdS)a�Create a leaf Fake directory.

        Args:
            dir_name: (str) Name of directory to create.
                Relative paths are assumed to be relative to '/'.
            mode: (int) Mode to create directory with.  This argument defaults
                to 0o777.  The umask is applied to this mode.
            dir_fd: If not `None`, the file descriptor of a directory,
                with `dir_name` being relative to this directory.
                New in Python 3.3.

        Raises:
            OSError: if the directory name is invalid or parent directory is
                read only or as per FakeFilesystem.add_object.
        N)r~r^rSr�r�ror�r�)r3r]r1r�r�r)r)r*r^_szFakeOsModule.mkdircCs4|dkrd}ntjdkr td��|j�|||�dS)a�Create a leaf Fake directory + create any non-existent parent dirs.

        Args:
            dir_name: (str) Name of directory to create.
            mode: (int) Mode to create directory (and any necessary parent
                directories) with. This argument defaults to 0o777.
                The umask is applied to this mode.
            exist_ok: (boolean) If exist_ok is False (the default), an OSError
                is raised if the target directory already exists.
                New in Python 3.2.

        Raises:
            OSError: if the directory already exists and exist_ok=False, or as
                per :py:meth:`FakeFilesystem.create_dir`.
        NF)rrwz7makedir() got an unexpected keyword argument 'exist_ok')r;rr6rSr�)r3r]r1r�r)r)r*r�ws

zFakeOsModule.makedirscCs�|dk	r~tjdkr td|j��tt|j�}||jkr>td��t|t	�rVt
d|j��|j�|�s~|j�
|j�|���j|�S|S)z@Return the path considering dir_fd. Raise on nmvalid parameters.N)rrz0%s() got an unexpected keyword argument 'dir_fd'z#dir_fd unavailable on this platformz.%s: Can't specify dir_fd without matching path)r;rr6r6r�r��supports_dir_fdr�rdr4rRr�r0r{rSrGr<)r3r��fctr��real_fctr)r)r*r~�s 




zFakeOsModule._path_with_dir_fdc
Cs�|dk	rtjdkrtd��|�||j|�}y|j||d�}Wn4tk
rp}z|jtjkr^dS�Wdd}~XYnXt	�r�|t
jM}||jd?d@@|kS)a�Check if a file exists and has the specified permissions.

        Args:
            path: (str) Path to the file.
            mode: (int) Permissions represented as a bitwise-OR combination of
                os.F_OK, os.R_OK, os.W_OK, and os.X_OK.
            dir_fd: If not `None`, the file descriptor of a directory, with
                `path` being relative to this directory.
                New in Python 3.3.
            follow_symlinks: (bool) If `False` and `path` points to a symlink,
                the link itself is queried instead of the linked object.
                New in Python 3.3.

        Returns:
            bool, `True` if file is accessible, `False` otherwise.
        N)rrz=access() got an unexpected keyword argument 'follow_symlinks')r#Frurg)
r;rr6r~rVr�r�ror'r/r��W_OKrD)r3r�r1r�r#rX�os_errorr)r)r*rV�szFakeOsModule.accesscCsD|dkrd}ntjdkr td��|�||j|�}|j�|||�dS)aChange the permissions of a file as encoded in integer mode.

        Args:
            path: (str) Path to the file.
            mode: (int) Permissions.
            dir_fd: If not `None`, the file descriptor of a directory, with
                `path` being relative to this directory.
                New in Python 3.3.
            follow_symlinks: (bool) If `False` and `path` points to a symlink,
                the link itself is queried instead of the linked object.
                New in Python 3.3.
        NT)rrz<chmod() got an unexpected keyword argument 'follow_symlinks')r;rr6r~r2rS)r3r�r1r�r#r)r)r*r2�s

zFakeOsModule.chmodcCs&|jjrtdf�|jj||dd�dS)z�Change the permissions of a file as encoded in integer mode.
        If the file is a link, the permissions of the link are changed.

        Args:
          path: (str) Path to the file.
          mode: (int) Permissions.
        zname 'lchmod' is not definedF)r#N)rSrV�	NameErrorr2)r3r�r1r)r)r*r\�szFakeOsModule.lchmodcCs`|dkrd}ntjdkr td��|�||j|�}|dk	rJtjdkrJtd��|j�||||�dS)a�Change the access and modified times of a file.

        Args:
            path: (str) Path to the file.
            times: 2-tuple of int or float numbers, of the form (atime, mtime)
                which is used to set the access and modified times in seconds.
                If None, both times are set to the current time.
            ns: 2-tuple of int numbers, of the form (atime, mtime)  which is
                used to set the access and modified times in nanoseconds.
                If None, both times are set to the current time.
                New in Python 3.3.
            dir_fd: If not `None`, the file descriptor of a directory,
                with `path` being relative to this directory.
                New in Python 3.3.
            follow_symlinks: (bool) If `False` and `path` points to a symlink,
                the link itself is queried instead of the linked object.
                New in Python 3.3.

            Raises:
                TypeError: If anything other than the expected types is
                    specified in the passed `times` or `ns` tuple,
                    or if the tuple length is not equal to 2.
                ValueError: If both times and ns are specified.
        NT)rrz<utime() got an unexpected keyword argument 'follow_symlinks'z/utime() got an unexpected keyword argument 'ns')r;rr6r~r;rS)r3r�r7r8r�r#r)r)r*r;�s
zFakeOsModule.utimec
Cs�|dkrd}ntjdkr td��|�||j|�}y|jj||dd�}Wn@tk
r�}z"|jtj	krt|j�
tj	|��Wdd}~XYnXt|�s�|dkr�t|�s�|dks�td��|dkr�||_|dkr�||_
dS)aISet ownership of a faked file.

        Args:
            path: (str) Path to the file or directory.
            uid: (int) Numeric uid to set the file or directory to.
            gid: (int) Numeric gid to set the file or directory to.
            dir_fd: (int) If not `None`, the file descriptor of a directory,
                with `path` being relative to this directory.
                New in Python 3.3.
            follow_symlinks: (bool) If `False` and path points to a symlink,
                the link itself is changed instead of the linked object.
                New in Python 3.3.

        Raises:
            OSError: if path does not exist.

        `None` is also allowed for `uid` and `gid`.  This permits `os.rename`
        to use `os.chown` even when the source file `uid` and `gid` are
        `None` (unset).
        NT)rrz<chown() got an unexpected keyword argument 'follow_symlinks')rzAn integer is requiredrM)r;rr6r~rXrSrr�ror'r�rrHrI)r3r�r(r-r�r#r$r%r)r)r*rXs(
zFakeOsModule.chownc
Cs.|jjrtdf�|dkr tdB}|s2|t@s@t�s@|j�tj�|�||j	|�}|j
�|�\}}|s�|jj|dd�r�|j�tj
|�|j�tj|�|dkr�|j�tj|�|jj|dd�r�|j�tj
|�y(|j�|t|||jj@|jd��Wn4tk
�r(}z|j�|j|�Wdd}~XYnXdS)a9Create a filesystem node named 'filename'.

        Does not support device special files or named pipes as the real os
        module does.

        Args:
            filename: (str) Name of the file to create
            mode: (int) Permissions to use and type of file to be created.
                Default permissions are 0o666.  Only the stat.S_IFREG file type
                is supported by the fake implementation.  The umask is applied
                to this mode.
            device: not supported in fake implementation
            dir_fd: If not `None`, the file descriptor of a directory,
                with `filename` being relative to this directory.
                New in Python 3.3.

        Raises:
          OSError: if called with unsupported options or the file can not be
          created.
        z%module 'os' has no attribute 'mknode'Ni�T)r�)r�rLs..z..)rS)rSrVr�rr/r�ror�r~r_r�r�r�r�r'r�rCr�r�)r3r�r1�devicer�r�r�r�r)r)r*r_1s,
zFakeOsModule.mknodcCs&|�||j|�}|jj||dd�dS)a�Creates the specified symlink, pointed at the specified link target.

        Args:
            link_target: The target of the symlink.
            path: Path to the symlink to create.
            dir_fd: If not `None`, the file descriptor of a directory,
                with `link_target` being relative to this directory.
                New in Python 3.3.

        Raises:
            OSError:  if the file already exists.
        F)r�N)r~rarSr�)r3r�r�r�r)r)r*ra`s
zFakeOsModule.symlinkcCs"|�||j|�}|j�||�dS)a�Create a hard link at new_path, pointing at old_path.

        Args:
            oldpath: An existing link to the target file.
            newpath: The destination path to create a new link at.
            dir_fd: If not `None`, the file descriptor of a directory,
                with `oldpath` being relative to this directory.
                New in Python 3.3.

        Returns:
            The FakeFile object referred to by `oldpath`.

        Raises:
            OSError:  if something already exists at new_path.
            OSError:  if the parent directory doesn't exist.
            OSError:  if on Windows before Python 3.2.
        N)r~r�rS)r3�oldpathrMr�r)r)r*r�qszFakeOsModule.linkcCs`d|krtkr&nn|j�tj�|j�|�}|jjr\t|d�rJ|js\|j�tj	|j
�dS)aPerform fsync for a fake file (in other words, do nothing).

        Args:
            file_des: The file descriptor of the open file.

        Raises:
            OSError: file_des is an invalid file descriptor.
            TypeError: file_des is not an integer.
        r�allow_updateN)�NR_STD_STREAMSrSr�ror(rGrVr!r�rFr4)r3rDr$r)r)r*r[�s
zFakeOsModule.fsynccCsN|jjs|jjrtd��d|kr,tkr>nn|j�tj�|j�|�dS)aPerform fdatasync for a fake file (in other words, do nothing).

        Args:
            file_des: The file descriptor of the open file.

        Raises:
            OSError: file_des is an invalid file descriptor.
            TypeError: file_des is not an integer.
        z(module 'os' has no attribute 'fdatasync'rN)	rSrVr�r�r�r�ror(rG)r3rDr)r)r*rd�s
zFakeOsModule.fdatasynccCst|j|�S)z5Forwards any unfaked calls to the standard os module.)r�rj)r3rUr)r)r*r��szFakeOsModule.__getattr__)N)rN)NN)N)T)NT)T)rT)r)TNF)N)NN)N)N)N)N)N)NN)NN)NNNN)NN)NNN)N)N);r6r7r8r9r�r�r5r2rmrkrur�rYr�rcr�rZr�rWr@rr>r?r�r;rr�r�rerfrgrhr
rrr�r�r]r�rbr�rIr�r`r�r^r�r~rVr2r\r;rXr_rar�r[rdr�r)r)r)r*rU�
sr


C






!











$
*
/

rUc@s6eZdZdZedd��Zdd�Zdd
d�Zdd
�ZdS)�FakeIoModulea(Uses FakeFilesystem to provide a fake io module replacement.

    Currently only used to wrap `io.open()` which is an alias to `open()`.

    You need a fake_filesystem to use this:
    filesystem = fake_filesystem.FakeFilesystem()
    my_io_module = fake_filesystem.FakeIoModule(filesystem)
    cCsdS)zqReturn the list of patched function names. Used for patching
        functions imported from the module.
        )r�r)r)r)r)r*r5�szFakeIoModule.dircCs||_t|_dS)zg
        Args:
            filesystem: FakeFilesystem used to provide file system information.
        N)rSr��
_io_module)r3rSr)r)r*r2�szFakeIoModule.__init__rrMNTc	
	Cs>|dk	rtjdkrtd��t|jdd�}	|	||||||||�S)z\Redirect the call to FakeFileOpen.
        See FakeFileOpen.call() for description.
        N)rrz2open() got an unexpected keyword argument 'opener'T)�use_io)r;rr6rorS)
r3�filer1�	bufferingrYrZ�newline�closefd�opener�	fake_openr)r)r*r��szFakeIoModule.opencCst|j|�S)z5Forwards any unfaked calls to the standard io module.)r�r�)r3rUr)r)r*r��szFakeIoModule.__getattr__)rrMNNNTN)	r6r7r8r9r�r5r2r�r�r)r)r)r*r��s
r�c
@seZdZdZd@dd�Zdd�Zd	d
�Zdd�Zd
d�Zdd�Z	dd�Z
edd��Zdd�Z
dd�Zdd�ZdAdd�Zdd�Zd d!�Zd"d#�Zd$d%�Zd&d'�Zd(d)�Zd*d+�Zd,d-�Zd.d/�Zd0d1�Zd2d3�Zd4d5�Zd6d7�Zd8d9�Zd:d;�Zd<d=�Z d>d?�Z!dS)B�FakeFileWrapperz�Wrapper for a stream object for use by a FakeFile object.

    If the wrapper has any data written to it, it will propagate to
    the FakeFile object on close() or flush().
    FNTcCs||_||_||_||_||_|
|_|j|_|
|_|	|_	||_
d|_|j}|pVt
�d�|_|p`d}||jkrptnt}|||��|	|||d�|_d|_d|_d|_|r�t|�|_|r�|s�|j�d�n"|j�|j�|r�|r�|j��|_|r�|s�td��||_||_|j|_d|_ dS)NFrQ)ri�binaryrYr�rZrz(delete_on_close=True requires filesystem)!r$r4�_append�_readr��_closefdr^�_file_epochr��_binary�	is_stream�_changedrcrgrh�	_encodingr�rrr��_io�_read_whence�
_read_seek�
_flush_posr]�seek�tellr��_filesystemr}�	opened_asrUr�)r3r$r4�updater�r?r}rSr�r�r�rYrZr�r�r�ra�buffer_classr)r)r*r2�sH

zFakeFileWrapper.__init__cCs|S)z=To support usage of this fake file with the 'with' statement.r))r3r)r)r*�	__enter__szFakeFileWrapper.__enter__cCs|��dS)z=To support usage of this fake file with the 'with' statement.N)rY)r3�typer��	tracebackr)r)r*�__exit__szFakeFileWrapper.__exit__cCs2|jr|j�tj|j�tr$t|��t�	|��dS)N)
r�r�r�rorFr4rr�r��UnsupportedOperation)r3r�r)r)r*�_raises
zFakeFileWrapper._raisecCs|jS)zLReturn the FakeFile object that is wrapped by the current instance.
        )r$)r3r)r)r*r<szFakeFileWrapper.get_objectcCs|jS)z.Return the file descriptor of the file object.)r�)r3r)r)r*r�#szFakeFileWrapper.filenocCs�|��sdS|jr:|js:|��|jjr:|jr:t��|j_	|j
rP|j�|j�n|jj
|j�|�|jr||j�|��j�dS)zClose the file.N)�_is_openr�r�r�r�rVr�rWr$rLr�rEr�r�r�r}r�r<r�)r3r)r)r*rY'szFakeFileWrapper.closecCs
|��S)z(Simulate the `closed` attribute on file.)r�)r3r)r)r*�closed9szFakeFileWrapper.closedcCs�|��|jr�|js�|j��}|jrj|��t|�r<|jj	n|jj
}|||jd�}|�|�|�
�n
|j��|j�||j�r�|jjr�d|_nt��}||j_||j_|jj|_|js�|��dS)zFlush file contents to 'disk'.NT)�_check_open_filer�r�r��getvaluer�r�rr$rcrar��_set_stream_contentsr�r�rvr�r�rVr�rWrMrLr^r��_flush_related_files)r3ra�old_contentsr:r)r)r*r�>s(




zFakeFileWrapper.flushcCs|j��|_dS)N)r�r�r�)r3r)r)r*r�Ysz FakeFileWrapper.update_flush_poscCsVxP|jjdd�D]<}|dk	rx.|D]&}||k	r$|j|jkr$|js$|��q$WqWdS)Nr)r�r�r$r�r�)r3r��	open_filer)r)r*r�\s
z$FakeFileWrapper._flush_related_filesrcCs<|��|js|j�||�n||_||_|js8|��dS)z"Move read/write pointer in 'file'.N)r�r�r�r�r�r�r�r�)r3�offset�whencer)r)r*r�eszFakeFileWrapper.seekcCsn|��|��r|��|js(|j��S|jrh|j��}|j�|j|j�|j��|_d|_|j�|�|jS)zoReturn the file's current position.

        Returns:
          int, file's current position in bytes.
        r)	r��_flushes_after_tellr�r�r�r�r�r�r�)r3�
write_seekr)r)r*r�ps

zFakeFileWrapper.tellcCs|jo|jjptS)N)r�r�rVr)r3r)r)r*�_flushes_after_read�sz#FakeFileWrapper._flushes_after_readcCs|jo|jjptS)N)r�r�r�r)r3r)r)r*r��sz#FakeFileWrapper._flushes_after_tellcCsD|j|jjkrdS|jjr$|jj}n|jj}|�|�|jj|_dS)z;Update the stream with changes to the file object contents.N)r�r$r^r�r�rcrar�)r3rar)r)r*r��s

zFakeFileWrapper._sync_iocCs^|j��}|j�d�|j��|jjs<t|�r<|�|j�}|j�|�|j	sZ|j�|�dS)Nr)
r�r�r�ryr�rrfr��putvaluer�)r3rar�r)r)r*r��s

z$FakeFileWrapper._set_stream_contentscst�j|����fdd�}|S)a_Wrap a stream attribute in a read wrapper.

        Returns a read_wrapper which tracks our own read pointer since the
        stream object has no concept of a different read and write pointer.

        Args:
            name: The name of the attribute to wrap. Should be a read call.

        Returns:
            The read_wrapper function.
        cs@�j��j�j��||�}�j���_d�_�j�dd�|S)a�Wrap all read calls to the stream object.

            We do this to track the read pointer separate from the write
            pointer.  Anything that wants to read from the stream object
            while we're in append mode goes through this.

            Args:
                *args: pass through args
                **kwargs: pass through kwargs
            Returns:
                Wrapped stream object method
            rrw)r�r�r�r�r�)rprq�	ret_value)�io_attrr3r)r*�read_wrapper�s

z4FakeFileWrapper._read_wrappers.<locals>.read_wrapper)r�r�)r3rUr�r))r�r3r*�_read_wrappers�szFakeFileWrapper._read_wrapperscs t�j|�����fdd�}|S)z�Wrap a stream attribute in an other_wrapper.

        Args:
          name: the name of the stream attribute to wrap.

        Returns:
          other_wrapper which is described below.
        csD�j��}�||�}|�j��kr4�j���_d�_�r<ts@|SdS)a�Wrap all other calls to the stream Object.

            We do this to track changes to the write pointer.  Anything that
            moves the write pointer in a file open for appending should move
            the read pointer as well.

            Args:
                *args: Pass through args.
                **kwargs: Pass through kwargs.

            Returns:
                Wrapped stream object method.
            rN)r�r�r�r�r)rprqr�r�)r�r3�writingr)r*�
other_wrapper�s

z5FakeFileWrapper._other_wrapper.<locals>.other_wrapper)r�r�)r3rUr�r�r))r�r3r�r*�_other_wrapper�s	zFakeFileWrapper._other_wrappercCs\xV|jjdd�D]B}|dk	rx4|D],}||k	r$|j|jkr$|jr$|j|7_q$WqWdS)Nr)r�r�r$r�r�)r3rkr�r�r)r)r*�_adapt_size_for_related_files�s
z-FakeFileWrapper._adapt_size_for_related_filescst�jd����fdd�}|S)zwWrap truncate() to allow flush after truncate.

        Returns:
            Wrapper which is described below.
        rycs��jr�j��j�j��||�}����js�|�j_t	�j�
��}||kr��j�|��j�d||��j��j�
��j
�|�_�jjs�tjddkr���||����ts�|SdS)z0Wrap truncate call to call flush after truncate.r�rrwN)r�r�r�r�r�r�r�r$rkr]r�rcrvr�r�r�r�r;rr�r)rprqrk�buffer_size)r�r3r)r*�truncate_wrapper�s$
z;FakeFileWrapper._truncate_wrapper.<locals>.truncate_wrapper)r�r�)r3r�r))r�r3r*�_truncate_wrapper�sz!FakeFileWrapper._truncate_wrappercst|j|���fdd�}|S)zyWrap write() to adapt return value for Python 2.

        Returns:
            Wrapper which is described below.
        cs�||�}ts|SdS)z*Wrap all write calls to the stream object.N)r)rprqr�)r�r)r*�
write_wrappers
z5FakeFileWrapper._write_wrapper.<locals>.write_wrapper)r�r�)r3rUr�r))r�r*�_write_wrapperszFakeFileWrapper._write_wrappercCs|jjS)z5Return the content size in bytes of the wrapped file.)r$rJ)r3r)r)r*rk#szFakeFileWrapper.sizecCs�|j��rt|j��|�d�p$|dk}|dk}|�d�p:|}|sD|rL|��|js^|r^|��S|jsp|rp|�	�S|r�|�
�|��r�|��|j
js�t��|j_|r�|��S|jr�|r�|�|�S|�||�S|r�|�|�St|j|�S)Nr��nextryrc)r$rqr0r4rr�r��_read_errorr��_write_errorr�r�r�r�rVrWrKr�r�r�r�r�r�r�)r3rU�readingryr�r)r)r*r�'s4





zFakeFileWrapper.__getattr__cs�fdd�}|S)Ncs:|r,|ddkr,�jjr,�jr,�jr(dSdS��d�dS)z+Throw an error unless the argument is zero.rr�rzFile is not open for reading.N)r�rVr�r�r�)rprq)r3r)r*�
read_errorIsz/FakeFileWrapper._read_error.<locals>.read_errorr))r3r�r))r3r*r�HszFakeFileWrapper._read_errorcs�fdd�}|S)Ncs4�jr&�jjr&|r&t|d�dkr&dS��d�dS)zThrow an error.rzFile is not open for writing.N)r�r�rVr]r�)rprq)r3r)r*�write_errorSs
z1FakeFileWrapper._write_error.<locals>.write_errorr))r3r�r))r3r*r�RszFakeFileWrapper._write_errorcCs6|jt|jj�ko4|jj|jdk	o4||jj|jkS)N)r�r]r�r�)r3r)r)r*r�]szFakeFileWrapper._is_opencCs|js|��std��dS)NzI/O operation on closed file)r�r�rR)r3r)r)r*r�bsz FakeFileWrapper._check_open_filecCs|js|�d�|j��S)NzFile is not open for reading)r�r�r��__iter__)r3r)r)r*r�fs
zFakeFileWrapper.__iter__)
FFFFNNTTNNFFT)r)"r6r7r8r9r2r�r�r�r<r�rYr�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�rkr�r�r�r�r�r�r)r)r)r*r��sB
+	


$#	 !
r�c@s8eZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�ZdS)
r�zHWrapper for a system standard stream to be used in open files list.
    cCs||_d|_dS)N)�_stream_objectr�)r3�
stream_objectr)r)r*r2pszStandardStreamWrapper.__init__cCs|jS)N)r�)r3r)r)r*r<tsz StandardStreamWrapper.get_objectcCs|jS)z:Return the file descriptor of the wrapped standard stream.)r�)r3r)r)r*r�wszStandardStreamWrapper.filenocCsdS)z+We do not support closing standard streams.Nr))r3r)r)r*rY{szStandardStreamWrapper.closecCsdS)NTr))r3r)r)r*r�szStandardStreamWrapper.is_streamN)	r6r7r8r9r2r<r�rYr�r)r)r)r*r�lsr�c@s0eZdZdZdd�Zdd�Zdd�Zdd	�Zd
S)r�zFWrapper for a FakeDirectory object to be used in open files list.
    cCs||_||_||_d|_dS)N)r$r4r�r�)r3r$r4rSr)r)r*r2�szFakeDirWrapper.__init__cCs|jS)zLReturn the FakeFile object that is wrapped by the current instance.
        )r$)r3r)r)r*r<�szFakeDirWrapper.get_objectcCs|jS)z.Return the file descriptor of the file object.)r�)r3r)r)r*r��szFakeDirWrapper.filenocCs|j�|j�dS)zClose the directory.N)r�rEr�)r3r)r)r*rY�szFakeDirWrapper.closeN)r6r7r8r9r2r<r�rYr)r)r)r*r��s
r��Sizec@sJeZdZdZdZddd�Zdd�Zdd
d�Zdd
d�Zdd�Zdd�Z	d	S)roz�Faked `file()` and `open()` function replacements.

    Returns FakeFile objects in a FakeFilesystem in place of the `file()`
    or `open()` function.
    FcCsB||_||_to||_|p4tp4t��dkp4|jj|_||_dS)a5
        Args:
          filesystem:  FakeFilesystem used to provide file system information
          delete_on_close:  optional boolean, deletes file on close()
          use_io: if True, the io.open() version is used (ignored for Python 3,
                  where io.open() is an alias to open() )
        �PyPyN)	rS�_delete_on_closer�
_py2_newlinesr��python_implementationr��_use_ior�)r3rSr}r�r�r)r)r*r2�s	

zFakeFileOpen.__init__cOs"|jr|j||�S|j||�SdS)z:Redirects calls to file() or open() to appropriate method.N)r�rr�
_call_ver2)r3rprqr)r)r*�__call__�szFakeFileOpen.__call__rrMNcCs|p|}|j||||d�S)z8Limits args of open() or file() for Python 2.x versions.)r)rr)r3r4r1r�r�rr)r)r*r��szFakeFileOpen._call_ver2Tc
Csd|k}
|�|||	�\}}	|�|�\}}}
}|
s4d}|jrB|jjn|jj}|	jrt|sh|j�|�rt|jjst|t	j
|�|r�t�s�|	jr�|j
t@r�|	jr�|j
t@s�|t	j|�|	jr�|	jr�|�d�n�|	jr�|t	j|�|j�|�r�|jj|dd�}|j}n|}|j�|��r:|jj�rt	jn|jj�r*t	jnt	j}|||�|jj|dd|jd�}t|j
��r�|jj�rt|t	j|�n|t	j|�||_|	j�r�t��}||_ |jj�s�||_!t"|||	j|	j|	j#|j$|j||
||||j|j%d�}|
dk	�r|
|_&|jj'|
�#|�n|j�(|�|_&|S)	adReturn a file-like object with the contents of the target
        file object.

        Args:
            file_: Path to target file or a file descriptor.
            mode: Additional file modes (all modes in `open()` are supported).
            buffering: ignored. (Used for signature compliance with
                __builtin__.open)
            encoding: The encoding used to encode unicode strings / decode
                bytes.
            errors: (str) Defines how encoding errors are handled.
            newline: Controls universal newlines, passed to stream object.
            closefd: If a file descriptor rather than file name is passed,
                and this is set to `False`, then the file descriptor is kept
                open when file is closed.
            opener: not supported.
            open_modes: Modes for opening files if called from low-level API.

        Returns:
            A file-like object containing the contents of the target file.

        Raises:
            IOError, OSError depending on Python version / call mode:
                - if the target object is a directory
                - on an invalid path
                - if the file does not exist when it should
                - if the file exists but should not
                - if permission is denied
            ValueError: for an invalid mode or mode combination
        r{TrF)r#)r�r�r�)r�r�r?r}rSr�r�r�rYrZr�r�N))�_handle_file_mode�_handle_file_argr�rSr�rnrzr�rVror�r/rwrD�	PERM_READrxr�r�ryrvrvr'rrar&r(r�r�r�rr�rWrLrMr�r?r�r�r�r�rB)r3�file_r1r�rYrZr�r�r�rr�r$r4r��	real_pathr�r+r�r�r:�fakefiler)r)r*rr�s�!






zFakeFileOpen.callcCs�d}t|t�rB|}|j�|�}|j|_|j�|���}|j}|}nNd}|}||jjjkrf|jj}|}n*|jj	||j
d�}|j�|�r�|j�|�}||||fS)N)r�)
rdr4rSrGr}r�r<rUr�r�r�r�r�)r3r�r$r��wrapperr4r�r)r)r*r�6s&
zFakeFileOpen._handle_file_argcCs�|}d|kr,d|kr,tr |jjr,td|��|�dd��dd�}|jrRd|krRd}|�dd��dd�}|js�|tkr�td	|��tt|�}||fS)
Nr{�tzInvalid mode: r�U�-�rUrzInvalid mode: %r)	rrSrVrRrIr�r��_OPEN_MODE_MAPr)r3r1r�r�
orig_modesr)r)r*r�OszFakeFileOpen._handle_file_mode)FFF)rrMNN)rrMNNNTNN)
r6r7r8r9r2r�r�rrr�r�r)r)r)r*ro�s


nrocCsddl}ddlm}|�|�S)Nr)�fake_filesystem)�doctest�pyfakefsr�testmod)rrr)r)r*�_run_doctestasr�__main__)�r9ror=r�rgr�r�r;rWr9�collectionsrr�rrrrrrr	�pyfakefs.deprecatorr
�pyfakefs.fake_scandirrr�pyfakefs.extra_packagesr
�pyfakefs.helpersrrrrrrrrrr�
__pychecker__�__version__r�r�r�r�r�r0rrrrr�r;r��getuidr'�getgidr,r+r.r/�	Exceptionr0rB�objectrCr��addrmrvrqr�r�r�r�r�r�r�rrrlr�r2r;rBrEr�rGrKrUrr|rfrrzrZrar�r�r�r<rr�r�r�r�rr�r�r�r�r�r�r�r}r�r�r�r�r�r)rUr�r�r�r�rkrorr6r)r)r)r*�<module>_s<$0P(@.





*C