__init__.py000064400000000070150043321510006644 0ustar00from pyfakefs._version import __version__ # noqa: F401 __pycache__/__init__.cpython-311.pyc000064400000000422150043321510013205 0ustar00 bg8ddlmZdS)) __version__N)pyfakefs._versionrb/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/__init__.pyrs))))))))r__pycache__/_version.cpython-311.pyc000064400000000343150043321510013274 0ustar00 bg dZdS)z5.2.3N) __version__b/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/_version.pyrs r__pycache__/extra_packages.cpython-311.pyc000064400000001555150043321510014437 0ustar00 bg}dZ ddlZn #e$rdZYnwxYw ddlZdZdZn&#e$r ddlmZdZdZn#e$rdZdZYnwxYwYnwxYwepeZdS)zImports external packages that replace or emulate internal packages. If the external module is not present, the build-in module is imported. NTF)scandir)__doc__pathlib2 ImportErrorruse_scandir_packageuse_builtin_scandiros use_scandirh/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/extra_packages.pyrsOOOOHHH $NNN$$$$"# $$$##$ $"8%8 s6  A 1A =A=AA__pycache__/fake_file.cpython-311.pyc000064400000176773150043321510013402 0ustar00 bgddZddlZddlZddlZddlZddlZddlmZmZddl m Z ddl m Z m Z mZmZmZmZmZmZmZmZmZmZmZddlmZddlmZmZmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%erddl&m'Z'ed Z(ed Z)Gd d e*Z+Gd dZ,Gdde,Z-Gdde,Z.Gdde,Z/Gdde/Z0GddZ1GddZ2GddZ3GddZ4dS)z1Fake implementations for different file objects. N)S_IFREGS_IFDIR) TracebackType) ListOptionalCallableUnionAnyDictcastAnyStrNoReturnIteratorTextIOType TYPE_CHECKING)helpers) FakeStatResultBinaryBufferIO TextBufferIO is_int_typeis_unicode_string to_stringmatching_string real_encodingAnyPath AnyString)FakeFilesystem)FakeFileWrapperFakeDirWrapperStandardStreamWrapperFakePipeWrapper)FakeFile FakeDirectoryc,eZdZdZdeddffd ZxZS)FakeLargeFileIoExceptionz|Exception thrown on unsupported operations for fake large files. Fake large files have a size with no real content. file_pathreturnNc^tt|d|zdS)Nz?Read and write operations not supported for fake large file: %s)superr&__init__)selfr' __class__s c/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/fake_file.pyr+z!FakeLargeFileIoException.__init__Js= &--66 "$- .     )__name__ __module__ __qualname____doc__strr+ __classcell__r-s@r.r&r&EsU # $          r/r&c&eZdZdZdZeejzdddddfdede de ede dd e e d e e d e e dgdffd Z ed e efdZed e e fdZed efdZejded dfdZed efdZejded dfdZed efdZejded dfdZde d dfdZde d dfdZd efdZdee edfd e efdZded efdZd*ded e e d efdZed e fdZejde d dfd Zed efd!Z e!j"d"kred efd#Z#d$e d e$ffd% Z%d&e d'e$d dffd( Z&d e fd)Z'xZ(S)+r#aProvides 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_modest_inost_devst_nlinkst_uidst_gidst_sizest_atimest_mtimest_ctime st_atime_ns st_mtime_ns st_ctime_nsNnamer8contents filesystemrencodingerrors side_effectc0|td||_||_||_t |jt jt jt j |_ |dz dkr |tz}||j _ d|_ t||_|pd|_|||_|jt'|jnd|j _ d|_d|_i|_d|_dS)a 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), and the file permissions. If no file type is set (e.g. permission flags only), a regular file type is assumed. contents: The contents of the filesystem object; should be a string or byte object for regular files, and a dict of other FakeFile or FakeDirectory objects wih the file names as keys 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 rstrict) ValueErrorrG _side_effectrEr is_windows_fsrget_uidget_gidnow stat_resultrr8r>rrHrI_encode_contents_byte_contentslenepoch parent_dirxattr opened_as)r,rEr8rFrGrHrIrJs r.r+zFakeFile.__init__s :  ;<< <,60;  )  $ O   O   KMM    b=A   w G#*  '4X'>'> !-X /3/D/DX/N/N(,(;(GC# $ $ $Q   37 $&r/r(c|jS)z&Return the contents as raw byte array.rWr,s r. byte_contentszFakeFile.byte_contentss ""r/ct|jtr:|j|jpt jd|jSdS)z9Return the contents as string with the original encoding.F)rIN) isinstancer`bytesdecoderHlocalegetpreferredencodingrIr_s r.rFzFakeFile.contentssZ d(% 0 0 %,, C!c|||jrd|_|jr&|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: OSError: if the st_size is not a non-negative integer, or if st_size exceeds the available file system space rN)_check_positive_intr>sizerGchange_disk_usagerEr:rWr,r>s r.set_large_file_sizezFakeFile.set_large_file_sizesg   ))) < DI ? O O - -gty$+ N N N "r/rvct|r|dkr,|jtj|jdSdSNr)rrGraise_os_errorerrnoENOSPCrE)r,rvs r.ruzFakeFile._check_positive_intsD4   DD1HH O * *5< C C C C C%-Hr/c|jduS)zVReturn `True` if this file was initialized with size but no contents. Nr^r_s r. is_large_filezFakeFile.is_large_files"d**r/ct|rBttt||jpt jd|j}tt|SNF)rrcr r4rHrerfrIr,rFs r.rVzFakeFile._encode_contentssZ X & & S(## C!rGrwrEr:rY)r,rFr`changedr> current_sizes r.set_initial_contentszFakeFile.set_initial_contentss--h77 %6(5<#m$$$1|(q  )) l "DIt{   ,  a r/ct||_||}|j|||S)ahSets the file contents and size and increases the modification time. Also executes the side_effects if available. Args: contents: (str, bytes) 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. Returns: True if the contents have been changed. Raises: OSError: if `st_size` is not a non-negative integer, or if it exceeds the available file system space. )rrHrrP)r,rFrHrs r. set_contentszFakeFile.set_contents*sH"&h// ++H55   (   d # # #r/c|jS)z.Return the size in bytes of the file contents.)r>r_s r.rvz FakeFile.sizeAs |r/c2|||jpd}|j||z |j|j|jr1||kr|jd||_n|xjd||z zz c_||_|xjdz c_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: OSError: if the st_size arg is not a non-negative integer or if st_size exceeds the available file system space rNr)rur>rGrwrEr:rWrY)r,r>rs r.rvz FakeFile.sizeFs   )))|(q  )) l "DIt{      H%%&*&9(7(&C####u,0F'GG##  a r/cg}|}|r7|dt|j|j|j}|7|j|d}|d|krR|d||}|j|d}|s||z}n||}|j |S)z+Return the full path of the current object.r) insertrrErZrGget_path_separatorpopjoin splitdrive absnormpath)r,namesobjsepdir_pathdrives r.pathz FakeFile.path`s!"& ! LLODIsx@@ A A A.C !o00q:: 8s?? IIaLLLxxHO..x88;E *>xxH**8444r/)rLc@|j|jSN)rG isjunctionrr_s r. is_junctionzFakeFile.is_junctionws?--di88 8r/itemc||jvrt|j|St|Sz'Forward some properties to stat_result.) stat_typesgetattrrUr*__getattribute__)r,rr-s r. __getattr__zFakeFile.__getattr__{s; 4? " "4+T22 2ww''---r/keyvaluec||jvrt|j||St||Sr)rsetattrrUr* __setattr__)r,rrr-s r.rzFakeFile.__setattr__s? $/ ! !4+S%88 8ww""3...r/c$d|j|jfzS)Nz%r(%o))rEr8r_s r.__str__zFakeFile.__str__s49dl333r/r))r0r1r2r3rrr PERM_DEF_FILEr intrr4rr+propertyrcr`rFfloatrAsetterr?r@ryruboolrr rVrrrvrsys version_inforr rrrr5r6s@r.r#r#QsB:J&!66%)15"& $>B6'6'6'6'6" 6' -. 6' 3- 6' 6'h |T'9:;6'6'6'6'p#x###X#(3-X)%)))X)_(E(d(((_()%)))X)_(E(d(((_()%)))X)_(E(d(((_(#3#4####.DDDDDD +t++++ %sE4/?)@%Xe_%%%%V6Vx}PT.cX [CD[25f555X5( 7""  9 9 9 9  9........ /s/3/4////// 444444444r/r#cLeZdZd fd ZedefdZdedefdZ xZ S) FakeNullFilerGrr(Nct|jrdnd}tt|||ddS)Nnulz /dev/nullrN)rGrF)rQr*rr+)r,rGdevnullr-s r.r+zFakeNullFile.__init__s@%3D%% lD!!**7zTV*WWWWWr/cdS)Nr/r_s r.r`zFakeNullFile.byte_contentsssr/rFcdSrrrs r.rz!FakeNullFile.set_initial_contentssur/)rGrr(N) r0r1r2r+rrcr`r rrr5r6s@r.rrsXXXXXXuXVr/rc ~eZdZdZ d dedddeeddffd Zedee fd Z d fd Z d Z xZ S) FakeFileFromRealFileztRepresents a fake file copied from the real file system. The contents of the file are read on demand only. Nr'rGrrJr(cttj|||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. )rErGrJFN)r*r+osrbasename contents_read)r,r'rGrJr-s r.r+zFakeFileFromRealFile.__init__sO !!),,!#    #r/c|jsRd|_tj|jd5}||_dddn #1swxYwYt j|jj|_|jS)NTrb) rioopenr'readrWrstatr?)r,fs r.r`z"FakeFileFromRealFile.byte_contentss! /!%D .. /!&'ffhh# / / / / / / / / / / / / / / ///8 ""sAAAchd|_tt|||dSNT)rr*rr)r,rFrHr-s r.rz!FakeFileFromRealFile.set_contentss2! "D))66xJJJJJr/cdS)zThe contents are never faked.Frr_s r.rz"FakeFileFromRealFile.is_large_fileur/r)r0r1r2r3r4rrr+rrcr`rrr5r6s@r.rrs+/ ###%#h' #  ######,#x###X#KKKKKKr/rcjeZdZdZejdfdedededfdZ dde d eed e fd Z e d eeeffd Ze d eefd Zded dfdZded efdZded efdZddede d dfdZe d efdZejded dfdZddd e fdZd effd ZxZS)r$z,Provides the appearance of a real directory.NrE perm_bitsrGrct||t|zd||xjdz c_i|_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 rN)rGrN)r#r+rr;_entries)r,rErrGs r.r+zFakeDirectory.__init__sE $g &92*UUU  ,. r/rFrHr(cV|jtj|jrrGr|r}EISDIRr)r,rFrHs r.rzFakeDirectory.set_contentsso,,U\49EEEr/c|jS)z/Return the list of contained directory entries.)rr_s r.entrieszFakeDirectory.entriess }r/chdt|jdDS)z^Return the list of contained directory entry names ordered by creation order. cg|] }|d Srr.0rs r. z.FakeDirectory.ordered_dirs..s,    G   r/c|djS)Nr)r9)entrys r.z,FakeDirectory.ordered_dirs..s ar/)r)sortedritemsr_s r. ordered_dirszFakeDirectory.ordered_dirssB   t}2244:W:WXXX    r/ path_objectc~tjs@|jtjzs,|jjs t tjd|j t|j }||j vr*|j tj|j ||j|<||_|j&|jxjdz c_|jj|_|xjdz c_|xjdz c_|j|_|jdkr-|j|j|j |jdSdS)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 DeniedNr)ris_rootr8 PERM_WRITErGrQOSErrorr}EACCESrrrErr|EEXISTrrZr9last_inor;r:rwrv)r,rpath_object_names r. add_entryzFakeDirectory.add_entrysC!! HL7#55 HO1 H %,(;TYGG G )+*: ; ; t| + + O * *5< C C C*5 &'!%    % O $ $ ) $ $!%!9K   !![   1 $ $ O - - +"2DK      % $r/ pathname_namec`||}|jt|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_entrynamerr)r,rs r. get_entryzFakeDirectory.get_entrys,22=AA |Im4455r/cZ|jjsfd|jD}|r|dS)Nchg|].}|k,|/Sr)lower)rrErs r.rz7FakeDirectory._normalized_entryname.."s>ATATAVAV1V1V1V1V1Vr/r)rGis_case_sensitiver)r,rmatching_namess ` r.rz#FakeDirectory._normalized_entryname sT0 2!%N 2 .q 1 r/T recursivec||}||}|jjr}|jt jzdkr%|jtj ||j |r%|jtj |ntt j sa|jt jt j zzt jt j zkr%|jtj ||rQt|tr<|jr4|t#|jd|j4n2|jdkr'|j|j ||j|xjdzc_|xjdzc_|jdksJ|jt-|=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. rrN)rrrGrQr8rrr|r}r has_open_filerPERM_EXErbr$r remove_entrylistr;rwrvr:r)r,rrrs r.rzFakeDirectory.remove_entry)s22=AA }-- ? ( L}w11Q66..u|]KKK,,U33 L..u|]KKK?$$ L  2W5E EF%(8899..u|]KKK  XE=99 X- ;""4 #6#6q#9:::- ; ^q O - -uzk=%, W W W   !~"""" L=11 2 2 2r/cbtd|jDS)zUReturn the total size of all files contained in this directory tree. c(g|]}|djS)r)rvrs r.rz&FakeDirectory.size..VsBBBTDGLBBBr/)sumrrr_s r.rvzFakeDirectory.sizeQs/ BBT\-?-?-A-ABBBCCCr/r>cV|jtj|j)z-Setting the size is an error for a directory.rrxs r.rvzFakeDirectory.sizeXs o,,U\49EEEr/ dir_objectc0|}|r||krdS|j}|dS)zmReturn `True` if dir_object is a direct or indirect parent directory, or if both are the same object.TF)rZ)r,rrs r.has_parent_objectzFakeDirectory.has_parent_object]s9(, !j  t.C !ur/ctt|dz}|jD]F}|j|}|dD]}|r |dz|zdz}G|S)Nz:  z )r*r$rrsplit)r, descriptionr item_descliner-s r.rzFakeDirectory.__str__gsM40088::UB L C CD T*2244I!-- C CC"-"4t";d"BK Cr/r)T)r0r1r2r3rPERM_DEFr4rrr+r rrrr r#rrrrAnyFilerrrrvrrrr5r6s@r.r$r$s@66 !)15 ////-. ////&FFVFx}FPTFFFFc8m,X d3i   X  X $    D 6s 6w 6 6 6 633&3&3#&3$&3$&3&3&3&3PDcDDDXD  [FCFDFFF[FOr/r$c eZdZdZ ddedddedeeffd Zed e e e ffd Z ed e ffd Zejd e d dfd ZxZS)FakeDirectoryFromRealDirectoryz~Represents a fake directory copied from the real file system. The contents of the directory are read on demand only. N source_pathrGr read_only target_pathc|p|}tj|}tt|t tj|d|j||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)rErrGFN)rrr*r r+rrrr8rAr?r@r=r<rrr)r,rrGrr real_statr-s r.r+z'FakeDirectoryFromRealDirectory.__init__ws*"0[ GK((  ,d33<<27==55a899'! =   "* !* !* & & &""r/r(c<|jsd|_|j}tj|jD]}tj|j|}tj||}tj|r|j||tj |r#|j ||j ||j ||j ||j S)z[Return the list of contained directory entries, loading them if not already loaded.T)r)rrrlistdirrrislinkrGadd_real_symlinkisdiradd_real_directoryr add_real_filer)r,baserrrs r.rz&FakeDirectoryFromRealDirectory.entriess! !%D 9DD$455   gll4+;UCC  gll477 7>>+.. O44[+NNNNW]];//O66#T^7O11#T^2}r/cJ|jsdStt|jSr{)rr*r rv)r,r-s r.rvz#FakeDirectoryFromRealDirectory.sizes)! 13T::??r/r>cV|jtj|jrrrxs r.rvz#FakeDirectoryFromRealDirectory.sizeso,,U\49EEEr/r)r0r1r2r3rrrr+rr r4r#rrrvrr5r6s@r.r r qs*. $#$#$#%$# $# g& $#$#$#$#$#$#Lc8m,X*@c@@@@@X@  [FCFDFFF[FFFFFr/r cJeZdZdZ d=dedededededed d d eed ed edeedeede dedefdZ d>dZ dee e dee deeddfdZdedefdZdefdZde fdZd?dZedefd Zd!e ddfd"Zd?d#Zd?d$Zd?d%Zd@d'e d(e ddfd)Zde fd*Zd?d+Zd,eddfd-Zd.ede fd/Z!d.ede fd0Z"d.ede fd1Z#d2e ddfd3Z$de fd4Z%de fd5Z&d.ede'fd6Z(de fd7Z)de fd8Z*defd9Z+d?d:Z,de-e.ee.effd;Z/d<Z0dS)ArzWrapper 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(). F file_objectr'updaterappenddelete_on_closerGrnewlinebinaryclosefdrHrI bufferingraw_io is_streamcR||_||_||_||_||_| |_|j|_||_| |_ ||_ d|_ | |_ |j dkr| std|j dks| stj|_ | o| dk|_|j}| pt%jd|_| pd} | rt+|nt-|| || |_d|_d|_d|_|rpt7||_|rZ|s|jdn=|j|j|j|_|r |s Jd||_||_|j |_!d|_"dS) NFrzcan't have unbuffered text I/OrrM)rHr"rIz(delete_on_close=True requires filesystem)#rr'_append_read allow_update_closefdrY _file_epochr&_binaryr'_changed _buffer_sizerOrDEFAULT_BUFFER_SIZE_use_line_bufferr`rerf _encodingrr_io _read_whence _read_seek _flush_posrXseektell _filesystemr!r\rEfiledes)r,rr'rrr r!rGr"r#r$rHrIr%r&r'rFs r.r+zFakeFileWrapper.__init__s$'"  " &,  " %   ! !& !=>> >  " $ $F $ " 6D $* =yA~,!GV%@%G%G#8 N8 $ $ $8WV   6!(mmDO 66HMM!$$$$HMM$/222&*hmmooDO  J I II I I:%. ) &* r/r(c|S)=To support usage of this fake file with the 'with' statement.rr_s r. __enter__zFakeFileWrapper.__enter__  r/exc_typeexc_valexc_tbNc.|dS)r>Ncloser,rArBrCs r.__exit__zFakeFileWrapper.__exit__ r/messagec|jr*|jtj|jt j|r)r&r;r|r}EBADFr'rUnsupportedOperation)r,rJs r._raisezFakeFileWrapper._raises; ; I   + +EK H H H%g...r/c|jS)zTReturn the FakeFile object that is wrapped by the current instance. rr_s r. get_objectzFakeFileWrapper.get_objects r/cR|j|jSttjdz.Return the file descriptor of the file object.NInvalid file descriptorr<rr}rLr_s r.filenozFakeFileWrapper.fileno"% < #< ek#<===r/c |sdS|jrK|jsD||jjr$|jrtj|j _ |j J|j r |j |j n0|jj|j }|J|||jr3|j|jdSdS)zClose the file.N)_is_openr,r&flushr;rQr0rrTrr@r<r-_close_open_file open_filesremover! remove_objectrQrr,r\s r.rFzFakeFileWrapper.close(s}}  F   :T[ : JJLLL- :$- :,3KMM )|''' = $   - -dl ; ; ; ;)4T\BJ)))   d # # #      * *!!&       r/c,| S)z(Simulate the `closed` attribute on file.)rYr_s r.closedzFakeFileWrapper.closed@s==??""r/old_posc|j} |dS#t$r<|j||j||_wxYw)z0Try to flush and reset the position if it fails.N)r8rZrr5r9truncate)r,rb flush_poss r. _try_flushzFakeFileWrapper._try_flushEslO   JJLLLLL    HMM' " " " H     'DO   s AA%c||jr0|js*|j}|jrL||jj}|J|||j dz}| |n|j |j ||j }||r?|jjrd|_n+t%j}||j_||j_|jj|_|js|dSdSdSdS)zFlush file contents to 'disk'.NT)_check_open_filer,r'r5getvaluer*_sync_iorr`r8_set_stream_contentsrZrr4update_flush_posr;rQr0rrTrAr@rYr._flush_related_files)r,rF old_contentsr current_times r.rZzFakeFileWrapper.flushQsc    ,T^ ,x((**H| ! #/= #///'(4?3D3D*EE))(3333   &33HdnMMG  ! ! # # # =#1=$(DMM#*;==L0 ,))+++++- , , , ,* , ,r/cB|j|_dSr)r5r:r8r_s r.rlz FakeFileWrapper.update_flush_posls(--//r/c|jjddD]M}|I|D]F}||ur@t|tr+|j|jkr|js|GNdSNr)r;r\rbrrr*rj)r,r\ open_files r.rmz$FakeFileWrapper._flush_related_filesos*5abb9 - -J%!+--I!--&y/BB. , 0EEE ) 1F"**,,, - -r/roffsetwhencec||js|j||n||_||_|js|dSdS)z"Move read/write pointer in 'file'.N)rhr*r5r9r7r6r'rZ)r,rtrus r.r9zFakeFileWrapper.seek{sk | ' HMM&& ) ) ) )$DO &D ~  JJLLLLL  r/c||js||js|jS|jr}|j}|j|j|j|j|_d|_|j||jS)zoReturn the file's current position. Returns: int, file's current position in bytes. r) rhr'rZr*r5r:r6r9r7)r, write_seeks r.r:zFakeFileWrapper.tells ~  JJLLL| #8==?? "   &J HMM$/4+< = = ="hmmooDO !D  HMM* % % %r/c|j|jjkrdS|jj}|J|||jj|_dS)z;Update the stream with changes to the file object contents.N)r.rrYr`rkrs r.rjzFakeFileWrapper._sync_iosZ  t/5 5 5 F#1### !!(++++1r/rFc|j}|jd|j|j||js|j|dSdSr{)r5r:r9rdputvaluer*)r,rFrus r.rkz$FakeFileWrapper._set_stream_contentss}  a  (###| " HMM& ! ! ! ! ! " "r/rEc@tj|fd}|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. cjjj|i|}j_d_jdd|S)aWrap 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 r)r5r9r7r6r:)argskwargs ret_valueio_attrr,s r. read_wrapperz4FakeFileWrapper._read_wrappers..read_wrappersi HMM$/4+< = = =000I"hmmooDO !D  HMM!Q    r/rr5)r,rErrs` @r._read_wrapperszFakeFileWrapper._read_wrapperss=$(D))      (r/c@tj|fd}|S)zWrap a stream attribute in an other_wrapper. Args: name: the name of the stream attribute to wrap. Returns: other_wrapper which is described below. cj}|i|}|jkr%j_d_|S)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. r)r5r:r7r6)rrrxrrr,s r. other_wrapperz5FakeFileWrapper._other_wrapper..other_wrappers\J000ITX]]__,,"&(--//$%! r/r)r,rErrs` @r._other_wrapperzFakeFileWrapper._other_wrappers=$(D))      ,r/c@tj|fd}|S)zWrap a stream attribute in a write_wrapper. Args: name: the name of the stream attribute to wrap. Returns: write_wrapper which is described below. cj}|i|}j}jo d|dv}|jz jks|rd||z jkp|}|s3j|j||s|i|}jr%j_ d_ |S)rrr) r5r:r3r8r1r9rdrfr*r7r6) rrrbrnew_pos use_line_buf flush_allrr,s r. write_wrapperz5FakeFileWrapper._write_wrapper..write_wrappershmmooG000IhmmooG 0DTT!W_L(4+<<< <#g-0AAQ\ !(HMM'***H%%'''((( 9 ' 8 8 8I| &"&(--//$%! r/r)r,rErrs` @r._write_wrapperzFakeFileWrapper._write_wrappers>$(D))" " " " " " Hr/rvc|jjddD]\}|X|D]U}||urOt|tr:|j|jkr*t t|jr|xj|z c_V]dSrr)r;r\rbrrr r*r7)r,rvr\rss r._adapt_size_for_related_filesz-FakeFileWrapper._adapt_size_for_related_files$s*5abb9 5 5J%!+55I!--&y/BB. , 0EEE )<<DF",,4,, 5 5r/c.jjfd}|S)zwWrap truncate() to allow flush after truncate. Returns: Wrapper which is described below. c^jr%jjj|i|}js|j_tj }||krj|j d||z zj j j |_||z |S)z0Wrap truncate call to call flush after truncate.r)r*r5r9r7r6rZr'rrvrXrir{rr4r8r)rrrv buffer_sizerr,s r.truncate_wrapperz;FakeFileWrapper._truncate_wrapper..truncate_wrapper8s| B dot/@AAA7D+F++D JJLLL> K(, %!$("3"3"5"566 %%HMM+...H%%etk/A&BCCC$11$(2C2C2E2Et~VVV&*DO66tk7IJJJ JJLLLKr/)r5rd)r,rrs` @r._truncate_wrapperz!FakeFileWrapper._truncate_wrapper0s6 (#      & r/c|jjS)z5Return the content size in bytes of the wrapped file.)rr>r_s r.rvzFakeFileWrapper.sizeMs''r/c|jrt|j|dp|dk}|dk}|dp|}|s|r||js|r|S|js|r| S|rX| |j s| |j jstj|j_|r|S|jr.|r||S|s||S|r||St/|j|S)Nrnextrdwrite)rrr&r' startswithrhr+ _read_errorr, _write_errorrjr'rZr;rQrrTr?rr*rrrrr5)r,rEreadingrdwritings r.rzFakeFileWrapper.__getattr__Qs   ) ) + + ;*4>:: ://&));TV^:%//'**6h  $g $  ! ! # # #z &g &##%% %  'W '$$&& &  : MMOOO>  #1 :,3KMM )  ,))++ + < 1 1**4000 1**4000  -&&t,, ,tx&&&r/cfd}|S)Nc|r*|ddkrjjrjr jrdndSddS)z+Throw an error unless the argument is zero.rr/rNzFile is not open for reading.N)r;rQr&r/rNrrr,s r. read_errorz/FakeFileWrapper._read_error..read_errorssX 7Q1 #17dk7"&,633B6 KK7 8 8 8 8 8r/r)r,rs` r.rzFakeFileWrapper._read_errorrs$ 9 9 9 9 9r/cfd}|S)Ncjr)jjr|rt|ddkrdSddS)zThrow an error.rzFile is not open for writing.N)r&r;rQrXrNrs r. write_errorz1FakeFileWrapper._write_error..write_error}sT{ #1ds47||q?P?P1 KK7 8 8 8 8 8r/r)r,rs` r.rzFakeFileWrapper._write_error|s$ 9 9 9 9 9r/c|jA|jt|jjkr|jj|j}|||vrdSdS)NTF)r<rXr;r\r_s r.rYzFakeFileWrapper._is_opensP < # s4;K;V7W7W(W(W)4T\BJ%$**<*<tur/c^|js#|stddSdS)NzI/O operation on closed file)r'rYrOr_s r.rhz FakeFileWrapper._check_open_files>~ =dmmoo =;<< < = = = =r/cl|js|d|jSNzFile is not open for reading)r+rNr5__iter__r_s r.rzFakeFileWrapper.__iter__s3z 8 KK6 7 7 7x  """r/cb|js|dt|jSr)r+rNrr5r_s r.__next__zFakeFileWrapper.__next__s-z 8 KK6 7 7 7DH~~r/)F)r(rr(Nr)1r0r1r2r3r#r rrr4rr+r?r BaseExceptionrrHrrNrQrVrFrrarfrZrlrmr9r:rjrcrkrrrrrrrvr rrrrYrhr rrrrr/r.rrsH, !B+B+B+B+ B+  B+  B+B+%B+#B+B+B+3-B+ B+B+B+ !B+B+B+B+H4 ./-('   /c/h////  H    >>>>> 0####X# # $    ,,,,6**** - - - -  3  D    c(2222"U"t"""""3"8""""H!3!8!!!!F/3/8////b 5# 5$ 5 5 5 5 8    :(c((((''''''BXh$====#% x >?#### r/rc\eZdZdZdefdZdefdZdefdZd dede fd Z dd Z de fd Z d S)r!zCWrapper for a system standard stream to be used in open files list. stream_objectc"||_d|_dSr)_stream_objectr<)r,rs r.r+zStandardStreamWrapper.__init__s+&* r/r(c|jSr)rr_s r.rQz StandardStreamWrapper.get_objects ""r/cR|j|jSttjd)z:Return the file descriptor of the wrapped standard stream.NrTrUr_s r.rVzStandardStreamWrapper.filenorWr/r)ncZtt|jSr)r rcrr)r,rs r.rzStandardStreamWrapper.reads!E4.3355666r/NcdS)z+We do not support closing standard streams.Nrr_s r.rFzStandardStreamWrapper.closer/cdSrrr_s r.r'zStandardStreamWrapper.is_streamstr/r)r)r0r1r2r3rr+rQrrVrcrrFrr'rr/r.r!r!sMM+f++++#F####>>>>> 77c757777::::4r/r!cFeZdZdZdededdfdZdefdZdefd Z d d Z d S) r zAWrapper for a FakeDirectory object to be used in open files list.rr'rGrc>||_||_||_d|_dSr)rr'r;r<)r,rr'rGs r.r+zFakeDirWrapper.__init__s& '"%&* r/r(c|jS)zKReturn the FakeFile object that is wrapped by the current instance.rPr_s r.rQzFakeDirWrapper.get_objects r/cR|j|jSttjdrSrUr_s r.rVzFakeDirWrapper.filenorWr/NcV|jJ|j|jdS)zClose the directory.N)r<r;r[r_s r.rFzFakeDirWrapper.closes/|''' ))$,77777r/r) r0r1r2r3r$rr+rQrrVrFrr/r.r r sKK +" + +% + + + + M    >>>>> 888888r/r c eZdZdZ ddddededefdZdd Zd e e e d e e d e e d dfdZ ddZd efdZdded efdZddZded efdZddZd efdZd efdZd efdZdS) r"zdWrapper for a read or write descriptor of a real pipe object to be used in open files list. rNrGrfd can_writemodec||_||_||_d|_d|_d|_|rt |||_dSdSr)r;rrrr< real_filer)r,rGrrrs r.r+zFakePipeWrapper.__init__sU&"&*   ,!"d^^DNNN , ,r/r(c|S)=To support usage of this fake pipe with the 'with' statement.rr_s r.r?zFakePipeWrapper.__enter__r@r/rArBrCNc.|dS)rNrErGs r.rHzFakePipeWrapper.__exit__rIr/c|jSrrPr_s r.rQzFakePipeWrapper.get_objects r/cR|j|jSttjd)z3Return the fake file descriptor of the pipe object.NrTrUr_s r.rVzFakePipeWrapper.filenorWr/r)numBytescx|jr|j|Stj|j|S)zRead from the real pipe.)rrrr)r,rs r.rzFakePipeWrapper.reads6 > 1>&&x00 0wtw)))r/cdS)zFlush the real pipe?Nrr_s r.rZzFakePipeWrapper.flushrr/rFcx|jr|j|Stj|j|S)zWrite to the real pipe.)rrrrrs r.rzFakePipeWrapper.write s6 > 2>''11 1x***r/c|jJ|jj|j}|J|||jr|jdSt j|jdS)zClose the pipe descriptor.N)r<r;r\r]rrFrrr_s r.rFzFakePipeWrapper.closes~|'''%0> %%%$ >  N " " " " " HTW     r/c|j Sz0The pipe end can either be readable or writable.rr_s r.readablezFakePipeWrapper.readables >!!r/c|jSrrr_s r.writablezFakePipeWrapper.writables ~r/cdS)zA pipe is not seekable.Frr_s r.seekablezFakePipeWrapper.seekable"rr/)rN)r(r"rr)r0r1r2r3rrr4r+r?rrrrrHrQrVrcrrZrrFrrrrr/r.r"r"s ,,$, , ,  ,,,, 4 ./-('       >>>>> **S*%**** ####+e+++++    "$""""$$r/r")5r3r}rrerrrrrtypesrtypingrrrr r r r r rrrrrpyfakefsrpyfakefs.helpersrrrrrrrrrrpyfakefs.fake_filesystemrAnyFileWrapperr  Exceptionr&r#rrr$r rr!r r"rr/r.rs                           8777777 + ,      y    w4w4w4w4w4w4w4w4t     8   ,,,,,8,,,^gggggHgggTKFKFKFKFKF]KFKFKF\ZZZZZZZZz488888888>OOOOOOOOOOr/__pycache__/fake_filesystem.cpython-311.pyc000064400000410504150043321510014626 0ustar00 bgDdZddlZddlZddlZddlZddlZddlZddlmZm Z ddl m Z ddl m Z ddlmZmZmZmZmZmZmZddlmZmZmZmZmZmZmZmZmZm Z m!Z!ddl"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(dd l)m*Z*m+Z+dd l,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2ej34d rd Z5nd Z5Gdde Z6e#j7Z7e#j8Z8e#j9Z9e#j:Z:e#j;Z;e#j<ZZ>e#j?Z?e$j@Z@e&jAZAe(jBZBe%jCZCej3dkre%jDZDe%jEZEe'jFZFe'jGZGe'jHZHe'jIZIe'jJZJe'jKZKe'jLZLe'jMZMe'jNZNe'jOZOe'jPZPe'jQZQGddZRde fdZSdZTeUdkr eSdSdS)a"A fake filesystem implementation for unit testing. :Usage: >>> from pyfakefs import fake_filesystem, fake_os >>> filesystem = fake_filesystem.FakeFilesystem() >>> os_module = fake_os.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 OSError 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 OrderedDict) TestResults)Enum)S_IFREGS_IFDIRS_ISLNKS_IFMTS_ISDIRS_IFLNKS_ISREG) ListOptionalCallableUnionAnyDictTuplecastAnyStroverloadNoReturn) fake_file fake_pathfake_iofake_oshelpers fake_open)AnyFileWrapperAnyFile) is_int_typemake_string_path to_stringmatching_stringAnyPath AnyStringlinux( ceZdZdZdZdZdZdS)OSTypez?Defines the real or simulated OS of the underlying file system.r'macoswindowsN)__name__ __module__ __qualname____doc__LINUXMACOSWINDOWSi/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/fake_filesystem.pyr+r+s#II E EGGGr6r+win32c eZdZdZejjdddfdedee de de ddf d Z e de fd Ze de fd Zejd e ddfd Ze de fdZejd e ddfdZe defdZejd eddfdZe defdZe defdZe defdZejd eddfdZddee de fdZdZddZddZddZdefdZ dde deed ee defd!Zd"e de fd#Z!d"e dee fd$Z"d"e de fd%Z# dd"e dee d&e de$fd'Z%d(e&defd)Z'd"e dee$fd*Z(d"e de$fd+Z)defd,Z*d-e dee$fd.Z+dd"ee de,e e e ffd/Z-dde d"ee ddfd0Z.d1e d2e d3e ddfd4Z/dd5e d6e fd7Z0 dd5e d8e1d6e d9e ddf d:Z2 dd"e d;e d6e dd"e d?ee,e4e e5fe4e e5ffd@ee,e e fd6e ddf dAZ6e7d@ee,e e fd?ee,e4e e5fe4e e5fffdBZ8dCe9de fdDZ:dEe ddfdFZ;dEe de9fdGZd"e de fdJZ?d"e de fdKZ@d"e de fdLZAd"e de fdMZBd"e de,e e ffdNZCd"e de,e e ffdOZDd"e fdPZEdQe de fdRZFdSe de fdTZGeHd"edeIefdUZJeHd"eKdeIeKfdVZJd"e deIe fdWZJd2e de fdXZLd2e de fdYZMd"e de fdZZNd2e de fd[ZOd2e de fd\ZPd"e4e e&fde fd]ZQd"e de fd^ZRd_ed`ede,eeeeSffdaZTdd2e&dbe de fdcZUdd2e dde de fdeZVdfZWdgeIe deIefdhZXd2e de fdiZYdjeIedkeSdefdlZZ dd2e&dme dne deSfdoZ[e7dpZ\dd2e&dme de1fdqZ] dd2e d6e dde dme dne de1f drZ^d"e&de1fdsZ_d2e d8eSddfdtZ` ddue&dve&dwe ddfdxZadyZbd"e ddfdzZcdve due d{e ddfd|Zddwe dve due d}e1d{e dee f d~Zedwe dve de1d}e1d{e ddf dZfdve due dee fdZgd2e ddfdZhd"e&de fdZiejjkfd(e&de defdZlemejjnzdddddddfd2e&de dedee de de deedeedeeode1fdZp dde&de dee&de1fdZq dde&dee&de1fdZr dde&de de dee&def dZs ddeIe de de ddfdZtemejjnzddddddddf d2e&de dedee de de deedeede deeode1fdZu dd2e&de&de de1fdZv dde&de&d6e de de1f dZw dde&de&d6e de1fdZxde1de fdZyd"e&defdZzejjkfde&d;e ddfdZ{d"e de fdZ|ejjkdfde d;e de ddfdZ} dd"e&de d6e dme de f dZ~dd"e&d6e de fdZdd"e&d6e de fdZd"e&de fdZejdkrd"e&de fdZ dde dne defdZd"e ddfdZdde de ddfdZde deIe fdZdefdZddZdZdS)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. 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. patch_open_code: Defines how `io.open_code` will be patched; patching can be on, off, or in automatic mode. shuffle_listdir_results: If `True`, `os.listdir` will not sort the results to match the real file system behavior. NFpath_separator total_sizepatchercreate_temp_dirreturncF||_tjj|_||_||_|tjkrd|_tj dk|_ tj dk|_ |j p|j |_ |d|_tjd|_tj|jg|_g|_d|_d|_t)|_d|_||dt0j|_d|_dS) al Args: path_separator: optional substitute for os.path.sep total_size: if not None, the total size in bytes of the root filesystem. patcher: the Patcher instance if created from the Patcher create_temp_dir: If True, a temp directory is created on initialization. Under Posix, if the temp directory is not `/tmp`, a link to the temp path is additionally created at `/tmp`. Example usage to use the same path separator under all systems: >>> filesystem = FakeFilesystem(path_separator='/') Nr8darwinrF)r< init_pathlib)r;ospathaltsepalternative_path_separatorr=r>sepsysplatform_is_windows_fs _is_macos is_windows_fsis_case_sensitive_cwdumask open_files _free_fd_heaplast_inolast_devr mount_pointsdev_nullreset PatchModeOFFpatch_open_codeshuffle_listdir_results)selfr;r<r=r>s r7__init__zFakeFilesystem.__init__s,$29;' . RV # #.2D + "lg51-1,>,P$.'Q   (4..  AC(*  3>==!  ju === )}',$$$r6c"|j o|j SN)rNis_macosr]s r7is_linuxzFakeFilesystem.is_linuxs%%;dm*;;r6c|jSr`)rLrbs r7rNzFakeFilesystem.is_windows_fs s ""r6valuec|j|kr7||_|t|dSdSr`)rLrXFakePathModuler]res r7rNzFakeFilesystem.is_windows_fs sG  % ' '"'D  JJLLL   & & & & & ( 'r6c|jSr`)rMrbs r7razFakeFilesystem.is_macoss ~r6c|j|kr7||_|t|dSdSr`)rMrXrgrhs r7razFakeFilesystem.is_macossE >U " ""DN JJLLL   & & & & & # "r6c|jS)z||_||dS)zSet the current working directory of the fake filesystem. Make sure a new drive or share is auto-mounted under Windows. N)rP_auto_mount_drive_if_neededrhs r7rlzFakeFilesystem.cwd$s%   ((/////r6cF|jr|S|jS)ziReturn the root directory, which represents "/" under POSIX, and the current drive under Windows.)rN_mount_point_dir_for_cwdrootrbs r7root_dirzFakeFilesystem.root_dir,s)   30022 2yr6ct|jj}||js ||jzS|S)zwReturn the root directory name, which is "/" under POSIX, and the root path of the current drive under Windows.)r#rrnameendswithr;)r]rrs r7 root_dir_namezFakeFilesystem.root_dir_name4sBT]/00  !455 2d11 1r6cf|jr tjn|jr tjn tjS)z6Return the real or simulated type of operating system.)rNr+r4rar3r2rbs r7rEzFakeFilesystem.os=s1 ! FNN}  r6cD|tjk|_|tjk|_|tjk|_|tjkrdnd|_|tjkrdnd|_| t |dS)zSSet the simulated type of operating system underlying the fake file system.\/N) r+r4rLr3rMr2rOr;rHrXrgrhs r7rEzFakeFilesystem.osHs$v~5&,.!&&,!6&+v~&=&=dd316&.1H1H##d' T"""""r6TrDct|j||_t||_|j|jd|_d|_ |j | || |j r||rddlm}||dSdS)z3Remove all file system contents and reset the root. filesystemr) fake_pathlibN) FakeDirectoryr;rq FakeNullFilerWrRclearrSrTrUrV_add_root_mount_point_add_standard_streamsr>_create_temp_dirpyfakefsr~ init_module)r]r<rDr~s r7rXzFakeFilesystem.resetTs!$"5$GGG $T**     """   !!! "":... ""$$$   $  ! ! # # #  + - - - - - -  $ $T * * * * * + +r6c|jrdn|j}||_|j|js|xj|jz c_|||dS)NzC:)rNr;rPrlruadd_mount_point)r]r< mount_points r7rz$FakeFilesystem._add_root_mount_pointgsg"0Iddd6I  x  !455 - II, ,II [*55555r6cd|jtd|jdS)aPause 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= RuntimeErrorpauserbs r7rzFakeFilesystem.pausens? < <  r6cd|jtd|jdS)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=rresumerbs r7rzFakeFilesystem.resumes? < <  r6cJ|jr|jdSdS)z'Clear the cache of non-patched modules.N)r= clear_cacherbs r7rzFakeFilesystem.clear_caches0 < ' L $ $ & & & & & ' 'r6c|jrdndS)Nz  )rNrbs r7line_separatorzFakeFilesystem.line_separators+5vv5r6err_nofilenamewinerrorctj|dz}|)tjdkr|jrt ||||t |||)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: err_no: 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. z in the fake filesystemNr8)rEstrerrorrJrKrNOSError)r]rrrmessages r7raise_os_errorzFakeFilesystem.raise_os_errorsY$+f%%(AA  CLG$;$;@R$;&'8X>> >fgx000r6rFc,t||jS)z2Return the path separator as the same type as path)r$r;r]rFs r7get_path_separatorz!FakeFilesystem.get_path_separatorstT%8999r6c,t||jS)z>Return the alternative path separator as the same type as path)r$rHrs r7_alternative_path_separatorz*FakeFilesystem._alternative_path_separatorstT%DEEEr6c||}||}||p|duo||S)z1Return True if path starts with a path separator.N)rr startswith)r]rFrIrGs r7starts_with_sepzFakeFilesystem.starts_with_sepsU%%d++11$77s##UvT'9'Udoof>U>UUr6 can_existc|||}|jD]}|jr|t ||ks?|jsi|t ||kr1|r|j|cS|tj||xj dz c_ |j |dd|j|<|t ||j j kr$|j }|xj dz c_ |j |_ n||}|j |_|j|S)aaAdd 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. can_exist: If True, no error is raised if the mount point already exists Returns: The newly created mount point dict. Raises: OSError: if trying to mount an existing mount point again, and `can_exist` is False. r)idevr< used_size)normpathnormcaserVrOr$lowerrerrnoEEXISTrUrqrtrTst_ino_create_mount_point_dirst_dev)r]rFr<rrrrs r7rzFakeFilesystem.add_mount_pointsR2}}T]]40011, 8 8K& 8OD+>>>>-?JJLLOD+:K:K:M:M$N$NNN:,[9999##EL$777  M$# # $ ?488 8 8yH MMQ MM"mHOO33D99H- &&r6directory_pathc||}||}|j}g}d|DD]}||t |d}|s>t ||}|||||}ktt |}|D]}ttj z|_ |S)zA version of `create_dir` for the mount point directory creation, which avoids circular calls and unneeded checks. c,g|]}t|Sr5r#.0ps r7 z:FakeFilesystem._create_mount_point_dir..@@@1)A,,@@@r6rr|) r"_path_componentsrq_directory_contentr#rappend add_entryrrrPERM_DEFst_mode) r]rdir_pathpath_components current_dirnew_dirs component directorynew_dirs r7rz&FakeFilesystem._create_mount_point_dirs((88//99i @@@@@ = =I// Yy=Q=QRRSTUI =' dCCC(((%%g...% "=)<<  9 9G%(88GOOr6c||jr4||d}|r||dSdS)zWindows only: if `path` is located on an unmounted drive or UNC mount point, the drive/mount point is added to the mount points.rT)rFrN)rN splitdriver)r]rFdrives r7rnz*FakeFilesystem._auto_mount_drive_if_needed sM   HOOD))!,E H++$+GGGtr6cB|||}|jD]%}|t||kr|j|cS&t|d}||d}|jD]a}t||}|r||s*||r"t |t |kr|}b|r|jt|S||}|sJ|S)NrBr) absnormpath_original_pathrVr$rrlenr#rn)r]rF mount_pathr root_pathrs r7_mount_point_for_pathz$FakeFilesystem._mount_point_for_paths; 3 3D 9 9::+ 5 5JtZ8888(44449$T2.. %%a(* ' 'I'i88I Y11%88 y)) 'c)nns:.N.N&  <$Yz%:%:; ;66t<< {r6cdtffd }tj}jD]"}|t|kr ||cS#d}t|d}jD]`}t|}|r||s)||r"t |t |kr|}a||S)zjReturn the fake directory object of the mount point where the current working directory points to.r?c|}j}|D]*}tt||}+|Sr`)rrqrr get_entry) file_pathrtargetrr]s r7object_from_pathzAFakeFilesystem._mount_point_dir_for_cwd..object_from_path)sR"33I>>OYF, J J mV-=-=i-H-HIIMr6rBr)rr#rlrVrrr)r]rrFrrr str_root_paths` r7rpz'FakeFilesystem._mount_point_dir_for_cwd%s =      ""+ 4 4Jy,,,,'' 33333- $//$//233* ' 'I%i00M ]55e<< }-- '#m2D2Ds:2V2V&  +++r6rc^|jD]}|d|kr|cSdS)Nr)rVvalues)r]rrs r7_mount_point_for_devicez&FakeFilesystem._mount_point_for_device>sF,3355 # #K6"d**""""+tr6cTtdd}|4tt|j}n$t |}||}|r0|d(||d|d|d|dz S|dddS)aReturn 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). DiskUsageztotal, used, freeNr<rlr)rnextiterrVrr"r)r]rFrrrs r7get_disk_usagezFakeFilesystem.get_disk_usageDs{,?@@ <tD$5$<$<$>$>??@@KK(..I44Y??K  ;|4@9L)K(L)K ,DD  y2A7PQQQr6c||n|j}||}|d,|d|kr |tj|||d<dS)aChanges 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: OSError: if the new space is smaller than the used size. Nr<r)rvrrrENOSPC)r]r<rFrrs r7set_disk_usagezFakeFilesystem.set_disk_usage]sp $DD$*< 00;;  % 1K(:55    d 3 3 3$. L!!!r6 usage_changerrc||}|rK|d}|/||dz |kr |tj||dxx|z cc<dSdS)aChange 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: OSError: if usage_change exceeds the free file system space r<Nr)rrrr)r]rrrrr<s r7change_disk_usagez FakeFilesystem.change_disk_usagews 226::  5$\2J% K 88<GG'' i@@@  $ $ $ 4 $ $ $ $ $  5 5r6 entry_pathfollow_symlinkscD |||dd}n%#t$r||}YnwxYwts#|j}|r||j|||||jS)aReturn 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. TF)allow_fdcheck_read_perm) resolve TypeErroris_root parent_dir get_objectrF(raise_for_filepath_ending_with_separator stat_resultcopy)r]rr file_objectrs r7statzFakeFilesystem.stats 3,, % 'KK  3 3 3,,z22KKK 3yy 1$/J 1 000 55  _   &++---s >>rmacos_handlingcz||r"t|jr ||}n\#t$rO}|jr|jt jkrYd}~dS|jr | t j |d}~wwxYw|r|js|jr|}|jrt|j}n4|jr|rt|j }nt|j }|r9|jr t j n t j }| ||dSdSdSr`)ends_with_path_separatorr rrrrarENOENTrNrEINVALr r ENOTDIR) r]rrrr link_objectexcis_errorerror_nrs r7rz7FakeFilesystem.raise_for_filepath_ending_with_separatorsu  ( ( 4 4 :{*++ ."&,,z":":KK}el)B)B)F++EL*EEE  '.$*<. ."-K! <";#677 <> <&{':;;;&{':;;; :+/+=P5<<5=##Hj99999) : :$ : :sA B B.(BBmodeforce_unix_modec,|||dd}|jr1|s/|tjzr|jdz|_n:|jdz|_n*|jtjz|tjzz|_tj|_dS)aChange 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. force_unix_mode: if True and run under Windows, the mode is not adapted for Windows to allow making dirs unreadable T)r check_ownerimN)rrNr PERM_WRITErPERM_ALLnowst_ctime)r]rFrrrrs r7chmodzFakeFilesystem.chmods"ll /Dd#     o g(( E&1&9E&A ##&1&9H&D ###.#6':J9J#Jw''#K  '{}} r6)nsrtimesr c||||||d}|L|D]-}t|ttfst d.|d|_|d|_dS|E|D]&}t|tst d'|d|_|d|_ dStj }||_||_dS)aChange 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. follow_symlinks: If `False` and entry_path points to a symlink, the link itself is queried instead of the linked object. 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. TrNzatime and mtime must be numbersrrzatime and mtime must be ints) _handle_utime_arg_errorsr isinstanceintfloatrst_atimest_mtime st_atime_ns st_mtime_nsrr)r]rFr r rr file_time current_times r7utimezFakeFilesystem.utimes6 %%b%000ll44lHH  " G G !)c5\::G#$EFFFG$)8K #(8K ^ D D !)S11D#$BCCCD')eK #&(eK # # #";==L#/K #/K r6c||td|"t|dkrtd|"t|dkrtddSdS)Nz:utime: you may specify either 'times' or 'ns' but not bothz9utime: 'times' must be either a tuple of two ints or Nonez'utime: 'ns' must be a tuple of two ints) ValueErrorrr)r r s r7r z'FakeFilesystem._handle_utime_arg_errors su  L   UqWXX X >c"ggllEFF F >llr6file_objc|jr&tj|j}|g|j|<|S|j|gt |jdz S)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)rSheapqheappoprRrr)r]ropen_fds r7_add_open_filezFakeFilesystem._add_open_file.sa   mD$677G(0zDOG $N z***4?##a''r6file_descNd|j|<tj|j|dS)zRemove 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)rRrheappushrS)r]r!s r7_close_open_filezFakeFilesystem._close_open_fileBs+%)! t)844444r6ct|std|t|jk}|r|j|}||dS|t jt|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)r!rrrRrrEBADFstr)r]r!valid file_lists r7 get_open_filezFakeFilesystem.get_open_fileOs8$$ 6455 53t///  $1I$ |# EKX77777r6c(|d|jDvS)zReturn 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. cFg|]}||dS)r)r)rwrapperss r7rz0FakeFilesystem.has_open_file..ns=   )1 QK " " $ $   r6)rR)r]rs r7 has_open_filezFakeFilesystem.has_open_filees/  59_     r6c||}|)||||S|Sr`)rreplacer)r]rFalt_seps r7_normalize_path_sepz"FakeFilesystem._normalize_path_seprsB22488  <<)@)@)F)FGG G r6cJt|}||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. )r"r2)r]rFrs r7rzFakeFilesystem.normcasexs%%T** '' 222r6c||}||\}}||}||}||}g}t |d}t |d} |D]L} | r| |kr | | kr&|r!|d| kr|4|r7|| M||} |r|| z} || zp|S)aMimic 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. ...) rrrrsplitr$poprjoin) r]rFpath_strrrIis_absolute_pathrcollapsed_path_componentsdotdotdotrcollapsed_paths r7rzFakeFilesystem.normpathsG,==&&//(33x%%h//#..s33(0 ) )   "h,, 400( 8 8I 9#3#3F"", -b1V;;.11333% % , ,Y 7 7 7 7";<<  2 >1N~%,,r6cfd}jssSgj}D]}t |t s |cS|t|\}}|'t |t r|j|j dkr |cStt |} ||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. cttkr4dtdDj}|}r|s||z}t|dkr|r||z }|S)Nc34K|]}t|VdSr`rrs r7 zLFakeFilesystem._original_path..components_to_path..s9--%&IaLL------r6r)rextendr;r:rstarts_with_drive_letter)rInormalized_pathnormalized_componentsrFrr]s r7components_to_pathz9FakeFilesystem._original_path..components_to_paths?##c*?&@&@@@%,,--*9#>S:T:T:V:V*W---%C!hh'<==O##D)) 8$2F2F2W2W 8"%"7?##q((T-J-J..( 3&" "r6Nr) rOreplace_windows_rootrrqrrrr#_byte_contentsst_sizerr) r]rFrIrrdir_namerrHrs `` @@r7rzFakeFilesystem._original_pathsR # # # # # # # #  !  K((..//55 "i ( 3 3Ik=99 ,))+++++"&"9"9Yy11## Hi 9m44!,4%**))+++++}i88K ! ( ( 2 2 2 2!!###r6c||}t||j}|s||}|t|dkr|}n||s]t||jj}t|d}||||kr|p||f}n||}| |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. r5rB) rr$rlr_starts_with_root_pathrqrtr:rJr)r]rFrl root_nameemptys r7rzFakeFilesystem.absnormpaths}}T""dDH-- 1**400D ?4-- - -DD,,T22 3'din==I#D"--E**40055 !)c2UD9DD,,T22D}}T"""r6c~t|}||}||}||n||z}||\}}t |}|r!||dz |vr|dz}|r ||dz |v|d|||d}}||p|}||z|fS)aMimic os.path.split using the specified path_separator. Mimics os.path.split 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. Nr)r"rrrrrstrip) r]rFrIr1sepsriheadtails r7 splitpathzFakeFilesystem.splitpath s %%%%d++22488oss3=ood++ t II DQKt++ FA DQKt++"1"XtABBxd{{4  (Dt|T!!r6c^t|}|jr t|dkr||}||}|dd|dzkr|dd|kr||d}|dkr |dd|fS|||dz}||dzkr |dd|fS|dkrt|}|d|||dfS|ddt |dkr|dd|ddfS|dd|fS)aSplits 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. rrr7Nr:)r"rNrrrfindr$)r]rFr;norm_strrI sep_index sep_index2s r7rzFakeFilesystem.splitdrive&sb$D))   68}}!!==22--h77QqSMS1W,,8AaC=C3G3G!) c1 5 5I B'|X55!)sIM!B!BJ!Y]22'|X55!R''%(]] #KZK0(:;;2GGGAaC=OHc$B$BBB#BQB<!""55|X%%r6ctj|}t|trB|j}d}|jr|j}d}d}d}n|j}|j}d}d}d}|jr*|r|||n|}|dd|kr|dd |kr|dd  |krd nd } | || } | d kr|||fS| || dz} | d kr|||fS|d| || | dz|| dzdfS||dd|ddfS|dd |kr@|d d |kr|dd |d d |d dfS|dd ||d dfS|||fS|dd|kr|||fS|dd |ks|d d |kr |||ddfS||dd |d dfS) zlSplit a pathname into drive, root and tail. Implementation taken from ntpath and posixpath. N:s\\?\UNC\r6r[z\\?\UNC\rBrrr7rZ) rEfspathrbytesr;encoderHrNr0upperr\) r]rFrrIrGcolon unc_prefixrQnormpstartindexindex2s r7 splitrootzFakeFilesystem.splitrootJs IdOO a   %,,..CF. B8??AAE(JEE%C4FE'JE  # +.4;AIIfc***!ERaRyC1:$$"'rr!2!2j!@!@AAaE!JJsE22E{{ %."ZZUQY77F|| %.WfW:q&1*)<'=q!NN!!BQB%122..qsu$$1:$$RaR5!AaC&!ABB%//RaR5%122..eQ&!u||eQ&1Q33!AaC&C--c1QRR5((aeQqrrU**r6 all_pathsc<|d}|dd}||}|||g}||\}}|D]}||\} } | r| dd|vr | s|s| }| }1| r>| |kr8|js*| |kr| }| }o| }|r|dd|vr||z}|| z}t |d} |r$|dd|vr|r|dd| kr||z|zS||zS)zSTaken from Python 3.5 os.path.join() code in ntpath.py and slightly adaptedrrNr7r[)rrrrOrr$) r]rn base_path paths_to_addrIrT result_drive result_pathrF drive_part path_partrgs r7_join_paths_with_drive_supportz-FakeFilesystem._join_paths_with_drive_supportsaL  } %%i00T55i@@A$(OOI$>$>! k  2 2D$(OOD$9$9 !J  *Yrr]d22.\.#-L'  * l : :)Z-=-=-?-?.s 888$bioo888r6rrr7rB) rrNrvrrOrurr$r:)r]rw file_pathsjoined_path_segmentsrI path_segments r7 joinpathszFakeFilesystem.joinpathss98%888 z??a  8O   D646 C C!%%jm44& > >L**<88 >(4~$$'50DR0H0Q0QRU0V0V5(//444>(// ===z!}b11667KLLLr6cdSr`r5rs r7rzFakeFilesystem._path_components r6cdSr`r5rs r7rzFakeFilesystem._path_componentsrr6c\|r|||krgS||\}}|||}|s|sJ|ds(t|dkr |dsg}n |dd}|r|d||S)a6Breaks 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.entries: raise OSError _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. rrN)rrr8rinsert)r]rFrrs r7rzFakeFilesystem._path_componentss0 tt66t<<<<Iood++ t**T%<%>Q  9QqS>#9#9#;#;  !A#RW@W@W! tw$!11)<<<4!!! 55!us(A?? B  B c6t||jj}||}||pU|j o8||p||Sr`)r$rqrtr2rrOrrFr]rrPs r7rOz%FakeFilesystem._starts_with_root_path s#Ity~>> ,,Y77   + + 8))@!!,,Y__->->?? 8,,Y77  r6cX|r|jr|jr||}|dd|krvt|dks|dd|krU|jD]+}t ||}||r|cS,t ||j}||ddz}|S)zIn windows, if a path starts with a single separator, it points to the root dir of the current mount point, usually a drive - replace it with that mount point path to get the real path. rrrN)rNrrrrrVr$rrv)r]rFrIrrs r7rJz#FakeFilesystem.replace_windows_roots  .D& .4= .))$//CAaCyCSYY!^^tAaCyC7G7G!%!2$$I /i @ @Iy11$# $.dD4FGG "T!""X- r6clt||jj}||kp||Sr`)r$rqrtis_mount_pointrs r7 _is_root_pathzFakeFilesystem._is_root_path*s3#Ity~>> I%G)<)->-@-@@@ttur6ct|trdSt|}|sdS||}||}|||fvo-||p|duo||S)z>Return True if ``file_path`` ends with a valid path separator.FN)rrr"rrru)r]rFrrIrGs r7rz'FakeFilesystem.ends_with_path_separatorBs dC  5$T**  5%%i0011)<<f -   s # # XvT'9'Xi>P>PQW>X>X r6c||sdS|||SNF)risfile!_path_without_trailing_separatorsrs r7!is_filepath_ending_with_separatorz0FakeFilesystem.is_filepath_ending_with_separatorOs=,,T22 5{{4AA$GGHHHr6rrcttsdSjvrjfS|jsfdjD}|r|dSdS)NNNcg|];}|k,|j|f.\sM   <<>>Y__%6%666*623666r6r)rrrrO)r]rrmatching_contents `` r7rz!FakeFilesystem._directory_contentTs)]33 :  ) ) )i/ :: :% +     '/       +'**zr6 check_linkcZ|r||rdSt||}|t|sdS||jjkr|j ptjdkS | |rdS| |}n#t$rYdSwxYw| |rdS| |}|j}|D]E}||t|d}|dSt!t"|}FdS)aHReturn true if a path points to an existing file system object. Args: file_path: The path to examine. check_link: If True, links are not followed Returns: (bool) True if the corresponding object exists. Raises: TypeError: if file_path is None. TNF)rZrbr)islinkr#r"rrWrtrNrJ version_infor resolve_pathrrrrqrrr)r]rrrFrrrrs r7existszFakeFilesystem.existsfs`  $++i00 4..y99:: <O 5 4=% % %))GS-=-G G 55d;; u$$T**DD   55    d # # 4%)%:%:4%@%@i ( 9 9I// Yy=Q=QRRSTUI uu}i88KKts2B B B-,B-rc|rAt|tr,||jSt |}|t d|r||s |tj || | |}| |}||r|S|t||jjkr|S||}||}||}| |S)aFollow 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. Returns: The resolved_path (str or byte). Raises: TypeError: if `file_path` is `None`. OSError: if `file_path` is '' or a part of the path doesn't exist. Nz/Expected file system path string, received None)rrr*rrFr"r_valid_relative_pathrrrrrrJrr$rWrtr_resolve_components_components_to_path)r]rrrFrresolved_componentss r7rzFakeFilesystem.resolve_pathsXL  C 9c22 C%%i00;;==B B ** <MNN N 4444T:: 4    d 3 3 3 3 3D 9 9::((..   d # # K ?4);<< < <K//55"66GG''(;<<((...r6c|r||dn|j}||}||s||z}|SNr)rr;r:rO)r]component_foldersrIrFs r7rz"FakeFilesystem._components_to_pathsh! %D # #$5a$8 9 9 9$ xx)****400 :D r6 componentscH|j}d}d|D}g}|r|d}|||||d}|||nt |jr}|tkr3|tj | || ||}| |} | |z}g}|j}|dz }ntt|}||S)Nrc,g|]}t|Sr5r)rcomps r7rz6FakeFilesystem._resolve_components..sBBBt9T??BBBr6r)rqr9rrrEr r_MAX_LINK_DEPTHrrELOOPr _follow_linkrrr) r]rr link_depthrrrr link_pathtarget_componentss r7rz"FakeFilesystem._resolve_componentssQi  BBzBBB)+! ='++A..I  & &y 1 1 1// YGGJI $**?;;;*++ =//'' 001DEE!--.A9MM %)$9$9)$D$D!"3o"E&(#"i a "=)<< C! =D#"r6c|jrdSt||jdz}|rQ||vrM|d||}|||sdS|r||vMdS)NTr6F)rNr$r;rfindrr)r]r slash_dotdots r7rz#FakeFilesystem._valid_relative_paths   4&y$2E2LMM  LI55!"AIOOL$A$A"ABI;;t// ::;; u LI55tr6link_path_componentslinkcd|j}||jr|dr |dd}||}||s4|dd}||||}||Std)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: OSError: if there are too many levels of symbolic link Nz\\?\r7z Invalid link) contentsrNrrrOrr:rr)r]rrrrIrs r7rzFakeFilesystem._follow_links.M  ! *i&:&:9&E&E *%abbM )))44C..y99 1 2#2#6 !!),,,HHZ00 ==++ +(((r6rrct|}|t||jjkr|jS|t||jjkr|jS||}||}|j} |D]}t|jr4|j r-tt| |j }t|jsG|js |t j||t j|||}t)s?|r=|r;|||s%|t j|j n0#t0$r#|t j|YnwxYw|S)aSearch 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. check_read_perm: If True, raises OSError if a parent directory does not have read permission check_owner: If True, and check_read_perm is also True, only checks read permission if the current user id is different from the file object user id Returns: The FakeFile object corresponding to file_path. Raises: OSError: if the object is not found. )r"r$rqrtrWrrr rrrrrr rNrrrrrr _can_readEACCESrFKeyError)r]rrrrFrrrs r7rz'FakeFilesystem.get_object_from_normpath6s0 ** ?488 8 89  ?4);<< < <= ""4((//55 4, C C 6>**TT!%mT\\&/5R5R!S!Sv~..<-A++EM4@@@'' d;;;)))44 C'CC!NN6;?? C '' fkBBB C  4 4 4    d 3 3 3 3 3 4 s D F*GGc|jtjkr|s |jdzrdS|jt kr |jdzrdS|jdzS)NTr)r)st_uidrget_uidrst_gidget_gid)rowner_can_reads r7rzFakeFilesystem._can_readlsd =GO-- - - %!7 t =GII % %~% t~%%r6ct|}|||}|||S)aSearch for the specified filesystem object within the fake filesystem. Args: file_path: Specifies the target FakeFile object to retrieve. check_read_perm: If True, raises OSError if a parent directory does not have read permission Returns: The FakeFile object corresponding to `file_path`. Raises: OSError: if the object is not found. )r"rrr)r]rrrFs r7rzFakeFilesystem.get_objectvsH ** 3 3D 9 9::,,T?CCCr6c t|tr8|r'||St d|r+||||||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 check_read_perm: If True, raises OSError if a parent directory does not have read permission check_owner: If True, and check_read_perm is also True, only checks read permission if the current user id is different from the file object user id Returns: The FakeFile object corresponding to `file_path`. Raises: OSError: if the object is not found. z4path should be string, bytes or os.PathLike, not int)rrr*rrrrlresolve)r]rrrrrs r7rzFakeFilesystem.resolves6 i % % W B)))44??AAAUVV V  00!!)X66  }}Y'''r6ct|}|sttj||t ||jjkr|jS||}|t |dkrt ||j}| |}| |\}}|st ||j} | |}|sJt|ts\|js5t|tr |tj||tj||jt&jzs |tj||r"|t/|n|S#t0$rYnwxYwttj|)aSearch 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: OSError: if the object is not found. r5)r"rrrr$rqrtrrlrrXrrrrNFakeFilerrrr PERM_READrrr#r)r]rFr;parent_directory child_name parent_objs r7rzFakeFilesystem.lresolves$D)) 2%,11 1 x@@ @ @9 99(CC x55 5 5&x::H&&x00'+~~h'?'?$* C.xBB  &677J  :j-88 <)AjX.N.NA'' x@@@##EL(;;;%(99 D##EL2BCCC $$Yz%:%:;;;      D elH---sC#F88 GGc&|s|j}nqtt||}t |js5|jr tjn tj }| ||| |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. Raises: OSError: if file_path does not correspond to a directory. N) rrrrrr rrNrrrrr)r]rrtarget_directoryerrors r7 add_objectzFakeFilesystem.add_objects 6#}  #M4<< 3J3JKK +344 6(,(:M  ##E9555"";/////r6 old_file_path new_file_path force_replacect|}t|}||}||}||}||ds!|t j|d|r||||}|j s| |||||dr| |||||}|dS|}| |\} } | |\} } || s |t j| | | } | | }| j|jkr |t j|t!|js3||j r t jn t j|||r |t j||| | || dS)aRenames 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). TrrN)r"rrrrrr%_handle_broken_link_with_trailing_seprrN_handle_posix_dir_link_errors_rename_to_existing_pathrXrrEXDEVr rrrhas_parent_objectr _do_rename)r]rrrold_pathnew_path ends_with_sep old_object renamed_pathold_dirold_namernew_nameold_dir_objectnew_dir_objects r7renamezFakeFilesystem.renamesV<$M22#M2255h?? ##H--##H--{{8{55 ;    h : : :  A  6 6x @ @ @]]8,, ! R  . .x= Q Q Q ;;xD; 1 1 (88x:}L#' NN844 NN844{{7## 7    g 6 6 6g..g..  N$9 9 9    X 6 6 6~-..     $ 2E  x     + +J 7 7 8    h 7 7 7 .(KKKKKr6c||}||d||_||}||jvr||nd} |r||||dS#t $r>|r||jvr||||_||wxYw)NF) recursive)r remove_entryrt_normalized_entrynamerrr)r]rrrrobject_to_rename old_entrys r7rzFakeFilesystem._do_rename=s)33H==##H#>>> (!77AA>111  $ $X . . .   6++H555  $ $%5 6 6 6 6 6    4X^-CCC((333$,  !  $ $%5 6 6 6   s *,BAC c||r_||sL|jr tjn|jr tjn tj}|||dSdSdSr`) rrrarrrNrrr)r]rFrs r7rz4FakeFilesystem._handle_broken_link_with_trailing_sepTs ;;t   1;;t$$ 1}'ELL)' ##E400000 1 1 1 1r6rc||dr5||r |tj|||drP||r;|r |jrdS|r tjn tj}||||rD||r1||kr-|js(|tj|dSdSdSdSdSNFr)isdirrrrrraEISDIRrN)r]rrrrs r7rz,FakeFilesystem._handle_posix_dir_link_errorsas8 ::mU: ; ; > A A  >    } = = = ::mU: ; ; 6 A A  6  %2DEMM E   } 5 5 5  > M** >..&/    } = = = = =  > > > >/...r6rc||}||krMt|js7|r5|jr tjn tj}|||dS||kr|||St|jst|jr| |||||nt|jr6|jr tj n tj}|||n?|jr#|s!|tj |n| ||Sr`) rr rrNrrrr_rename_same_objectr $_handle_rename_error_for_dir_or_linkr remove_object)r]rrrrr new_objectrs r7rz'FakeFilesystem._rename_to_existing_pathwsf__]33 M ) ):-.. := :(,(:M  ##E=9994  # #++M=II I :% & & .'*2D*E*E .  5 5     Z' ( ( .$($6IELLEME   } 5 5 5 5   .  .    m < < < <   } - - -r6rc|jrC|r!|tj|n |tj|t |jsz|jr=t |jr |r|js |tj |t|jr$|tj |dSdSdSr`) rNrrrrr rrra ENOTEMPTYr r)r]rrrrrs r7rz3FakeFilesystem._handle_rename_error_for_dir_or_links   A A##EL-@@@@##EL-@@@z)** A! H 233H(H =H ''GGGz)** A##EL-@@@@@ A A A Ar6c||k}|s> ||}||}||}||krz||k||kkrH||d}tj||jkp|j }n*||k}|rA| |\}} | ||| }n#t$rYnwxYw|sdS|Sr) rrrrrErFbasenamertrarXr}r) r]rr do_rename real_old_pathoriginal_old_path real_new_path real_objectparent file_names r7rz"FakeFilesystem._rename_same_objects"''))]-@-@-B-BB    $ 1 1- @ @ $($7$7 $F$F! $ 1 1- @ @  $555!]2#))++}/B/B/D/DD;F;F#',,}e,"T"TK((77;;KK-#},I !. 3 3 5 59L9L9N9N NI)-}(E(E%FI$(NN++F33Y%%M       4sD,E E)(E)c|||}||r |tj| ||\}}||d}||dS#t$r$|tj |YdSt$r$|tj |YdSwxYw)anRemove an existing file or directory. Args: file_path: The path to the file relative to self. Raises: OSError: 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 '/'). FrN) rrrrrEBUSYrXrrrrAttributeErrorr)r]rdirnamerrs r7rzFakeFilesystem.remove_objects $$T%8%8%C%CDD   i ( ( 8    Y 7 7 7 : $y 9 9 GX#||GU|KK   ) )( 3 3 3 3 3 9 9 9    i 8 8 8 8 8 8 : : :    y 9 9 9 9 9 9 :sAB%%*C?)C?>C?ct|}t|tj}||}|||Sr`)r"r$rErIrr0)r]rFr;os_sepfake_seps r7r"zFakeFilesystem.make_string_pathsI#D)) 2622**844111r6 perm_bitsc||}||}||||dr)||jvr |t j|||}|j }g}d|DD]}| |t|d}|sWt||} | | |jr||j kr|j}|| | }t#|jr'|jsJ||j}|sJt+t|}|jt,zt,kr%|t j|j|D]} t,|z| _|S)aCreate `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. Trc,g|]}t|Sr5rrs r7rz-FakeFilesystem.create_dir.. rr6rr|)r"rrnrrVrrrrrqrr#rrrNrrrr rrrrrrrF) r]rr rrrrrrrs r7 create_dirzFakeFilesystem.create_dirs"((88##H-- ((222 ;;xD; 1 1 8hdFW6W6W    h 7 7 7//99i @@@@@ I II// Yy=Q=QRRSTUI I' dCCC(((%0+*B*B"&-K%%g...% 9,--%$---- $ Y-? @ @I$$$9"=)<< $w.'99'' {7GHHH  2 2G% 1GOOr6rBrrrLcreate_missing_dirs apply_umaskencodingerrors side_effectc >||||||||||  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: OSError: if the file already exists. OSError: if the containing directory is required and missing. )r)create_file_internally) r]rrrrLrrrrrs r7 create_filezFakeFilesystem.create_file%s=R**        #+   r6 source_path read_only target_pathc4|p|}t|}tj|}||d}|j||r|xjdzc_||_||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. OSError: 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$) r"rErrrset_from_stat_resultrrrsizertr)r]rrrsource_path_str real_statrs r7 add_real_filezFakeFilesystem.add_real_fileZs<"0[ *;77GO,, // t/TT  229===  *    )  -  y~y~y?OPPPr6ct|}||}tj|s?tj|s |tj|tj |}|r| ||S| ||S)a]Create a symlink at source_path (or target_path, if given). It will point to the same path as the symlink on the real filesystem. Relative symlinks will point relative to their new location. Absolute symlinks will point to the same, absolute path as on the real filesystem. Args: source_path: The path to the existing symlink. target_path: If given, the name of the symlink in the fake filesystem, otherwise, the same as `source_path`. Returns: the newly created FakeFile object. Raises: OSError: if the directory does not exist in the real file system. OSError: if the symlink could not be created (see :py:meth:`create_file`). OSError: if the directory already exists in the fake file system. ) r"rrErFrrrrrreadlinkcreate_symlink)r]rrrrs r7add_real_symlinkzFakeFilesystem.add_real_symlinks,+;77@@QQw~~o.. ?rw~~o7V7V ?    o > > >_--  @&&{F;; ;&&?? ?r6 lazy_readc ,t|}||}tj|s |t j|t|p|}|||rtj |d}||r| |}n| |}t||||} | | nz| |} tj|D]O\} } } tj| jtj| |} tj| D]v}tj| |}tj|sB||tj| |w| D]w}tj| |}tj|rB|||tj| |xQ| 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. Symlinks are supported. 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. OSError: if the directory already exists in the fake file system. r)r"rrErFrrrrrnr8rrFakeDirectoryFromRealDirectoryrwalkr:relpathlistdirrr%r!)r]rrr&rrtarget_path_str parent_pathrrbase_filesnew_base fileEntry abs_fileEntryrFs r7add_real_directoryz!FakeFilesystem.add_real_directorysYD+;77@@QQw~~o.. ?    o > > >*;+I/JJ ((999  '--88;K{{;'' :!__[99 !__[99 4y/G   ) ) ) )ooo66G"$'/":":  a7<<LGOOD/::"$D!1!1I$&GLLy$A$AM7>>-88! ))%rw||Hi'H'H"'I7<<i88Dw~~d++! &&ih )J)J r6 path_list lazy_dir_readc|D]O}tj|r||||9|||PdS)aThis 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)rErFrr4r!)r]r5rr6rFs r7add_real_pathszFakeFilesystem.add_real_pathssg4 4 4Dw}}T"" 4''iGGGG""43333  4 4r6rc ||} || } t|std|| dr |t j| || \} } | st| |j } | | || sK|s |t j | t| | | j} n|| } |r ||jz}| r t#t%| || }nt'| ||||| }|| |||d}| sW||S |||n||n$#t.$r|| wxYw|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. 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?Tr)r}r)r}rrrNrB)r"rr!rrrrrrXr$rlrnrrrFrrQFakeFileFromRealFiler#rrset_large_file_sizeset_initial_contentsrr)r]rrrrLrrrrrrrFrnew_filers r7rz%FakeFilesystem.create_file_internally sQF$$Y//%%7## M  ;;t; - - 4    d 3 3 3%)^^D%9%9"( ?.tTX>>  (()9:::{{+,, E& D##EL2BCCC.doo&677<     $223CDD   #  { "G  .$DkKK#!' K (+666 ?x/H  h&:g>Q &33G<<<<44X>>>   ""4((( s -G!G/ link_targetc||}||}||}||r7||r |t j|||r(|js |t j|n|jr |t j ||| |ds |t j||j r-||dr| |n |t j|| |s||}||t t"jz||S)aCreate 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`). Tr)rrr)r"rrrrrrrNrrrrarrrrr rr)r]rr>rrlink_target_paths r7r$zFakeFilesystem.create_symlinkl s*)))44 00==MM),,  ( ( 3 3 H{{9%% =##EL)<<<{{+,, H)A'' i@@@%H'' 6FGGG{{::9EE##H'' 6FGGG=H{{9{>>6**9555'' 6FGGG{{9%% 5)))44I** g..% 3 +   r6rrc.t|}t|}||}||dr |tj|||\}} |st||j}||s8|r| |n |tj || |r5|j r tj n tj} || ||j s5| |r |tj | |||} n0#t $r#|tj |YnwxYw| jt$zr3||j r tjn tj|| | _||| | S)aCreate 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. follow_symlinks: If False and old_path is a symlink, link the symlink instead of the object it points to. create_missing_dirs: If `True`, any missing parent directories of file_path will be created 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. Trr)r"rrrrrrXr$rlrrrrNrrrrrrrEPERMrtr) r]rrrr old_path_str new_path_strnew_path_normalizednew_parent_directory new_basenamerold_files r7 create_linkzFakeFilesystem.create_link s2(11 '11 "..|<< ;;*t; < < <    l ; ; ;-1^^ ||||jzdS#t"$r} | jtjkr|r(t'||tsS|jr&| jtjkrtj| _|| j| jYd} ~ dSYd} ~ dSd} ~ wwxYw)azCreate 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. Raises: OSError: if the directory already exists and exist_ok=False, or as per :py:meth:`create_dir`. rBTrrN)rrrrrrarrr#rrrhasattrrrrrrQrrrrrNrr) r]rMrrVr dir_name_strrrres r7makedirszFakeFilesystem.makedirse s$ 2    b 1 1 155h?? ##H--  )  ) H 66 )KK))  )   x ( ( ( ** // ==m ( R RIK33 RK$777"=+2Ei2PQQ  9 OOHddj[&8 9 9 9 9 9 9 9 9w%,&& 9:dll8.D.Dm#T#T 9%+!'U]*B*B#lAG##AGQZ888888888 9 9 9 9 9 9  9sD$$ G .B GG st_flagc|tt|} ||||}|r1|||| t |j|kSn#t $rYdSwxYwdS)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 check_read_perm: If True (default) False is returned for existing but unreadable file paths. Returns: (boolean) `True` if the st_flag is set in path's st_mode. Raises: TypeError: if path is None Nr)rF)rr"rrr rr)r]rFr\rrrobjs r7 _is_of_typezFakeFilesystem._is_of_type s. <O$T**  ,,?OC 6==s3F>ck**g55  6    55 usA A&& A43A4c:||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_rr]rFrs r7rzFakeFilesystem.isdir sg???r6c>||t|dS)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. Fr)r_rras r7rzFakeFilesystem.isfile s"gPUVVVr6c<||tdS)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. Fr)r_r rs r7rzFakeFilesystem.islink sguEEEr6)rZ cdS)z)Returns False. Junctions are never faked.Fr5rs r7 isjunctionzFakeFilesystem.isjunction s5r6rctt|||}|jtzs!|t j|d|S)aTest that the target is actually a directory, raising OSError if not. Args: target_directory: Path to the target directory within the fake filesystem. check_owner: If True, only checks read permission if the current user id is different from the file object user id Returns: The FakeDirectory object corresponding to target_directory. Raises: OSError: if the target is not a directory. ri )rrrrrrrr)r]rrrs r7 confirmdirzFakeFilesystem.confirmdir s^$  LL){L C C   7* F    /? E E Er6cjt|}||}||r||||r9||d}t |jtkr| |}t |jtkrJ|j r tj }n |jr tj}n tj}||||||rJ|j r tj }n |jr tj}n tj}|||n|||||dS)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. FrN)r"rrrrrr rrrr rNrrrarBrrrurrrr)r]rF norm_pathr^rKrs r7removezFakeFilesystem.remove s%T** $$Y//  ( ( . . B  6 6y A A A ;;y ! ! I,,y%,@@Cck""g--==33(*++w66)- % - %  % ''y999==!8!8!>!>??:). % . %  % ''y999==dCHHH 9%%%%%r6 allow_symlinkcV|t|dkr5|jr tjn tj}|||||}||}||dr|jsB| |r-|rdS|r|j s |tj || |d}|j r |tj|||dSdS)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 '.'. r5TrhN)r$rNrrrrrrrirrarrrrr)r]rrmrr dir_objects r7rmdirzFakeFilesystem.rmdir7 sB /?EE E E'+'9Ku||u|H   *: ; ; ;556FGG ++,<== ??+? > > 1% I$++6F*G*G I F$IDMI'' 7GHHH&6DIIJ! G##EO5EFFF   / 0 0 0 0 0 1 1r6c||d}||}t|j}|jrt j||S)aReturn 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. If `shuffle_listdir_results` is set, the order is not the same in subsequent calls to avoid tests relying on any ordering. Raises: OSError: if the target is not a directory. Tr )rrilistrkeysr\randomshuffle)r]rrdirectory_contentss r7r+zFakeFilesystem.listdirV so ,,-=,MMOO$455 !)"3"8"8":":;;  ' / N- . . .!!r6c*t|jSr`)r'rrrbs r7__str__zFakeFilesystem.__str__l s4=!!!r6c|ttj|ttj|ttjdSr`)r StandardStreamWrapperrJstdinstdoutstderrrbs r7rz$FakeFilesystem._add_standard_streamso se 1#)<<=== 1#*==>>> 1#*==>>>>>r6cjtj}||s||tjdkrc|dsP|d|dtt|j d<dSdSdS)Nr8z/tmprr) tempfile gettempdirrrrJrKr$rrrVr)r]temp_dirs r7rzFakeFilesystem._create_temp_dirt s&(({{8$$ & OOH % % % <7 " "4;;v+>+> "    1 1 1CDDd'..0011 2 2; ? ? ? # " " "r6)NT)r?Nrrr`)T)TF)F)TFTF)TN)TTN)TT)r.r/r0r1rErFrIr'rrrboolr^propertyrcrNsetterrarlrrrrvr+rXrrrrrr&rrrrrrrrr%rrnrrprrrrrrrrrrrr staticmethodr rr r$r*r.r2rrrrrXrrmrvr}rrrrdrFrOrJrrrrr rrrrrrrrrrrrrrrrrrrrrr"rrrr PERM_DEF_FILErrr!r%r4r8rr$rIrrMr#rTrr[r_rrrrJrrfrirlrpr+rxrrr5r6r7r:r:s(!gk$( % ?-?-?-SM?- ?-  ?-  ?-?-?-?-B<$<<<X<#t###X#'4'D'''' $X_'d't'''_' SX Z00000Z0-XsX F   X Y # #4 # # #Y #++ +D++++&666$    '''' 66666 )-"& 1119%13- 1  1111.:v:&::::FF8F;KFFFFVFVtVVVV%) 3'3'3'SM3' 3'  3'3'3'3'jg-08D>&T&,-,,,,2CHTN RR8F#3RuS#s]?SRRRR2///HV4D/PT////455,25""""4"&v"&%*?"&"&"&"&H6+f6+6+6+6+p%*%*F%*%*%*%*NMM6MMMM8 S T#Y   X  U tE{   X %V%V %%%%N&T2  4    F&HvH$HHHH4(  U3<-@  T     IfIIIII &36 x}hw// 0$&&&T&d&&&&P:/:/f:/:/:/:/:/:/x   '#d6l'#tCy'#'#'#'#Rf,)c,)',)c,),),),)b!%! 4444 4  4444l&&\&DDGDdDhDDDD,!% $! &(&(&(&( &(  &(  &( &(&(&(&(P/.W/././././.b0F00T00000$ ELELELEL EL  ELELELELN. 1& 1T 1 1 1 1>#>4:>KO> >>>>,         &     DAAA A  A  A AAAA0"#"4:" & """"H:v:$::::.2W222229@8H11%1251 1111l!66 !%$(!"& $*.3 3 3 3  3 # 3 " 3 3 3-3  3 h'3  3 3 3 3 p)- ))))g& )  ))))XFJ @ @" @19'1B @  @ @ @ @J)- JJJJ J g& J  JJJJ^" 44<44 4  4444F!66 !%$(!"& $"'*.WWWW W # W " WW3-W W Wh'W WWWWz%) 7 7 7 7 " 7  7 7 7 7 z!%$( @@@@ @ " @  @@@@L!%            4(t%!W%!%!%!%!%!N6=5E. . . s. $. . . . `f -4,""4<"""","""""???? D D D D Dr6r:r?cFddl}ddl}||jSr)doctestrtestmodfake_filesystem)rrs r7 _run_doctestr s)NNNOOO ??83 4 44r6cp|dkr tjS|dkr tjStd|d)NUSER_IDGROUP_IDz No attribute r5)rrrr)rts r7 __getattr__r sC y z 2222 3 33r6__main__)Vr1rrrErtrJr collectionsrrrrenumrrrrr r r r r typingrrrrrrrrrrrrrrrrrrpyfakefs.fake_filerr pyfakefs.helpersr!r"r#r$r%r&rKrrr+rrr:rr(FakeFileWrapperrzFakeDirWrapperFakePipeWrapperrg FakeOsModule FakeFileOpen FakeIoModuleFakeFcntlModulerYrrset_uidrset_gid reset_idsrrPERM_EXErrrr:rrr.r5r6r7rsCCH ////////                          POOOOOOOOOOOOOOO66666666<7##OOOT  %  5' !*!I+!7)+)# % # <7-O   / / / / /          %  N+DN+DN+DN+DN+DN+DN+DN+DbV5k5555444 zLNNNNNr6__pycache__/fake_filesystem_shutil.cpython-311.pyc000064400000010424150043321510016213 0ustar00 bg<dZddlZddlZddlZGddZdS)aA fake shutil module implementation that uses fake_filesystem for unit tests. Note that only `shutildisk_usage()` is faked, the rest of the functions shall work fine with the fake file system if `os`/`os.path` are patched. :Includes: FakeShutil: Uses a FakeFilesystem to provide a fake replacement for the shutil module. :Usage: The fake implementation is automatically involved if using `fake_filesystem_unittest.TestCase`, pytest fs fixture, or directly `Patcher`. NceZdZdZedZdZdZej dkr)ej dkrddd Z d d e j d d fd Z e j fd ZdZd S)FakeShutilModulezOUses a FakeFilesystem to provide a fake replacement for shutil module. cdS)zqReturn the list of patched function names. Used for patching functions imported from the module. ) disk_usagerp/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/fake_filesystem_shutil.pydirzFakeShutilModule.dir's rc,||_t|_dS)zConstruct fake shutil module using the fake filesystem. Args: filesystem: FakeFilesystem used to provide file system information N) filesystemshutil_shutil_module)selfr s r __init__zFakeShutilModule.__init__.s %$rc6|j|S)zReturn the total, used and free disk space in bytes as named tuple or placeholder holder values simulating unlimited space if not set. Args: path: defines the filesystem device which is queried )r get_disk_usage)rpaths r rzFakeShutilModule.disk_usage7s--d333r) win32Tfollow_symlinksc |j|r8|j|tj|}|||||||||S)zSince Python 3.12, there is an optimization fow Windows, using the Windows API. We just remove this and fall back to the previous implementation. r)r isdir joinpathsosrbasenamecopyfilecopystat)rsrcdstrs r copy2zFakeShutilModule.copy2Bsy $$S)) Lo//RW5E5Ec5J5JKK MM#sOM D D D MM#sOM D D DJrFNc p|tjkr|j}|j|||||||Sz*Make sure the default argument is patched.)r r"rcopytree)rr r!symlinksignore copy_functionignore_dangling_symlinks dirs_exist_oks r r%zFakeShutilModule.copytreeNsH ,, $ &//( rch|tjkr|j}|j|||Sr$)r r"rmove)rr r!r(s r r,zFakeShutilModule.movees1 ,, $ &++CmDD Drc,t|j|S)z;Forwards any non-faked calls to the standard shutil module.)getattrr)rnames r __getattr__zFakeShutilModule.__getattr__kst*D111r)__name__ __module__ __qualname____doc__ staticmethodr rrsys version_infoplatformr"r r%r,r0rrr rr"s\ %%%444 7""s|w'>'>59       ,%*    .06| E E E E 22222rr)r4rr r6rrrr r9sh   K2K2K2K2K2K2K2K2K2K2r__pycache__/fake_filesystem_unittest.cpython-311.pyc000064400000143331150043321510016566 0ustar00 bgdZddlZddlZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl Z ddl Z ddl Z ddlmZmZddlmZmZmZddlmZmZmZmZmZmZmZmZmZmZm Z m!Z!m"Z"ddl#Z#ddl$Z$ddl#m%Z%ddl&m'Z'm(Z(m)Z)m*Z*m+Z+ddl,m-Z-dd l.m/Z/dd l0m1Z1dd l2m3Z3dd l4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z:dd l4m;Z;ddl4mm?Z?m@Z@e@rddl4mAZAe jBdkrdndZCe jBdkrdndZD d4ddddde*jEddddeedeeeeFefdeeedeeeFefdeGdeGd e*d!eGd"eGd#efd$ZHdZIddddde*jEdfd%ed&e%d'ed(edeeeeFefdeeedeeeFefdeGdeGd e*d!eGd#e%fd)ZJGd*d+ZKGd,d-e#jLeKZLGd.d/ZMGd0d1ZNGd2d3eeZOdS)5aThis module provides a base class derived from `unittest.TestClass` for unit tests using the :py:class:`pyfakefs` module. `fake_filesystem_unittest.TestCase` searches `sys.modules` for modules that import the `os`, `io`, `path` `shutil`, and `pathlib` modules. The `setUpPyfakefs()` method binds these modules to the corresponding fake modules from `pyfakefs`. Further, the `open()` built-in is bound to a fake `open()`. It is expected that `setUpPyfakefs()` be invoked at the beginning of the derived class' `setUp()` method. There is no need to add anything to the derived class' `tearDown()` method. During the test, everything uses the fake file system and modules. This means that even in your test fixture, familiar functions like `open()` and `os.makedirs()` manipulate the fake file system. Existing unit tests that use the real file system can be retrofitted to use pyfakefs by simply changing their base class from `:py:class`unittest.TestCase` to `:py:class`pyfakefs.fake_filesystem_unittest.TestCase`. N)LoaderMetaPathFinder) ModuleType TracebackType FunctionType) AnyCallableDictListSetTupleOptionalUnionTypeIteratorcast ItemsViewSequence) TestSuite)set_uidset_gid reset_ids PatchModeFakeFilesystem)IS_PYPY)StubOutForTesting) ModuleSpec)reload)fake_filesystemfake_iofake_os fake_open fake_path fake_file)fake_filesystem_shutil) fake_pathlib) mox3_stubout)pathlib2 use_scandir) fake_scandirwin32ntposixntpath posixpathTFadditional_skip_namesmodules_to_reloadmodules_to_patchallow_root_useruse_known_patchespatch_open_codepatch_default_args use_cache_funcr1r2r3r4r5r6r7r8returnc dtdtffd } |rRt|stdt|drt |j|_| |S| S)a=Convenience decorator to use patcher with additional parameters in a test function. Usage:: @patchfs def test_my_function(fake_fs): fake_fs.create_file('foo') @patchfs(allow_root_user=False) def test_with_patcher_args(fs): os.makedirs('foo/bar') fr:c Xtj f d}|S)Nc  t  5}t|}||j|i|cdddS#1swxYwYdS)Nr0)Patcherlistappendfs) argskwargspr1r4r<r3r2r7r6r8r5s r/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/fake_filesystem_unittest.pywrappedz.patchfs..wrap_patchfs..wrapped}s&;"3!1 /"3 /#5#    *Dzz AD!!!q$)&)) * * * * * * * * * * * * * * * * * *s1AAA) functoolswraps) r<rGr1r4r3r2r7r6r8r5s ` rF wrap_patchfszpatchfs..wrap_patchfs|sa    * * * * * * * * * * * *   *zYDecorator argument is not a function. Did you mean `@patchfs(additional_skip_names=...)`? patchings)r callable TypeErrorhasattrlenrL nr_patches) r9r1r2r3r4r5r6r7r8rJs ```````` rFpatchfsrRbs4X& # F  5+ & & 4"5?33E |E""" rKloadertestsignoremodulec ntjdu} | s!t|||||| | dt_tjJtjt|} |t j|| tjjtjj|S)aYLoad the doctest tests for the specified module into unittest. Args: loader, tests, ignore : arguments passed in from `load_tests()` module: module under test remaining args: see :py:class:`TestCase` for an explanation File `example_test.py` in the pyfakefs release provides a usage example. NT)r1r2r3r4r5r6r7 is_doc_test)globssetUptearDown) r? DOC_PATCHER replace_globsvarsaddTestsdoctest DocTestSuiterZr[) rSrTrUrVr1r2r3r4r5r6r7 has_patcherrYs rF load_doctestsrcs*%T1K   %"7/-+/+1       * * *   - -d6ll ; ;E NN %+(1     LrKcJeZdZUdZdZeeeee fe d<dZ eee e d<dZ ee ee fe d<edZedefdZdddd d ejd d fdeeeee fdeee dee ee fd ed ed edededdfdZedddd d ejd d fdeeeee fdeee dee ee fd ed ed edededdfdZedZddZddZdS) TestCaseMixinaTest case mixin that automatically replaces file-system related modules by fake implementations. Attributes: additional_skip_names: names of modules inside of which no module replacement shall be performed, in addition to the names in :py:attr:`fake_filesystem_unittest.Patcher.SKIPNAMES`. Instead of the module names, the modules themselves may be used. modules_to_reload: A list of modules that need to be reloaded to be patched dynamically; may be needed if the module imports file system modules under an alias .. caution:: Reloading modules may have unwanted side effects. modules_to_patch: A dictionary of fake modules mapped to the fully qualified patched module names. Can be used to add patching of modules not provided by `pyfakefs`. If you specify some of these attributes here and you have DocTests, consider also specifying the same arguments to :py:func:`load_doctests`. Example usage in derived test classes:: from unittest import TestCase from fake_filesystem_unittest import TestCaseMixin class MyTestCase(TestCase, TestCaseMixin): def __init__(self, methodName='runTest'): super(MyTestCase, self).__init__( methodName=methodName, additional_skip_names=['posixpath']) import sut class AnotherTestCase(TestCase, TestCaseMixin): def __init__(self, methodName='runTest'): super(MyTestCase, self).__init__( methodName=methodName, modules_to_reload=[sut]) Nr1r2r3c`t|dr|jp tjStjS)N_patcher)rOrgr?PATCHERselfs rFpatcherzTestCaseMixin.patchers+ 4 $ $ 4=3GO 3rKr:c@tt|jjSN)rrrkrBris rFrBzTestCaseMixin.fssNDLO444rKTFr4r5r6r7r8c &tjdS||j}||j}||j}t|||||||||_|jtt| |jj dS)a4Bind the file-related modules to the :py:class:`pyfakefs` fake file system instead of the real file system. Also bind the fake `open()` function. Invoke this at the beginning of the `setUp()` method in your unit test class. For the arguments, see the `TestCaseMixin` attribute description. If any of the arguments is not None, it overwrites the settings for the current test case. Settings the arguments here may be a more convenient way to adapt the setting than overwriting `__init__()`. Nr0) r?rhr1r2r3rgrZrTestCase addCleanupr[) rjr1r2r3r4r5r6r7r8s rF setUpPyfakefszTestCaseMixin.setUpPyfakefss. ? & F ($($> !  $ $ 6   ##4 "7/-+/+1       Xt'' (>?????rKc tjdkrtdtjdS||j}||j}||j}t||||||||t_tjtt| tjj dS)aSimilar to :py:func:`setUpPyfakefs`, but as a class method that can be used in `setUpClass` instead of in `setUp`. The fake filesystem will live in all test methods in the test class and can be used in the usual way. Note that using both :py:func:`setUpClassPyfakefs` and :py:func:`setUpPyfakefs` in the same class will not work correctly. .. note:: This method is only available from Python 3.8 onwards. )zIsetUpClassPyfakefs is only available in Python versions starting from 3.8Nr0) sys version_infoNotImplementedErrorr?rhr1r2r3rZrroaddClassCleanupr[) clsr1r2r3r4r5r6r7r8s rFsetUpClassPyfakefsz TestCaseMixin.setUpClassPyfakefs1s*  f $ $%4  ? & F ($'$= !  $ # 5   #"3 !"7/-+/+1      Xs++GO,DEEEEErKc@tjrtjjSdS)zConvenience class method for accessing the fake filesystem. For use inside `setUpClass`, after :py:func:`setUpClassPyfakefs` has been called. N)r?rhrB)rys rFfake_fszTestCaseMixin.fake_fsds ? &?% %trKc8|jdSzPause 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. N)rkpauseris rFrzTestCaseMixin.pausens rKc8|jdSzResume 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. N)rkresumeris rFrzTestCaseMixin.resumews rKr:N)__name__ __module__ __qualname____doc__r1rr rstrr__annotations__r2r3r propertyrkrrBrOFFboolrq classmethodrzr|rrrKrFreres%%NEI8DsJ)?$@AHHH48xZ 018888<htCO45<<< X 5N555X5 IM8<<@ $"&%.]#(,@,@'U3 ?-C(DE,@$D$45,@#4Z#89 ,@  ,@  ,@#,@!,@,@ ,@,@,@,@\IM8<<@ $"&%.]#(0F0F'U3 ?-C(DE0F$D$450F#4Z#89 0F  0F  0F#0F!0F0F 0F0F0F[0Fd[rKrec eZdZdZ d dedeeeeefdeeedee eefffd Z d d Z xZ S) rozTest case class that automatically replaces file-system related modules by fake implementations. Inherits :py:class:`TestCaseMixin`. The arguments are explained in :py:class:`TestCaseMixin`. runTestN methodNamer1r2r3ctt|||_||_||_dS)zCreates the test class instance and the patcher used to stub out file system related modules. Args: methodName: The name of the test method (same as in unittest.TestCase) N)super__init__r1r2r3)rjrr1r2r3 __class__s rFrzTestCase.__init__s; $$$%:"!2 0rKr:cdS)zgThis method is deprecated and exists only for backward compatibility. It does nothing. Nrris rFtearDownPyfakefszTestCase.tearDownPyfakefssrK)rNNNr) rrrrrrr rrr rr __classcell__rs@rFroros$HL8<<@ 111 (U3 ?-C(DE1$D$45 1 #4Z#89 111111(        rKroceZdZUdZ deeeeee e e e e eeeeejhZe jdkr3ddlZddlZeeeenKddlZddlZddlZeeeeeeeZeeed<iZ e!e"ee#ee"ffed<iZ$e!e#e"e"e"feefed<gZ%e&e#e'e(e)de*ffed <iZ+e!e"ee#ee"ffed <devs Jd e jd vZ,eZ-ee"ed <eZ.ee"ed<eZ/ee"ed<dZ0dZ1e2ded<dZ3e2ded<dZ4dZ5fdZ6ddddde7j8dddf de2e&e9e"efde2e&ede2e!e"efde:de:de7de:de:de:ddfdZ;dAd ZdBd#Z?d$e2e@eAd%e2eAd&e2eBddfd'ZCd(ed)e"d*e&e"de:fd+ZDd,e'de:fd-ZEd.e'deFe#e'e(e*ffd/ZGd0eHe"e'fddfd1ZIdAd2ZJdAd3ZKdCd4e*ddfd5ZLdAd6ZMdAd7ZNdAd8ZOdAd9ZPd:e!e"e*fde!e"e*ffd;ZQdCd4e*fd<ZRdAd=ZSdAd>ZTdAd?ZUdAd@ZVxZWS)Dr?at Instantiate a stub creator to bind and un-bind the file-related modules to the :py:mod:`pyfakefs` fake modules. The arguments are explained in :py:class:`TestCaseMixin`. :py:class:`Patcher` is used in :py:class:`TestCaseMixin`. :py:class:`Patcher` also works as a context manager for other tests:: with Patcher(): doStuff() Nr+rCACHED_MODULES FS_MODULES FS_FUNCTIONS. FS_DEFARGSSKIPPED_FS_MODULESz3sys.modules contains 'None' values; must skip them.)r+cygwin SKIPNAMESPATCHED_MODULE_NAMESADDITIONAL_SKIP_NAMESFrhr\c|ddr4|j&t||_|jS|j&t||_|jS)NrXF)getr\r__new__rh)ryrCrDrs rFrzPatcher.__new__sg ::mU + + #&"'''//#"6"6? " ; ''//#..CK{rKTr1r2r3r4r5r6r7r8rXr:c  | |_| r|jdkrdSn |jdkrdS|stdt d|j|_t|_ ||_ ||&d|D} |j | i|_ i|_ i|_|t jdkrgnt$g|_||j|||_||_|roddlm} m} m} |pi}| | |j | |j | |4|D]\}}||j |<t9|}nt9}| }|rU||jkr||j_d}|j|jkr|j|j_d}||j kr||j_ d}|r|!i|_"|#d|_$d|_%i|_&i|_'d|_(d|_)d|_*dS) aq Args: additional_skip_names: names of modules inside of which no module replacement shall be performed, in addition to the names in :py:attr:`fake_filesystem_unittest.Patcher.SKIPNAMES`. Instead of the module names, the modules themselves may be used. modules_to_reload: A list of modules that need to be reloaded to be patched dynamically; may be needed if the module imports file system modules under an alias .. caution:: Reloading modules may have unwanted side effects. modules_to_patch: A dictionary of fake modules mapped to the fully qualified patched module names. Can be used to add patching of modules not provided by `pyfakefs`. allow_root_user: If True (default), if the test is run as root user, the user in the fake file system is also considered a root user, otherwise it is always considered a regular user. use_known_patches: If True (the default), some patches for commonly used packages are applied which make them usable with pyfakefs. patch_open_code: If True, `io.open_code` is patched. The default is not to patch it, as it mostly is used to load compiled modules that are not in the fake file system. patch_default_args: If True, default arguments are checked for file system functions, which are patched. This check is expansive, so it is off by default. use_cache: If True (default), patched and non-patched modules are cached between tests for performance reasons. As this is a new feature, this argument allows to turn it off in case it causes any problems. rNcg|]E}tj|rtt|jntt |FSr)inspectismodulerrrr).0ms rF z$Patcher.__init__..6sS180@0C0CUZ##,,cSTrKr+)get_modules_to_patchget_classes_to_patchget_fake_module_classesTF)+rX DOC_REF_COUNT REF_COUNTrrrcopy _skip_namesopen original_openr6update_fake_module_classes_unfaked_module_classes_class_modules_init_fake_module_classesruplatformtempfiler2extendr7r8pyfakefs.patched_packagesrrritemssetrrrPATCH_DEFAULT_ARGS clear_cache_fake_module_functions_init_fake_module_functions_stubsrB fake_modulesunfaked_modules_isStale _dyn_patcher _patching)rjr1r2r3r4r5r6r7r8rX skip_namesrrrname fake_modulepatched_module_namesrs rFrzPatcher.__init__sV'  !A%%& ^a   F  AJJJ AJJJ>..00!. . ,.J   # #J / / /46!79$46 &&(((,'))BBz   (  " ) )*; < < <"4"  H           052   # #$8$8$:$: ; ; ;   & &';';'='= > > >  % , ,-D-D-F-F G G G  '%5%;%;%=%= > >!k2=)$//#&'7#8#8 #&55 #m  ##t'@@@6J3" 4#===7;7G4" !T%<<<4F1"        79# ((***48 ,0,./1 6:rKct|j_i|j_i|j_g|j_i|j_dS)zClear the module cache.N)rrrrrrrris rFrzPatcher.clear_cachexs>(+%$&!&(#$&!,.)))rKc|tjtjtjt jd|_trtj|jd<tj dkrtj |jd<ntj|jd<dg|jd<t j|jd<t&rHt j|jd<|jddt j|jd<t j|jd<t j|jd<t.rt0j|jd <dSdS) N)osshutiliopathlib_ior+r,fcntlrPathr(scandir)r! FakeOsModuler%FakeShutilModuler FakeIoModuler&FakePathlibModulerrrurr# FakeNtModulerFakeFcntlModulerRealPathlibModulerr(rAFakePathlibPathModuleRealPathlibPathModuler)r*FakeScanDirModuleris rFrz!Patcher._init_fake_module_classess' &,=&#5 % % !  D/6/CD %e , <7 " ".7.DD %d + +1@1PD %g . (1kF#2>2P$Y/  V4@4RD %j 1   ' . .z : : :7C7UD ( 4,8,N!&)/;/Q$V,  R3?3QD %i 0 0 0 R RrKcp|jD]\}}t|dr|j}t j|rp|D][}t |||f}||j|i|<|dkr#||j|it<\tj }|D]Z}t ||tf}||j|id<||j|it<[dS)Ndirr genericpath) rrrOrr isfunctiongetattrr setdefault OS_MODULErFakePathModule PATH_MODULE)rjmod_namer module_dirfct_name module_attrs rFrz#Patcher._init_fake_module_functionssi&*%>%D%D%F%F , , !Hk{E** ,(_ %j11 ,$/OO$5$5,,'.{H'E'Ex&P (3>>xLL$$t++!,!7BB8RPP ) &4 #))  H";99;GK  ' 2 28R @ @    ' 2 28R @ @     rKc.||S)zContext manager for usage outside of fake_filesystem_unittest.TestCase. Ensure that all patched modules are removed in case of an unhandled exception. )rZris rF __enter__zPatcher.__enter__s  rKexc_typeexc_valexc_tbc.|dSrm)r[)rjrrrs rF__exit__zPatcher.__exit__s rKmodr module_namesc tj|r |j|vp5tj|o!|j|j|gvS#t$rYdSwxYwNF)rrrisclassrrr Exception)rjrrrs rF _is_fs_modulezPatcher._is_fs_modules  %%1LL0H?3''HNd&9&=&=dB&G&GG      55  sAA A#"A#fctc tj|stj|o&|j|jvo|j|j|jvS#t $rYdSwxYwr)rr isbuiltinrrrr)rjrs rF_is_fs_functionzPatcher._is_fs_functions} #C((BG,=c,B,BPLD$??PNd&A#,&OO     55 sAA AAitemc#K |jrJtj|r6t|jD]!\}}||r|||fV"n#t $rYnwxYw tj|r{tj|tjD]\}tt|d}|jr6t|jD]!\}}||r|||fV"[dSdS#t $rYdSwxYw)zFind default arguments that are file-system functions to be patched in top-level functions and members of top-level classes.) predicaterN) __defaults__rr enumeraterrr getmembersrr)rjridrr<s rF _def_valueszPatcher._def_valuessf    )W%7%=%= )%d&788))DAq++A..)"Aqj(((    D  t$$ .!+DG.%s'KKKBv//KKKrKcJi|]\}}|||| Sr)r)rrrrrjs rF z)Patcher._find_modules..)sGD#%%c4>>crKcFi|]\}}|||Sr)r)rrrrjs rFrz)Patcher._find_modules..9sC"+$t?S?STW?X?X#rKN)r@rkeysrrumodulesrr8rrrrradd SKIPMODULESanyr__dict__rrrrrrrrr7r) rjrskippedr rr functionsrrVrs ` @@rF _find_moduleszPatcher._find_moduless D5::<<== M  !2!2!4!4553 :3 :LD& N$"555"+F3366    >>N155f===  00CKKKK$:JKKK55G"?//117799L!-G  8!(ID#N5@@suuMMQQ. ")ID#N-88suuEEII./; "+!2!2""ID#N/::s|S^=B>cb|j|jtj|_t j|d|_|j|j_tj |j|_|j D]W}|j ||j|j |<t|j |dr|j |j |_X|j dj|j t <|jD]}|j||j|< d|_dS)z@Renew the fake file system and set the _isStale flag to `False`.NT)rkcreate_temp_dirrrF)rsmart_unset_allr'rrrrBr6r" FakeFileOpenrrrOrrpathrrrrrjrs rF_refreshzPatcher._refreshIs! ; " K ' ' ) ) )"466 !0tTTT"&"6"/88- F FD&Ed&?&Edg&N&ND d #t(. == F595E!$'2)-):4)@)E+&0 N ND)K)Ed)K)M)MD  & & rK doctesterc|jr(|jxjdz c_|jjdkrdSn'|jxjdz c_|jjdkrdStjdko t tdo tj|_ |j r dt_tj 5tj d| dddn #1swxYwY||||j|_||jt&_|jt*_dS)zBind the file-related modules to the :py:mod:`pyfakefs` fake modules real ones. Also bind the fake `file()` and `open()` functions. rNdarwin_HAS_FCOPYFILEFrU)rXrrrrurrOrr+has_fcopy_filewarningscatch_warningsfilterwarningsr r'r]rYstart_patchingr linecachertokenize _builtin_openrjr(s rFrZz Patcher.setUp\s    N ( (A - ( (~+a//0 N $ $ ) $ $~'!++ LH $ & 011 &%    *$)F !  $ & & ! !  #H - - -     ! ! ! ! ! ! ! ! ! ! ! ! ! ! !   "00AAIO + !%!3s3)C((C,/C,c|jsd|_|||t ||_t jd|j|j D]9}t j |j |urt|8dSdS)NTr)r patch_modulespatch_functionspatch_defaultsDynamicPatcherrru meta_pathinsertr2rrrr)rjrVs rFr0zPatcher.start_patching~s~ #!DN     " " "    ! ! ! .t 4 4D  M D$5 6 6 60 # #;??6?33v==6NNN # # # #rKc|jJ|jD]h\\}}}}|j||\}}|j|}|||j}|D]} |j| ||idSrm)rrrrr__get__r smart_set) rjrft_nameft_modrmethodrrattrrVs rFr7zPatcher.patch_functionss{&&&040A0G0G0I0I : : , #T7FW#:7CFK FH+H5K>>[2D" : : %%fdD9999 :  : :rKc|jJ|jD]4\}}|D],\}}|j|||j|-5|jD]=\}}|D]5\}}||jvr'|j|||j|6>tjdkr(|jtd|j dSdS)N)rs r) rrrr>rrrrurvbuiltinsr")rjrrrVrBs rFr6zPatcher.patch_moduless{&&&!_2244 M MMD' ' M M  %%fdD4Ed4KLLLL M!4::<< T TMD' ' T T 4///K))&$8LT8RSSS T  w & & K ! !(FDN C C C C C ' &rKc|jD]\}}}|j|j|j\}}|j|}|||j}g}|jJt|jD]6\} } | |kr| |!| | 7t||_dSrm) rrrrrr=rrrrAtuple) rjridxftrArrrB new_defaultsr r s rFr8zPatcher.patch_defaultss O 3 3LCb#:2;G V FH+H5K>>[2DL#///!#"233 + +188 ''---- ''****$\22C   3 3rKglobs_c|}|jr||jD]$}||vr|j||j||<%|Srm)rrr'rrB)rjrKrYrs rFr]zPatcher.replace_globssf  =  MMOOO- G GDu}}=d7=dgFFd  rKc^|jr(|jxjdzc_|jjdkrdSn'|jxjdzc_|jjdkrdS||jr dt _t|jrd|j_ dSd|j_ dS)z8Clear the fake filesystem bindings created by `setUp()`.rrNT) rXrrr stop_patchingr,rr+rr\rhr4s rFr[zPatcher.tearDowns    N ( (A - ( (~+a//0 N $ $ ) $ $~'!++    )$(F !   *)-DN & & &%)DN " " "rKc|jrd|_d|_|jr|j||jr<|jtj ddSdSdS)NTFr) rrrr#unset_defaultsrcleanuprur:popris rFrNzPatcher.stop_patchings > % DM"DN{ . ++---    ! ! !  %!))+++ !!!$$$$$ % %  % %rKc |jD]z\}}}g}ttt|jD]6\}}||kr||!||7t ||_{dSrm)rrrr rrArG)rjrrHrIrJr r s rFrPzPatcher.unset_defaultss O 3 3LCbL!$uc.>"?"?@@ + +188 ''++++ ''****$\22C   3 3rKc.|dSr~)rNris rFrz Patcher.pauses rKc.|dSr)r0ris rFrzPatcher.resumes rKr)r:r?rm)Xrrrrrr%r!r r"r#r$rur1r2rrrrr%rrr,r.rr-r/rrrr rrrr rr rrr rintr rr IS_WINDOWSrrrrrhrr\rrrrrrrrrrrrr BaseExceptionrrrrrr rrr r'rZr0r7r6r8r]r[rNrPrrrrs@rFr?r?s        !K$ |w     """'*ceeNC O+++9;JS#eJO4556;;;@BL$uS#s]+S_<=BBBEGJU<hsCx.@@ABGGGACS#eJO&<"==>CCC ;    X   !44J#%%Is3x&)SUU#c(***&)cee3s8+++#'GXi ''''+K)$+++IMIM8<<@ $"&%.]#(!}}'U3 ?-C(DE}$D$45}#4Z#89 }  }  }#}!}}} }}}}~////RRRRB:4 ./-('   %(8cdrKrZc eZdZdZdeddfdZddZdedefdZ dd ed e e e e efd e ede efd Zd edefd ZdS)r9zA file loader that replaces file system related modules by their fake implementation if they are loaded after calling `setUpPyfakefs()`. Implements the protocol needed for import hooks. rkr:Ncn||_i|_|jj|_t |_|jD]L}||r5|tjvr'tj||j|<tj|=M|jD]\}}|tj|<dSrm) rg sysmodulesrrr_loaded_module_names needs_patchrur)rjrkrrVs rFrzDynamicPatcher.__init__ s }1 .1ee!L & &D%% &$#+*=*=(+ D(9%K% L..00 ' 'LD& &CK   ' 'rKc.|jD]}|j|tj|<|jjD]$}|jtjvrt |%d|jjD}|jD]!}|tjvr||vr tj|="dS)Ncg|] }|j Sr)r)rrVs rFrz*DynamicPatcher.cleanup..6s'! ! ! &FO! ! ! rK)rdrurrgr2rrre)rj module_namerVreloaded_module_namesrs rFrQzDynamicPatcher.cleanup0s? D DK'+{'CCK $ $m5  F#+--v! ! *.-*I! ! !  - & &Ds{""t3H'H'HK% & &rKrc||jvr|j|dS|tjvr0t tj||j|krdSdS)z:Check if the module with the given name shall be replaced.FT)rrerrutyper&s rFrfzDynamicPatcher.needs_patch@sb t| # #  % ) )$ / / /5 3;  4 D(9#:#:dl4>P#P#P5trKfullnamer%targetcP||rt||SdS)zModule finder.N)rfr)rjrmr%rns rF find_speczDynamicPatcher.find_specIs/   H % % .h-- -trKcP|j|tj|<|j|S)z/Replaces the module by its fake implementation.)rru)rjrms rF load_modulezDynamicPatcher.load_moduleTs" $ X 6 H|H%%rKrrm)rrrrr?rrQrrrfrrrbytesrrrprrrrKrFr9r9s ''D'''' &&&& (,   xeSj 123 $  *     &C&J&&&&&&rKr9rm)PrrrEr`rHrrrr1rrrurr2 importlib.abcrrtypesrrrtypingrr r r r r rrrrrrrunittestr-rpyfakefs.fake_filesystemrrrrrpyfakefs.helpersrpyfakefs.mox3_stuboutrimportlib.machineryr importlibrpyfakefsrr r!r"r#r$r%r&r'pyfakefs.extra_packagesr(r)r*rrrrrrrRDOCTEST_PATCHERrcreror?rZr9rrKrFrsx ,   000000009999999999%$$$$$333333******WWWWWWWWWWWWWWWW++++++!!!!!!!!!!!!99999999&%%%%%%LG++DD ,'11hh{ !%7EI488< "!*$777 H 7$DsJ)?$@A7 Z 01 7 tCO45 7  777777777tEI488< "!*$++ + + +  + $DsJ)?$@A +  Z 01 +tCO45+++++++++\ppppppppf     x -   BT T T T T T T T nD=&=&=&=&=&^V=&=&=&=&=&rK__pycache__/fake_io.cpython-311.pyc000064400000020533150043321510013050 0ustar00 bgdZddlZddlZddlZddlZddlmZddlmZm Z m Z m Z m Z m Z mZmZddlmZddlmZddlmZerddlmZGd d eZGd d Zejd krddlZGddZdSdS)zP Uses :py:class:`FakeIoModule` to provide a fake ``io`` module replacement. N)Enum)ListOptionalCallableUnionAnyAnyStrIO TYPE_CHECKING)AnyFileWrapper) FakeFileOpen)IS_PYPY)FakeFilesystemceZdZdZdZdZdZdS) PatchModezvDefines if patching shall be on, off, or in automatic mode. Currently only used for `patch_open_code` option. N)__name__ __module__ __qualname____doc__OFFAUTOONa/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/fake_io.pyrr*s) C D BBBrrceZdZdZedeefdZddZ dd e e e fd ed e de ede ede ede de ede eeeffdZejdkrdZdZd S) FakeIoModulezUses FakeFilesystem to provide a fake io module replacement. You need a fake_filesystem to use this: filesystem = fake_filesystem.FakeFilesystem() my_io_module = fake_io.FakeIoModule(filesystem) returncVdg}tjdkr|d|S)zqReturn the list of patched function names. Used for patching functions imported from the module. openr open_code)sys version_infoappend)_dirs rdirzFakeIoModule.dir<s0 x  v % % KK $ $ $ r filesystemrc:||_g|_t|_dS)zg Args: filesystem: FakeFilesystem used to provide file system information. N)r, skip_namesio _io_moduleselfr,s r__init__zFakeIoModule.__init__Fs %%'rrNTfilemode bufferingencodingerrorsnewlineclosefdopenerc  tjd} tj| djd tjd t fd|j Drtj ||||||||St|j } | ||||||||S)z\Redirect the call to FakeFileOpen. See FakeFileOpen.call() for description. r)limitr.cLg|] }|kpd|z!S)r@)endswith).0sn module_names r z%FakeIoModule.open..esE   r!C[%9%9#(%C%C   r) traceback extract_stackospathsplitextfilenamereplacesepanyr.r/r#r r,) r2r6r7r8r9r:r;r<r=stack fake_openrEs @rr#zFakeIoModule.openOs$'a000g&&uQx'899!< !))"&#66     /       7   !11 y $ 8VWgv   rr$cFt|tststd|jj}|t jkr|j|s|t j kr| |dS|j |S)zRedirect the call to open. Note that the behavior of the real function may be overridden by an earlier call to the PyFile_SetOpenCodeHook(). This behavior is not reproduced here. z0open_code() argument 'path' must be str, not intrb)r7) isinstancestrr TypeErrorr,patch_open_coderrexistsrr#r0r&)r2rJ patch_modes rr&zFakeIoModule.open_code{s dC(( T T RSSS8Jin,,O**400---yyDy111?,,T22 2rc,t|j|S)z5Forwards any unfaked calls to the standard io module.)getattrr0r2names r __getattr__zFakeIoModule.__getattr__st---rr,r)r4r5NNNTN)rrrr staticmethodrrUr+r3rr intrboolrr r rr#r'r(r&r^rrrr r 4s<c\"& $!%%)( ( FCK ( (  ( 3- (  ( #( ( "(  ~r#w& '( ( ( ( T 6!! 3 3 3$.....rr win32c eZdZdZedeefdZddZdde d e d e de e e ffd Z dde d e d e de de e e ff dZde de ddfdZ dde d e de de def dZdZdS)FakeFcntlModulezvReplaces the fcntl module. Only valid under Linux/MacOS, currently just mocks the functionality away. r!c gdS)zyReturn the list of patched function names. Used for patching functions imported from the module. )fcntlioctlflocklockfrrrrr+zFakeFcntlModule.dirs 877 7rr,rc,||_t|_dS)z Args: filesystem: FakeFilesystem used to provide file system information (currently not used). N)r,rg _fcntl_moduler1s rr3zFakeFcntlModule.__init__s )DO!&D   rrfdcmdargc4t|trdn|SNrrTra)r2rmrnros rrgzFakeFcntlModule.fcntls"3,,511# 5rTrequest mutate_flagc4t|trdn|Srqrr)r2rmrsrorts rrhzFakeFcntlModule.ioctls#3,,511# 5r operationNcdSNr)r2rmrvs rrizFakeFcntlModule.flocks DrlenstartcdSrxr)r2rmrnryrzwhences rrjzFakeFcntlModule.lockfs  Drc,t|j|S)z8Forwards any unfaked calls to the standard fcntl module.)r[rlr\s rr^zFakeFcntlModule.__getattr__s4-t44 4rr_)r)rT)rrr)rrrrr`rrUr+r3rarbytesrgrbrhrirrjr^rrrreresl    8T#Y 8 8 8  8  ' ' ' ' 6 6C 6c 6 6E#u*rs                     .-----++++++$$$$$$8777777        [.[.[.[.[.[.[.[.|<7LLL'5'5'5'5'5'5'5'5'5'5r__pycache__/fake_open.cpython-311.pyc000064400000032355150043321510013407 0ustar00 bgH4 dZddlZddlZddlZddlmZddlmZddlm Z m Z m Z m Z m Z mZmZddlmZddlmZmZmZmZddlmZmZmZmZerdd lmZed d Zd d dddddddZGddZ dS)zGA fake open() function replacement. See ``fake_filesystem`` for usage. N) namedtuple)S_ISDIR)OptionalUnionAnyTuplecastAnyStr TYPE_CHECKING)helpers)FakePipeWrapperFakeFileWrapperFakeFileAnyFileWrapper) AnyStringis_root PERM_READ PERM_WRITE)FakeFilesystem _OpenModeszek+IJJJ1':H''''{ .@@ @ @@% # * G 55g>>H&GON$$$ G D) D D ?)))44 D 5 D O * *5< C C C$$$,, J    ;& ' ' H, H..u|YGGGG..u|YGGG!*    4";==L#/K ?0 4'3 $"  '$$ 1;     &H "o8AO"...  " "8 , , , ,#==hGGH r%cld}|jr|jr|tjz}n-|jr|tjz}n|jr|tjz}|jr|tjz}|jr|tj z}|j s|jr|tj z}|j r|jr|tj z}|S)Nr)rZrIosO_RDWRO_RDONLYO_WRONLYr;O_APPENDrVO_TRUNC must_existO_CREATrLO_EXCL)r5flagss r#r@z(FakeFileOpen._open_flags_from_open_modess   !:#7 ! RY EE   ! R[ EE  ! ! R[ E   ! R[ E   RZ E$ )= RZ E  $ )=  RY E r%r[r\r]c>|rtsQ|jr|jtzr|jr4|jt zs%|jtj ||jr|j r| dn|j r%|jtj ||j|r@|j|d}|jJt#t$|j}n|}|j|rW|jjr tjn#|jjr tj n tj}|j|||j|dd}|S)NF)follow_symlinksT)create_missing_dirs apply_umask)rrZrRrrIrrrOrErSrV set_contentsrlENOENTrMresolvecontentsr r ends_with_path_separatorrNEINVALis_macosrTcreate_file_internally)r"r[r\r5r] link_object target_patherrors r#rQzFakeFileOpen._init_file_objects  99 H$ H-8-@9-L H( H1<1Dz1Q H..u|YGGG# 1&1,,R000$ H..u|YGGG%%i00 ("o55iQV5WW "+777"K0 ( 77 DD A4&ELL/& ..ui@@@/@@u$AKr%cd}t|tr|}|j|}t|trdd|dfSt|t r |j|_tt|j| }|J|j }|tt||tt|fStt|}||jj j kr|jj }|}nP|j|}|j|r|j|d}||d|fS)NF)check_read_perm)rGintr get_open_filer rrr!r r get_objectnamer dev_null resolve_pathexistsget_object_from_normpath)r"r-r[rKr`pathr\r]s r#rAzFakeFileOpen._handle_file_arg1sy eS ! !  Go33G<zFakeFileOpen._handle_file_modeVs  4KKC4KK  w & &3$;;-455 5||C$$,,S"55||D#&&..sC88{ ;>)) !3j!@AAA#^D%9:J%%% ""r%)FF)rr,NNNTNN)__name__r? __qualname____doc__boolr$rrr+rr rstrrrr* staticmethodr@rrrQrrAr>r%r#rrGsb H !&  $      *c*S*^****"& $!%+/OOVS[!OO O 3- O  O#OOOZ(O OOOOb s\&'h''' '  '  ''''R#763;'#7 x!8F#3Xc]HVDTT U#7#7#7#7J####Z( # x}j( ) ######r%r)!rrErfr collectionsrstatrtypingrrrrr r r pyfakefsr pyfakefs.fake_filer rrrpyfakefs.helpersrrrrpyfakefs.fake_filesystemrrrrrr%r#rs """""" 8777777ZB  2 1 1 1 1 1 1 1  b#b#b#b#b#b#b#b#b#b#r%__pycache__/fake_os.cpython-311.pyc000064400000174212150043321510013066 0ustar00 bgn(dZddlZddlZddlZddlZddlZddlZddlmZddl m Z m Z ddl m Z mZmZmZmZmZmZmZmZmZddlmZddlmZmZmZmZmZmZm Z ddl!m"Z"m#Z#dd l$m%Z%dd l&m'Z'm(Z(m)Z)dd l*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8erdd l9m:Z:d Z;GddZej?eeB6edZFdS)zV Uses :py:class:`FakeOsModule` to provide a fake :py:mod:`os` module replacement. N)contextmanager)S_IFREGS_IFSOCK) ListOptionalCallableUnionAnyTuplecastAnyStr TYPE_CHECKINGSet) use_scandir) FakeDirectoryFakeDirWrapperStandardStreamWrapperFakeFileWrapperFakePipeWrapperFakeFileAnyFileWrapper) FakeFileOpen _OpenModes)FakePathModule)scandirwalk ScanDirIter)FakeStatResult is_int_typeis_byte_stringmake_string_pathIS_PYPY to_stringmatching_string AnyStringto_bytesPERM_EXEPERM_DEFis_rootget_uidget_gid)FakeFilesystemceZdZdZdZedeefdZdsdZ e defdZ e defd Z e de efd Ze defd Ze defd Zd edededefdZdefdZ dtdddedede ede edef dZd eddfdZd ededefdZd ededefdZdeeeffdZd edefdZd edefd!Z deddfd"Z!defd#Z"defd$Z#dedeefd%Z$d&Z%d'Z&d(d)ded*e'd+e(de efd,Z) dtd(d)de ed+e(deefd-Z*d(d)ded*e'd+e(ddfd.Z+ dud(d)ded*e'd0eded+e(ddf d1Z,dvdede-fd3Z. dwd4ed5e(d6e e(d7e(fd8Z/dtdede edefd9Z0dd(d:dede ed+e(defd;Z1dddede edefd<Z2dtdede eddfd=Z3dddede eddfd>Z4ddd?d@edAedBe edCe eddf dDZ5dEedFefdGZ6ddd?d@edAedBe edCe eddf dHZ7dddede eddfdIZ8dJeddfdKZ9e:fdddedede eddfdLZ;e:dfdJededMe e(ddfdNZdedQeddfdRZ?d edQeddfdSZ@ddd(dTdedede edUe(d+e(de(f dVZAdd(d:dedede ed+e(ddf dWZBdededdfdXZC dxdedYe eeDeeEfeDeeEffdZe eeefde ed+e(ddf d[ZFdd(d:ded\ed]ede ed+e(ddf d^ZG dydddede ed_ede eddf d`ZH dzddd@edAedae(de eddf dbZIddd?d@edAedBe edCe eddf dcZJd eddfddZKd eddfdeZLdfedgedhediedef djZMdefdkZNdefdlZOdePfdmZQe dePe=fdnZRe dePe=fdoZSe dePe=fdpZTe dePe=fdqZUdJedefdrZVdS){ FakeOsModuleaUses 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_os.FakeOsModule(filesystem) Freturncgd}tjdr|gdz }tjdkr|ddgz }tr|dgz }|S)zqReturn the list of patched function names. Used for patching functions imported from the module. )accesschdirchmodchownclosefstatfsyncgetcwdlchmodlinklistdirlstatmakedirsmkdirmknodopenreadreadlinkremove removedirsrenamermdirstatsymlinkumaskunlinkutimerwritegetcwdbreplacelinux) fdatasyncgetxattr listxattr removexattrsetxattrwin32getgidgetuidr)sysplatform startswithr)_dirs a/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/fake_os.pydirzFakeOsModule.dir]s    B < " "7 + +   D <7 " "  D  YK D filesystemr,c||_t|_t|j||_d|_d|_d|_d|_dS)zAlso exposes self.path (to fake os.path). Args: filesystem: FakeFilesystem used to provide file system information N) r`os os_modulerpath_supports_follow_symlinks_supports_dir_fd_supports_effective_ids _supports_fd)selfr`s r]__init__zFakeOsModule.__init__sK % "4?D99 8<&/36:$+/r_c|jjSN)rddevnullris r]rmzFakeOsModule.devnull y  r_c|jjSrl)rdseprns r]rqzFakeOsModule.seps y}r_c|jjSrl)rdaltseprns r]rszFakeOsModule.altseps yr_c|jjSrl)rdlineseprns r]ruzFakeOsModule.linesepror_c|jjSrl)rdpathseprns r]rwzFakeOsModule.pathsepror_fdargskwargsczt|stdt|j|g|Ri|S)a[Redirector to open() builtin function. Args: fd: The file descriptor of the file to open. *args: Pass through args. **kwargs: Pass through kwargs. Returns: File object corresponding to file_des. Raises: TypeError: if file descriptor is not an integer. an integer is required)r TypeErrorrr`)rirxryrzs r]fdopenzFakeOsModule.fdopensK2 6455 5,|DO,,RA$AAA&AAAr_c|jjrdStjdkrdSt jd}t j||S)zReturn the current umask.rrV)r` is_windows_fsrYrZrbrJ)rimasks r]_umaskzFakeOsModule._umasksG ? ( 1 <7 " "5 8A;;D HTNNNKr_N)dir_fdrdflagsmoderc |||j|}|'|jjrd}nd|z}t t do|t jzt jk}t|t j z o| |t j z |t j t j zzdk|t j zdk|t j zdk|t jzdk}|jr|jrt#d|rG|j|t'|t)t+j}|jjs|j|r|j|}t3|t4rx|js |jjr|jr%|jt<j|tA|||j}|j!|} | |_"| Sd} |} t t d r|t j#zt j#k} tI|j| d || | } t3| tJrJ| j&|jj'kr|(||| )S) aReturn the file descriptor for a FakeFile. Args: 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. Returns: A file descriptor. Raises: OSError: if the path cannot be found ValueError: if invalid mode is given NotImplementedError: if `os.O_EXCL` is used without `os.O_CREAT` Nii O_TMPFILEr) must_existcan_read can_writetruncateappendmust_not_existz,O_EXCL without O_CREAT mode is not supportedb O_TEMPORARYT)delete_on_closeraw_io) open_modes)*_path_with_dir_fdrAr`rrhasattrrbrrO_CREATO_WRONLYO_RDWRO_TRUNCO_APPENDO_EXCLrrNotImplementedError joinpathsr$struuiduuid4existsresolve isinstanceris_macosrraise_os_errorerrnoEISDIRr_add_open_filefiledesrrr file_objectdev_nullr4fileno) rirdrrrhas_tmpfile_flagrobj dir_wrapperfile_des str_flagsr fake_files r]rAzFakeOsModule.opens6%%dDIv>> <, . ~- B $ $ M)=)M   2:--F6F2F,,ry2;671<RZ'1,2;&!+ 29,1      $ V)> V%&TUU U  ?,,odC ,=,=>>D, 1G1G1M1M /))$//C#}-- "-G6:o6NG)GO225<FFF,S$HH ?99+FF&. # * 2} % % G#bn4FO L O_T    j222 i)>?????  DO$< < < JJtT " " "!!!r_cb|j|}|dS)zClose a file descriptor. Args: fd: An integer file descriptor for the file object requested. Raises: OSError: bad file descriptor. TypeError: if file descriptor is not an integer. N)r` get_open_filer6)rirx file_handles r]r6zFakeOsModule.close*s1o33B77 r_nc|j|}t|trd|_t|t r*|jtj|j | |S)aRead number of bytes from a file descriptor, returns bytes read. Args: fd: An integer file descriptor for the file object requested. n: 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) r`rrrrrrrEBADF file_pathrB)rirxrrs r]rBzFakeOsModule.read7swo33B77 k? 3 3 &!%K  k> 2 2 O O * *5; 8M N N N"""r_contentsctt|j|}t |t r*|jtj|j t |tr| |Sd|_ | || ||t!|S)aWrite string to file descriptor, returns number of bytes written. Args: fd: 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)r rr`rrrrrrrrrMr_sync_ioupdate_flush_posflushlen)rirxrrs r]rMzFakeOsModule.writeLs?DO,I,I",M,MNN k> 2 2 O O * *5; 8M N N N k? 3 3 /$$X.. .! $$&&&(###8}}r_c&tj\}}t|j|d}|j|}||_t|j|d}|j|}||_|j|jfS)NFT)rbpiperr`rr)riread_fdwrite_fd read_wrapperr write_wrappers r]rzFakeOsModule.pipehsGII&tGG ?11,??' '4HH ?11-@@ ( #]%:::r_c|j|}t|tsJ|jS)aCReturn the os.stat-like tuple for the FakeFile object of file_des. Args: fd: 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. )r`r get_objectrr stat_resultcopyrirxrs r]r7zFakeOsModule.fstatrsPo33B77BBDD +x00000&++---r_rcrt|std|jj}||j_|S)zChange the current umask. Args: mask: (int) The new umask value. Returns: The old umask. Raises: TypeError: if new_mask is of an invalid type. r|)rr}r`rJ)rir old_umasks r]rJzFakeOsModule.umasks=4   6455 5O) $r_c  |j|d}n^#t$rQ}|jjr?|jtjkr*ttjdt|zd}~wwxYw|j||j |}ts9|j tzs*|j tj|j||j_dS)aChange current working directory to target directory. Args: path: 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. Tallow_fdzNot a directory: N)r` resolve_pathOSErrorrrrENOTDIRr confirmdirrr)st_moder'rEACCESnamecwd)rirdexc directorys r]r3zFakeOsModule.chdirs ?//t/DDDD   ' NCI,D,Dem-@3t99-LMMM   ""4(((O++D11 yy I!2X!= I O * *5< H H H"s A:A A55A:c4t|jjS)z!Return current working directory.)r#r`rrns r]r9zFakeOsModule.getcwds,---r_c4t|jjS)z*Return current working directory as bytes.)r&r`rrns r]rNzFakeOsModule.getcwdbs+,,,r_c6|j|S)a]Return a list of file names in target_directory. Args: path: 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. )r`r<rirds r]r<zFakeOsModule.listdirs&&t,,,r_rTfollow_symlinks attributerc|jjstdt|tr&|t j}|j||d}|j |S)a;Return 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'Tr) r`is_linuxAttributeErrorrbytesdecoderYgetfilesystemencodingrxattrgetrirdrrfile_objs r]rRzFakeOsModule.getxattrs(' L !JKK K i ' ' F!(()B)D)DEEI?**44*PP~!!),,,r_c|jjstd| |jjn|}|jt t ||d}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'NTr) r`rrrrr r listrkeys)rirdrpath_strrs r]rSzFakeOsModule.listxattrs"' M !KLL L*.,4?&&D?**  " " +   HN''))***r_c|jjstdt|tr&|t j}|j||d}||j vr |j |=dSdS)aRemoves 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'TrN) r`rrrrrrYrrrrs r]rTzFakeOsModule.removexattrs' O !MNN N i ' ' F!(()B)D)DEEI?**44*PP  & &y))) ' &r_rvaluec*|jjstdt|tr&|t j}t|std|j ||d}||j v}|r5||j kr*|j tj|j|s5||jkr*|j tj|j||j |<dS)a'Sets 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 requiredTrN)r`rrrrrrYrr r}rr XATTR_CREATErrENODATArd XATTR_REPLACEEEXIST)rirdrrrrrrs r]rUzFakeOsModule.setxattrs 0' L !JKK K i ' ' F!(()B)D)DEEIe$$ ?=>> >?**44*PPhn,  Iet000 O * *5=(- H H H H%4#555 O * *5< G G G$)y!!!r_.c,t|j|S)aReturn 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. )rr`rs r]rzFakeOsModule.scandir?st---r_toptopdownonerror followlinksc2t|j||||S)aPerform 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. )rr`)rirrrrs r]rzFakeOsModule.walkOs.DOS'7KHHHr_cn|||j|}|j|S)a!Read 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. 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 )rrCr`rirdrs r]rCzFakeOsModule.readlinkhs3 %%dDM6BB''---r_)rrcp|||j|}|j||S)axReturn the os.stat-like tuple for the FakeFile object of entry_path. Args: 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. follow_symlinks: (bool) If `False` and `entry_path` points to a symlink, the link itself is changed instead of the linked object. Returns: The FakeStatResult object corresponding to entry_path. Raises: OSError: if the filesystem object doesn't exist. )rrHr`)rirdrrs r]rHzFakeOsModule.stat{s5.%%dDIv>>##D/:::r_cr|||j|}|j|dS)aReturn the os.stat-like tuple for entry_path, not following symlinks. Args: path: path to filesystem object to retrieve. dir_fd: If not `None`, the file descriptor of a directory, with `path` being relative to this directory. Returns: the FakeStatResult object corresponding to `path`. Raises: OSError: if the filesystem object doesn't exist. Fr)rr=r`rHrs r]r=zFakeOsModule.lstats8 %%dDJ??##D%#@@@r_cr|||j|}|j|dSaRemove 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. Raises: OSError: if path points to a directory. OSError: if path does not exist. OSError: if removal failed. N)rrDr`rs r]rDzFakeOsModule.remove9%%dDK@@ t$$$$$r_cr|||j|}|j|dSr)rrKr`rDrs r]rKzFakeOsModule.unlinkrr_) src_dir_fd dst_dir_fdsrcdstrrc|||j|}|||j|}|j||dS)aSRename 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: src: Path to filesystem object to rename. dst: Path to where the filesystem object will live after this call. src_dir_fd: If not `None`, the file descriptor of a directory, with `src` being relative to this directory. dst_dir_fd: If not `None`, the file descriptor of a directory, with `dst` being relative to this directory. 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) NrrFr`rirr rrs r]rFzFakeOsModule.renamesU@$$S$+zBB$$S$+zBB sC(((((r_oldnewcj|j|\}}|r1|r/|j|s||||||j|\}}|r+|r+ ||dS#t $rYdSwxYwdSdS)aFakes `os.renames`, documentation taken from there. Super-rename; create directories as necessary and delete any left empty. Works like rename, except creation of any intermediate directories needed to make the new pathname good is attempted first. After the rename, directories corresponding to rightmost path segments of the old name will be pruned until either the whole path is consumed or a nonempty directory is found. Note: this function can fail with the new directory structure made if you lack permissions needed to unlink the leaf directory or file. N)r` splitpathrr>rFrEr)rir rheadtails r]renameszFakeOsModule.renamess_..s33 d  D !7!7!=!= MM$    C_..s33 d  D  %%%%%        s B B.-B.c|||j|}|||j|}|j||ddS)aRenames a FakeFile object at old_file_path to new_file_path, preserving all properties. Also replaces existing new_file_path object, if one existed. Arg src: Path to filesystem object to rename. dst: Path to where the filesystem object will live after this call. src_dir_fd: If not `None`, the file descriptor of a directory, with `src` being relative to this directory. dst_dir_fd: If not `None`, the file descriptor of a directory, with `dst` being relative to this directory. 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) force_replaceNr r s r]rOzFakeOsModule.replacesY<$$S$+zBB$$S$+zBB sCt<<<<|jt j|j|n| ||j |\}}|s|j |\}}|rd|rd|j|}|jrdS|j |d|j |\}}|r|`dSdSdSdS)aRemove a leaf fake directory and all empty intermediate ones. Args: name: 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) allow_symlinkN) r` absnormpathrentriesrr ENOTEMPTYrdbasenamerGsplit)rirrrrhead_dirs r]rEzFakeOsModule.removedirs7sM**400O..t44    O * *5?DI)rirrr"s r]r>zFakeOsModule.makedirsks/"  H   tX66666r_fctc t|}n#t$r|}YnwxYw|||jvrtdt |t rt d|jz|j |s_|j |}|j tt|j|S|S)z@Return the path considering dir_fd. Raise on invalid parameters.Nz#dir_fd unavailable on this platformz2%s: Can't specify dir_fd without matching path_str)r!r}supports_dir_fdrrint ValueError__name__rdisabsr`rjoinr rr)rirdr$r open_files r]rzFakeOsModule._path_with_dir_fds #D))DD   DDD   $...)*OPPP$$$  (*-,79??4((  O99&AA y~~9#7#7#9#9::? s  !!lengthcL|j|d}||_dS)aTruncate the file corresponding to path, so that it is length bytes in size. If length is larger than the current size, the file is filled up with zero bytes. Args: path: (str or int) Path to the file, or an integer file descriptor for the file object. length: (int) Length of the file after truncating it. Raises: OSError: if the file does not exist or the file descriptor is invalid. TrN)r`rsize)rirdr-rs r]rzFakeOsModule.truncates,o--dT-BB ! r_c|j|}t|tr ||_dSt tjd)aTruncate the file corresponding to fd, so that it is length bytes in size. If length is larger than the current size, the file is filled up with zero bytes. Args: fd: (int) File descriptor for the file object. length: (int) Maximum length of the file after truncating it. Raises: OSError: if the file descriptor is invalid zInvalid file descriptorN) r`rrrrr/rrr)rirxr-rs r] ftruncatezFakeOsModule.ftruncatesYo33B77BBDD k? 3 3 B%K   %+'@AA Ar_)r effective_idsrr2cf|r|jjrtd|||j|} |||}n.#t $r!}|jtjkrYd}~dSd}~wwxYwtr|tj z}||j dz dzz|kS)aCheck 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. effective_ids: (bool) Unused. Only here to match the signature. follow_symlinks: (bool) If `False` and `path` points to a symlink, the link itself is queried instead of the linked object. Returns: bool, `True` if file is accessible, `False` otherwise. z2access: effective_ids unavailable on this platformrNF) r`rrrr2rHrrENOENTr)rbW_OKr)rirdrrr2rros_errors r]r2zFakeOsModule.accesss0  T_: %D %%dDK@@ ))D/)JJKK   ~--uuuuu   99  RWH D,1Q67D@@sA A>A98A99A>c|s$|j|jvstrtd|||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. follow_symlinks: (bool) If `False` and `path` points to a symlink, the link itself is queried instead of the linked object. z=`follow_symlinks` for chmod() is not available on this systemN)r4supports_follow_symlinksr"rrr`)rirdrrrs r]r4zFakeOsModule.chmodsq$  Jd; ; ;w ;%R %%dDJ?? dD/:::::r_cv|jjrtd|j||ddS)zChange 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 definedFrN)r`r NameErrorr4)rirdrs r]r:zFakeOsModule.lchmodsC ? ( <:;; ; dD%@@@@@r_timesnscz|||j|}|j||||dS)acChange 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. dir_fd: If not `None`, the file descriptor of a directory, with `path` being relative to this directory. follow_symlinks: (bool) If `False` and `path` points to a symlink, the link itself is queried instead of the linked object. 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. )r=r>rN)rrLr`)rirdr=r>rrs r]rLzFakeOsModule.utime sB:%%dDJ?? d%BXXXXXr_uidgidc"|||j|}|j||d}t |t rt |t st d|dkr||_|dkr ||_dSdS)aSet 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. follow_symlinks: (bool) If `False` and path points to a symlink, the link itself is changed instead of the linked object. 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). TrzAn integer is requiredN) rr5r`rrr'r}st_uidst_gid)rirdr@rArrrs r]r5zFakeOsModule.chown*s6%%dDJ??o--dOd-SS #s## 6:c3+?+? 6455 5 "99!$K  "99!$K    9r_devicec|jjrtd| tdz}|s|tzs2t s$|jt j|||j |}|j |\}}|sf|j |dr%|jt j ||jt j||t|dt|dfvr%|jt j||j |dr%|jt j ||j|t#|||jjz|jdS) aCreate a filesystem node named 'filename'. Does not support device special files or named pipes as the real os module does. Args: path: (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 `path` being relative to this directory. Raises: OSError: if called with unsupported options or the file can not be created. z%module 'os' has no attribute 'mknode'NiT) check_linkrz..)r`)r`rrrr)rrEPERMrr@rdrrrr6r$ add_objectrrJ)rirdrrFrrrs r]r@zFakeOsModule.mknodNs6 ? ( J !HII I <U?D  8 8  8 O * *5; 7 7 7%%dDJ??Y__T** d ?%%dt%<< C..u|TBBB O * *5< > > > OD#..d0K0KL L L O * *5< > > > ? ! !$4 ! 8 8 ? O * *5< > > > ""  T44?#8"88T_ U U U     r_target_is_directorycx|||j|}|j||ddS)aCreates the specified symlink, pointed at the specified link target. Args: src: The target of the symlink. dst: Path to the symlink to create. target_is_directory: Currently ignored. dir_fd: If not `None`, the file descriptor of a directory, with `src` being relative to this directory. Raises: OSError: if the file already exists. F)create_missing_dirsN)rrIr`create_symlink)rirr rKrs r]rIzFakeOsModule.symlinks@($$S$,?? &&sCU&KKKKKr_c|||j|}|||j|}|j||dS)a_Create a hard link at new_path, pointing at old_path. Args: src: An existing path to the target file. dst: The destination path to create a new link at. src_dir_fd: If not `None`, the file descriptor of a directory, with `src` being relative to this directory. dst_dir_fd: If not `None`, the file descriptor of a directory, with `dst` being relative to this directory. Raises: OSError: if something already exists at new_path. OSError: if the parent directory doesn't exist. N)rr;r`r s r]r;zFakeOsModule.linksT,$$S$)Z@@$$S$)Z@@ S#&&&&&r_ctd|cxkr tkr'nn$|jtjt t |j|}|jjrCt|dr|j s.|jtj |j dSdSdS)a Perform fsync for a fake file (in other words, do nothing). Args: fd: 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_STREAMSr`rrEINVALr rrrrrQrrrs r]r8zFakeOsModule.fsyncs  # # # #^ # # # # # O * *5< 8 8 8?DO,I,I",M,MNN ? ( S;77 S{?W S..u{K??? >' > <==={{5))HH{{}}H KK   zzdo6z!;;==!;;u-- KK ! ! !  jj**G JJLLLNqr_cT|jjrtdtS)zReturns the user id set in the fake filesystem. If not changed using ``set_uid``, this is the uid of the real system. zname 'getuid' is not defined)r`rr<r*rns r]rXzFakeOsModule.getuid* ? ( <:;; ;yyr_cT|jjrtdtS)zReturns the group id set in the fake filesystem. If not changed using ``set_gid``, this is the gid of the real system. zname 'getgid' is not defined)r`rr<r+rns r]rWzFakeOsModule.getgid rbr_ct}|D]U}t||jr)|t ||j@||V|Srl)setrr)addgetattr)rioriginal_functions functionsfns r]fake_functionszFakeOsModule.fake_functionssjEE $ " "BtR[)) " gdBK889999 b!!!!r_cf|j$||jj|_|jSrl)rerkrcr:rns r]r:z%FakeOsModule.supports_follow_symlinkss6  ) 1-1-@-@7..D *--r_cf|j$||jj|_|jSrl)rfrkrcr&rns r]r&zFakeOsModule.supports_dir_fd%s/  ($($7$78V$W$WD !$$r_cf|j$||jj|_|jSrl)rhrkrc supports_fdrns r]rozFakeOsModule.supports_fd+s/   $ $ 3 3DN4N O OD   r_cf|j$||jj|_|jSrl)rgrkrcsupports_effective_idsrns r]rqz#FakeOsModule.supports_effective_ids1s6  ' /+/+>+>5,,D (++r_c,t|j|S)z5Forwards any unfaked calls to the standard os module.)rgrc)rirs r] __getattr__zFakeOsModule.__getattr__9st~t,,,r_)r`r,rl)r)r)TNF)NNNT)Nr)F)Wr) __module__ __qualname____doc__ use_original staticmethodrrr^rjpropertyrmrqrrsrurwr'r rr~rr rAr6rrBrMr rrr7rJr3r9rNr<rrr%boolrRrSrTrUrrrrCrHr=rDrKrFrrOrGrEr(r?r>rrrr1r2r4r:r floatrLr5r@rIr;r8rQr`rXrWrrkr:r&rorqrsr_r]r/r/Ns   L4c444\4l 0 0 0 0!!!!X!SX     X !!!!X!!!!!X!BBSBCBNBBBB$(# P" !% P"P"P"P"P"sm P"  P" P"P"P"P"d      #s#s#u####*u8;eCHo;;;;......"##$#&#T####0.....------F-tF|---- LMNR----'0-FJ- %----:(,+HL+++V$+AE+ c++++:NR****'0*FJ* ****: %*!%%*%*%*%*%* %*  %*%* %*%*%*%*N..C.+....&"&! II II$ I  IIII2..V.Xc].c.....!% $ ;;;; ;  ;  ;;;;4>BAAA&AXc]AnAAAA&%%6%8C=%D%%%% ?C%%%6%hsm%t%%%%*%)$( ")")") ")") SM ") SM ") ")")")")H6>%)$( = = =  = = SM = SM =  = = = =D>B $ $ $& $Xc] $d $ $ $ $/v/$////8)1MQ"%=Ec] 4)1T777"%7.wrappedEso( @$JtAw ==$8D.wr1:..????1d%f%% %r_) functoolswraps)r~rs` r]handle_original_callr@s:    & & & &   &r__c#fK dt_dVdt_dS#dt_wxYw)zTemporarily use original os functions instead of faked ones. Used to ensure that skipped modules do not use faked calls. TNF)r/rwr|r_r]use_original_osrUs> *$( ! $) !!!E !))))s"0)GrvrrinspectrbrYr contextlibrrHrrtypingrrrr r r r r rrpyfakefs.extra_packagesrpyfakefs.fake_filerrrrrrrpyfakefs.fake_openrrpyfakefs.fake_pathrpyfakefs.fake_scandirrrrpyfakefs.helpersrrr r!r"r#r$r%r&r'r(r)r*r+pyfakefs.fake_filesystemr,rRr/ version_infor getmembers isfunctionrrjr)r[setattrrr|r_r]rs`  %%%%%%                        0/////87777777------<<<<<<<<<<"8777777m-m-m-m-m-m-m-m-`'gX 'G&|W5GHHBBb{%%c** B GL$(<( %* %.. 47 :r!c|j|_|j|_||_|jrdnd|_|jrdnd|_dS)Nnulz /dev/null;:) path_separatorr'alternative_path_separatorr(line_separatorr) is_windows_fsr&r*)clsrKs rrPzFakePathModule.resetusS+:  //11 )7Hee[ '5>cc3 r!pathc6|j|S)zDetermine whether the file object exists within the fake filesystem. Args: path: The path to the file object. Returns: (bool) `True` if the file exists. rKr.rQr\s rr.zFakePathModule.exists}s%%d+++r!c:|j|dS)zTest whether a path exists. Returns True for broken symbolic links. Args: path: path to the symlink object. Returns: bool (if file exists). T) check_linkr^r_s rr:zFakePathModule.lexistss%%dt%<<.getcwd s;$&& (w(((w~~'''r!N)rr4r9rKrZrostarts_with_drive_letterr<)rQr\rcwds`` rr,zFakePathModule.abspath s ( ( ( ( ( ( %%zz$ 099VVXXt,,DD _ * 0t/N/Nt/T/T 0&((C77<< 0yyRaR$//}}T"""r!pc |jj|S)z8Return the completed path with a separator of the parts.)rK joinpaths)rQrs rr9zFakePathModule.joins(t(!,,r!c6|j|S)z?Split the path into the directory and the filename of the path.)rK splitpathr_s rr?zFakePathModule.split"s((...r!c6|j|S)zRSplit the path into the drive part and the rest of the path, if supported.)rKr@r_s rr@zFakePathModule.splitdrive&s))$///r!c6|j|S)z0Normalize path, eliminating double slashes, etc.)rKr<r_s rr<zFakePathModule.normpath+s''---r!cz|j|}|jjr|}|S)zPConvert to lower case under windows, replaces additional path separator.)rKr;rZlowerr_s rr;zFakePathModule.normcase/s8''-- ? ( ::<)rQr\rr' system_sepr(s rr>zFakePathModule.relpath7s9 2011 1%%33D99dDO$BCC  $U++EE#D$/*=>>E44U;;$T4=+<== ? 5 A$T4?+UVVF<< 33DMM&*55E||C,, c:..}$$T511||J,,,r!filenamestrictcN|tjdkrtd|r|j||jjr||St|}||dd|i\}}||}|S)z}Return the canonical path of the specified filename, eliminating any symbolic links encountered in the path. N)rC z6realpath() got an unexpected keyword argument 'strict'r) rrH TypeErrorrKrcrZr,r_join_real_path)rQrrr\oks rr=zFakePathModule.realpathNs  #"2W"<"<WXX X  . O # #H - - - ? ( *<<)) )#H--''! hCCb||D!! r!path1path2c|j|}|j|}|j|jko|j|jkS)aMReturn whether path1 and path2 point to the same file. 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. )rKstatst_inost_dev)rQrrstat1stat2s rrAzFakePathModule.samefile^sK$$U++$$U++|u|+L  0LLr!restseencdSNrQr\rrs rrzFakePathModule._join_real_pathm  r!cdSrrrs rrzFakePathModule._join_real_pathsrr!c Dt|d}t|d}|j|}||r |dd}|}|r?||\}}}|r||kr%||krE|r@|j|\}}||kr|j|||}n|}p|j||} |j| s| }| |vr*|| } | | }|j| |dfSd|| <||t||j | |\}} | s|j||dfS||| <|?|dfS)zJoin two paths, normalizing and eliminating any symbolic links encountered in the second path. Taken from Python source and adapted. .z..rnNFT) rrKget_path_separatorr4 partitionrrr7rreadlink) rQr\rrcurdirpardirr'name_newpath seen_pathrs rrzFakePathModule._join_real_pathys!s++ t,,o0066 ::d   8DD% ! NN3//MD!T 46>>v~~"!%!:!:4!@!@JD$v~~#88vvNN!Do//d;;G?))'22 $ M ($D00$??FF DM++do&>&>w&G&GHHHD"  D00t<r=rAr r rrr-r/r8rrr!rr#r#:s &bg..M3...GXc]C#&*FHXc] #***GXc]GXc]c\@    ???[? ,6 ,d , , , , =F =t = = = = F    $5&5T5555+&+T++++,6,d,,,, ,6 ,d , , , , 7"" 46 4d 4 4 4 4 3& 3 3 3 3 EVEEEEE&!V!!!!!,!V!!!!!&#F#v####(-v-&----/&/U66>%:////0v0%*?0000 .V.....V--F-8F+;-v----.$6 Mf MV M M M M M  " *.sHSM/A*B sDy    X   !& .25(5/3I.J ud{    X 55"(504VXf=M5M0N5 vt| 5555n#F#v#### v &    Ft@,,,,,,,,r!r#win32ceZdZdZedZddZejdkr!de de fd Z de de fd Z de de fd Z de de fd Znde de fd ZdedefdZdS) FakeNtModulezUnder windows, a few function of `os.path` are taken from the `nt` module for performance reasons. These are patched here. c0tjdkrgdSdgS)NrB) _path_exists _path_isfile _path_isdir _path_islink_isdirrGrr!rrJzFakeNtModule.dirs$7**VVVV z!r!rKrc*ddl}||_||_dS)zxInit. Args: filesystem: FakeFilesystem used to provide file system information rN)ntrK nt_module)rQrKrs rrRzFakeNtModule.__init__s III(DO"$DNNNr!rBr\rc6|j|Srrqr_s rrzFakeNtModule._path_isdir,,T222r!c6|j|Srrsr_s rrzFakeNtModule._path_isfile--d333r!c6|j|Srrur_s rrzFakeNtModule._path_islinkrr!c6|j|Srr^r_s rrzFakeNtModule._path_existsrr!c6|j|Srrqr_s rrzFakeNtModule._isdir rr!rc,t|j|S)z3Forwards any non-faked calls to the real nt module.)rrrs rrzFakeNtModule.__getattr__s4>400 0r!N)rKr)rrrrrrJrRrrHr rrrrrrrr rrr!rrrs.    " "  " % % % %  w & & 3 34 3 3 3 3 4 4D 4 4 4 4 4 4D 4 4 4 4 4 4D 4 4 4 4 4  36 3d 3 3 3 3 1C 1C 1 1 1 1 1 1r!r) rrfrOrrrrtypesrtypingrrrr r r r r rrpyfakefs.helpersrrrpyfakefs.fake_filesystemrpyfakefs.fake_osrr r#platformrrr!rrs                          .777777------jZf,f,f,f,f,f,f,f,R <7,1,1,1,1,1,1,1,1,1,1r!__pycache__/fake_pathlib.cpython-311.pyc000064400000136341150043321510014071 0ustar00 bgAdZddlZddlZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddlm Z ddl m Z ddlmZddlmZddlmZddlmZdd lmZdd lmZmZdd lmZd Zd ZdZ dZ! ej"Z#n #e$$re%Z#YnwxYwGdde#Z&e&Z'e j(dkr1ej)Z*Gdde*Z+Gdde+Z,Gdde+Z-Gddej.Z/GddZ0GddZ1Gdd ej.Z2e j(d!krOd"e d#e fd$Z3ej4e2ej5D]0\Z6Z7e68d%se9e2e6e3e71Gd&d'Z:Gd(d)Z;dS)*aA fake implementation for pathlib working with FakeFilesystem. New in pyfakefs 3.0. Usage: * With fake_filesystem_unittest: If using fake_filesystem_unittest.TestCase, pathlib gets replaced by fake_pathlib together with other file system related modules. * Stand-alone with FakeFilesystem: `filesystem = fake_filesystem.FakeFilesystem()` `fake_pathlib_module = fake_filesystem.FakePathlibModule(filesystem)` `path = fake_pathlib_module.Path('/foo/bar')` Note: as the implementation is based on FakeFilesystem, all faked classes (including PurePosixPath, PosixPath, PureWindowsPath and WindowsPath) get the properties of the underlying fake filesystem. N)PurePath)Callable)quote_from_bytes) fake_scandir) use_scandir)FakeFilesystem) FakeFileOpen) FakeOsModuleuse_original_os)IS_PYPYc*|t_tjdkr>t |t j_t|t j _dSt|}|j }|t j_|t j _dS)z6Initializes the fake module with the fake file system. N) FakePath filesystemsys version_info_FakeWindowsFlavourFakePathlibModulePureWindowsPath_flavour_FakePosixFlavour PurePosixPathr path)rfake_os fake_paths f/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/fake_pathlib.py init_moduler5s|%H '!!5H5T5T)23DZ3P3P'000z**L 5>)23<'000c`tjfd}t|S)NcB|jt|g|Ri|SNrstr)pathobjargskwargsstrfuncs r_wrappedz_wrap_strfunc.._wrappedFs.ww)3w<<I$III&IIIr  functoolswraps staticmethodr)r*s` r _wrap_strfuncr0EsF_WJJJJJ  ! !!r c`tjfd}t|S)NcX|jt|t|g|RSr#r$pathobj1pathobj2r'r)s rr*z&_wrap_binary_strfunc.._wrappedN.wx*CMM3x==P4PPPPr r+r/s` r_wrap_binary_strfuncr7MF_WQQQQQ  ! !!r c`tjfd}t|S)NcX|jt|t|g|RSr#r$r3s rr*z._wrap_binary_strfunc_reverse.._wrappedVr6r r+r/s` r_wrap_binary_strfunc_reverser;Ur8r ceZdZdZeejZedZeejZe ree j Z e e dr edZndZdZeejZeejZeejZeejZedZedZd ejkr ed Zejd kred Zd ZeejZeej Z dS) _FakeAccessorzQAccessor which forwards some of the functions to FakeFilesystem methods. c0tj||dSNF)follow_symlinks)rstat)fsrs rz_FakeAccessor.ks,RuMMMr lchmodc2tj|||dSr?)rchmod)rBrmodes rrCz_FakeAccessor.us!>#7D$$$$r c td)z+Raises not implemented for Windows systems.z%lchmod() not available on this systemNotImplementedErrorselfr&r'r(s rrDz_FakeAccessor.lchmod{s%&MNN Nr cd|vrUtjdkrtd|ds.tjtjvst rtd|jjt|g|Ri|S)Nr@r zs!~'< ($( ( ( r c2tj|||dS)NF)create_missing_dirs)rcreate_symlink)rBfpathtarget target_is_dirs rrCz_FakeAccessor.s!1N v52 2 2 r )rc.tj|||Sr#rlinkrB file_path link_targets rrCz_FakeAccessor.~/BI{00r rNc.tj|||Sr#r`rbs rrCz_FakeAccessor.rer c(tjSr#)rQgetcwdrLs rrhz_FakeAccessor.getcwds9;; r N)!__name__ __module__ __qualname____doc__r0rrAlstatlistdirrrscandirhasattrrQrDrFmakedirmkdirremoveunlinkrmdirr7rUreplacer;symlinkrrlink_torarhreadlinkutimer rr=r=cs =, - -D MMM  EmN233G6- 455wr8 O     O O O G G G M.0 1 1E ]>0 1 1F M.. / /E ! !."7 8 8F""  G +*  G !!!&&      7""##       }^455H M.. / /EEEr r=rcFeZdZdZdZdZdZdZdZde e de dd zDd e e d e d d zDzZ fd Z e efdZdZe dZddZdZdZdZdZdZdZxZS) _FakeFlavourz9Fake Flavour implementation used by PurePath and _FlavourN/Fz\\?\c,h|]}t|Sr|chr.0xs r z_FakeFlavour.sGGGAQGGGr azc,h|]}t|Sr|rrs rrz_FakeFlavour.s1K K K CFFK K K r AZc||_|j|_|j|_|j|_tt| dSr#) rpath_separatorsepalternative_path_separatoraltsep is_windows_fshas_drvsuperr~__init__)rLr __class__s rrz_FakeFlavour.__init__sJ(DO!0DH$?DK%3DL , % % . . 0 0 0 0 0r cd}||rC|dd}|dd}|dr||ddz }d|ddz}||fS)NzUNC\r\) startswith)r ext_prefixprefixs r_split_extended_pathz!_FakeFlavour._split_extended_pathsvFz** +bqbABBx??7+++d2A2h&F$qrr(?D4< r c|dd}|dd}||kr3||kr-||\}}|dd}|dd}nd}|dd}||kr||kr||kr||d}|dkrl|||dz}||dzkrJ|dkrt|}|r||d|z|||dzdfS|d||||dzdfSdx} } |dkr||jvr|dd} |dd}|}||kr|} ||}|| z| |fS)Nrrrr:)rfindlen drive_letterslstrip) rLrrfirstsecondrthirdindexindex2drvroots r_splitroot_with_drivez"_FakeFlavour._splitroot_with_drives1IE!A#YF}}# $88>> QqS ac1IE}}#%3,,  #q))B;;!YYsEAI66F**!R<<%(YYF!T#)D6N#:CfqjllAS#SS#GVG}c4 3EEEOC$}}$*z/_FakeFlavour.casefold_parts..s 111a 111r )rrrLpartss rcasefold_partsz_FakeFlavour.casefold_partss(, 21151111Lr cjifd|rdn jj}|t |pS)Nc| rd}| D]}|r|dkr |dkr| \}}}+| z|z}|vr|}|Btd|z j|}d|<||}||<#t $r$}|jtjkr r|}Yd}~d}~wwxYw|S)Nr.z..zSymlink loop from %r) rsplit rpartition RuntimeErrorrrzOSErrorerrnoEINVAL) rrestname_newpathr\e_resolveseenrLrstricts rrz-_FakeFlavour._resolve_posix.._resolve&s;??3''D JJsOO--D!43;; t||%)__S%9%9 a "Sj4/G$#G}+$++AG+KLLL -!%!9!9'!B!B)-W 'xf55(,W #'''7el22v2! ' ' sB44 C">CC"r)r is_absolutercwdr%)rLrrbaserrrs` ` @@@r_resolve_posixz_FakeFlavour._resolve_posix"s(CD$ $ $ $ $ $ $ $ $ P))++D221DD8D#d)),,3 3r ct|}|stjSd}|rY|j|s%|jt j||j|S |j|}||S|j |tj |S#t$r%|}|j |d}YnwxYw)NTr)r%rQrhrexistsraise_os_errorrENOENT resolve_path joinpathsrbasenamer splitpath)rLrr previous_ss r_resolve_windowsz_FakeFlavour._resolve_windowsQst99D #y{{"J --d33GO225<FFF33D999  #;;DAA &-#'K#88 "'"2"2:">">   #BBB%) #88>>qAB sC,D D cr|jjr|||S|||S)z/Make the path absolute, resolving any symlinks.)rrrr)rLrrs rresolvez_FakeFlavour.resolvehs;, ;,,T6:::&&tV44 4r c(|sR tjdS#t$r2ddl}|tjjcYSwxYwddl} ||jS#t$rtd|zwxYw).Return the home directory of the current user.HOMErN%Can't determine home directory for %r rQenvironKeyErrorpwdgetpwuidgetuidpw_dirgetpwnamrrLusernamers r gethomedirz_FakeFlavour.gethomedirn <:f--<<<JJJ<< 44;;;;<  <<1188&BXM9AAA44Br#)rjrkrlrmrrrrext_namespace_prefixrangeordrrr.rrrrrrrrrr __classcell__)rs@rr~r~sGG (GGss3xxSA)F)FGGGK K !E##c((CCHHqL99K K K   1 1 1 1 1 2F     $ ,$ ,$ ,L  $ $  $ 4 4 4 4        - 4- 4- 4^   . 5 5 5        r r~ceZdZdZhddeddDzdeddDzZeZdZdZ d Z d Z d S) rzFlavour used by PureWindowsPath with some Windows specific implementations independent of FakeFilesystem properties. >AUXCONNULPRNch|]}d|zS)zCOM%dr|ris rrz_FakeWindowsFlavour.111qw{111r rrOch|]}d|zS)zLPT%dr|rs rrz_FakeWindowsFlavour.rr c|sdS|jjr|ddrdS|ddd|jvS)z=Return True if the path is considered reserved under Windows.Fr\\rr)rrr partitionupperreserved_namesrs r is_reservedz_FakeWindowsFlavour.is_reservedsm u, q1D1DV1L1L u9&&s++A.4466$:MM Mr cj|j}t|dkrc|ddkrW|ddd}d|dt |dSdt |dzS) z$Return a file URI for the given pathrrrNrzfile:///zutf-8zfile:)driveras_posixrurlquote_from_bytesencode)rLrrrs rmake_uriz_FakeWindowsFlavour.make_uris JE5zzQ58s??}}qrr*11#66EE' G(<(<=== !4T]]__5K5KG5T5T!U!UUUr cdtjvrtjd}nzdtjvrtjd}nYdtjvr< tjd}n#t$rd}YnwxYw|tjdz}ntd|rtjd|kr||f\}}}|dtjdkrtd |z||d<|s|r$||z||d d z}n||}|S) rr USERPROFILEHOMEPATH HOMEDRIVErzCan't determine home directoryUSERNAMErrrN)rQrrr parse_partsjoin)rLruserhomerrrs rrz_FakeWindowsFlavour.gethomedirs\##:f-"*,,:m4rz))*[1CCCCCJ!77"#CDDD 4 :j)X55'+'7'7 'D'D$CuRyBJz$:::*FQ!)E"I4d4#&: %)0D0D#D#'99U#3#3OsA%% A43A4cntjtj|tjjSr#)recompilefnmatch translate IGNORECASE fullmatchrLpatterns rcompile_patternz#_FakeWindowsFlavour.compile_patterns$:g/88"-HHR Rr N) rjrkrlrmrrntpathpathmodrr rrr|r rrrs  ) ( (11EE!RLL111 211EE!RLL111 2   N N N V V V"! ! ! F S S S S Sr rc.eZdZdZeZdZdZdZdZ dS)rzFlavour used by PurePosixPath with some Unix specific implementations independent of FakeFilesystem properties. cdS)NFr|rs rrz_FakePosixFlavour.is_reserveds5r cDt|}dt|zS)Nzfile://)bytesr)rLrbpaths rr z_FakePosixFlavour.make_uris#$KKE25999 9r c(|sR tjdS#t$r2ddl}|tjjcYSwxYwddl} ||jS#t$rtd|zwxYw)Nrrrrrs rrz_FakePosixFlavour.gethomedirrrcXtjtj|jSr#)rrrrrrs rrz!_FakePosixFlavour.compile_patterns :g/8899C Cr N) rjrkrlrm posixpathrrr rrr|r rrrsf      : : :    & D D D D Dr rcBeZdZdZdZdZejdddkredZ edZ ejdkrdd Z d Z ed Z ejd krdd ZddZdZd dZdZd!dZedZdZdZdZd"dZejd kr dZdZdSdS)#rzReplacement for pathlib.Path. Reimplement some methods to use fake filesystem. The rest of the methods work as they are, as they will use the fake accessor. New in pyfakefs 3.0. Nc|tjur$|jjr tjn tj}t jdkr||St |S))Creates the correct subclass based on OS.r) rPathrr WindowsPath PosixPathrr _from_partsobject__new__clsr'r(s rr.zFakePath.__new__sh #( ( (>/1!--&0   g % %??4(( (>>#&& &r rrNct|}|||\}}}||_||_||_|Sr#)r-r._init _parse_args_drv_root_parts)r0r'rLrrrs rr,zFakePath._from_partssT>>#&&D JJLLL#//55 CuDIDJDKKr ct|}||_||_||_||Sr#)r-r.r4r5r6r2)r0rrrrLs r_from_parsed_partszFakePath._from_parsed_partss:>>#&&DDIDJDK JJLLLKr )r c,t|_d|_dS)z#Initializer called from base class.FN)_fake_accessor _accessor_closed)rLtemplates rr2zFakePath._init(s,DN DLLLr c t|S)zSReturns the underlying path string as used by the fake filesystem. )r%ris r_pathzFakePath._path/s4yyr c,||jjS)zjReturn a new path pointing to the current working directory (as returned by os.getcwd()). )rr)r0s rrz FakePath.cwd5s s3>%&&&r rcrtjdkr|d}n|tdd}||j||}|5|t|}|j |}t|S)aMake the path absolute, resolving all symlinks on the way and also normalizing it (for example turning slashes into backslashes under Windows). Args: strict: If False (default) no exception is raised if the path does not exist. New in Python 3.6. Raises: OSError: if the path doesn't exist (strict=True or Python < 3.6) )rNFz5resolve() got an unexpected keyword argument 'strict'T)r) rrrP_raise_on_closedrrrAr%absoluter absnormpathr)rLrrs rrzFakePath.resolve>s6))>"F%#O  ! ! # # #=((V)D| 4==??++?..t44DD>> !r rrc|t|j||||||S)zOpen the file pointed by this path and return a fake file object. Raises: OSError: if the target object is a directory, the path is invalid or permission is denied. )rDr rr@)rLrG bufferingencodingerrorsnewlines ropenz FakePath.open^sI ,|DO,, JJLL$ 8VW   r ct|j|d5}|cdddS#1swxYwYdS)zOpen the fake file in bytes mode, read it, and close the file. Raises: OSError: if the target object is a directory, the path is invalid or permission is denied. rbrGNr rr@read)rLfs r read_byteszFakePath.read_bytesjs+\$/ * * JJLLt     6688                  sAAAct|j|d||5}|cdddS#1swxYwYdS)zO Open the fake file in text mode, read it, and close the file. rG)rGrJrKNrQ)rLrJrKrSs r read_textzFakePath.read_textvs+\$/ * * JJLLsXf     6688                  sAAAct|}t|j|d5}||cdddS#1swxYwYdS)a Open the fake file in bytes mode, write to it, and close the file. Args: data: the bytes to be written Raises: OSError: if the target object is a directory, the path is invalid or permission is denied. wbrPN) memoryviewr rr@write)rLdataviewrSs r write_byteszFakePath.write_bytess$ *\$/ * * JJLLt    ! 774== ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !sA##A'*A'clt|tstd|jjz|t jdkrtdt|j| d|||5}| |cdddS#1swxYwYdS)atOpen the fake file in text mode, write to it, and close the file. Args: data: the string to be written encoding: the encoding used for the string; if not given, the default locale encoding is used errors: (str) Defines how encoding errors are handled. newline: Controls universal newlines, passed to stream object. New in Python 3.10. Raises: TypeError: if data is not of type 'str'. OSError: if the target object is a directory, the path is invalid or permission is denied. zdata must be str, not %sNrNz9write_text() got an unexpected keyword argument 'newline'w)rGrJrKrL) isinstancer%rPrrjrrr rr@rZ)rLr[rJrKrLrSs r write_textzFakePath.write_texts $$$ R69PPQQ Q  3#3g#=#=N +\$/ * * JJLL     ! 774== ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !sB))B-0B-c0tjd}|jjtjdkkrtj|d}|jjr"tjdd|}n tjd|}|j|s|j ||| tj |jj S)zrReturn a new path pointing to the user's home directory (as returned by os.path.expanduser('~')). ~ntrzC:Usershome) rQr expanduserrrrrrr create_dirrwrr)r0rfrs rrfz FakePath.homes w!!#&& > 'BGtO < <w}}T**1-H~+ 6w||D'8<<w||FH55>((.. 0))$///s4<<(EFFGGGr c|} |}n*#t$r|j|}YnwxYw|j|jko|j|jkS)a/Return whether other_path is the same or not as this file (as returned by os.path.samefile()). Args: other_path: A path object or string of the file object to be compared with Raises: OSError: if the filesystem object doesn't exist. )rAAttributeErrorrst_inost_dev)rL other_pathstother_sts rsamefilezFakePath.samefilesxYY[[ 8!((HH 8 8 8++J77HHH 8yHO+L X_0LLs+$AActtj|tjj|jjS)zkReturn a new path with expanded ~ and ~user constructs (as returned by os.path.expanduser) ) rrQrrgr@rwrrrris rrgzFakePath.expandusersO G  tzz|| , , 4 4 T_;     r cdtjdkr|jr|dSdSdS)N)r )rrr= _raise_closedris rrDzFakePath._raise_on_closeds=  f $ $ $     % $ $ $r Tc||rk|r0|j|ddS|jt j|dS|d}| | |dS)aCreate a fake file for the path with the given access mode, if it doesn't exist. Args: mode: the file mode for the file if it does not exist exist_ok: if the file already exists and this is True, nothing happens, otherwise FileExistError is raised Raises: FileExistsError: if the file exists and exits_ok is False. N)timesr_) rDrrr{r@rrEEXISTrMcloserF)rLrGexist_ok fake_files rtouchzFakePath.touchs  ;;==  K%%djjll$%?????..u|TZZ\\JJJJJ #I OO    JJt     r c|jjr|jo|jStj|Sr#)rrrrrQrisabsr@ris rrzFakePath.is_absolutes:, 0z/di/7==.. .r cT|jjr|jsdS|jddrdS|jdddddd}|tjvS)NFrrrrr ) rr_tailrrrstriprpathlib_WIN_RESERVED_NAMESrLrs rrzFakePath.is_reserveds?0   uz!}''// u:b>++C003==cBB1ELLSQQD::<<7#>> >r r#)rGrNNN)NN)NNN)ruT)rjrkrlrmrr.rr classmethodr,r8r2r@rrrMrTrVr]rarfrprgrDr|rrr|r rrrsJ ' ' ' w&&           '!! ! ! ! ! ''['  '!! " " " "@         ! ! !!!!!> H H[ HMMM$   !!!. 7""  / / /  ? ? ? ? ?#"r rceZdZdZdZGddeZGddeZGddeeZ Gd d eeZ eZ d Z d S) raaUses FakeFilesystem to provide a fake pathlib module replacement. Can be used to replace both the standard `pathlib` module and the `pathlib2` package available on PyPi. You need a fake_filesystem to use this: `filesystem = fake_filesystem.FakeFilesystem()` `fake_pathlib_module = fake_filesystem.FakePathlibModule(filesystem)` c<t|t|_dS)z Initializes the module with the given filesystem. Args: filesystem: FakeFilesystem used to provide file system information N)rr_pathlib_modulerLrs rrzFakePathlibModule.__init__s  J&r ceZdZdZdZdS)FakePathlibModule.PurePosixPathzLA subclass of PurePath, that represents non-Windows filesystem pathsr|Nrjrkrlrm __slots__r|r rrrs   r rceZdZdZdZdS)!FakePathlibModule.PureWindowsPath@A subclass of PurePath, that represents Windows filesystem pathsr|Nrr|r rrr"NN r rc(eZdZdZdZdZdZdZdS)FakePathlibModule.WindowsPathzjA subclass of Path and PureWindowsPath that represents concrete Windows filesystem paths. r|c td)Nz*Path.owner() is unsupported on this systemrIris rownerz#FakePathlibModule.WindowsPath.owner.%&RSS Sr c td)Nz*Path.group() is unsupported on this systemrIris rgroupz#FakePathlibModule.WindowsPath.group1rr c td)Nz-Path.is_mount() is unsupported on this systemrIris ris_mountz&FakePathlibModule.WindowsPath.is_mount4s%&UVV Vr N)rjrkrlrmrrrrr|r rr*r's]    T T T T T T W W W W Wr r*c"eZdZdZdZdZdZdS)FakePathlibModule.PosixPathzlA subclass of Path and PurePosixPath that represents concrete non-Windows filesystem paths. r|clddl}||jjS)zReturn the username of the file owner. It is assumed that `st_uid` is related to a real user, otherwise `KeyError` is raised. rN)rrrAst_uidpw_name)rLrs rrz!FakePathlibModule.PosixPath.owner>- JJJ<< 233; ;r clddl}||jjS)zReturn the group name of the file group. It is assumed that `st_gid` is related to a real group, otherwise `KeyError` is raised. rN)grpgetgrgidrAst_gidgr_name)rLrs rrz!FakePathlibModule.PosixPath.groupGrr N)rjrkrlrmrrrr|r rr+r7sC    < < < < < < < >#&& &r N)rjrkrlrmrrrQrr_WindowsFlavour _PosixFlavourrrr%r.r|r rrrls  '!!w$ $G # % % %&&((   W__66) ' ' ' ' 'r rrNrSreturncFtjfd}|S)zuDecorator used for real pathlib Path methods to ensure that real os functions instead of faked ones are used.cdt5|i|cdddS#1swxYwYdSr#)r )r'r(rSs rwrappedz!with_original_os..wrappeds "" * *q$)&)) * * * * * * * * * * * * * * * * * *s %)))r,r-)rSrs` rwith_original_osrs:    * * * *   *r __c>eZdZdZdZedZdZdZdZ dS)RealPathlibPathModulezAPatches `pathlib.Path` by passing all calls to RealPathlibModule.Nc,t|tSr#rrs rrz'RealPathlibPathModule.__instancecheck__s(H---r cH|jt|j_dSdSr#) real_pathlibrrris rrzRealPathlibPathModule.__init__s)   $*;*=*=DN ' ' ' % $r ct|i|Sr#)rrs rrzRealPathlibPathModule.__call__s((((r c6t|jj|Sr#)rrr)rs rrz!RealPathlibPathModule.__getattr__rr ) rjrkrlrmrrrrrrr|r rrrseKKL..[. >>>)))55555r rceZdZdZdZGddeZGddeZej dkrGdd e eZ nGd d e eZ e Z d Zd S)rzUsed to replace `pathlib` for skipped modules. As the original `pathlib` is always patched to use the fake path, we need to provide a version which does not do this. ct|_dSr#)rrris rrzRealPathlibModule.__init__s&r ceZdZdZdZdS)RealPathlibModule.PurePosixPathz>A subclass of PurePath, that represents Posix filesystem pathsr|Nrr|r rrrsLL r rceZdZdZdZdS)!RealPathlibModule.PureWindowsPathrr|Nrr|r rrrrr rwin32ceZdZdZdZdS)RealPathlibModule.WindowsPathzrA subclass of Path and PureWindowsPath that represents concrete Windows filesystem paths. r|Nrr|r rr*r  IIIr r*ceZdZdZdZdS)RealPathlibModule.PosixPathztA subclass of Path and PurePosixPath that represents concrete non-Windows filesystem paths. r|Nrr|r rr+rrr r+c,t|j|Srrrs rrzRealPathlibModule.__getattr__rr N)rjrkrlrmrrrrrplatformrr*r+r)rr|r rrrs ''' (  |w     (O         -    D33333r r)rs!$   @@@@@@!!!!!!//////333333++++++::::::::$$$$$$ = = = """"""""" HHHHHS0S0S0S0S0HS0S0S0lgGAAAAAwAAAFOSOSOSOSOSlOSOSOSb$D$D$D$D$DL$D$D$DNL?L?L?L?L?w|L?L?L?^L3L3L3L3L3L3L3L3^........*'''''w|''':g H     'G&x1CDD::bt$$ : GHd$4$4R$8$8 9 9 955555555,)3)3)3)3)3)3)3)3)3)3s0A88BB__pycache__/fake_scandir.cpython-311.pyc000064400000034717150043321510014075 0ustar00 bg;,dZddlZddlZddlmZddlmZmZejdkrej Z ne Z Gdde Z Gdd Z dd Zd ZddZGddZdS)zA fake implementation for the `scandir` function working with FakeFilesystem. Works with both the function integrated into the `os` module since Python 3.5 and the standalone function available in the standalone `scandir` python package. N)use_scandir_package) to_stringmake_string_pathc~eZdZdZdZdZddZddZdZddZ e j d krd Z e j d krd e fd ZdSdS)DirEntryzNEmulates os.DirEntry. Note that we did not enforce keyword only arguments.c||_d|_d|_d|_d|_d|_d|_d|_d|_dS)zInitialize the dir entry with unset values. Args: filesystem: the fake filesystem used for implementation. NF) _filesystemnamepath_abspath_inode_islink_isdir _statresult_statresult_symlinkself filesystems f/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/fake_scandir.py__init__zDirEntry.__init__#sL &      #'   cJ|j|d|jS)z%Return the inode number of the entry.NF)follow_symlinks)rstatrs rinodezDirEntry.inode3s& ;  IIeI , , ,{rTc$|jo |p|j S)aReturn True if this entry is a directory entry. Args: follow_symlinks: If True, also return True if this entry is a symlink pointing to a directory. Returns: True if this entry is an existing directory entry, or if follow_symlinks is set, and this entry points to an existing directory entry. rrrrs ris_dirzDirEntry.is_dir9s{D Ct|3CDrc&|j o |p|j S)aReturn True if this entry is a regular file entry. Args: follow_symlinks: If True, also return True if this entry is a symlink pointing to a regular file. Returns: True if this entry is an existing file entry, or if follow_symlinks is set, and this entry points to an existing file entry. r"r#s ris_filezDirEntry.is_fileGs;HO$G4<7GHrc|jS)z>Return True if this entry is a symbolic link (even if broken).)rrs r is_symlinkzDirEntry.is_symlinkUs |rc|rc|jU|j|j}|j|_|jjr d|j_|jS|ja|j |j}|j |_ |j|_|jjr d|j_|jS)zReturn a stat_result object for this entry. Args: follow_symlinks: If False and the entry is a symlink, return the result for the symlink, otherwise for the object it points to. Nr) rr resolver stat_resultcopy is_windows_fsst_nlinkrlresolvest_inor)rr file_objects rrz DirEntry.statYs  ,'/".66t}EE +6+B+G+G+I+I(#1:89D,5+ +   #*33DMBBK%,DK*6;;==D - .,- )rrc|jSN)rrs r __fspath__zDirEntry.__fspath__rs 9 r)r returncj|jjsdS|j|j}|jS)z`Return True if this entry is a junction. Junctions are not a part of posix semantic.F)r r-r*r is_junction)rr1s rr8zDirEntry.is_junctionws8#1 u*224=AAK* *rN)T)__name__ __module__ __qualname____doc__rr r$r&r(rsys version_infor4boolr8rrr r s(((  E E E E I I I I    . 6!!    7"" + + + + + + +#"rr cPeZdZdZdZdZdZejdkr dZ dZ dZ d Sd S) ScanDirIterzEIterator for DirEntry objects returned from `scandir()` function.cB||_t|trts+tjdks |jjrtd|j|j | j |_ d|_ nBt|}|j||_ t||_ |j|j j}t#||_dS)N)rz6scandir does not support file descriptor path argumentr )r isinstanceintrr=r>r-NotImplementedError absnormpath get_open_file get_objectrabspathrr confirmdirentriesiter entry_iter)rrrrMs rrzScanDirIter.__init__s$ dC  (&  6))T_-J))O ?66--d33>>@@EDLDII#D))D?66t<rZr`r\r@rrrBrBs(((( 6!!           "!rrBr c"t||S)aReturn an iterator of DirEntry objects corresponding to the entries in the directory given by path. Args: filesystem: The fake filesystem used for implementation 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. )rB)rrs rscandirrcs z4 ( ((rcg}g}||D]V}||||r||A||W|||fS)aTClassify contents of a directory as files/directories. Args: filesystem: The fake filesystem used for implementation root: (str) Directory to examine. Returns: (tuple) A tuple consisting of three values: the directory examined, a list containing all of the directory entries, and a list containing all of the non-directory entries. (This is the same format as returned by the `os.walk` generator.) Raises: Nothing on its own, but be ready to catch exceptions generated by underlying mechanisms like `os.listdir`. )listdirrUrTappend)rrootdirsfilesrWs r_classify_directory_contentsrjs" D E##D))     J00u== > > KK     LL     u rTFcTdfd t|dS)aPerform an os.walk operation over the fake filesystem. Args: filesystem: The fake filesystem used for implementation 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. Fc3lK|s s|rdS t|}n&#t$r}d}  |Yd}~nd}~wwxYw|Y r|V|dD]B}||} s|r0|D]}|VC s|VdSdSdS)N)rVrjOSErrorrT) top_dirtop_most top_contentsexc directoryrcontentsdo_walkr followlinksonerrortopdowns rruzwalk..do_walks9    0A0A'0J0J  F 7 GLLLL   L"    # #"""")!_ # # !++GY??"z'8'8'>'> ' ##H"NNNN# #"""""" $ # # #s1 AAAT)rp)F)r)rtoprxrwrvrus` ```@rwalkrzsV&##########. 79S>>D 1 1 11rc>eZdZdZedZdZd dZd d ZdS) FakeScanDirModuleaUses FakeFilesystem to provide a fake `scandir` module replacement. .. Note:: The ``scandir`` function is a part of the standard ``os`` module since Python 3.5. This class handles the separate ``scandir`` module that is available on pypi. You need a fake_filesystem to use this: `filesystem = fake_filesystem.FakeFilesystem()` `fake_scandir_module = fake_filesystem.FakeScanDirModule(filesystem)` cdS)zqReturn the list of patched function names. Used for patching functions imported from the module. )rcrzr@r@rrdirzFakeScanDirModule.dirs ! rc||_dSr3)rrs rrzFakeScanDirModule.__init__s $r.c,t|j|S)aReturn 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. )rcr)rrs rrczFakeScanDirModule.scandir!st---rTNFc2t|j||||S)aPerform a 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. )rzr)rryrxrwrvs rrzzFakeScanDirModule.walk1s"DOS'7KHHHr)rTNF) r9r:r;r< staticmethodr~rrcrzr@rrr|r| sv  !!\! %%%.... IIIIIIrr|)r r)r<osr=pyfakefs.extra_packagesrpyfakefs.helpersrrr>PathLike BaseClassobjectr rBrcrjrzr|r@rrrs9  77777788888888v III^+^+^+^+^+y^+^+^+B........b))))$6*2*2*2*2Z7I7I7I7I7I7I7I7I7I7Ir__pycache__/helpers.cpython-311.pyc000064400000050467150043321510013126 0ustar00 bgy3dZddlZddlZddlZddlZddlZddlZddlZddlmZddlm Z ddl m Z m Z m Z mZmZmZe eefZe eejfZejdkZejdkZejdZd Zd Zd Zd Zd Z dZ!ejdkrda"da#nej$a"ej%a#de&fdZ'de&ddfdZ(de&fdZ)de&ddfdZ*d6dZ+de,fdZ-de de,fdZ.de de,fdZ/de de,fdZ0ededefdZ1edejdefdZ1dedefd Z1d!e ee eeffdefd"Z2d!e ee eeffdefd#Z3d$ed%edefd&Z4d'e ede efd(Z5d)Z6ed*ed+edefd,Z7ed*ed+edefd-Z7ed*ed+dddfd.Z7d*ed+e ede efd/Z7Gd0d1Z8Gd2d3ej9Z:Gd4d5ej;ZpCrcdSr<rr=s rr>r>ur?rcPtttj|Sr<)r r r'fspathr=s rr>r>zs  (++ , ,,rpathc~t|tr'|tjdS|S)zzReturn the string representation of a byte string using the preferred encoding, or the string itself if path is a str.F)r/bytesdecodelocalegetpreferredencodingrCs r to_stringrJ~s8$?{{66u==>>> Krctt|tr"t|tjdS|S)zReturn the bytes representation of a string using the preferred encoding, or the byte string itself if path is a byte string.F)r/strrErGrHrIs rto_bytesrMs6$?T66u==>>> Krs1s2c ||zS)z!?!?!%!2!%!2rotherrclt|to|j|jko|j|jko|j|jkoo|j|jko_|j|jkoO|j|jko?|j|jko/|j |j ko|j |j ko|j |j kSr<) r/rdrrrtrsst_sizerprornrmrlrkrurws r__eq__zFakeStatResult.__eq__s un - - .!U%77 .!U%77 .!U%77 .  - .  u|+ .  u|+ . / . u|+ . u|+ .  - rc||k Sr<rrzs r__ne__zFakeStatResult.__ne__s5=  rc$t|}|S)ztReturn a copy where the float usage is hard-coded to mimic the behavior of the real os.stat_result. rru stat_results rrzFakeStatResult.copys4jj rrc|j|_|j|_|j|_|j|_|j|_|j|_|j |_ dS)zSet values from a real os.stat_result. Note: values that are controlled by the fake filesystem are not set. This includes st_ino, st_dev and st_nlink. N) rkrorpryrq st_atime_nsrr st_mtime_nsrs st_ctime_nsrtrs rset_from_stat_resultz#FakeStatResult.set_from_stat_resultsS #* !( !( #+ '3'3'3rc|jdz S)z$Return the creation time in seconds.rjrtrus rst_ctimezFakeStatResult.st_ctime 3&&rr-c4t|dz|_dS)z!Set the creation time in seconds.rjN)r0rtrur-s rrzFakeStatResult.st_ctime c NNrc|jdz S)z"Return the access time in seconds.rjrrrs rst_atimezFakeStatResult.st_atimerrc4t|dz|_dS)zSet the access time in seconds.rjN)r0rrrs rrzFakeStatResult.st_atime rrc|jdz S)z(Return the modification time in seconds.rjrsrs rst_mtimezFakeStatResult.st_mtimerrc4t|dz|_dS)z%Set the modification time in seconds.rjN)r0rsrs rrzFakeStatResult.st_mtimerrcR|jtztkr |jrdS|jS)Nr)rkrrerqrs rryzFakeStatResult.st_sizes( <' !W , , ,1}rc||_dSr<)rqrs rryzFakeStatResult.st_sizes  rcx|jrtdd}|dz}|j|z}|j|zr|dz }||zS)aReturn the number of 512-byte blocks allocated for the file. Assumes a page size of 4096 (matches most systems). Ignores that this may not be available under some systems, and that the result may differ if the file has holes. z4'os.stat_result' object has no attribute 'st_blocks'iir)reAttributeErrorrq)ru page_sizeblocks_in_pagepagess r st_blockszFakeStatResult.st_blocks#s\ ? Y !WXX X "c) * =9 $  QJE~%%rcN|jstdd}|j}|tjzr|tjz}|tjzr|tjz}|tjtj zzr|tj z}|tj zr|tj z}|S)Nz=module 'os.stat_result' has no attribute 'st_file_attributes'r) rerrkstatS_IFDIRFILE_ATTRIBUTE_DIRECTORYS_IFREGFILE_ATTRIBUTE_NORMALS_IFCHRS_IFBLKFILE_ATTRIBUTE_DEVICErFILE_ATTRIBUTE_REPARSE_POINT)rumoderks rst_file_attributesz!FakeStatResult.st_file_attributes3s  R , T\ ! 2 D1 1D T\ ! / D. .D dlT\1 2 / D. .D T\ ! 6 D5 5D rc|jrtjdkrtd|jt jzr t jSdS)N)rTz9module 'os.stat_result' has no attribute 'st_reparse_tag'r)rer%rVrrkrrIO_REPARSE_TAG_SYMLINKrs rst_reparse_tagzFakeStatResult.st_reparse_tagEsO #"2V";"; N  <$, & /. .qritemcddl}||jkr|jS||jkr|jS||jkr|jS||jkr|jS||j kr|j S||j kr|j S||j kr|jS||jkrt!|jS||jkrt!|jS||jkrt!|jSt-d)z9Implement item access to mimic `os.stat_result` behavior.rNz Invalid item)rST_MODErkST_INOrlST_DEVrmST_NLINKrnST_UIDroST_GIDrpST_SIZEryST_ATIMEr0rST_MTIMErST_CTIMEr ValueError)rurrs r __getitem__zFakeStatResult.__getitem__Os 4<  <  4;  ;  4;  ;  4= = 4;  ;  4;  ;  4<  <  4= t}%% % 4= t}%% % 4= t}%% %(((rc|jS)z&Return the access time in nanoseconds.rrs rrzFakeStatResult.st_atime_nsj   rc||_dS)z#Set the access time in nanoseconds.Nrrs rrzFakeStatResult.st_atime_nso rc|jS)z,Return the modification time in nanoseconds.rrs rrzFakeStatResult.st_mtime_nstrrc||_dS)z:Set the modification time of the fake file in nanoseconds.Nrrs rrzFakeStatResult.st_mtime_nsyrrc|jS)z(Return the creation time in nanoseconds.rrs rrzFakeStatResult.st_ctime_ns~rrc||_dS)z6Set the creation time of the fake file in nanoseconds.Nrrs rrzFakeStatResult.st_ctime_nsrrr<)rrd)__name__ __module__ __qualname____doc__boolr0rfloatrvrr{r}rr'rrpropertyrrsetterrrryrrrrrrrrrrrdrds)- 3333 3 uo 3333&  C  D     !C!D!!!! 4 44 4 4 4 4'%U +'''X'_+E#u*-+$+++_+'%U +'''X'_+E#u*-+$+++_+'%U +'''X'_+E#u*-+$+++_+X  ^34^ &3 & & &X &CX"X)) ))))6!S!!!X! s t    !S!!!X! s t    !S!!!X! s t      rrdcDeZdZdZdeeffd ZdeddfdZxZS)BinaryBufferIOz2Stream class that handles byte contents for files.contentscNt|pddSNr)superrv)rur __class__s rrvzBinaryBufferIO.__init__s% S)))))rvaluerNc0||dSr<)writerurs rputvaluezBinaryBufferIO.putvalues 5r) rrrrrrErvr __classcell__rs@rrrsp<<*%******errc ~eZdZdZ d deedeedeedeffd Zd efd Zd ed dfd Z xZ S) TextBufferIOz;Stream class that handles Python string contents for files.NstrictrnewlinerRerrorsctj|pd|_t|j|||dSr)ioBytesIO _bytestreamrrv)rurrrRrrs rrvzTextBufferIO.__init__sB:ho#66 )8VWEEEEErrc4|jSr<)rgetvaluers rrzTextBufferIO.getvalues((***rrc:|j|dSr<)rrrs rrzTextBufferIO.putvalues u%%%%%r)NNNr) rrrrrrErLrvrrrrs@rrrsEE%)!%"& FF5/F#F3- F  FFFFFF+%++++&e&&&&&&&&&rr)rN)=rrrGr'r&rr%rYrrtypingrrrr r r rLrE AnyStringPathLikeAnyPathpython_implementationIS_PYPYIS_WINrCexists IN_DOCKER PERM_READ PERM_WRITEPERM_EXEPERM_DEF PERM_DEF_FILEPERM_ALLrrr(r)r0rrr r#r*rr,r2r7r9r>rJrMrQrWrZr_rdrr TextIOWrapperrrrrrs>=  ???????????????? #u*   # $ (( ( * *f 4   GNN= ) )     <7GHHbikkGry{{H         S T    &&&&&& "3"4""""  v&  r{s -w-6----E&%U "3345sEz!223VF HSMhsm UFu  S&S  VTd    %f-  i    J J J J J J J J ZRZ&&&&&2#&&&&&r__pycache__/mox3_stubout.cpython-311.pyc000064400000015066150043321510014133 0ustar00 bg,dZddlZGddZdS)a This is a fork of the pymox library intended to work with Python 3. The file was modified by quermit@gmail.com and dawid.fatyga@gmail.com Previously, pyfakefs used just this file from the mox3 library. However, mox3 will soon be decommissioned, yet standard mock cannot be used because of the problem described in pyfakefs #182 and mock issue 250 (https://github.com/testing-cabal/mock/issues/250). Therefore just this file was forked from mox3 and incorporated into pyfakefs. Nc6eZdZdZdZdZdZdZdZdZ dS) StubOutForTestingaSample Usage: You want os.path.exists() to always return true during testing. stubs = StubOutForTesting() stubs.Set(os.path, 'exists', lambda x: 1) ... stubs.UnsetAll() The above changes os.path.exists into a lambda that returns 1. Once the ... part of the code finishes, the UnsetAll() looks up the old value of os.path.exists and restores it. c"g|_g|_dSN)cachestubsselfs f/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/mox3_stubout.py__init__zStubOutForTesting.__init__.s  cV||dSr)smart_unset_all unset_allr s r __del__zStubOutForTesting.__del__2s*  r ctj|stj|s||jvr|}t ||}ntj|s't tj|j}n!t tj|}|d}|D]%} |}t ||}#t$rY"wxYw|td|j |}|$t|trt|}|j |||ft|||dS)aReplace obj.attr_name with new_attr. This method is smart and works at the module, class, and instance level while preserving proper inheritance. It will not stub out C types however unless that has been explicitly allowed by the type. This method supports the case where attr_name is a staticmethod or a classmethod of obj. Notes: - If obj is an instance, then it is its class that will actually be stubbed. Note that the method Set() does not do that: if obj is an instance, it (and not its class) will be stubbed. - The stubbing is using the builtin getattr and setattr. So, the __get__ and __set__ will be called when stubbing (TODO: A better idea would probably be to manipulate obj.__dict__ instead of getattr() and setattr()). Raises AttributeError if the attribute cannot be found. NzAttribute not found.)inspectismoduleisclass__dict__getattrlistgetmro __class__reverseAttributeErrorget isinstance staticmethodrappendsetattr) r obj attr_namenew_attrorig_obj orig_attrmrocls old_attributes r smart_setzStubOutForTesting.smart_set6ss*  C  $$ )2cl)B)BHY//II?3'' 07>#-88997>#..// KKMMMI  "H 'Y 7 7II%H   !788 8 ((33  $M<)P)P $$Y//I 8Y :;;;)X.....s<C CCcl|j|jD] }t| g|_dS)zReverses all the SmartSet() calls. Restores things to their original definition. Its okay to call SmartUnsetAll() repeatedly, as later calls have no effect if no SmartSet() calls have been made. N)rrr!)r argss r rz!StubOutForTesting.smart_unset_allns? J  D TNNN r cVt||}|j|}|Nt|trt |}n)t|t rt |j}|j|||ft|||dS)aReplace child_name's old definition with new_child. Replace definition in the context of the given parent. The parent could be a module when the child is a function at module scope. Or the parent could be a class when a class' method is being replaced. The named child is set to new_child, while the prior definition is saved away for later, when unset_all() is called. This method supports the case where child_name is a staticmethod or a classmethod of parent. N) rrrrr classmethod__func__rr r!)r parent child_name new_child old_childr)s r setzStubOutForTesting.set|sFJ// ++J77  $-66 <(33 M;77 <' (:;;  69j9::: I.....r c|j|jD]\}}}t|||g|_dS)zReverses all the Set() calls. Restores things to their original definition. Its okay to call unset_all() repeatedly, as later calls have no effect if no Set() calls have been made. N)rrr!)r r0r3r1s r rzStubOutForTesting.unset_allsP -1Z 3 3 )FIz FJ 2 2 2 2 r N) __name__ __module__ __qualname____doc__r rr*rr4rr r rrsy  6/6/6/p   ///0r r)r9rrr:r r r;sV  DDDDDDDDDDr __pycache__/patched_packages.cpython-311.pyc000064400000014605150043321510014724 0ustar00 bg5dZddlZ ddlZddlmcmZn #e$rdZYnwxYw ddlZn #e$rdZYnwxYw ddl m Z n #e$rdZ YnwxYweduo)dej dDgdkZ dZdZd Ze Gd d Ze rGd d ZGddZe GddZdSdS)zY Provides patches for some commonly used modules that enable them to work with pyfakefs. N)locksc,g|]}t|S)int).0vs j/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/patched_packages.py r %s'R'R'R1A'R'R'R.)rcNi}t t|d<t t|d<|S)Nxlrdzdjango.core.files.locks)r XLRDModuler FakeLocks)modules_to_patchs r get_modules_to_patchr,s1 #-  6?23 r c$i}trdg|d<|S)Nzpandas.io.parsersTextFileReader) patch_pandas)classes_to_patchs r get_classes_to_patchr5s&C.A-B)* r c,i}tr t|d<|S)Nr)rFakeTextFileReader)fake_module_classess r get_fake_module_classesr<s#C0B,- r c BeZdZdZdZdejdddddddf dZdZdS)rzPatches the xlrd module, which is used as the default Excel file reader by pandas. Disables using memory mapped files, which are implemented platform-specific on OS level.ct|_dSN)r _xlrd_moduleself_s r __init__zXLRDModule.__init__Js $D   r NrFc F|j|||d||||| S)NF)r! open_workbook) r#filenamelogfile verbosityuse_mmap file_contentsencoding_overrideformatting_info on_demand ragged_rowss r r'zXLRDModule.open_workbookMs:$22!   r c,t|j|Sz7Forwards any unfaked calls to the standard xlrd module.)getattrr!r#names r __getattr__zXLRDModule.__getattr__es4,d33 3r ) __name__ __module__ __qualname____doc__r%sysstdoutr'r6rr r rrEso 6 6 % % % J"!    0 4 4 4 4 4r rc$eZdZdZdZdZdZdS)rNcJ|jt||j_dSdSr ) fake_parsers ParsersModule __class__)r# filesystems r r%zFakeTextFileReader.__init__qs+ (.;J.G.G+++)(r c&|jj|i|Sr )r?r)r#argskwargss r __call__zFakeTextFileReader.__call__us34$3TDVDD Dr c6t|jj|Sr )r3r?rr4s r r6zFakeTextFileReader.__getattr__xs4,;TBB Br )r7r8r9r?r%rFr6rr r rrnsQ  H H H E E E C C C C Cr rc@eZdZdZGddejZdZdS)r@ct|_dSr )parsers_parsers_moduler"s r r%zParsersModule.__init__|s#*D r ceZdZfdZxZS)ParsersModule.TextFileReadercDd|d<tj|i|dS)Npythonengine)superr%)r#rDrErAs r r%z%ParsersModule.TextFileReader.__init__s/#+x   $1&11111r )r7r8r9r% __classcell__)rAs@r rrMs8 2 2 2 2 2 2 2 2 2r rc,t|j|Sr2)r3rKr4s r r6zParsersModule.__getattr__s4/66 6r N)r7r8r9r%rJrr6rr r r@r@{s_ + + + 2 2 2 2 2W3 2 2 2  7 7 7 7 7r r@cNeZdZdZeZdZedZedZ dZ dS)rz=django.core.files.locks uses low level OS functions, fake it.cdSr rr"s r r%zFakeLocks.__init__s Dr cdSNTr)fflagss r lockzFakeLocks.lock4r cdSrWr)rXs r unlockzFakeLocks.unlockr[r c,t|j|Sr )r3 _locks_moduler4s r r6zFakeLocks.__getattr__s4-t44 4r N) r7r8r9r:rr_r% staticmethodrZr]r6rr r rrssKK               5 5 5 5 5r r)r:r;pandaspdpandas.io.parsersiorJ ImportErrorrdjango.core.filesr __version__splitrrrrrrr@rrr r ris* ''''''''''GGGKKKK DDD''''''' EEE d"'R'R8L8LS8Q8Q'R'R'RVVV( "4"4"4"4"4"4"4"4J7 C C C C C C C C 7 7 7 7 7 7 7 7 5555555555s'   )33>AA__pycache__/pytest_plugin.cpython-311.pyc000064400000005766150043321510014374 0ustar00 bgdZddlZddlZddlmZddlmZ ddlmZn #e$rdZYnwxYwej eej eej eeej eej dZ ej dd Z ej d d Zej d d ZdS)zA pytest plugin for using pyfakefs as a fixture When pyfakefs is installed, the "fs" fixture becomes available. :Usage: def my_fakefs_test(fs): fs.create_file('/var/data/xx1.txt') assert os.path.exists('/var/data/xx1.txt') N)capture)Patcher)pathlibc#Kt|drt|j}nt}||jV|dS)zFake filesystem.paramNhasattrrrsetUpfstearDownrequestpatchers g/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/pytest_plugin.pyr r sdw  7=))) MMOOO * class)scopec#Kt|drt|j}nt}||jV|dS)z%Class-scoped fake filesystem fixture.rNrr s rfs_classr*dw  7=))) MMOOO * rmodulec#Kt|drt|j}nt}||jV|dS)z&Module-scoped fake filesystem fixture.rNrr s r fs_moduler6rrsessionc#Kt|drt|j}nt}||jV|dS)z'Session-scoped fake filesystem fixture.rNrr s r fs_sessionrBrr)__doc__pypytest_pytestr!pyfakefs.fake_filesystem_unittestrr ImportError SKIPMODULESaddfixturer rrrrrr's   555555GGG   G$$$   gh i   ! s ))_version.py000064400000000026150043321510006732 0ustar00__version__ = "5.2.3" extra_packages.py000064400000002175150043321510010076 0ustar00# Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Imports external packages that replace or emulate internal packages. If the external module is not present, the build-in module is imported. """ try: import pathlib2 except ImportError: pathlib2 = None try: import scandir use_scandir_package = True use_builtin_scandir = False except ImportError: try: from os import scandir # noqa: F401 use_builtin_scandir = True use_scandir_package = False except ImportError: use_builtin_scandir = False use_scandir_package = False use_scandir = use_scandir_package or use_builtin_scandir fake_file.py000064400000131544150043321510007025 0ustar00# Copyright 2009 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Fake implementations for different file objects. """ import errno import io import locale import os import sys from stat import ( S_IFREG, S_IFDIR, ) from types import TracebackType from typing import ( List, Optional, Callable, Union, Any, Dict, cast, AnyStr, NoReturn, Iterator, TextIO, Type, TYPE_CHECKING, ) from pyfakefs import helpers from pyfakefs.helpers import ( FakeStatResult, BinaryBufferIO, TextBufferIO, is_int_type, is_unicode_string, to_string, matching_string, real_encoding, AnyPath, AnyString, ) if TYPE_CHECKING: from pyfakefs.fake_filesystem import FakeFilesystem AnyFileWrapper = Union[ "FakeFileWrapper", "FakeDirWrapper", "StandardStreamWrapper", "FakePipeWrapper", ] AnyFile = Union["FakeFile", "FakeDirectory"] class FakeLargeFileIoException(Exception): """Exception thrown on unsupported operations for fake large files. Fake large files have a size with no real content. """ def __init__(self, file_path: str) -> None: super(FakeLargeFileIoException, self).__init__( "Read and write operations not supported for " "fake large file: %s" % file_path ) class FakeFile: """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. """ stat_types = ( "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_ns", ) def __init__( self, name: AnyStr, st_mode: int = S_IFREG | helpers.PERM_DEF_FILE, contents: Optional[AnyStr] = None, filesystem: Optional["FakeFilesystem"] = None, encoding: Optional[str] = None, errors: Optional[str] = None, side_effect: Optional[Callable[["FakeFile"], None]] = None, ): """ 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), and the file permissions. If no file type is set (e.g. permission flags only), a regular file type is assumed. contents: The contents of the filesystem object; should be a string or byte object for regular files, and a dict of other FakeFile or FakeDirectory objects wih the file names as keys 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. """ # to be backwards compatible regarding argument order, we raise on None if filesystem is None: raise ValueError("filesystem shall not be None") self.filesystem: "FakeFilesystem" = filesystem self._side_effect: Optional[Callable] = side_effect self.name: AnyStr = name # type: ignore[assignment] self.stat_result = FakeStatResult( filesystem.is_windows_fs, helpers.get_uid(), helpers.get_gid(), helpers.now(), ) if st_mode >> 12 == 0: st_mode |= S_IFREG self.stat_result.st_mode = st_mode self.st_size: int = 0 self.encoding: Optional[str] = real_encoding(encoding) self.errors: str = errors or "strict" self._byte_contents: Optional[bytes] = self._encode_contents(contents) self.stat_result.st_size = ( len(self._byte_contents) if self._byte_contents is not None else 0 ) self.epoch: int = 0 self.parent_dir: Optional[FakeDirectory] = None # Linux specific: extended file system attributes self.xattr: Dict = {} self.opened_as: AnyString = "" @property def byte_contents(self) -> Optional[bytes]: """Return the contents as raw byte array.""" return self._byte_contents @property def contents(self) -> Optional[str]: """Return the contents as string with the original encoding.""" if isinstance(self.byte_contents, bytes): return self.byte_contents.decode( self.encoding or locale.getpreferredencoding(False), errors=self.errors, ) return None @property def st_ctime(self) -> float: """Return the creation time of the fake file.""" return self.stat_result.st_ctime @st_ctime.setter def st_ctime(self, val: float) -> None: """Set the creation time of the fake file.""" self.stat_result.st_ctime = val @property def st_atime(self) -> float: """Return the access time of the fake file.""" return self.stat_result.st_atime @st_atime.setter def st_atime(self, val: float) -> None: """Set the access time of the fake file.""" self.stat_result.st_atime = val @property def st_mtime(self) -> float: """Return the modification time of the fake file.""" return self.stat_result.st_mtime @st_mtime.setter def st_mtime(self, val: float) -> None: """Set the modification time of the fake file.""" self.stat_result.st_mtime = val def set_large_file_size(self, st_size: int) -> None: """Sets 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: OSError: if the st_size is not a non-negative integer, or if st_size exceeds the available file system space """ self._check_positive_int(st_size) if self.st_size: self.size = 0 if self.filesystem: self.filesystem.change_disk_usage(st_size, self.name, self.st_dev) self.st_size = st_size self._byte_contents = None def _check_positive_int(self, size: int) -> None: # the size should be an positive integer value if not is_int_type(size) or size < 0: self.filesystem.raise_os_error(errno.ENOSPC, self.name) def is_large_file(self) -> bool: """Return `True` if this file was initialized with size but no contents. """ return self._byte_contents is None def _encode_contents(self, contents: Union[str, bytes, None]) -> Optional[bytes]: if is_unicode_string(contents): contents = bytes( cast(str, contents), self.encoding or locale.getpreferredencoding(False), self.errors, ) return cast(bytes, contents) def set_initial_contents(self, contents: AnyStr) -> bool: """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: OSError: if the st_size is not a non-negative integer, or if st_size exceeds the available file system space """ byte_contents = self._encode_contents(contents) changed = self._byte_contents != byte_contents st_size = len(byte_contents) if byte_contents else 0 current_size = self.st_size or 0 self.filesystem.change_disk_usage( st_size - current_size, self.name, self.st_dev ) self._byte_contents = byte_contents self.st_size = st_size self.epoch += 1 return changed def set_contents(self, contents: AnyStr, encoding: Optional[str] = None) -> bool: """Sets the file contents and size and increases the modification time. Also executes the side_effects if available. Args: contents: (str, bytes) 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. Returns: True if the contents have been changed. Raises: OSError: if `st_size` is not a non-negative integer, or if it exceeds the available file system space. """ self.encoding = real_encoding(encoding) changed = self.set_initial_contents(contents) if self._side_effect is not None: self._side_effect(self) return changed @property def size(self) -> int: """Return the size in bytes of the file contents.""" return self.st_size @size.setter def size(self, st_size: int) -> None: """Resizes file content, padding with nulls if new size exceeds the old size. Args: st_size: The desired size for the file. Raises: OSError: if the st_size arg is not a non-negative integer or if st_size exceeds the available file system space """ self._check_positive_int(st_size) current_size = self.st_size or 0 self.filesystem.change_disk_usage( st_size - current_size, self.name, self.st_dev ) if self._byte_contents: if st_size < current_size: self._byte_contents = self._byte_contents[:st_size] else: self._byte_contents += b"\0" * (st_size - current_size) self.st_size = st_size self.epoch += 1 @property def path(self) -> AnyStr: """Return the full path of the current object.""" names: List[AnyStr] = [] # pytype: disable=invalid-annotation obj: Optional[FakeFile] = self while obj: names.insert(0, matching_string(self.name, obj.name)) # type: ignore obj = obj.parent_dir sep = self.filesystem.get_path_separator(names[0]) if names[0] == sep: names.pop(0) dir_path = sep.join(names) drive = self.filesystem.splitdrive(dir_path)[0] # if a Windows path already starts with a drive or UNC path, # no extra separator is needed if not drive: dir_path = sep + dir_path else: dir_path = sep.join(names) return self.filesystem.absnormpath(dir_path) if sys.version_info >= (3, 12): @property def is_junction(self) -> bool: return self.filesystem.isjunction(self.path) def __getattr__(self, item: str) -> Any: """Forward some properties to stat_result.""" if item in self.stat_types: return getattr(self.stat_result, item) return super().__getattribute__(item) def __setattr__(self, key: str, value: Any) -> None: """Forward some properties to stat_result.""" if key in self.stat_types: return setattr(self.stat_result, key, value) return super().__setattr__(key, value) def __str__(self) -> str: return "%r(%o)" % (self.name, self.st_mode) class FakeNullFile(FakeFile): def __init__(self, filesystem: "FakeFilesystem") -> None: devnull = "nul" if filesystem.is_windows_fs else "/dev/null" super(FakeNullFile, self).__init__(devnull, filesystem=filesystem, contents="") @property def byte_contents(self) -> bytes: return b"" def set_initial_contents(self, contents: AnyStr) -> bool: return False class FakeFileFromRealFile(FakeFile): """Represents a fake file copied from the real file system. The contents of the file are read on demand only. """ def __init__( self, file_path: str, filesystem: "FakeFilesystem", side_effect: Optional[Callable] = None, ) -> None: """ 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. """ super().__init__( name=os.path.basename(file_path), filesystem=filesystem, side_effect=side_effect, ) self.contents_read = False @property def byte_contents(self) -> Optional[bytes]: if not self.contents_read: self.contents_read = True with io.open(self.file_path, "rb") as f: self._byte_contents = f.read() # On MacOS and BSD, the above io.open() updates atime on the real file self.st_atime = os.stat(self.file_path).st_atime return self._byte_contents def set_contents(self, contents, encoding=None): self.contents_read = True super(FakeFileFromRealFile, self).set_contents(contents, encoding) def is_large_file(self): """The contents are never faked.""" return False class FakeDirectory(FakeFile): """Provides the appearance of a real directory.""" def __init__( self, name: str, perm_bits: int = helpers.PERM_DEF, filesystem: Optional["FakeFilesystem"] = None, ): """ 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 """ FakeFile.__init__(self, name, S_IFDIR | perm_bits, "", filesystem=filesystem) # directories have the link count of contained entries, # including '.' and '..' self.st_nlink += 1 self._entries: Dict[str, AnyFile] = {} def set_contents(self, contents: AnyStr, encoding: Optional[str] = None) -> bool: raise self.filesystem.raise_os_error(errno.EISDIR, self.path) @property def entries(self) -> Dict[str, FakeFile]: """Return the list of contained directory entries.""" return self._entries @property def ordered_dirs(self) -> List[str]: """Return the list of contained directory entry names ordered by creation order. """ return [ item[0] for item in sorted(self._entries.items(), key=lambda entry: entry[1].st_ino) ] def add_entry(self, path_object: FakeFile) -> None: """Adds 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 """ if ( not helpers.is_root() and not self.st_mode & helpers.PERM_WRITE and not self.filesystem.is_windows_fs ): raise OSError(errno.EACCES, "Permission Denied", self.path) path_object_name: str = to_string(path_object.name) if path_object_name in self.entries: self.filesystem.raise_os_error(errno.EEXIST, self.path) self._entries[path_object_name] = path_object path_object.parent_dir = self if path_object.st_ino is None: self.filesystem.last_ino += 1 path_object.st_ino = self.filesystem.last_ino self.st_nlink += 1 path_object.st_nlink += 1 path_object.st_dev = self.st_dev if path_object.st_nlink == 1: self.filesystem.change_disk_usage( path_object.size, path_object.name, self.st_dev ) def get_entry(self, pathname_name: str) -> AnyFile: """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. """ pathname_name = self._normalized_entryname(pathname_name) return self.entries[to_string(pathname_name)] def _normalized_entryname(self, pathname_name: str) -> str: if not self.filesystem.is_case_sensitive: matching_names = [ name for name in self.entries if name.lower() == pathname_name.lower() ] if matching_names: pathname_name = matching_names[0] return pathname_name def remove_entry(self, pathname_name: str, recursive: bool = True) -> None: """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. """ pathname_name = self._normalized_entryname(pathname_name) entry = self.get_entry(pathname_name) if self.filesystem.is_windows_fs: if entry.st_mode & helpers.PERM_WRITE == 0: self.filesystem.raise_os_error(errno.EACCES, pathname_name) if self.filesystem.has_open_file(entry): self.filesystem.raise_os_error(errno.EACCES, pathname_name) else: if not helpers.is_root() and ( self.st_mode & (helpers.PERM_WRITE | helpers.PERM_EXE) != helpers.PERM_WRITE | helpers.PERM_EXE ): self.filesystem.raise_os_error(errno.EACCES, pathname_name) if recursive and isinstance(entry, FakeDirectory): while entry.entries: entry.remove_entry(list(entry.entries)[0]) elif entry.st_nlink == 1: self.filesystem.change_disk_usage(-entry.size, pathname_name, entry.st_dev) self.st_nlink -= 1 entry.st_nlink -= 1 assert entry.st_nlink >= 0 del self.entries[to_string(pathname_name)] @property def size(self) -> int: """Return the total size of all files contained in this directory tree. """ return sum([item[1].size for item in self.entries.items()]) @size.setter def size(self, st_size: int) -> None: """Setting the size is an error for a directory.""" raise self.filesystem.raise_os_error(errno.EISDIR, self.path) def has_parent_object(self, dir_object: "FakeDirectory") -> bool: """Return `True` if dir_object is a direct or indirect parent directory, or if both are the same object.""" obj: Optional[FakeDirectory] = self while obj: if obj == dir_object: return True obj = obj.parent_dir return False def __str__(self) -> str: description = super(FakeDirectory, self).__str__() + ":\n" for item in self.entries: item_desc = self.entries[item].__str__() for line in item_desc.split("\n"): if line: description = description + " " + line + "\n" return description class FakeDirectoryFromRealDirectory(FakeDirectory): """Represents a fake directory copied from the real file system. The contents of the directory are read on demand only. """ def __init__( self, source_path: AnyPath, filesystem: "FakeFilesystem", read_only: bool, target_path: Optional[AnyPath] = None, ): """ 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 """ target_path = target_path or source_path real_stat = os.stat(source_path) super(FakeDirectoryFromRealDirectory, self).__init__( name=to_string(os.path.split(target_path)[1]), perm_bits=real_stat.st_mode, filesystem=filesystem, ) self.st_ctime = real_stat.st_ctime self.st_atime = real_stat.st_atime self.st_mtime = real_stat.st_mtime self.st_gid = real_stat.st_gid self.st_uid = real_stat.st_uid self.source_path = source_path # type: ignore self.read_only = read_only self.contents_read = False @property def entries(self) -> Dict[str, FakeFile]: """Return the list of contained directory entries, loading them if not already loaded.""" if not self.contents_read: self.contents_read = True base = self.path for entry in os.listdir(self.source_path): source_path = os.path.join(self.source_path, entry) target_path = os.path.join(base, entry) # type: ignore if os.path.islink(source_path): self.filesystem.add_real_symlink(source_path, target_path) elif os.path.isdir(source_path): self.filesystem.add_real_directory( source_path, self.read_only, target_path=target_path ) else: self.filesystem.add_real_file( source_path, self.read_only, target_path=target_path ) return self._entries @property def size(self) -> int: # we cannot get the size until the contents are loaded if not self.contents_read: return 0 return super(FakeDirectoryFromRealDirectory, self).size @size.setter def size(self, st_size: int) -> None: raise self.filesystem.raise_os_error(errno.EISDIR, self.path) class FakeFileWrapper: """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(). """ def __init__( self, file_object: FakeFile, file_path: AnyStr, update: bool, read: bool, append: bool, delete_on_close: bool, filesystem: "FakeFilesystem", newline: Optional[str], binary: bool, closefd: bool, encoding: Optional[str], errors: Optional[str], buffering: int, raw_io: bool, is_stream: bool = False, ): self.file_object = file_object self.file_path = file_path # type: ignore[var-annotated] self._append = append self._read = read self.allow_update = update self._closefd = closefd self._file_epoch = file_object.epoch self.raw_io = raw_io self._binary = binary self.is_stream = is_stream self._changed = False self._buffer_size = buffering if self._buffer_size == 0 and not binary: raise ValueError("can't have unbuffered text I/O") # buffer_size is ignored in text mode elif self._buffer_size == -1 or not binary: self._buffer_size = io.DEFAULT_BUFFER_SIZE self._use_line_buffer = not binary and buffering == 1 contents = file_object.byte_contents self._encoding = encoding or locale.getpreferredencoding(False) errors = errors or "strict" self._io: Union[BinaryBufferIO, TextBufferIO] = ( BinaryBufferIO(contents) if binary else TextBufferIO( contents, encoding=encoding, newline=newline, errors=errors ) ) self._read_whence = 0 self._read_seek = 0 self._flush_pos = 0 if contents: self._flush_pos = len(contents) if update: if not append: self._io.seek(0) else: self._io.seek(self._flush_pos) self._read_seek = self._io.tell() if delete_on_close: assert filesystem, "delete_on_close=True requires filesystem" self._filesystem = filesystem self.delete_on_close = delete_on_close # override, don't modify FakeFile.name, as FakeFilesystem expects # it to be the file name only, no directories. self.name = file_object.opened_as self.filedes: Optional[int] = None def __enter__(self) -> "FakeFileWrapper": """To support usage of this fake file with the 'with' statement.""" return self def __exit__( self, exc_type: Optional[Type[BaseException]], exc_val: Optional[BaseException], exc_tb: Optional[TracebackType], ) -> None: """To support usage of this fake file with the 'with' statement.""" self.close() def _raise(self, message: str) -> NoReturn: if self.raw_io: self._filesystem.raise_os_error(errno.EBADF, self.file_path) raise io.UnsupportedOperation(message) def get_object(self) -> FakeFile: """Return the FakeFile object that is wrapped by the current instance. """ return self.file_object def fileno(self) -> int: """Return the file descriptor of the file object.""" if self.filedes is not None: return self.filedes raise OSError(errno.EBADF, "Invalid file descriptor") def close(self) -> None: """Close the file.""" # ignore closing a closed file if not self._is_open(): return # for raw io, all writes are flushed immediately if self.allow_update and not self.raw_io: self.flush() if self._filesystem.is_windows_fs and self._changed: self.file_object.st_mtime = helpers.now() assert self.filedes is not None if self._closefd: self._filesystem._close_open_file(self.filedes) else: open_files = self._filesystem.open_files[self.filedes] assert open_files is not None open_files.remove(self) if self.delete_on_close: self._filesystem.remove_object( self.get_object().path # type: ignore[arg-type] ) @property def closed(self) -> bool: """Simulate the `closed` attribute on file.""" return not self._is_open() def _try_flush(self, old_pos: int) -> None: """Try to flush and reset the position if it fails.""" flush_pos = self._flush_pos try: self.flush() except OSError: # write failed - reset to previous position self._io.seek(old_pos) self._io.truncate() self._flush_pos = flush_pos raise def flush(self) -> None: """Flush file contents to 'disk'.""" self._check_open_file() if self.allow_update and not self.is_stream: contents = self._io.getvalue() if self._append: self._sync_io() old_contents = self.file_object.byte_contents assert old_contents is not None contents = old_contents + contents[self._flush_pos :] self._set_stream_contents(contents) else: self._io.flush() changed = self.file_object.set_contents(contents, self._encoding) self.update_flush_pos() if changed: if self._filesystem.is_windows_fs: self._changed = True else: current_time = helpers.now() self.file_object.st_ctime = current_time self.file_object.st_mtime = current_time self._file_epoch = self.file_object.epoch if not self.is_stream: self._flush_related_files() def update_flush_pos(self) -> None: self._flush_pos = self._io.tell() def _flush_related_files(self) -> None: for open_files in self._filesystem.open_files[3:]: if open_files is not None: for open_file in open_files: if ( open_file is not self and isinstance(open_file, FakeFileWrapper) and self.file_object == open_file.file_object and not open_file._append ): open_file._sync_io() def seek(self, offset: int, whence: int = 0) -> None: """Move read/write pointer in 'file'.""" self._check_open_file() if not self._append: self._io.seek(offset, whence) else: self._read_seek = offset self._read_whence = whence if not self.is_stream: self.flush() def tell(self) -> int: """Return the file's current position. Returns: int, file's current position in bytes. """ self._check_open_file() if not self.is_stream: self.flush() if not self._append: return self._io.tell() if self._read_whence: write_seek = self._io.tell() self._io.seek(self._read_seek, self._read_whence) self._read_seek = self._io.tell() self._read_whence = 0 self._io.seek(write_seek) return self._read_seek def _sync_io(self) -> None: """Update the stream with changes to the file object contents.""" if self._file_epoch == self.file_object.epoch: return contents = self.file_object.byte_contents assert contents is not None self._set_stream_contents(contents) self._file_epoch = self.file_object.epoch def _set_stream_contents(self, contents: bytes) -> None: whence = self._io.tell() self._io.seek(0) self._io.truncate() self._io.putvalue(contents) if not self._append: self._io.seek(whence) def _read_wrappers(self, name: str) -> Callable: """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. """ io_attr = getattr(self._io, name) def read_wrapper(*args, **kwargs): """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 """ self._io.seek(self._read_seek, self._read_whence) ret_value = io_attr(*args, **kwargs) self._read_seek = self._io.tell() self._read_whence = 0 self._io.seek(0, 2) return ret_value return read_wrapper def _other_wrapper(self, name: str) -> Callable: """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. """ io_attr = getattr(self._io, name) def other_wrapper(*args, **kwargs): """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. """ write_seek = self._io.tell() ret_value = io_attr(*args, **kwargs) if write_seek != self._io.tell(): self._read_seek = self._io.tell() self._read_whence = 0 return ret_value return other_wrapper def _write_wrapper(self, name: str) -> Callable: """Wrap a stream attribute in a write_wrapper. Args: name: the name of the stream attribute to wrap. Returns: write_wrapper which is described below. """ io_attr = getattr(self._io, name) def write_wrapper(*args, **kwargs): """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. """ old_pos = self._io.tell() ret_value = io_attr(*args, **kwargs) new_pos = self._io.tell() # if the buffer size is exceeded, we flush use_line_buf = self._use_line_buffer and "\n" in args[0] if new_pos - self._flush_pos > self._buffer_size or use_line_buf: flush_all = new_pos - old_pos > self._buffer_size or use_line_buf # if the current write does not exceed the buffer size, # we revert to the previous position and flush that, # otherwise we flush all if not flush_all: self._io.seek(old_pos) self._io.truncate() self._try_flush(old_pos) if not flush_all: ret_value = io_attr(*args, **kwargs) if self._append: self._read_seek = self._io.tell() self._read_whence = 0 return ret_value return write_wrapper def _adapt_size_for_related_files(self, size: int) -> None: for open_files in self._filesystem.open_files[3:]: if open_files is not None: for open_file in open_files: if ( open_file is not self and isinstance(open_file, FakeFileWrapper) and self.file_object == open_file.file_object and cast(FakeFileWrapper, open_file)._append ): open_file._read_seek += size def _truncate_wrapper(self) -> Callable: """Wrap truncate() to allow flush after truncate. Returns: Wrapper which is described below. """ io_attr = self._io.truncate def truncate_wrapper(*args, **kwargs): """Wrap truncate call to call flush after truncate.""" if self._append: self._io.seek(self._read_seek, self._read_whence) size = io_attr(*args, **kwargs) self.flush() if not self.is_stream: self.file_object.size = size buffer_size = len(self._io.getvalue()) if buffer_size < size: self._io.seek(buffer_size) self._io.putvalue(b"\0" * (size - buffer_size)) self.file_object.set_contents(self._io.getvalue(), self._encoding) self._flush_pos = size self._adapt_size_for_related_files(size - buffer_size) self.flush() return size return truncate_wrapper def size(self) -> int: """Return the content size in bytes of the wrapped file.""" return self.file_object.st_size def __getattr__(self, name: str) -> Any: if self.file_object.is_large_file(): raise FakeLargeFileIoException(self.file_path) reading = name.startswith("read") or name == "next" truncate = name == "truncate" writing = name.startswith("write") or truncate if reading or writing: self._check_open_file() if not self._read and reading: return self._read_error() if not self.allow_update and writing: return self._write_error() if reading: self._sync_io() if not self.is_stream: self.flush() if not self._filesystem.is_windows_fs: self.file_object.st_atime = helpers.now() if truncate: return self._truncate_wrapper() if self._append: if reading: return self._read_wrappers(name) elif not writing: return self._other_wrapper(name) if writing: return self._write_wrapper(name) return getattr(self._io, name) def _read_error(self) -> Callable: def read_error(*args, **kwargs): """Throw an error unless the argument is zero.""" if args and args[0] == 0: if self._filesystem.is_windows_fs and self.raw_io: return b"" if self._binary else "" self._raise("File is not open for reading.") return read_error def _write_error(self) -> Callable: def write_error(*args, **kwargs): """Throw an error.""" if self.raw_io: if self._filesystem.is_windows_fs and args and len(args[0]) == 0: return 0 self._raise("File is not open for writing.") return write_error def _is_open(self) -> bool: if self.filedes is not None and self.filedes < len(self._filesystem.open_files): open_files = self._filesystem.open_files[self.filedes] if open_files is not None and self in open_files: return True return False def _check_open_file(self) -> None: if not self.is_stream and not self._is_open(): raise ValueError("I/O operation on closed file") def __iter__(self) -> Union[Iterator[str], Iterator[bytes]]: if not self._read: self._raise("File is not open for reading") return self._io.__iter__() def __next__(self): if not self._read: self._raise("File is not open for reading") return next(self._io) class StandardStreamWrapper: """Wrapper for a system standard stream to be used in open files list.""" def __init__(self, stream_object: TextIO): self._stream_object = stream_object self.filedes: Optional[int] = None def get_object(self) -> TextIO: return self._stream_object def fileno(self) -> int: """Return the file descriptor of the wrapped standard stream.""" if self.filedes is not None: return self.filedes raise OSError(errno.EBADF, "Invalid file descriptor") def read(self, n: int = -1) -> bytes: return cast(bytes, self._stream_object.read()) def close(self) -> None: """We do not support closing standard streams.""" def is_stream(self) -> bool: return True class FakeDirWrapper: """Wrapper for a FakeDirectory object to be used in open files list.""" def __init__( self, file_object: FakeDirectory, file_path: AnyString, filesystem: "FakeFilesystem", ): self.file_object = file_object self.file_path = file_path self._filesystem = filesystem self.filedes: Optional[int] = None def get_object(self) -> FakeDirectory: """Return the FakeFile object that is wrapped by the current instance.""" return self.file_object def fileno(self) -> int: """Return the file descriptor of the file object.""" if self.filedes is not None: return self.filedes raise OSError(errno.EBADF, "Invalid file descriptor") def close(self) -> None: """Close the directory.""" assert self.filedes is not None self._filesystem._close_open_file(self.filedes) class FakePipeWrapper: """Wrapper for a read or write descriptor of a real pipe object to be used in open files list. """ def __init__( self, filesystem: "FakeFilesystem", fd: int, can_write: bool, mode: str = "", ): self._filesystem = filesystem self.fd = fd # the real file descriptor self.can_write = can_write self.file_object = None self.filedes: Optional[int] = None self.real_file = None if mode: self.real_file = open(fd, mode) def __enter__(self) -> "FakePipeWrapper": """To support usage of this fake pipe with the 'with' statement.""" return self def __exit__( self, exc_type: Optional[Type[BaseException]], exc_val: Optional[BaseException], exc_tb: Optional[TracebackType], ) -> None: """To support usage of this fake pipe with the 'with' statement.""" self.close() def get_object(self) -> None: return self.file_object def fileno(self) -> int: """Return the fake file descriptor of the pipe object.""" if self.filedes is not None: return self.filedes raise OSError(errno.EBADF, "Invalid file descriptor") def read(self, numBytes: int = -1) -> bytes: """Read from the real pipe.""" if self.real_file: return self.real_file.read(numBytes) # pytype: disable=bad-return-type return os.read(self.fd, numBytes) def flush(self) -> None: """Flush the real pipe?""" def write(self, contents: bytes) -> int: """Write to the real pipe.""" if self.real_file: return self.real_file.write(contents) return os.write(self.fd, contents) def close(self) -> None: """Close the pipe descriptor.""" assert self.filedes is not None open_files = self._filesystem.open_files[self.filedes] assert open_files is not None open_files.remove(self) if self.real_file: self.real_file.close() else: os.close(self.fd) def readable(self) -> bool: """The pipe end can either be readable or writable.""" return not self.can_write def writable(self) -> bool: """The pipe end can either be readable or writable.""" return self.can_write def seekable(self) -> bool: """A pipe is not seekable.""" return False fake_filesystem.py000064400000343716150043321510010300 0ustar00# Copyright 2009 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """A fake filesystem implementation for unit testing. :Usage: >>> from pyfakefs import fake_filesystem, fake_os >>> filesystem = fake_filesystem.FakeFilesystem() >>> os_module = fake_os.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 OSError 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 """ import errno import heapq import os import random import sys import tempfile from collections import namedtuple, OrderedDict from doctest import TestResults from enum import Enum from stat import ( S_IFREG, S_IFDIR, S_ISLNK, S_IFMT, S_ISDIR, S_IFLNK, S_ISREG, ) from typing import ( List, Optional, Callable, Union, Any, Dict, Tuple, cast, AnyStr, overload, NoReturn, ) from pyfakefs import fake_file, fake_path, fake_io, fake_os, helpers, fake_open from pyfakefs.fake_file import AnyFileWrapper, AnyFile from pyfakefs.helpers import ( is_int_type, make_string_path, to_string, matching_string, AnyPath, AnyString, ) if sys.platform.startswith("linux"): # on newer Linux system, the default maximum recursion depth is 40 # we ignore older systems here _MAX_LINK_DEPTH = 40 else: # on MacOS and Windows, the maximum recursion depth is 32 _MAX_LINK_DEPTH = 32 class OSType(Enum): """Defines the real or simulated OS of the underlying file system.""" LINUX = "linux" MACOS = "macos" WINDOWS = "windows" # definitions for backwards compatibility FakeFile = fake_file.FakeFile FakeNullFile = fake_file.FakeNullFile FakeFileFromRealFile = fake_file.FakeFileFromRealFile FakeDirectory = fake_file.FakeDirectory FakeDirectoryFromRealDirectory = fake_file.FakeDirectoryFromRealDirectory FakeFileWrapper = fake_file.FakeFileWrapper StandardStreamWrapper = fake_file.StandardStreamWrapper FakeDirWrapper = fake_file.FakeDirWrapper FakePipeWrapper = fake_file.FakePipeWrapper FakePathModule = fake_path.FakePathModule FakeOsModule = fake_os.FakeOsModule FakeFileOpen = fake_open.FakeFileOpen FakeIoModule = fake_io.FakeIoModule if sys.platform != "win32": FakeFcntlModule = fake_io.FakeFcntlModule PatchMode = fake_io.PatchMode is_root = helpers.is_root get_uid = helpers.get_uid set_uid = helpers.set_uid get_gid = helpers.get_gid set_gid = helpers.set_gid reset_ids = helpers.reset_ids PERM_READ = helpers.PERM_READ PERM_WRITE = helpers.PERM_WRITE PERM_EXE = helpers.PERM_EXE PERM_DEF = helpers.PERM_DEF PERM_DEF_FILE = helpers.PERM_DEF_FILE PERM_ALL = helpers.PERM_ALL class FakeFilesystem: """Provides 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. 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. patch_open_code: Defines how `io.open_code` will be patched; patching can be on, off, or in automatic mode. shuffle_listdir_results: If `True`, `os.listdir` will not sort the results to match the real file system behavior. """ def __init__( self, path_separator: str = os.path.sep, total_size: Optional[int] = None, patcher: Any = None, create_temp_dir: bool = False, ) -> None: """ Args: path_separator: optional substitute for os.path.sep total_size: if not None, the total size in bytes of the root filesystem. patcher: the Patcher instance if created from the Patcher create_temp_dir: If True, a temp directory is created on initialization. Under Posix, if the temp directory is not `/tmp`, a link to the temp path is additionally created at `/tmp`. Example usage to use the same path separator under all systems: >>> filesystem = FakeFilesystem(path_separator='/') """ self.path_separator: str = path_separator self.alternative_path_separator: Optional[str] = os.path.altsep self.patcher = patcher self.create_temp_dir = create_temp_dir if path_separator != os.sep: self.alternative_path_separator = None # is_windows_fs can be used to test the behavior of pyfakefs under # Windows fs on non-Windows systems and vice verse; # is it used to support drive letters, UNC paths and some other # Windows-specific features self._is_windows_fs = sys.platform == "win32" # can be used to test some MacOS-specific behavior under other systems self._is_macos = sys.platform == "darwin" # is_case_sensitive can be used to test pyfakefs for case-sensitive # file systems on non-case-sensitive systems and vice verse self.is_case_sensitive: bool = not (self.is_windows_fs or self._is_macos) self.root: FakeDirectory self._cwd = "" # We can't query the current value without changing it: self.umask: int = os.umask(0o22) os.umask(self.umask) # A list of open file objects. Their position in the list is their # file descriptor number self.open_files: List[Optional[List[AnyFileWrapper]]] = [] # A heap containing all free positions in self.open_files list self._free_fd_heap: List[int] = [] # last used numbers for inodes (st_ino) and devices (st_dev) self.last_ino: int = 0 self.last_dev: int = 0 self.mount_points: Dict[AnyString, Dict] = OrderedDict() self.dev_null: Any = None self.reset(total_size=total_size, init_pathlib=False) # set from outside if needed self.patch_open_code = PatchMode.OFF self.shuffle_listdir_results = False @property def is_linux(self) -> bool: return not self.is_windows_fs and not self.is_macos @property def is_windows_fs(self) -> bool: return self._is_windows_fs @is_windows_fs.setter def is_windows_fs(self, value: bool) -> None: if self._is_windows_fs != value: self._is_windows_fs = value self.reset() FakePathModule.reset(self) @property def is_macos(self) -> bool: return self._is_macos @is_macos.setter def is_macos(self, value: bool) -> None: if self._is_macos != value: self._is_macos = value self.reset() FakePathModule.reset(self) @property def cwd(self) -> str: """Return the current working directory of the fake filesystem.""" return self._cwd @cwd.setter def cwd(self, value: str) -> None: """Set the current working directory of the fake filesystem. Make sure a new drive or share is auto-mounted under Windows. """ self._cwd = value self._auto_mount_drive_if_needed(value) @property def root_dir(self) -> FakeDirectory: """Return the root directory, which represents "/" under POSIX, and the current drive under Windows.""" if self.is_windows_fs: return self._mount_point_dir_for_cwd() return self.root @property def root_dir_name(self) -> str: """Return the root directory name, which is "/" under POSIX, and the root path of the current drive under Windows.""" root_dir = to_string(self.root_dir.name) if not root_dir.endswith(self.path_separator): return root_dir + self.path_separator return root_dir @property def os(self) -> OSType: """Return the real or simulated type of operating system.""" return ( OSType.WINDOWS if self.is_windows_fs else OSType.MACOS if self.is_macos else OSType.LINUX ) @os.setter def os(self, value: OSType) -> None: """Set the simulated type of operating system underlying the fake file system.""" self._is_windows_fs = value == OSType.WINDOWS self._is_macos = value == OSType.MACOS self.is_case_sensitive = value == OSType.LINUX self.path_separator = "\\" if value == OSType.WINDOWS else "/" self.alternative_path_separator = "/" if value == OSType.WINDOWS else None self.reset() FakePathModule.reset(self) def reset(self, total_size: Optional[int] = None, init_pathlib: bool = True): """Remove all file system contents and reset the root.""" self.root = FakeDirectory(self.path_separator, filesystem=self) self.dev_null = FakeNullFile(self) self.open_files.clear() self._free_fd_heap.clear() self.last_ino = 0 self.last_dev = 0 self.mount_points.clear() self._add_root_mount_point(total_size) self._add_standard_streams() if self.create_temp_dir: self._create_temp_dir() if init_pathlib: from pyfakefs import fake_pathlib fake_pathlib.init_module(self) def _add_root_mount_point(self, total_size): mount_point = "C:" if self.is_windows_fs else self.path_separator self._cwd = mount_point if not self.cwd.endswith(self.path_separator): self._cwd += self.path_separator self.add_mount_point(mount_point, total_size) def pause(self) -> None: """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. """ if self.patcher is None: raise RuntimeError( "pause() can only be called from a fake file " "system object created by a Patcher object" ) self.patcher.pause() def resume(self) -> None: """Resume 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`. """ if self.patcher is None: raise RuntimeError( "resume() can only be called from a fake file " "system object created by a Patcher object" ) self.patcher.resume() def clear_cache(self) -> None: """Clear the cache of non-patched modules.""" if self.patcher: self.patcher.clear_cache() def line_separator(self) -> str: return "\r\n" if self.is_windows_fs else "\n" def raise_os_error( self, err_no: int, filename: Optional[AnyString] = None, winerror: Optional[int] = None, ) -> NoReturn: """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: err_no: 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. """ message = os.strerror(err_no) + " in the fake filesystem" if winerror is not None and sys.platform == "win32" and self.is_windows_fs: raise OSError(err_no, message, filename, winerror) raise OSError(err_no, message, filename) def get_path_separator(self, path: AnyStr) -> AnyStr: """Return the path separator as the same type as path""" return matching_string(path, self.path_separator) def _alternative_path_separator(self, path: AnyStr) -> Optional[AnyStr]: """Return the alternative path separator as the same type as path""" return matching_string(path, self.alternative_path_separator) def starts_with_sep(self, path: AnyStr) -> bool: """Return True if path starts with a path separator.""" sep = self.get_path_separator(path) altsep = self._alternative_path_separator(path) return path.startswith(sep) or altsep is not None and path.startswith(altsep) def add_mount_point( self, path: AnyStr, total_size: Optional[int] = None, can_exist: bool = False, ) -> Dict: """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. can_exist: If True, no error is raised if the mount point already exists Returns: The newly created mount point dict. Raises: OSError: if trying to mount an existing mount point again, and `can_exist` is False. """ path = self.normpath(self.normcase(path)) for mount_point in self.mount_points: if ( self.is_case_sensitive and path == matching_string(path, mount_point) or not self.is_case_sensitive and path.lower() == matching_string(path, mount_point.lower()) ): if can_exist: return self.mount_points[mount_point] self.raise_os_error(errno.EEXIST, path) self.last_dev += 1 self.mount_points[path] = { "idev": self.last_dev, "total_size": total_size, "used_size": 0, } if path == matching_string(path, self.root.name): # special handling for root path: has been created before root_dir = self.root self.last_ino += 1 root_dir.st_ino = self.last_ino else: root_dir = self._create_mount_point_dir(path) root_dir.st_dev = self.last_dev return self.mount_points[path] def _create_mount_point_dir(self, directory_path: AnyPath) -> FakeDirectory: """A version of `create_dir` for the mount point directory creation, which avoids circular calls and unneeded checks. """ dir_path = self.make_string_path(directory_path) path_components = self._path_components(dir_path) current_dir = self.root new_dirs = [] for component in [to_string(p) for p in path_components]: directory = self._directory_content(current_dir, to_string(component))[1] if not directory: new_dir = FakeDirectory(component, filesystem=self) new_dirs.append(new_dir) current_dir.add_entry(new_dir) current_dir = new_dir else: current_dir = cast(FakeDirectory, directory) for new_dir in new_dirs: new_dir.st_mode = S_IFDIR | helpers.PERM_DEF return current_dir def _auto_mount_drive_if_needed(self, path: AnyStr) -> Optional[Dict]: """Windows only: if `path` is located on an unmounted drive or UNC mount point, the drive/mount point is added to the mount points.""" if self.is_windows_fs: drive = self.splitdrive(path)[0] if drive: return self.add_mount_point(path=drive, can_exist=True) return None def _mount_point_for_path(self, path: AnyStr) -> Dict: path = self.absnormpath(self._original_path(path)) for mount_path in self.mount_points: if path == matching_string(path, mount_path): return self.mount_points[mount_path] mount_path = matching_string(path, "") drive = self.splitdrive(path)[0] for root_path in self.mount_points: root_path = matching_string(path, root_path) if drive and not root_path.startswith(drive): continue if path.startswith(root_path) and len(root_path) > len(mount_path): mount_path = root_path if mount_path: return self.mount_points[to_string(mount_path)] mount_point = self._auto_mount_drive_if_needed(path) assert mount_point return mount_point def _mount_point_dir_for_cwd(self) -> FakeDirectory: """Return the fake directory object of the mount point where the current working directory points to.""" def object_from_path(file_path) -> FakeDirectory: path_components = self._path_components(file_path) target = self.root for component in path_components: target = cast(FakeDirectory, target.get_entry(component)) return target path = to_string(self.cwd) for mount_path in self.mount_points: if path == to_string(mount_path): return object_from_path(mount_path) mount_path = "" drive = to_string(self.splitdrive(path)[0]) for root_path in self.mount_points: str_root_path = to_string(root_path) if drive and not str_root_path.startswith(drive): continue if path.startswith(str_root_path) and len(str_root_path) > len(mount_path): mount_path = root_path return object_from_path(mount_path) def _mount_point_for_device(self, idev: int) -> Optional[Dict]: for mount_point in self.mount_points.values(): if mount_point["idev"] == idev: return mount_point return None def get_disk_usage(self, path: Optional[AnyStr] = None) -> Tuple[int, int, int]: """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). """ DiskUsage = namedtuple("DiskUsage", "total, used, free") if path is None: mount_point = next(iter(self.mount_points.values())) else: file_path = make_string_path(path) mount_point = self._mount_point_for_path(file_path) if mount_point and mount_point["total_size"] is not None: return DiskUsage( mount_point["total_size"], mount_point["used_size"], mount_point["total_size"] - mount_point["used_size"], ) return DiskUsage(1024 * 1024 * 1024 * 1024, 0, 1024 * 1024 * 1024 * 1024) def set_disk_usage(self, total_size: int, path: Optional[AnyStr] = None) -> None: """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: OSError: if the new space is smaller than the used size. """ file_path: AnyStr = ( path if path is not None else self.root_dir_name # type: ignore ) mount_point = self._mount_point_for_path(file_path) if ( mount_point["total_size"] is not None and mount_point["used_size"] > total_size ): self.raise_os_error(errno.ENOSPC, path) mount_point["total_size"] = total_size def change_disk_usage( self, usage_change: int, file_path: AnyStr, st_dev: int ) -> None: """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: OSError: if usage_change exceeds the free file system space """ mount_point = self._mount_point_for_device(st_dev) if mount_point: total_size = mount_point["total_size"] if total_size is not None: if total_size - mount_point["used_size"] < usage_change: self.raise_os_error(errno.ENOSPC, file_path) mount_point["used_size"] += usage_change def stat(self, entry_path: AnyStr, follow_symlinks: bool = True): """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. """ # stat should return the tuple representing return value of os.stat try: file_object = self.resolve( entry_path, follow_symlinks, allow_fd=True, check_read_perm=False, ) except TypeError: file_object = self.resolve(entry_path) if not is_root(): # make sure stat raises if a parent dir is not readable parent_dir = file_object.parent_dir if parent_dir: self.get_object(parent_dir.path) # type: ignore[arg-type] self.raise_for_filepath_ending_with_separator( entry_path, file_object, follow_symlinks ) return file_object.stat_result.copy() def raise_for_filepath_ending_with_separator( self, entry_path: AnyStr, file_object: FakeFile, follow_symlinks: bool = True, macos_handling: bool = False, ) -> None: if self.ends_with_path_separator(entry_path): if S_ISLNK(file_object.st_mode): try: link_object = self.resolve(entry_path) except OSError as exc: if self.is_macos and exc.errno != errno.ENOENT: return if self.is_windows_fs: self.raise_os_error(errno.EINVAL, entry_path) raise if not follow_symlinks or self.is_windows_fs or self.is_macos: file_object = link_object if self.is_windows_fs: is_error = S_ISREG(file_object.st_mode) elif self.is_macos and macos_handling: is_error = not S_ISLNK(file_object.st_mode) else: is_error = not S_ISDIR(file_object.st_mode) if is_error: error_nr = errno.EINVAL if self.is_windows_fs else errno.ENOTDIR self.raise_os_error(error_nr, entry_path) def chmod( self, path: AnyStr, mode: int, follow_symlinks: bool = True, force_unix_mode: bool = False, ) -> None: """Change 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. force_unix_mode: if True and run under Windows, the mode is not adapted for Windows to allow making dirs unreadable """ file_object = self.resolve( path, follow_symlinks, allow_fd=True, check_owner=True ) if self.is_windows_fs and not force_unix_mode: if mode & helpers.PERM_WRITE: file_object.st_mode = file_object.st_mode | 0o222 else: file_object.st_mode = file_object.st_mode & 0o777555 else: file_object.st_mode = (file_object.st_mode & ~helpers.PERM_ALL) | ( mode & helpers.PERM_ALL ) file_object.st_ctime = helpers.now() def utime( self, path: AnyStr, times: Optional[Tuple[Union[int, float], Union[int, float]]] = None, *, ns: Optional[Tuple[int, int]] = None, follow_symlinks: bool = True, ) -> None: """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. follow_symlinks: If `False` and entry_path points to a symlink, the link itself is queried instead of the linked object. 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. """ self._handle_utime_arg_errors(ns, times) file_object = self.resolve(path, follow_symlinks, allow_fd=True) if times is not None: for file_time in times: if not isinstance(file_time, (int, float)): raise TypeError("atime and mtime must be numbers") file_object.st_atime = times[0] file_object.st_mtime = times[1] elif ns is not None: for file_time in ns: if not isinstance(file_time, int): raise TypeError("atime and mtime must be ints") file_object.st_atime_ns = ns[0] file_object.st_mtime_ns = ns[1] else: current_time = helpers.now() file_object.st_atime = current_time file_object.st_mtime = current_time @staticmethod def _handle_utime_arg_errors( ns: Optional[Tuple[int, int]], times: Optional[Tuple[Union[int, float], Union[int, float]]], ): if times is not None and ns is not None: raise ValueError( "utime: you may specify either 'times' or 'ns' but not both" ) if times is not None and len(times) != 2: raise TypeError("utime: 'times' must be either a tuple of two ints or None") if ns is not None and len(ns) != 2: raise TypeError("utime: 'ns' must be a tuple of two ints") def _add_open_file(self, file_obj: AnyFileWrapper) -> int: """Add 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. """ if self._free_fd_heap: open_fd = heapq.heappop(self._free_fd_heap) self.open_files[open_fd] = [file_obj] return open_fd self.open_files.append([file_obj]) return len(self.open_files) - 1 def _close_open_file(self, file_des: int) -> None: """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. """ self.open_files[file_des] = None heapq.heappush(self._free_fd_heap, file_des) def get_open_file(self, file_des: int) -> AnyFileWrapper: """Return 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. """ if not is_int_type(file_des): raise TypeError("an integer is required") valid = file_des < len(self.open_files) if valid: file_list = self.open_files[file_des] if file_list is not None: return file_list[0] self.raise_os_error(errno.EBADF, str(file_des)) def has_open_file(self, file_object: FakeFile) -> bool: """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. """ return file_object in [ wrappers[0].get_object() for wrappers in self.open_files if wrappers ] def _normalize_path_sep(self, path: AnyStr) -> AnyStr: alt_sep = self._alternative_path_separator(path) if alt_sep is not None: return path.replace(alt_sep, self.get_path_separator(path)) return path def normcase(self, path: AnyStr) -> AnyStr: """Replace 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. """ file_path = make_string_path(path) return self._normalize_path_sep(file_path) def normpath(self, path: AnyStr) -> AnyStr: """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. """ path_str = self.normcase(path) drive, path_str = self.splitdrive(path_str) sep = self.get_path_separator(path_str) is_absolute_path = path_str.startswith(sep) path_components: List[AnyStr] = path_str.split( sep ) # pytype: disable=invalid-annotation collapsed_path_components: List[ AnyStr ] = [] # pytype: disable=invalid-annotation dot = matching_string(path_str, ".") dotdot = matching_string(path_str, "..") for component in path_components: if (not component) or (component == dot): continue if component == dotdot: if collapsed_path_components and ( collapsed_path_components[-1] != dotdot ): # Remove an up-reference: directory/.. collapsed_path_components.pop() continue elif is_absolute_path: # Ignore leading .. components if starting from the # root directory. continue collapsed_path_components.append(component) collapsed_path = sep.join(collapsed_path_components) if is_absolute_path: collapsed_path = sep + collapsed_path return drive + collapsed_path or dot def _original_path(self, path: AnyStr) -> AnyStr: """Return 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. """ def components_to_path(): if len(path_components) > len(normalized_components): normalized_components.extend( to_string(p) for p in path_components[len(normalized_components) :] ) sep = self.path_separator normalized_path = sep.join(normalized_components) if self.starts_with_sep(path) and not self.starts_with_sep(normalized_path): normalized_path = sep + normalized_path if len(normalized_path) == 2 and self.starts_with_drive_letter( normalized_path ): normalized_path += sep return normalized_path if self.is_case_sensitive or not path: return path path = self.replace_windows_root(path) path_components = self._path_components(path) normalized_components = [] current_dir = self.root for component in path_components: if not isinstance(current_dir, FakeDirectory): return components_to_path() dir_name, directory = self._directory_content( current_dir, to_string(component) ) if directory is None or ( isinstance(directory, FakeDirectory) and directory._byte_contents is None and directory.st_size == 0 ): return components_to_path() current_dir = cast(FakeDirectory, directory) normalized_components.append(dir_name) return components_to_path() def absnormpath(self, path: AnyStr) -> AnyStr: """Absolutize 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. """ path = self.normcase(path) cwd = matching_string(path, self.cwd) if not path: path = self.get_path_separator(path) if path == matching_string(path, "."): path = cwd elif not self._starts_with_root_path(path): # Prefix relative paths with cwd, if cwd is not root. root_name = matching_string(path, self.root.name) empty = matching_string(path, "") path = self.get_path_separator(path).join( (cwd != root_name and cwd or empty, path) ) else: path = self.replace_windows_root(path) return self.normpath(path) def splitpath(self, path: AnyStr) -> Tuple[AnyStr, AnyStr]: """Mimic os.path.split using the specified path_separator. Mimics os.path.split 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. """ path = make_string_path(path) sep = self.get_path_separator(path) alt_sep = self._alternative_path_separator(path) seps = sep if alt_sep is None else sep + alt_sep drive, path = self.splitdrive(path) i = len(path) while i and path[i - 1] not in seps: i -= 1 head, tail = path[:i], path[i:] # now tail has no slashes # remove trailing slashes from head, unless it's all slashes head = head.rstrip(seps) or head return drive + head, tail def splitdrive(self, path: AnyStr) -> Tuple[AnyStr, AnyStr]: """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. """ path_str = make_string_path(path) if self.is_windows_fs: if len(path_str) >= 2: norm_str = self.normcase(path_str) sep = self.get_path_separator(path_str) # UNC path_str handling if (norm_str[0:2] == sep * 2) and (norm_str[2:3] != sep): # UNC path_str handling - splits off the mount point # instead of the drive sep_index = norm_str.find(sep, 2) if sep_index == -1: return path_str[:0], path_str sep_index2 = norm_str.find(sep, sep_index + 1) if sep_index2 == sep_index + 1: return path_str[:0], path_str if sep_index2 == -1: sep_index2 = len(path_str) return path_str[:sep_index2], path_str[sep_index2:] if path_str[1:2] == matching_string(path_str, ":"): return path_str[:2], path_str[2:] return path_str[:0], path_str def splitroot(self, path: AnyStr): """Split a pathname into drive, root and tail. Implementation taken from ntpath and posixpath. """ p = os.fspath(path) if isinstance(p, bytes): sep = self.path_separator.encode() altsep = None if self.alternative_path_separator: altsep = self.alternative_path_separator.encode() colon = b":" unc_prefix = b"\\\\?\\UNC\\" empty = b"" else: sep = self.path_separator altsep = self.alternative_path_separator colon = ":" unc_prefix = "\\\\?\\UNC\\" empty = "" if self.is_windows_fs: normp = p.replace(altsep, sep) if altsep else p if normp[:1] == sep: if normp[1:2] == sep: # UNC drives, e.g. \\server\share or \\?\UNC\server\share # Device drives, e.g. \\.\device or \\?\device start = 8 if normp[:8].upper() == unc_prefix else 2 index = normp.find(sep, start) if index == -1: return p, empty, empty index2 = normp.find(sep, index + 1) if index2 == -1: return p, empty, empty return p[:index2], p[index2 : index2 + 1], p[index2 + 1 :] else: # Relative path with root, e.g. \Windows return empty, p[:1], p[1:] elif normp[1:2] == colon: if normp[2:3] == sep: # Absolute drive-letter path, e.g. X:\Windows return p[:2], p[2:3], p[3:] else: # Relative path with drive, e.g. X:Windows return p[:2], empty, p[2:] else: # Relative path, e.g. Windows return empty, empty, p else: if p[:1] != sep: # Relative path, e.g.: 'foo' return empty, empty, p elif p[1:2] != sep or p[2:3] == sep: # Absolute path, e.g.: '/foo', '///foo', '////foo', etc. return empty, sep, p[1:] else: return empty, p[:2], p[2:] def _join_paths_with_drive_support(self, *all_paths: AnyStr) -> AnyStr: """Taken from Python 3.5 os.path.join() code in ntpath.py and slightly adapted""" base_path = all_paths[0] paths_to_add = all_paths[1:] sep = self.get_path_separator(base_path) seps = [sep, self._alternative_path_separator(base_path)] result_drive, result_path = self.splitdrive(base_path) for path in paths_to_add: drive_part, path_part = self.splitdrive(path) if path_part and path_part[:1] in seps: # Second path is absolute if drive_part or not result_drive: result_drive = drive_part result_path = path_part continue elif drive_part and drive_part != result_drive: if self.is_case_sensitive or drive_part.lower() != result_drive.lower(): # Different drives => ignore the first path entirely result_drive = drive_part result_path = path_part continue # Same drive in different case result_drive = drive_part # Second path is relative to the first if result_path and result_path[-1:] not in seps: result_path = result_path + sep result_path = result_path + path_part # add separator between UNC and non-absolute path colon = matching_string(base_path, ":") if ( result_path and result_path[:1] not in seps and result_drive and result_drive[-1:] != colon ): return result_drive + sep + result_path return result_drive + result_path def joinpaths(self, *paths: AnyStr) -> AnyStr: """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. """ file_paths = [os.fspath(path) for path in paths] if len(file_paths) == 1: return paths[0] if self.is_windows_fs: return self._join_paths_with_drive_support(*file_paths) joined_path_segments = [] sep = self.get_path_separator(file_paths[0]) for path_segment in file_paths: if self._starts_with_root_path(path_segment): # An absolute path joined_path_segments = [path_segment] else: if joined_path_segments and not joined_path_segments[-1].endswith(sep): joined_path_segments.append(sep) if path_segment: joined_path_segments.append(path_segment) return matching_string(file_paths[0], "").join(joined_path_segments) @overload def _path_components(self, path: str) -> List[str]: ... @overload def _path_components(self, path: bytes) -> List[bytes]: ... def _path_components(self, path: AnyStr) -> List[AnyStr]: """Breaks 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.entries: raise OSError _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. """ if not path or path == self.get_path_separator(path): return [] drive, path = self.splitdrive(path) path_components = path.split(self.get_path_separator(path)) assert drive or path_components if not path_components[0]: if len(path_components) > 1 and not path_components[1]: path_components = [] else: # This is an absolute path. path_components = path_components[1:] if drive: path_components.insert(0, drive) return path_components def starts_with_drive_letter(self, file_path: AnyStr) -> bool: """Return 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. """ colon = matching_string(file_path, ":") if len(file_path) >= 2 and file_path[0:1].isalpha() and file_path[1:2] == colon: if self.is_windows_fs: return True if os.name == "nt": # special case if we are emulating Posix under Windows # check if the path exists because it has been mapped in # this is not foolproof, but handles most cases try: self.get_object_from_normpath(file_path) return True except OSError: return False return False def _starts_with_root_path(self, file_path: AnyStr) -> bool: root_name = matching_string(file_path, self.root.name) file_path = self._normalize_path_sep(file_path) return ( file_path.startswith(root_name) or not self.is_case_sensitive and file_path.lower().startswith(root_name.lower()) or self.starts_with_drive_letter(file_path) ) def replace_windows_root(self, path: AnyStr) -> AnyStr: """In windows, if a path starts with a single separator, it points to the root dir of the current mount point, usually a drive - replace it with that mount point path to get the real path. """ if path and self.is_windows_fs and self.root_dir: sep = self.get_path_separator(path) # ignore UNC paths if path[0:1] == sep and (len(path) == 1 or path[1:2] != sep): # check if we already have a mount point for that path for root_path in self.mount_points: root_path = matching_string(path, root_path) if path.startswith(root_path): return path # must be a pointer to the current drive - replace it mount_point = matching_string(path, self.root_dir_name) path = mount_point + path[1:] return path def _is_root_path(self, file_path: AnyStr) -> bool: root_name = matching_string(file_path, self.root.name) return file_path == root_name or self.is_mount_point(file_path) def is_mount_point(self, file_path: AnyStr) -> bool: """Return `True` if `file_path` points to a mount point.""" for mount_point in self.mount_points: mount_point = matching_string(file_path, mount_point) if ( file_path == mount_point or not self.is_case_sensitive and file_path.lower() == mount_point.lower() ): return True if ( self.is_windows_fs and len(file_path) == 3 and len(mount_point) == 2 and self.starts_with_drive_letter(file_path) and file_path[:2].lower() == mount_point.lower() ): return True return False def ends_with_path_separator(self, path: Union[int, AnyPath]) -> bool: """Return True if ``file_path`` ends with a valid path separator.""" if isinstance(path, int): return False file_path = make_string_path(path) if not file_path: return False sep = self.get_path_separator(file_path) altsep = self._alternative_path_separator(file_path) return file_path not in (sep, altsep) and ( file_path.endswith(sep) or altsep is not None and file_path.endswith(altsep) ) def is_filepath_ending_with_separator(self, path: AnyStr) -> bool: if not self.ends_with_path_separator(path): return False return self.isfile(self._path_without_trailing_separators(path)) def _directory_content( self, directory: FakeDirectory, component: str ) -> Tuple[Optional[str], Optional[AnyFile]]: if not isinstance(directory, FakeDirectory): return None, None if component in directory.entries: return component, directory.entries[component] if not self.is_case_sensitive: matching_content = [ (subdir, directory.entries[subdir]) for subdir in directory.entries if subdir.lower() == component.lower() ] if matching_content: return matching_content[0] return None, None def exists(self, file_path: AnyPath, check_link: bool = False) -> bool: """Return true if a path points to an existing file system object. Args: file_path: The path to examine. check_link: If True, links are not followed Returns: (bool) True if the corresponding object exists. Raises: TypeError: if file_path is None. """ if check_link and self.islink(file_path): return True path = to_string(self.make_string_path(file_path)) if path is None: raise TypeError if not path: return False if path == self.dev_null.name: return not self.is_windows_fs or sys.version_info >= (3, 8) try: if self.is_filepath_ending_with_separator(path): return False path = self.resolve_path(path) except OSError: return False if self._is_root_path(path): return True path_components: List[str] = self._path_components(path) current_dir = self.root for component in path_components: directory = self._directory_content(current_dir, to_string(component))[1] if directory is None: return False current_dir = cast(FakeDirectory, directory) return True def resolve_path(self, file_path: AnyStr, allow_fd: bool = False) -> AnyStr: """Follow 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. Returns: The resolved_path (str or byte). Raises: TypeError: if `file_path` is `None`. OSError: if `file_path` is '' or a part of the path doesn't exist. """ if allow_fd and isinstance(file_path, int): return self.get_open_file(file_path).get_object().path path = make_string_path(file_path) if path is None: # file.open(None) raises TypeError, so mimic that. raise TypeError("Expected file system path string, received None") if not path or not self._valid_relative_path(path): # file.open('') raises OSError, so mimic that, and validate that # all parts of a relative path exist. self.raise_os_error(errno.ENOENT, path) path = self.absnormpath(self._original_path(path)) path = self.replace_windows_root(path) if self._is_root_path(path): return path if path == matching_string(path, self.dev_null.name): return path path_components = self._path_components(path) resolved_components = self._resolve_components(path_components) path = self._components_to_path(resolved_components) # after resolving links, we have to check again for Windows root return self.replace_windows_root(path) # pytype: disable=bad-return-type def _components_to_path(self, component_folders): sep = ( self.get_path_separator(component_folders[0]) if component_folders else self.path_separator ) path = sep.join(component_folders) if not self._starts_with_root_path(path): path = sep + path return path def _resolve_components(self, components: List[AnyStr]) -> List[str]: current_dir = self.root link_depth = 0 path_components = [to_string(comp) for comp in components] resolved_components: List[str] = [] while path_components: component = path_components.pop(0) resolved_components.append(component) directory = self._directory_content(current_dir, component)[1] if directory is None: # The component of the path at this point does not actually # exist in the folder. We can't resolve the path any more. # It is legal to link to a file that does not yet exist, so # rather than raise an error, we just append the remaining # components to what return path we have built so far and # return that. resolved_components.extend(path_components) break # Resolve any possible symlinks in the current path component. elif S_ISLNK(directory.st_mode): # This link_depth check is not really meant to be an accurate # check. It is just a quick hack to prevent us from looping # forever on cycles. if link_depth > _MAX_LINK_DEPTH: self.raise_os_error( errno.ELOOP, self._components_to_path(resolved_components), ) link_path = self._follow_link(resolved_components, directory) # Following the link might result in the complete replacement # of the current_dir, so we evaluate the entire resulting path. target_components = self._path_components(link_path) path_components = target_components + path_components resolved_components = [] current_dir = self.root link_depth += 1 else: current_dir = cast(FakeDirectory, directory) return resolved_components def _valid_relative_path(self, file_path: AnyStr) -> bool: if self.is_windows_fs: return True slash_dotdot = matching_string(file_path, self.path_separator + "..") while file_path and slash_dotdot in file_path: file_path = file_path[: file_path.rfind(slash_dotdot)] if not self.exists(self.absnormpath(file_path)): return False return True def _follow_link(self, link_path_components: List[str], link: AnyFile) -> str: """Follow 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: OSError: if there are too many levels of symbolic link """ link_path = link.contents if link_path is not None: # ignore UNC prefix for local files if self.is_windows_fs and link_path.startswith("\\\\?\\"): link_path = link_path[4:] sep = self.get_path_separator(link_path) # For links to absolute paths, we want to throw out everything # in the path built so far and replace with the link. For relative # links, we have to append the link to what we have so far, if not self._starts_with_root_path(link_path): # Relative path. Append remainder of path to what we have # processed so far, excluding the name of the link itself. # /a/b => ../c should yield /a/../c # (which will normalize to /c) # /a/b => d should yield a/d components = link_path_components[:-1] components.append(link_path) link_path = sep.join(components) # Don't call self.NormalizePath(), as we don't want to prepend # self.cwd. return self.normpath(link_path) # pytype: disable=bad-return-type raise ValueError("Invalid link") def get_object_from_normpath( self, file_path: AnyPath, check_read_perm: bool = True, check_owner: bool = False, ) -> AnyFile: """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. check_read_perm: If True, raises OSError if a parent directory does not have read permission check_owner: If True, and check_read_perm is also True, only checks read permission if the current user id is different from the file object user id Returns: The FakeFile object corresponding to file_path. Raises: OSError: if the object is not found. """ path = make_string_path(file_path) if path == matching_string(path, self.root.name): return self.root if path == matching_string(path, self.dev_null.name): return self.dev_null path = self._original_path(path) path_components = self._path_components(path) target = self.root try: for component in path_components: if S_ISLNK(target.st_mode): if target.contents: target = cast(FakeDirectory, self.resolve(target.contents)) if not S_ISDIR(target.st_mode): if not self.is_windows_fs: self.raise_os_error(errno.ENOTDIR, path) self.raise_os_error(errno.ENOENT, path) target = target.get_entry(component) # type: ignore if ( not is_root() and check_read_perm and target and not self._can_read(target, check_owner) ): self.raise_os_error(errno.EACCES, target.path) except KeyError: self.raise_os_error(errno.ENOENT, path) return target @staticmethod def _can_read(target, owner_can_read): if target.st_uid == helpers.get_uid(): if owner_can_read or target.st_mode & 0o400: return True if target.st_gid == get_gid(): if target.st_mode & 0o040: return True return target.st_mode & 0o004 def get_object(self, file_path: AnyPath, check_read_perm: bool = True) -> FakeFile: """Search for the specified filesystem object within the fake filesystem. Args: file_path: Specifies the target FakeFile object to retrieve. check_read_perm: If True, raises OSError if a parent directory does not have read permission Returns: The FakeFile object corresponding to `file_path`. Raises: OSError: if the object is not found. """ path = make_string_path(file_path) path = self.absnormpath(self._original_path(path)) return self.get_object_from_normpath(path, check_read_perm) def resolve( self, file_path: AnyStr, follow_symlinks: bool = True, allow_fd: bool = False, check_read_perm: bool = True, check_owner: bool = False, ) -> FakeFile: """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 check_read_perm: If True, raises OSError if a parent directory does not have read permission check_owner: If True, and check_read_perm is also True, only checks read permission if the current user id is different from the file object user id Returns: The FakeFile object corresponding to `file_path`. Raises: OSError: if the object is not found. """ if isinstance(file_path, int): if allow_fd: return self.get_open_file(file_path).get_object() raise TypeError("path should be string, bytes or " "os.PathLike, not int") if follow_symlinks: return self.get_object_from_normpath( self.resolve_path(file_path, allow_fd), check_read_perm, check_owner, ) return self.lresolve(file_path) def lresolve(self, path: AnyPath) -> FakeFile: """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: OSError: if the object is not found. """ path_str = make_string_path(path) if not path_str: raise OSError(errno.ENOENT, path_str) if path_str == matching_string(path_str, self.root.name): # The root directory will never be a link return self.root # remove trailing separator path_str = self._path_without_trailing_separators(path_str) if path_str == matching_string(path_str, "."): path_str = matching_string(path_str, self.cwd) path_str = self._original_path(path_str) parent_directory, child_name = self.splitpath(path_str) if not parent_directory: parent_directory = matching_string(path_str, self.cwd) try: parent_obj = self.resolve(parent_directory) assert parent_obj if not isinstance(parent_obj, FakeDirectory): if not self.is_windows_fs and isinstance(parent_obj, FakeFile): self.raise_os_error(errno.ENOTDIR, path_str) self.raise_os_error(errno.ENOENT, path_str) if not parent_obj.st_mode & helpers.PERM_READ: self.raise_os_error(errno.EACCES, parent_directory) return ( parent_obj.get_entry(to_string(child_name)) if child_name else parent_obj ) except KeyError: pass raise OSError(errno.ENOENT, path_str) def add_object(self, file_path: AnyStr, file_object: AnyFile) -> None: """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. Raises: OSError: if file_path does not correspond to a directory. """ if not file_path: target_directory = self.root_dir else: target_directory = cast(FakeDirectory, self.resolve(file_path)) if not S_ISDIR(target_directory.st_mode): error = errno.ENOENT if self.is_windows_fs else errno.ENOTDIR self.raise_os_error(error, file_path) target_directory.add_entry(file_object) def rename( self, old_file_path: AnyPath, new_file_path: AnyPath, force_replace: bool = False, ) -> None: """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). """ old_path = make_string_path(old_file_path) new_path = make_string_path(new_file_path) ends_with_sep = self.ends_with_path_separator(old_path) old_path = self.absnormpath(old_path) new_path = self.absnormpath(new_path) if not self.exists(old_path, check_link=True): self.raise_os_error(errno.ENOENT, old_path, 2) if ends_with_sep: self._handle_broken_link_with_trailing_sep(old_path) old_object = self.lresolve(old_path) if not self.is_windows_fs: self._handle_posix_dir_link_errors(new_path, old_path, ends_with_sep) if self.exists(new_path, check_link=True): renamed_path = self._rename_to_existing_path( force_replace, new_path, old_path, old_object, ends_with_sep ) if renamed_path is None: return else: new_path = renamed_path old_dir, old_name = self.splitpath(old_path) new_dir, new_name = self.splitpath(new_path) if not self.exists(new_dir): self.raise_os_error(errno.ENOENT, new_dir) old_dir_object = self.resolve(old_dir) new_dir_object = self.resolve(new_dir) if old_dir_object.st_dev != new_dir_object.st_dev: self.raise_os_error(errno.EXDEV, old_path) if not S_ISDIR(new_dir_object.st_mode): self.raise_os_error( errno.EACCES if self.is_windows_fs else errno.ENOTDIR, new_path ) if new_dir_object.has_parent_object(old_object): self.raise_os_error(errno.EINVAL, new_path) self._do_rename(old_dir_object, old_name, new_dir_object, new_name) def _do_rename(self, old_dir_object, old_name, new_dir_object, new_name): object_to_rename = old_dir_object.get_entry(old_name) old_dir_object.remove_entry(old_name, recursive=False) object_to_rename.name = new_name new_name = new_dir_object._normalized_entryname(new_name) old_entry = ( new_dir_object.get_entry(new_name) if new_name in new_dir_object.entries else None ) try: if old_entry: # in case of overwriting remove the old entry first new_dir_object.remove_entry(new_name) new_dir_object.add_entry(object_to_rename) except OSError: # adding failed, roll back the changes before re-raising if old_entry and new_name not in new_dir_object.entries: new_dir_object.add_entry(old_entry) object_to_rename.name = old_name old_dir_object.add_entry(object_to_rename) raise def _handle_broken_link_with_trailing_sep(self, path: AnyStr) -> None: # note that the check for trailing sep has to be done earlier if self.islink(path): if not self.exists(path): error = ( errno.ENOENT if self.is_macos else errno.EINVAL if self.is_windows_fs else errno.ENOTDIR ) self.raise_os_error(error, path) def _handle_posix_dir_link_errors( self, new_file_path: AnyStr, old_file_path: AnyStr, ends_with_sep: bool ) -> None: if self.isdir(old_file_path, follow_symlinks=False) and self.islink( new_file_path ): self.raise_os_error(errno.ENOTDIR, new_file_path) if self.isdir(new_file_path, follow_symlinks=False) and self.islink( old_file_path ): if ends_with_sep and self.is_macos: return error = errno.ENOTDIR if ends_with_sep else errno.EISDIR self.raise_os_error(error, new_file_path) if ( ends_with_sep and self.islink(old_file_path) and old_file_path == new_file_path and not self.is_windows_fs ): self.raise_os_error(errno.ENOTDIR, new_file_path) def _rename_to_existing_path( self, force_replace: bool, new_file_path: AnyStr, old_file_path: AnyStr, old_object: FakeFile, ends_with_sep: bool, ) -> Optional[AnyStr]: new_object = self.get_object(new_file_path) if old_file_path == new_file_path: if not S_ISLNK(new_object.st_mode) and ends_with_sep: error = errno.EINVAL if self.is_windows_fs else errno.ENOTDIR self.raise_os_error(error, old_file_path) return None # Nothing to do here if old_object == new_object: return self._rename_same_object(new_file_path, old_file_path) if S_ISDIR(new_object.st_mode) or S_ISLNK(new_object.st_mode): self._handle_rename_error_for_dir_or_link( force_replace, new_file_path, new_object, old_object, ends_with_sep, ) elif S_ISDIR(old_object.st_mode): error = errno.EEXIST if self.is_windows_fs else errno.ENOTDIR self.raise_os_error(error, new_file_path) elif self.is_windows_fs and not force_replace: self.raise_os_error(errno.EEXIST, new_file_path) else: self.remove_object(new_file_path) return new_file_path def _handle_rename_error_for_dir_or_link( self, force_replace: bool, new_file_path: AnyStr, new_object: FakeFile, old_object: FakeFile, ends_with_sep: bool, ) -> None: if self.is_windows_fs: if force_replace: self.raise_os_error(errno.EACCES, new_file_path) else: self.raise_os_error(errno.EEXIST, new_file_path) if not S_ISLNK(new_object.st_mode): if new_object.entries: if ( not S_ISLNK(old_object.st_mode) or not ends_with_sep or not self.is_macos ): self.raise_os_error(errno.ENOTEMPTY, new_file_path) if S_ISREG(old_object.st_mode): self.raise_os_error(errno.EISDIR, new_file_path) def _rename_same_object( self, new_file_path: AnyStr, old_file_path: AnyStr ) -> Optional[AnyStr]: do_rename = old_file_path.lower() == new_file_path.lower() if not do_rename: try: real_old_path = self.resolve_path(old_file_path) original_old_path = self._original_path(real_old_path) real_new_path = self.resolve_path(new_file_path) if real_new_path == original_old_path and ( new_file_path == real_old_path ) == (new_file_path.lower() == real_old_path.lower()): real_object = self.resolve(old_file_path, follow_symlinks=False) do_rename = ( os.path.basename(old_file_path) == real_object.name or not self.is_macos ) else: do_rename = real_new_path.lower() == real_old_path.lower() if do_rename: # only case is changed in case-insensitive file # system - do the rename parent, file_name = self.splitpath(new_file_path) new_file_path = self.joinpaths( self._original_path(parent), file_name ) except OSError: # ResolvePath may fail due to symlink loop issues or # similar - in this case just assume the paths # to be different pass if not do_rename: # hard links to the same file - nothing to do return None return new_file_path def remove_object(self, file_path: AnyStr) -> None: """Remove an existing file or directory. Args: file_path: The path to the file relative to self. Raises: OSError: 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 '/'). """ file_path = self.absnormpath(self._original_path(file_path)) if self._is_root_path(file_path): self.raise_os_error(errno.EBUSY, file_path) try: dirname, basename = self.splitpath(file_path) target_directory = self.resolve(dirname, check_read_perm=False) target_directory.remove_entry(basename) except KeyError: self.raise_os_error(errno.ENOENT, file_path) except AttributeError: self.raise_os_error(errno.ENOTDIR, file_path) def make_string_path(self, path: AnyPath) -> AnyStr: path_str = make_string_path(path) os_sep = matching_string(path_str, os.sep) fake_sep = self.get_path_separator(path_str) return path_str.replace(os_sep, fake_sep) # type: ignore[return-value] def create_dir( self, directory_path: AnyPath, perm_bits: int = helpers.PERM_DEF ) -> FakeDirectory: """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. """ dir_path = self.make_string_path(directory_path) dir_path = self.absnormpath(dir_path) self._auto_mount_drive_if_needed(dir_path) if self.exists(dir_path, check_link=True) and dir_path not in self.mount_points: self.raise_os_error(errno.EEXIST, dir_path) path_components = self._path_components(dir_path) current_dir = self.root new_dirs = [] for component in [to_string(p) for p in path_components]: directory = self._directory_content(current_dir, to_string(component))[1] if not directory: new_dir = FakeDirectory(component, filesystem=self) new_dirs.append(new_dir) if self.is_windows_fs and current_dir == self.root: current_dir = self.root_dir current_dir.add_entry(new_dir) current_dir = new_dir else: if S_ISLNK(directory.st_mode): assert directory.contents directory = self.resolve(directory.contents) assert directory current_dir = cast(FakeDirectory, directory) if directory.st_mode & S_IFDIR != S_IFDIR: self.raise_os_error(errno.ENOTDIR, current_dir.path) # set the permission after creating the directories # to allow directory creation inside a read-only directory for new_dir in new_dirs: new_dir.st_mode = S_IFDIR | perm_bits return current_dir def create_file( self, file_path: AnyPath, st_mode: int = S_IFREG | helpers.PERM_DEF_FILE, contents: AnyString = "", st_size: Optional[int] = None, create_missing_dirs: bool = True, apply_umask: bool = False, encoding: Optional[str] = None, errors: Optional[str] = None, side_effect: Optional[Callable] = None, ) -> FakeFile: """Create `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: OSError: if the file already exists. OSError: if the containing directory is required and missing. """ return self.create_file_internally( file_path, st_mode, contents, st_size, create_missing_dirs, apply_umask, encoding, errors, side_effect=side_effect, ) def add_real_file( self, source_path: AnyPath, read_only: bool = True, target_path: Optional[AnyPath] = None, ) -> FakeFile: """Create `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. OSError: 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. """ target_path = target_path or source_path source_path_str = make_string_path(source_path) real_stat = os.stat(source_path_str) fake_file = self.create_file_internally(target_path, read_from_real_fs=True) # for read-only mode, remove the write/executable permission bits fake_file.stat_result.set_from_stat_result(real_stat) if read_only: fake_file.st_mode &= 0o777444 fake_file.file_path = source_path_str self.change_disk_usage(fake_file.size, fake_file.name, fake_file.st_dev) return fake_file def add_real_symlink( self, source_path: AnyPath, target_path: Optional[AnyPath] = None ) -> FakeFile: """Create a symlink at source_path (or target_path, if given). It will point to the same path as the symlink on the real filesystem. Relative symlinks will point relative to their new location. Absolute symlinks will point to the same, absolute path as on the real filesystem. Args: source_path: The path to the existing symlink. target_path: If given, the name of the symlink in the fake filesystem, otherwise, the same as `source_path`. Returns: the newly created FakeFile object. Raises: OSError: if the directory does not exist in the real file system. OSError: if the symlink could not be created (see :py:meth:`create_file`). OSError: if the directory already exists in the fake file system. """ source_path_str = make_string_path(source_path) # TODO: add test source_path_str = self._path_without_trailing_separators(source_path_str) if not os.path.exists(source_path_str) and not os.path.islink(source_path_str): self.raise_os_error(errno.ENOENT, source_path_str) target = os.readlink(source_path_str) if target_path: return self.create_symlink(target_path, target) else: return self.create_symlink(source_path_str, target) def add_real_directory( self, source_path: AnyPath, read_only: bool = True, lazy_read: bool = True, target_path: Optional[AnyPath] = None, ) -> FakeDirectory: """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. Symlinks are supported. 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. OSError: if the directory already exists in the fake file system. """ source_path_str = make_string_path(source_path) # TODO: add test source_path_str = self._path_without_trailing_separators(source_path_str) if not os.path.exists(source_path_str): self.raise_os_error(errno.ENOENT, source_path_str) target_path_str = make_string_path(target_path or source_path_str) self._auto_mount_drive_if_needed(target_path_str) new_dir: FakeDirectory if lazy_read: parent_path = os.path.split(target_path_str)[0] if self.exists(parent_path): parent_dir = self.get_object(parent_path) else: parent_dir = self.create_dir(parent_path) new_dir = FakeDirectoryFromRealDirectory( source_path_str, self, read_only, target_path_str ) parent_dir.add_entry(new_dir) else: new_dir = self.create_dir(target_path_str) for base, _, files in os.walk(source_path_str): new_base = os.path.join( new_dir.path, # type: ignore[arg-type] os.path.relpath(base, source_path_str), ) for fileEntry in os.listdir(base): abs_fileEntry = os.path.join(base, fileEntry) if not os.path.islink(abs_fileEntry): continue self.add_real_symlink( abs_fileEntry, os.path.join(new_base, fileEntry) ) for fileEntry in files: path = os.path.join(base, fileEntry) if os.path.islink(path): continue self.add_real_file( path, read_only, os.path.join(new_base, fileEntry) ) return new_dir def add_real_paths( self, path_list: List[AnyStr], read_only: bool = True, lazy_dir_read: bool = True, ) -> None: """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. """ for path in path_list: if os.path.isdir(path): self.add_real_directory(path, read_only, lazy_dir_read) else: self.add_real_file(path, read_only) def create_file_internally( self, file_path: AnyPath, st_mode: int = S_IFREG | helpers.PERM_DEF_FILE, contents: AnyString = "", st_size: Optional[int] = None, create_missing_dirs: bool = True, apply_umask: bool = False, encoding: Optional[str] = None, errors: Optional[str] = None, read_from_real_fs: bool = False, side_effect: Optional[Callable] = None, ) -> FakeFile: """Internal 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. side_effect: function handle that is executed when file is written, must accept the file object as an argument. """ path = self.make_string_path(file_path) path = self.absnormpath(path) if not is_int_type(st_mode): raise TypeError( "st_mode must be of int type - did you mean to set contents?" ) if self.exists(path, check_link=True): self.raise_os_error(errno.EEXIST, path) parent_directory, new_file = self.splitpath(path) if not parent_directory: parent_directory = matching_string(path, self.cwd) self._auto_mount_drive_if_needed(parent_directory) if not self.exists(parent_directory): if not create_missing_dirs: self.raise_os_error(errno.ENOENT, parent_directory) parent_directory = matching_string( path, self.create_dir(parent_directory).path # type: ignore ) else: parent_directory = self._original_path(parent_directory) if apply_umask: st_mode &= ~self.umask file_object: FakeFile if read_from_real_fs: file_object = FakeFileFromRealFile( to_string(path), filesystem=self, side_effect=side_effect ) else: file_object = FakeFile( new_file, st_mode, filesystem=self, encoding=encoding, errors=errors, side_effect=side_effect, ) self.add_object(parent_directory, file_object) if st_size is None and contents is None: contents = "" if not read_from_real_fs and (contents is not None or st_size is not None): try: if st_size is not None: file_object.set_large_file_size(st_size) else: file_object.set_initial_contents(contents) # type: ignore except OSError: self.remove_object(path) raise return file_object def create_symlink( self, file_path: AnyPath, link_target: AnyPath, create_missing_dirs: bool = True, ) -> FakeFile: """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`). """ link_path = self.make_string_path(file_path) link_target_path = self.make_string_path(link_target) link_path = self.normcase(link_path) # the link path cannot end with a path separator if self.ends_with_path_separator(link_path): if self.exists(link_path): self.raise_os_error(errno.EEXIST, link_path) if self.exists(link_target_path): if not self.is_windows_fs: self.raise_os_error(errno.ENOENT, link_path) else: if self.is_windows_fs: self.raise_os_error(errno.EINVAL, link_target_path) if not self.exists( self._path_without_trailing_separators(link_path), check_link=True, ): self.raise_os_error(errno.ENOENT, link_target_path) if self.is_macos: # to avoid EEXIST exception, remove the link # if it already exists if self.exists(link_path, check_link=True): self.remove_object(link_path) else: self.raise_os_error(errno.EEXIST, link_target_path) # resolve the link path only if it is not a link itself if not self.islink(link_path): link_path = self.resolve_path(link_path) return self.create_file_internally( link_path, st_mode=S_IFLNK | helpers.PERM_DEF, contents=link_target_path, create_missing_dirs=create_missing_dirs, ) def create_link( self, old_path: AnyPath, new_path: AnyPath, follow_symlinks: bool = True, create_missing_dirs: bool = True, ) -> FakeFile: """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. follow_symlinks: If False and old_path is a symlink, link the symlink instead of the object it points to. create_missing_dirs: If `True`, any missing parent directories of file_path will be created 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. """ old_path_str = make_string_path(old_path) new_path_str = make_string_path(new_path) new_path_normalized = self.absnormpath(new_path_str) if self.exists(new_path_normalized, check_link=True): self.raise_os_error(errno.EEXIST, new_path_str) new_parent_directory, new_basename = self.splitpath(new_path_normalized) if not new_parent_directory: new_parent_directory = matching_string(new_path_str, self.cwd) if not self.exists(new_parent_directory): if create_missing_dirs: self.create_dir(new_parent_directory) else: self.raise_os_error(errno.ENOENT, new_parent_directory) if self.ends_with_path_separator(old_path_str): error = errno.EINVAL if self.is_windows_fs else errno.ENOTDIR self.raise_os_error(error, old_path_str) if not self.is_windows_fs and self.ends_with_path_separator(new_path): self.raise_os_error(errno.ENOENT, old_path_str) # Retrieve the target file try: old_file = self.resolve(old_path_str, follow_symlinks=follow_symlinks) except OSError: self.raise_os_error(errno.ENOENT, old_path_str) if old_file.st_mode & S_IFDIR: self.raise_os_error( errno.EACCES if self.is_windows_fs else errno.EPERM, old_path_str, ) # abuse the name field to control the filename of the # newly created link old_file.name = new_basename # type: ignore[assignment] self.add_object(new_parent_directory, old_file) return old_file def link( self, old_path: AnyPath, new_path: AnyPath, follow_symlinks: bool = True, ) -> FakeFile: """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. follow_symlinks: If False and old_path is a symlink, link the symlink instead of the object it points to. 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. """ return self.create_link( old_path, new_path, follow_symlinks, create_missing_dirs=False ) def _is_circular_link(self, link_obj: FakeFile) -> bool: try: assert link_obj.contents self.resolve_path(link_obj.contents) except OSError as exc: return exc.errno == errno.ELOOP return False def readlink(self, path: AnyPath) -> str: """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) """ if path is None: raise TypeError link_path = make_string_path(path) link_obj = self.lresolve(link_path) if S_IFMT(link_obj.st_mode) != S_IFLNK: self.raise_os_error(errno.EINVAL, link_path) if self.ends_with_path_separator(link_path): if not self.is_windows_fs and self.exists(link_path): self.raise_os_error(errno.EINVAL, link_path) if not self.exists(link_obj.path): # type: ignore if self.is_windows_fs: error = errno.EINVAL elif self._is_circular_link(link_obj): if self.is_macos: return link_obj.path # type: ignore[return-value] error = errno.ELOOP else: error = errno.ENOENT self.raise_os_error(error, link_obj.path) assert link_obj.contents return link_obj.contents def makedir(self, dir_path: AnyPath, mode: int = helpers.PERM_DEF) -> None: """Create a leaf Fake directory. Args: dir_path: (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`. """ dir_name = make_string_path(dir_path) ends_with_sep = self.ends_with_path_separator(dir_name) dir_name = self._path_without_trailing_separators(dir_name) if not dir_name: self.raise_os_error(errno.ENOENT, "") if self.is_windows_fs: dir_name = self.absnormpath(dir_name) parent_dir, _ = self.splitpath(dir_name) if parent_dir: base_dir = self.normpath(parent_dir) ellipsis = matching_string(parent_dir, self.path_separator + "..") if parent_dir.endswith(ellipsis) and not self.is_windows_fs: base_dir, dummy_dotdot, _ = parent_dir.partition(ellipsis) if not self.exists(base_dir): self.raise_os_error(errno.ENOENT, base_dir) dir_name = self.absnormpath(dir_name) if self.exists(dir_name, check_link=True): if self.is_windows_fs and dir_name == self.root_dir_name: error_nr = errno.EACCES else: error_nr = errno.EEXIST if ends_with_sep and self.is_macos and not self.exists(dir_name): # to avoid EEXIST exception, remove the link self.remove_object(dir_name) else: self.raise_os_error(error_nr, dir_name) head, tail = self.splitpath(dir_name) self.add_object( to_string(head), FakeDirectory(to_string(tail), mode & ~self.umask, filesystem=self), ) def _path_without_trailing_separators(self, path: AnyStr) -> AnyStr: while self.ends_with_path_separator(path): path = path[:-1] return path def makedirs( self, dir_name: AnyStr, mode: int = helpers.PERM_DEF, exist_ok: bool = False ) -> None: """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. Raises: OSError: if the directory already exists and exist_ok=False, or as per :py:meth:`create_dir`. """ if not dir_name: self.raise_os_error(errno.ENOENT, "") ends_with_sep = self.ends_with_path_separator(dir_name) dir_name = self.absnormpath(dir_name) if ( ends_with_sep and self.is_macos and self.exists(dir_name, check_link=True) and not self.exists(dir_name) ): # to avoid EEXIST exception, remove the link self.remove_object(dir_name) dir_name_str = to_string(dir_name) path_components = self._path_components(dir_name_str) # Raise a permission denied error if the first existing directory # is not writeable. current_dir = self.root_dir for component in path_components: if ( not hasattr(current_dir, "entries") or component not in current_dir.entries ): break else: current_dir = cast(FakeDirectory, current_dir.entries[component]) try: self.create_dir(dir_name, mode & ~self.umask) except OSError as e: if e.errno == errno.EACCES: # permission denied - propagate exception raise if not exist_ok or not isinstance(self.resolve(dir_name), FakeDirectory): if self.is_windows_fs and e.errno == errno.ENOTDIR: e.errno = errno.ENOENT self.raise_os_error(e.errno, e.filename) def _is_of_type( self, path: AnyPath, st_flag: int, follow_symlinks: bool = True, check_read_perm: bool = True, ) -> bool: """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 check_read_perm: If True (default) False is returned for existing but unreadable file paths. Returns: (boolean) `True` if the st_flag is set in path's st_mode. Raises: TypeError: if path is None """ if path is None: raise TypeError file_path = make_string_path(path) try: obj = self.resolve( file_path, follow_symlinks, check_read_perm=check_read_perm ) if obj: self.raise_for_filepath_ending_with_separator( file_path, obj, macos_handling=not follow_symlinks ) return S_IFMT(obj.st_mode) == st_flag except OSError: return False return False def isdir(self, path: AnyPath, follow_symlinks: bool = True) -> bool: """Determine 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. """ return self._is_of_type(path, S_IFDIR, follow_symlinks) def isfile(self, path: AnyPath, follow_symlinks: bool = True) -> bool: """Determine 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. """ return self._is_of_type(path, S_IFREG, follow_symlinks, check_read_perm=False) def islink(self, path: AnyPath) -> bool: """Determine 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. """ return self._is_of_type(path, S_IFLNK, follow_symlinks=False) if sys.version_info >= (3, 12): def isjunction(self, path: AnyPath) -> bool: """Returns False. Junctions are never faked.""" return False def confirmdir( self, target_directory: AnyStr, check_owner: bool = False ) -> FakeDirectory: """Test that the target is actually a directory, raising OSError if not. Args: target_directory: Path to the target directory within the fake filesystem. check_owner: If True, only checks read permission if the current user id is different from the file object user id Returns: The FakeDirectory object corresponding to target_directory. Raises: OSError: if the target is not a directory. """ directory = cast( FakeDirectory, self.resolve(target_directory, check_owner=check_owner), ) if not directory.st_mode & S_IFDIR: self.raise_os_error(errno.ENOTDIR, target_directory, 267) return directory def remove(self, path: AnyStr) -> None: """Remove 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. """ norm_path = make_string_path(path) norm_path = self.absnormpath(norm_path) if self.ends_with_path_separator(path): self._handle_broken_link_with_trailing_sep(norm_path) if self.exists(norm_path): obj = self.resolve(norm_path, check_read_perm=False) if S_IFMT(obj.st_mode) == S_IFDIR: link_obj = self.lresolve(norm_path) if S_IFMT(link_obj.st_mode) != S_IFLNK: if self.is_windows_fs: error = errno.EACCES elif self.is_macos: error = errno.EPERM else: error = errno.EISDIR self.raise_os_error(error, norm_path) if path.endswith(self.get_path_separator(path)): if self.is_windows_fs: error = errno.EACCES elif self.is_macos: error = errno.EPERM else: error = errno.ENOTDIR self.raise_os_error(error, norm_path) else: self.raise_for_filepath_ending_with_separator(path, obj) self.remove_object(norm_path) def rmdir(self, target_directory: AnyStr, allow_symlink: bool = False) -> None: """Remove 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 '.'. """ if target_directory == matching_string(target_directory, "."): error_nr = errno.EACCES if self.is_windows_fs else errno.EINVAL self.raise_os_error(error_nr, target_directory) ends_with_sep = self.ends_with_path_separator(target_directory) target_directory = self.absnormpath(target_directory) if self.confirmdir(target_directory, check_owner=True): if not self.is_windows_fs and self.islink(target_directory): if allow_symlink: return if not ends_with_sep or not self.is_macos: self.raise_os_error(errno.ENOTDIR, target_directory) dir_object = self.resolve(target_directory, check_owner=True) if dir_object.entries: self.raise_os_error(errno.ENOTEMPTY, target_directory) self.remove_object(target_directory) def listdir(self, target_directory: AnyStr) -> List[AnyStr]: """Return 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. If `shuffle_listdir_results` is set, the order is not the same in subsequent calls to avoid tests relying on any ordering. Raises: OSError: if the target is not a directory. """ target_directory = self.resolve_path(target_directory, allow_fd=True) directory = self.confirmdir(target_directory) directory_contents = list(directory.entries.keys()) if self.shuffle_listdir_results: random.shuffle(directory_contents) return directory_contents # type: ignore[return-value] def __str__(self) -> str: return str(self.root_dir) def _add_standard_streams(self) -> None: self._add_open_file(StandardStreamWrapper(sys.stdin)) self._add_open_file(StandardStreamWrapper(sys.stdout)) self._add_open_file(StandardStreamWrapper(sys.stderr)) def _create_temp_dir(self): # the temp directory is assumed to exist at least in `tempfile`, # so we create it here for convenience temp_dir = tempfile.gettempdir() if not self.exists(temp_dir): self.create_dir(temp_dir) if sys.platform != "win32" and not self.exists("/tmp"): # under Posix, we also create a link in /tmp if the path does not exist self.create_symlink("/tmp", temp_dir) # reset the used size to 0 to avoid having the link size counted # which would make disk size tests more complicated next(iter(self.mount_points.values()))["used_size"] = 0 def _run_doctest() -> TestResults: import doctest import pyfakefs return doctest.testmod(pyfakefs.fake_filesystem) def __getattr__(name): # backwards compatibility for read access to globals moved to helpers if name == "USER_ID": return helpers.USER_ID if name == "GROUP_ID": return helpers.GROUP_ID raise AttributeError(f"No attribute {name!r}.") if __name__ == "__main__": _run_doctest() fake_filesystem_shutil.py000064400000007253150043321510011661 0ustar00# Copyright 2009 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """A fake shutil module implementation that uses fake_filesystem for unit tests. Note that only `shutildisk_usage()` is faked, the rest of the functions shall work fine with the fake file system if `os`/`os.path` are patched. :Includes: FakeShutil: Uses a FakeFilesystem to provide a fake replacement for the shutil module. :Usage: The fake implementation is automatically involved if using `fake_filesystem_unittest.TestCase`, pytest fs fixture, or directly `Patcher`. """ import os import shutil import sys class FakeShutilModule: """Uses a FakeFilesystem to provide a fake replacement for shutil module. """ @staticmethod def dir(): """Return the list of patched function names. Used for patching functions imported from the module. """ return ("disk_usage",) def __init__(self, filesystem): """Construct fake shutil module using the fake filesystem. Args: filesystem: FakeFilesystem used to provide file system information """ self.filesystem = filesystem self._shutil_module = shutil def disk_usage(self, path): """Return the total, used and free disk space in bytes as named tuple or placeholder holder values simulating unlimited space if not set. Args: path: defines the filesystem device which is queried """ return self.filesystem.get_disk_usage(path) if sys.version_info >= (3, 12) and sys.platform == "win32": def copy2(self, src, dst, *, follow_symlinks=True): """Since Python 3.12, there is an optimization fow Windows, using the Windows API. We just remove this and fall back to the previous implementation. """ if self.filesystem.isdir(dst): dst = self.filesystem.joinpaths(dst, os.path.basename(src)) self.copyfile(src, dst, follow_symlinks=follow_symlinks) self.copystat(src, dst, follow_symlinks=follow_symlinks) return dst def copytree( self, src, dst, symlinks=False, ignore=None, copy_function=shutil.copy2, ignore_dangling_symlinks=False, dirs_exist_ok=False, ): """Make sure the default argument is patched.""" if copy_function == shutil.copy2: copy_function = self.copy2 return self._shutil_module.copytree( src, dst, symlinks, ignore, copy_function, ignore_dangling_symlinks, dirs_exist_ok, ) def move(self, src, dst, copy_function=shutil.copy2): """Make sure the default argument is patched.""" if copy_function == shutil.copy2: copy_function = self.copy2 return self._shutil_module.move(src, dst, copy_function) def __getattr__(self, name): """Forwards any non-faked calls to the standard shutil module.""" return getattr(self._shutil_module, name) fake_filesystem_unittest.py000064400000123277150043321510012235 0ustar00# Copyright 2014 Altera Corporation. All Rights Reserved. # Copyright 2015-2017 John McGehee # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """This module provides a base class derived from `unittest.TestClass` for unit tests using the :py:class:`pyfakefs` module. `fake_filesystem_unittest.TestCase` searches `sys.modules` for modules that import the `os`, `io`, `path` `shutil`, and `pathlib` modules. The `setUpPyfakefs()` method binds these modules to the corresponding fake modules from `pyfakefs`. Further, the `open()` built-in is bound to a fake `open()`. It is expected that `setUpPyfakefs()` be invoked at the beginning of the derived class' `setUp()` method. There is no need to add anything to the derived class' `tearDown()` method. During the test, everything uses the fake file system and modules. This means that even in your test fixture, familiar functions like `open()` and `os.makedirs()` manipulate the fake file system. Existing unit tests that use the real file system can be retrofitted to use pyfakefs by simply changing their base class from `:py:class`unittest.TestCase` to `:py:class`pyfakefs.fake_filesystem_unittest.TestCase`. """ import _io # type:ignore[import] import builtins import doctest import functools import genericpath import inspect import io import linecache import os import shutil import sys import tempfile import tokenize from importlib.abc import Loader, MetaPathFinder from types import ModuleType, TracebackType, FunctionType from typing import ( Any, Callable, Dict, List, Set, Tuple, Optional, Union, Type, Iterator, cast, ItemsView, Sequence, ) import unittest import warnings from unittest import TestSuite from pyfakefs.fake_filesystem import ( set_uid, set_gid, reset_ids, PatchMode, FakeFilesystem, ) from pyfakefs.helpers import IS_PYPY from pyfakefs.mox3_stubout import StubOutForTesting from importlib.machinery import ModuleSpec from importlib import reload from pyfakefs import fake_filesystem, fake_io, fake_os, fake_open, fake_path, fake_file from pyfakefs import fake_filesystem_shutil from pyfakefs import fake_pathlib from pyfakefs import mox3_stubout from pyfakefs.extra_packages import pathlib2, use_scandir if use_scandir: from pyfakefs import fake_scandir OS_MODULE = "nt" if sys.platform == "win32" else "posix" PATH_MODULE = "ntpath" if sys.platform == "win32" else "posixpath" def patchfs( _func: Optional[Callable] = None, *, additional_skip_names: Optional[List[Union[str, ModuleType]]] = None, modules_to_reload: Optional[List[ModuleType]] = None, modules_to_patch: Optional[Dict[str, ModuleType]] = None, allow_root_user: bool = True, use_known_patches: bool = True, patch_open_code: PatchMode = PatchMode.OFF, patch_default_args: bool = False, use_cache: bool = True ) -> Callable: """Convenience decorator to use patcher with additional parameters in a test function. Usage:: @patchfs def test_my_function(fake_fs): fake_fs.create_file('foo') @patchfs(allow_root_user=False) def test_with_patcher_args(fs): os.makedirs('foo/bar') """ def wrap_patchfs(f: Callable) -> Callable: @functools.wraps(f) def wrapped(*args, **kwargs): with Patcher( additional_skip_names=additional_skip_names, modules_to_reload=modules_to_reload, modules_to_patch=modules_to_patch, allow_root_user=allow_root_user, use_known_patches=use_known_patches, patch_open_code=patch_open_code, patch_default_args=patch_default_args, use_cache=use_cache, ) as p: args = list(args) args.append(p.fs) return f(*args, **kwargs) return wrapped if _func: if not callable(_func): raise TypeError( "Decorator argument is not a function.\n" "Did you mean `@patchfs(additional_skip_names=...)`?" ) if hasattr(_func, "patchings"): _func.nr_patches = len(_func.patchings) # type: ignore return wrap_patchfs(_func) return wrap_patchfs DOCTEST_PATCHER = None def load_doctests( loader: Any, tests: TestSuite, ignore: Any, module: ModuleType, additional_skip_names: Optional[List[Union[str, ModuleType]]] = None, modules_to_reload: Optional[List[ModuleType]] = None, modules_to_patch: Optional[Dict[str, ModuleType]] = None, allow_root_user: bool = True, use_known_patches: bool = True, patch_open_code: PatchMode = PatchMode.OFF, patch_default_args: bool = False, ) -> TestSuite: # pylint:disable=unused-argument """Load the doctest tests for the specified module into unittest. Args: loader, tests, ignore : arguments passed in from `load_tests()` module: module under test remaining args: see :py:class:`TestCase` for an explanation File `example_test.py` in the pyfakefs release provides a usage example. """ has_patcher = Patcher.DOC_PATCHER is not None if not has_patcher: Patcher.DOC_PATCHER = Patcher( additional_skip_names=additional_skip_names, modules_to_reload=modules_to_reload, modules_to_patch=modules_to_patch, allow_root_user=allow_root_user, use_known_patches=use_known_patches, patch_open_code=patch_open_code, patch_default_args=patch_default_args, is_doc_test=True, ) assert Patcher.DOC_PATCHER is not None globs = Patcher.DOC_PATCHER.replace_globs(vars(module)) tests.addTests( doctest.DocTestSuite( module, globs=globs, setUp=Patcher.DOC_PATCHER.setUp, tearDown=Patcher.DOC_PATCHER.tearDown, ) ) return tests class TestCaseMixin: """Test case mixin that automatically replaces file-system related modules by fake implementations. Attributes: additional_skip_names: names of modules inside of which no module replacement shall be performed, in addition to the names in :py:attr:`fake_filesystem_unittest.Patcher.SKIPNAMES`. Instead of the module names, the modules themselves may be used. modules_to_reload: A list of modules that need to be reloaded to be patched dynamically; may be needed if the module imports file system modules under an alias .. caution:: Reloading modules may have unwanted side effects. modules_to_patch: A dictionary of fake modules mapped to the fully qualified patched module names. Can be used to add patching of modules not provided by `pyfakefs`. If you specify some of these attributes here and you have DocTests, consider also specifying the same arguments to :py:func:`load_doctests`. Example usage in derived test classes:: from unittest import TestCase from fake_filesystem_unittest import TestCaseMixin class MyTestCase(TestCase, TestCaseMixin): def __init__(self, methodName='runTest'): super(MyTestCase, self).__init__( methodName=methodName, additional_skip_names=['posixpath']) import sut class AnotherTestCase(TestCase, TestCaseMixin): def __init__(self, methodName='runTest'): super(MyTestCase, self).__init__( methodName=methodName, modules_to_reload=[sut]) """ additional_skip_names: Optional[List[Union[str, ModuleType]]] = None modules_to_reload: Optional[List[ModuleType]] = None modules_to_patch: Optional[Dict[str, ModuleType]] = None @property def patcher(self): if hasattr(self, "_patcher"): return self._patcher or Patcher.PATCHER return Patcher.PATCHER @property def fs(self) -> FakeFilesystem: return cast(FakeFilesystem, self.patcher.fs) def setUpPyfakefs( self, additional_skip_names: Optional[List[Union[str, ModuleType]]] = None, modules_to_reload: Optional[List[ModuleType]] = None, modules_to_patch: Optional[Dict[str, ModuleType]] = None, allow_root_user: bool = True, use_known_patches: bool = True, patch_open_code: PatchMode = PatchMode.OFF, patch_default_args: bool = False, use_cache: bool = True, ) -> None: """Bind the file-related modules to the :py:class:`pyfakefs` fake file system instead of the real file system. Also bind the fake `open()` function. Invoke this at the beginning of the `setUp()` method in your unit test class. For the arguments, see the `TestCaseMixin` attribute description. If any of the arguments is not None, it overwrites the settings for the current test case. Settings the arguments here may be a more convenient way to adapt the setting than overwriting `__init__()`. """ # if the class has already a patcher setup, we use this one if Patcher.PATCHER is not None: return if additional_skip_names is None: additional_skip_names = self.additional_skip_names if modules_to_reload is None: modules_to_reload = self.modules_to_reload if modules_to_patch is None: modules_to_patch = self.modules_to_patch self._patcher = Patcher( additional_skip_names=additional_skip_names, modules_to_reload=modules_to_reload, modules_to_patch=modules_to_patch, allow_root_user=allow_root_user, use_known_patches=use_known_patches, patch_open_code=patch_open_code, patch_default_args=patch_default_args, use_cache=use_cache, ) self._patcher.setUp() cast(TestCase, self).addCleanup(self._patcher.tearDown) @classmethod def setUpClassPyfakefs( cls, additional_skip_names: Optional[List[Union[str, ModuleType]]] = None, modules_to_reload: Optional[List[ModuleType]] = None, modules_to_patch: Optional[Dict[str, ModuleType]] = None, allow_root_user: bool = True, use_known_patches: bool = True, patch_open_code: PatchMode = PatchMode.OFF, patch_default_args: bool = False, use_cache: bool = True, ) -> None: """Similar to :py:func:`setUpPyfakefs`, but as a class method that can be used in `setUpClass` instead of in `setUp`. The fake filesystem will live in all test methods in the test class and can be used in the usual way. Note that using both :py:func:`setUpClassPyfakefs` and :py:func:`setUpPyfakefs` in the same class will not work correctly. .. note:: This method is only available from Python 3.8 onwards. """ if sys.version_info < (3, 8): raise NotImplementedError( "setUpClassPyfakefs is only available in " "Python versions starting from 3.8" ) # if the class has already a patcher setup, we use this one if Patcher.PATCHER is not None: return if additional_skip_names is None: additional_skip_names = cls.additional_skip_names if modules_to_reload is None: modules_to_reload = cls.modules_to_reload if modules_to_patch is None: modules_to_patch = cls.modules_to_patch Patcher.PATCHER = Patcher( additional_skip_names=additional_skip_names, modules_to_reload=modules_to_reload, modules_to_patch=modules_to_patch, allow_root_user=allow_root_user, use_known_patches=use_known_patches, patch_open_code=patch_open_code, patch_default_args=patch_default_args, use_cache=use_cache, ) Patcher.PATCHER.setUp() cast(TestCase, cls).addClassCleanup(Patcher.PATCHER.tearDown) @classmethod def fake_fs(cls): """Convenience class method for accessing the fake filesystem. For use inside `setUpClass`, after :py:func:`setUpClassPyfakefs` has been called. """ if Patcher.PATCHER: return Patcher.PATCHER.fs return None def pause(self) -> None: """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. """ self.patcher.pause() def resume(self) -> None: """Resume 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. """ self.patcher.resume() class TestCase(unittest.TestCase, TestCaseMixin): """Test case class that automatically replaces file-system related modules by fake implementations. Inherits :py:class:`TestCaseMixin`. The arguments are explained in :py:class:`TestCaseMixin`. """ def __init__( self, methodName: str = "runTest", additional_skip_names: Optional[List[Union[str, ModuleType]]] = None, modules_to_reload: Optional[List[ModuleType]] = None, modules_to_patch: Optional[Dict[str, ModuleType]] = None, ): """Creates the test class instance and the patcher used to stub out file system related modules. Args: methodName: The name of the test method (same as in unittest.TestCase) """ super().__init__(methodName) self.additional_skip_names = additional_skip_names self.modules_to_reload = modules_to_reload self.modules_to_patch = modules_to_patch def tearDownPyfakefs(self) -> None: """This method is deprecated and exists only for backward compatibility. It does nothing. """ class Patcher: """ Instantiate a stub creator to bind and un-bind the file-related modules to the :py:mod:`pyfakefs` fake modules. The arguments are explained in :py:class:`TestCaseMixin`. :py:class:`Patcher` is used in :py:class:`TestCaseMixin`. :py:class:`Patcher` also works as a context manager for other tests:: with Patcher(): doStuff() """ """Stub nothing that is imported within these modules. `sys` is included to prevent `sys.path` from being stubbed with the fake `os.path`. The `linecache` module is used to read the test file in case of test failure to get traceback information before test tear down. In order to make sure that reading the test file is not faked, we skip faking the module. We also have to set back the cached open function in tokenize. """ SKIPMODULES = { None, fake_filesystem, fake_filesystem_shutil, fake_os, fake_io, fake_open, fake_path, fake_file, sys, linecache, tokenize, os, io, _io, genericpath, os.path, } if sys.platform == "win32": import nt # type:ignore[import] import ntpath SKIPMODULES.add(nt) SKIPMODULES.add(ntpath) else: import posix import posixpath import fcntl SKIPMODULES.add(posix) SKIPMODULES.add(posixpath) SKIPMODULES.add(fcntl) # caches all modules that do not have file system modules or function # to speed up _find_modules CACHED_MODULES: Set[ModuleType] = set() FS_MODULES: Dict[str, Set[Tuple[ModuleType, str]]] = {} FS_FUNCTIONS: Dict[Tuple[str, str, str], Set[ModuleType]] = {} FS_DEFARGS: List[Tuple[FunctionType, int, Callable[..., Any]]] = [] SKIPPED_FS_MODULES: Dict[str, Set[Tuple[ModuleType, str]]] = {} assert None in SKIPMODULES, "sys.modules contains 'None' values;" " must skip them." IS_WINDOWS = sys.platform in ("win32", "cygwin") SKIPNAMES: Set[str] = set() # hold values from last call - if changed, the cache has to be invalidated PATCHED_MODULE_NAMES: Set[str] = set() ADDITIONAL_SKIP_NAMES: Set[str] = set() PATCH_DEFAULT_ARGS = False PATCHER: Optional["Patcher"] = None DOC_PATCHER: Optional["Patcher"] = None REF_COUNT = 0 DOC_REF_COUNT = 0 def __new__(cls, *args, **kwargs): if kwargs.get("is_doc_test", False): if cls.DOC_PATCHER is None: cls.DOC_PATCHER = super().__new__(cls) return cls.DOC_PATCHER if cls.PATCHER is None: cls.PATCHER = super().__new__(cls) return cls.PATCHER def __init__( self, additional_skip_names: Optional[List[Union[str, ModuleType]]] = None, modules_to_reload: Optional[List[ModuleType]] = None, modules_to_patch: Optional[Dict[str, ModuleType]] = None, allow_root_user: bool = True, use_known_patches: bool = True, patch_open_code: PatchMode = PatchMode.OFF, patch_default_args: bool = False, use_cache: bool = True, is_doc_test: bool = False, ) -> None: """ Args: additional_skip_names: names of modules inside of which no module replacement shall be performed, in addition to the names in :py:attr:`fake_filesystem_unittest.Patcher.SKIPNAMES`. Instead of the module names, the modules themselves may be used. modules_to_reload: A list of modules that need to be reloaded to be patched dynamically; may be needed if the module imports file system modules under an alias .. caution:: Reloading modules may have unwanted side effects. modules_to_patch: A dictionary of fake modules mapped to the fully qualified patched module names. Can be used to add patching of modules not provided by `pyfakefs`. allow_root_user: If True (default), if the test is run as root user, the user in the fake file system is also considered a root user, otherwise it is always considered a regular user. use_known_patches: If True (the default), some patches for commonly used packages are applied which make them usable with pyfakefs. patch_open_code: If True, `io.open_code` is patched. The default is not to patch it, as it mostly is used to load compiled modules that are not in the fake file system. patch_default_args: If True, default arguments are checked for file system functions, which are patched. This check is expansive, so it is off by default. use_cache: If True (default), patched and non-patched modules are cached between tests for performance reasons. As this is a new feature, this argument allows to turn it off in case it causes any problems. """ self.is_doc_test = is_doc_test if is_doc_test: if self.DOC_REF_COUNT > 0: return elif self.REF_COUNT > 0: return if not allow_root_user: # set non-root IDs even if the real user is root set_uid(1) set_gid(1) self._skip_names = self.SKIPNAMES.copy() # save the original open function for use in pytest plugin self.original_open = open self.patch_open_code = patch_open_code self.fake_open: fake_open.FakeFileOpen if additional_skip_names is not None: skip_names = [ cast(ModuleType, m).__name__ if inspect.ismodule(m) else cast(str, m) for m in additional_skip_names ] self._skip_names.update(skip_names) self._fake_module_classes: Dict[str, Any] = {} self._unfaked_module_classes: Dict[str, Any] = {} self._class_modules: Dict[str, List[str]] = {} self._init_fake_module_classes() # reload tempfile under posix to patch default argument self.modules_to_reload: List[ModuleType] = ( [] if sys.platform == "win32" else [tempfile] ) if modules_to_reload is not None: self.modules_to_reload.extend(modules_to_reload) self.patch_default_args = patch_default_args self.use_cache = use_cache if use_known_patches: from pyfakefs.patched_packages import ( get_modules_to_patch, get_classes_to_patch, get_fake_module_classes, ) modules_to_patch = modules_to_patch or {} modules_to_patch.update(get_modules_to_patch()) self._class_modules.update(get_classes_to_patch()) self._fake_module_classes.update(get_fake_module_classes()) if modules_to_patch is not None: for name, fake_module in modules_to_patch.items(): self._fake_module_classes[name] = fake_module patched_module_names = set(modules_to_patch) else: patched_module_names = set() clear_cache = not use_cache if use_cache: if patched_module_names != self.PATCHED_MODULE_NAMES: self.__class__.PATCHED_MODULE_NAMES = patched_module_names clear_cache = True if self._skip_names != self.ADDITIONAL_SKIP_NAMES: self.__class__.ADDITIONAL_SKIP_NAMES = self._skip_names clear_cache = True if patch_default_args != self.PATCH_DEFAULT_ARGS: self.__class__.PATCH_DEFAULT_ARGS = patch_default_args clear_cache = True if clear_cache: self.clear_cache() self._fake_module_functions: Dict[str, Dict] = {} self._init_fake_module_functions() # Attributes set by _refresh() self._stubs: Optional[StubOutForTesting] = None self.fs: Optional[FakeFilesystem] = None self.fake_modules: Dict[str, Any] = {} self.unfaked_modules: Dict[str, Any] = {} # _isStale is set by tearDown(), reset by _refresh() self._isStale = True self._dyn_patcher: Optional[DynamicPatcher] = None self._patching = False def clear_cache(self) -> None: """Clear the module cache.""" self.__class__.CACHED_MODULES = set() self.__class__.FS_MODULES = {} self.__class__.FS_FUNCTIONS = {} self.__class__.FS_DEFARGS = [] self.__class__.SKIPPED_FS_MODULES = {} def _init_fake_module_classes(self) -> None: # IMPORTANT TESTING NOTE: Whenever you add a new module below, test # it by adding an attribute in fixtures/module_with_attributes.py # and a test in fake_filesystem_unittest_test.py, class # TestAttributesWithFakeModuleNames. self._fake_module_classes = { "os": fake_os.FakeOsModule, "shutil": fake_filesystem_shutil.FakeShutilModule, "io": fake_io.FakeIoModule, "pathlib": fake_pathlib.FakePathlibModule, } if IS_PYPY: # in PyPy io.open, the module is referenced as _io self._fake_module_classes["_io"] = fake_io.FakeIoModule if sys.platform == "win32": self._fake_module_classes["nt"] = fake_path.FakeNtModule else: self._fake_module_classes["fcntl"] = fake_filesystem.FakeFcntlModule # class modules maps class names against a list of modules they can # be contained in - this allows for alternative modules like # `pathlib` and `pathlib2` self._class_modules["Path"] = ["pathlib"] self._unfaked_module_classes["pathlib"] = fake_pathlib.RealPathlibModule if pathlib2: self._fake_module_classes["pathlib2"] = fake_pathlib.FakePathlibModule self._class_modules["Path"].append("pathlib2") self._unfaked_module_classes["pathlib2"] = fake_pathlib.RealPathlibModule self._fake_module_classes["Path"] = fake_pathlib.FakePathlibPathModule self._unfaked_module_classes["Path"] = fake_pathlib.RealPathlibPathModule if use_scandir: self._fake_module_classes["scandir"] = fake_scandir.FakeScanDirModule def _init_fake_module_functions(self) -> None: # handle patching function imported separately like # `from os import stat` # each patched function name has to be looked up separately for mod_name, fake_module in self._fake_module_classes.items(): if hasattr(fake_module, "dir"): module_dir = fake_module.dir if inspect.isfunction(module_dir): for fct_name in fake_module.dir(): module_attr = (getattr(fake_module, fct_name), mod_name) self._fake_module_functions.setdefault(fct_name, {})[ mod_name ] = module_attr if mod_name == "os": self._fake_module_functions.setdefault(fct_name, {})[ OS_MODULE ] = module_attr # special handling for functions in os.path fake_module = fake_filesystem.FakePathModule for fct_name in fake_module.dir(): module_attr = (getattr(fake_module, fct_name), PATH_MODULE) self._fake_module_functions.setdefault(fct_name, {})[ "genericpath" ] = module_attr self._fake_module_functions.setdefault(fct_name, {})[ PATH_MODULE ] = module_attr def __enter__(self) -> "Patcher": """Context manager for usage outside of fake_filesystem_unittest.TestCase. Ensure that all patched modules are removed in case of an unhandled exception. """ self.setUp() return self def __exit__( self, exc_type: Optional[Type[BaseException]], exc_val: Optional[BaseException], exc_tb: Optional[TracebackType], ) -> None: self.tearDown() def _is_fs_module( self, mod: ModuleType, name: str, module_names: List[str] ) -> bool: try: return ( inspect.ismodule(mod) and mod.__name__ in module_names or inspect.isclass(mod) and mod.__module__ in self._class_modules.get(name, []) ) except Exception: # handle cases where the module has no __name__ or __module__ # attribute - see #460, and any other exception triggered # by inspect functions return False def _is_fs_function(self, fct: FunctionType) -> bool: try: return ( (inspect.isfunction(fct) or inspect.isbuiltin(fct)) and fct.__name__ in self._fake_module_functions and fct.__module__ in self._fake_module_functions[fct.__name__] ) except Exception: # handle cases where the function has no __name__ or __module__ # attribute, or any other exception in inspect functions return False def _def_values( self, item: FunctionType ) -> Iterator[Tuple[FunctionType, int, Any]]: """Find default arguments that are file-system functions to be patched in top-level functions and members of top-level classes.""" # check for module-level functions try: if item.__defaults__ and inspect.isfunction(item): for i, d in enumerate(item.__defaults__): if self._is_fs_function(d): yield item, i, d except Exception: pass try: if inspect.isclass(item): # check for methods in class # (nested classes are ignored for now) # inspect.getmembers is very expansive! for m in inspect.getmembers(item, predicate=inspect.isfunction): f = cast(FunctionType, m[1]) if f.__defaults__: for i, d in enumerate(f.__defaults__): if self._is_fs_function(d): yield f, i, d except Exception: # Ignore any exception, examples: # ImportError: No module named '_gdbm' # _DontDoThat() (see #523) pass def _find_def_values(self, module_items: ItemsView[str, FunctionType]) -> None: for _, fct in module_items: for f, i, d in self._def_values(fct): self.__class__.FS_DEFARGS.append((f, i, d)) def _find_modules(self) -> None: """Find and cache all modules that import file system modules. Later, `setUp()` will stub these with the fake file system modules. """ module_names = list(self._fake_module_classes.keys()) + [PATH_MODULE] for name, module in list(sys.modules.items()): try: if ( self.use_cache and module in self.CACHED_MODULES or not inspect.ismodule(module) ): continue except Exception: # workaround for some py (part of pytest) versions # where py.error has no __name__ attribute # see https://github.com/pytest-dev/py/issues/73 # and any other exception triggered by inspect.ismodule if self.use_cache: self.__class__.CACHED_MODULES.add(module) continue skipped = module in self.SKIPMODULES or any( [sn.startswith(module.__name__) for sn in self._skip_names] ) module_items = module.__dict__.copy().items() modules = { name: mod for name, mod in module_items if self._is_fs_module(mod, name, module_names) } if skipped: for name, mod in modules.items(): self.__class__.SKIPPED_FS_MODULES.setdefault(name, set()).add( (module, mod.__name__) ) else: for name, mod in modules.items(): self.__class__.FS_MODULES.setdefault(name, set()).add( (module, mod.__name__) ) functions = { name: fct for name, fct in module_items if self._is_fs_function(fct) } for name, fct in functions.items(): self.__class__.FS_FUNCTIONS.setdefault( (name, fct.__name__, fct.__module__), set() ).add(module) # find default arguments that are file system functions if self.patch_default_args: self._find_def_values(module_items) if self.use_cache: self.__class__.CACHED_MODULES.add(module) def _refresh(self) -> None: """Renew the fake file system and set the _isStale flag to `False`.""" if self._stubs is not None: self._stubs.smart_unset_all() self._stubs = mox3_stubout.StubOutForTesting() self.fs = fake_filesystem.FakeFilesystem(patcher=self, create_temp_dir=True) self.fs.patch_open_code = self.patch_open_code self.fake_open = fake_open.FakeFileOpen(self.fs) for name in self._fake_module_classes: self.fake_modules[name] = self._fake_module_classes[name](self.fs) if hasattr(self.fake_modules[name], "skip_names"): self.fake_modules[name].skip_names = self._skip_names self.fake_modules[PATH_MODULE] = self.fake_modules["os"].path for name in self._unfaked_module_classes: self.unfaked_modules[name] = self._unfaked_module_classes[name]() self._isStale = False def setUp(self, doctester: Any = None) -> None: """Bind the file-related modules to the :py:mod:`pyfakefs` fake modules real ones. Also bind the fake `file()` and `open()` functions. """ if self.is_doc_test: self.__class__.DOC_REF_COUNT += 1 if self.__class__.DOC_REF_COUNT > 1: return else: self.__class__.REF_COUNT += 1 if self.__class__.REF_COUNT > 1: return self.has_fcopy_file = ( sys.platform == "darwin" and hasattr(shutil, "_HAS_FCOPYFILE") and shutil._HAS_FCOPYFILE ) if self.has_fcopy_file: shutil._HAS_FCOPYFILE = False # type: ignore[attr-defined] with warnings.catch_warnings(): # ignore warnings, see #542 and #614 warnings.filterwarnings("ignore") self._find_modules() self._refresh() if doctester is not None: doctester.globs = self.replace_globs(doctester.globs) self.start_patching() linecache.open = self.original_open # type: ignore[attr-defined] tokenize._builtin_open = self.original_open # type: ignore def start_patching(self) -> None: if not self._patching: self._patching = True self.patch_modules() self.patch_functions() self.patch_defaults() self._dyn_patcher = DynamicPatcher(self) sys.meta_path.insert(0, self._dyn_patcher) for module in self.modules_to_reload: if sys.modules.get(module.__name__) is module: reload(module) def patch_functions(self) -> None: assert self._stubs is not None for (name, ft_name, ft_mod), modules in self.FS_FUNCTIONS.items(): method, mod_name = self._fake_module_functions[ft_name][ft_mod] fake_module = self.fake_modules[mod_name] attr = method.__get__( fake_module, fake_module.__class__ ) # pytype: disable=attribute-error for module in modules: self._stubs.smart_set(module, name, attr) def patch_modules(self) -> None: assert self._stubs is not None for name, modules in self.FS_MODULES.items(): for module, attr in modules: self._stubs.smart_set(module, name, self.fake_modules[attr]) for name, modules in self.SKIPPED_FS_MODULES.items(): for module, attr in modules: if attr in self.unfaked_modules: self._stubs.smart_set(module, name, self.unfaked_modules[attr]) if sys.version_info >= (3, 12): # workaround for patching open - does not work with skip modules self._stubs.smart_set(builtins, "open", self.fake_open) def patch_defaults(self) -> None: for fct, idx, ft in self.FS_DEFARGS: method, mod_name = self._fake_module_functions[ft.__name__][ft.__module__] fake_module = self.fake_modules[mod_name] attr = method.__get__( fake_module, fake_module.__class__ ) # pytype: disable=attribute-error new_defaults = [] assert fct.__defaults__ is not None for i, d in enumerate(fct.__defaults__): if i == idx: new_defaults.append(attr) else: new_defaults.append(d) fct.__defaults__ = tuple(new_defaults) def replace_globs(self, globs_: Dict[str, Any]) -> Dict[str, Any]: globs = globs_.copy() if self._isStale: self._refresh() for name in self._fake_module_classes: if name in globs: globs[name] = self._fake_module_classes[name](self.fs) return globs def tearDown(self, doctester: Any = None): """Clear the fake filesystem bindings created by `setUp()`.""" if self.is_doc_test: self.__class__.DOC_REF_COUNT -= 1 if self.__class__.DOC_REF_COUNT > 0: return else: self.__class__.REF_COUNT -= 1 if self.__class__.REF_COUNT > 0: return self.stop_patching() if self.has_fcopy_file: shutil._HAS_FCOPYFILE = True # type: ignore[attr-defined] reset_ids() if self.is_doc_test: self.__class__.DOC_PATCHER = None else: self.__class__.PATCHER = None def stop_patching(self) -> None: if self._patching: self._isStale = True self._patching = False if self._stubs: self._stubs.smart_unset_all() self.unset_defaults() if self._dyn_patcher: self._dyn_patcher.cleanup() sys.meta_path.pop(0) def unset_defaults(self) -> None: for fct, idx, ft in self.FS_DEFARGS: new_defaults = [] for i, d in enumerate(cast(Tuple, fct.__defaults__)): if i == idx: new_defaults.append(ft) else: new_defaults.append(d) fct.__defaults__ = tuple(new_defaults) def pause(self) -> None: """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. """ self.stop_patching() def resume(self) -> None: """Resume 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. """ self.start_patching() class Pause: """Simple context manager that allows to pause/resume patching the filesystem. Patching is paused in the context manager, and resumed after going out of it's scope. """ def __init__(self, caller: Union[Patcher, TestCaseMixin, FakeFilesystem]): """Initializes the context manager with the fake filesystem. Args: caller: either the FakeFilesystem instance, the Patcher instance or the pyfakefs test case. """ if isinstance(caller, (Patcher, TestCaseMixin)): assert caller.fs is not None self._fs: FakeFilesystem = caller.fs elif isinstance(caller, FakeFilesystem): self._fs = caller else: raise ValueError( "Invalid argument - should be of type " '"fake_filesystem_unittest.Patcher", ' '"fake_filesystem_unittest.TestCase" ' 'or "fake_filesystem.FakeFilesystem"' ) def __enter__(self) -> FakeFilesystem: self._fs.pause() return self._fs def __exit__(self, *args: Any) -> None: self._fs.resume() class DynamicPatcher(MetaPathFinder, Loader): """A file loader that replaces file system related modules by their fake implementation if they are loaded after calling `setUpPyfakefs()`. Implements the protocol needed for import hooks. """ def __init__(self, patcher: Patcher) -> None: self._patcher = patcher self.sysmodules = {} self.modules = self._patcher.fake_modules self._loaded_module_names: Set[str] = set() # remove all modules that have to be patched from `sys.modules`, # otherwise the find_... methods will not be called for name in self.modules: if self.needs_patch(name) and name in sys.modules: self.sysmodules[name] = sys.modules[name] del sys.modules[name] for name, module in self.modules.items(): sys.modules[name] = module def cleanup(self) -> None: for module_name in self.sysmodules: sys.modules[module_name] = self.sysmodules[module_name] for module in self._patcher.modules_to_reload: if module.__name__ in sys.modules: reload(module) reloaded_module_names = [ module.__name__ for module in self._patcher.modules_to_reload ] # Dereference all modules loaded during the test so they will reload on # the next use, ensuring that no faked modules are referenced after the # test. for name in self._loaded_module_names: if name in sys.modules and name not in reloaded_module_names: del sys.modules[name] def needs_patch(self, name: str) -> bool: """Check if the module with the given name shall be replaced.""" if name not in self.modules: self._loaded_module_names.add(name) return False if name in sys.modules and type(sys.modules[name]) == self.modules[name]: return False return True def find_spec( self, fullname: str, path: Optional[Sequence[Union[bytes, str]]], target: Optional[ModuleType] = None, ) -> Optional[ModuleSpec]: """Module finder.""" if self.needs_patch(fullname): return ModuleSpec(fullname, self) return None def load_module(self, fullname: str) -> ModuleType: """Replaces the module by its fake implementation.""" sys.modules[fullname] = self.modules[fullname] return self.modules[fullname] fake_io.py000064400000013715150043321510006514 0ustar00# Copyright 2009 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """ Uses :py:class:`FakeIoModule` to provide a fake ``io`` module replacement. """ import io import os import sys import traceback from enum import Enum from typing import ( List, Optional, Callable, Union, Any, AnyStr, IO, TYPE_CHECKING, ) from pyfakefs.fake_file import AnyFileWrapper from pyfakefs.fake_open import FakeFileOpen from pyfakefs.helpers import IS_PYPY if TYPE_CHECKING: from pyfakefs.fake_filesystem import FakeFilesystem class PatchMode(Enum): """Defines if patching shall be on, off, or in automatic mode. Currently only used for `patch_open_code` option. """ OFF = 1 AUTO = 2 ON = 3 class FakeIoModule: """Uses FakeFilesystem to provide a fake io module replacement. You need a fake_filesystem to use this: filesystem = fake_filesystem.FakeFilesystem() my_io_module = fake_io.FakeIoModule(filesystem) """ @staticmethod def dir() -> List[str]: """Return the list of patched function names. Used for patching functions imported from the module. """ _dir = ["open"] if sys.version_info >= (3, 8): _dir.append("open_code") return _dir def __init__(self, filesystem: "FakeFilesystem"): """ Args: filesystem: FakeFilesystem used to provide file system information. """ self.filesystem = filesystem self.skip_names: List[str] = [] self._io_module = io def open( self, file: Union[AnyStr, int], mode: str = "r", buffering: int = -1, encoding: Optional[str] = None, errors: Optional[str] = None, newline: Optional[str] = None, closefd: bool = True, opener: Optional[Callable] = None, ) -> Union[AnyFileWrapper, IO[Any]]: """Redirect the call to FakeFileOpen. See FakeFileOpen.call() for description. """ # workaround for built-in open called from skipped modules (see #552) # as open is not imported explicitly, we cannot patch it for # specific modules; instead we check if the caller is a skipped # module (should work in most cases) stack = traceback.extract_stack(limit=2) module_name = os.path.splitext(stack[0].filename)[0] module_name = module_name.replace(os.sep, ".") if any( [ module_name == sn or module_name.endswith("." + sn) for sn in self.skip_names ] ): return io.open( # pytype: disable=wrong-arg-count file, mode, buffering, encoding, errors, newline, closefd, opener, ) fake_open = FakeFileOpen(self.filesystem) return fake_open( file, mode, buffering, encoding, errors, newline, closefd, opener ) if sys.version_info >= (3, 8): def open_code(self, path): """Redirect the call to open. Note that the behavior of the real function may be overridden by an earlier call to the PyFile_SetOpenCodeHook(). This behavior is not reproduced here. """ if not isinstance(path, str) and not IS_PYPY: raise TypeError("open_code() argument 'path' must be str, not int") patch_mode = self.filesystem.patch_open_code if ( patch_mode == PatchMode.AUTO and self.filesystem.exists(path) or patch_mode == PatchMode.ON ): return self.open(path, mode="rb") # mostly this is used for compiled code - # don't patch these, as the files are probably in the real fs return self._io_module.open_code(path) def __getattr__(self, name): """Forwards any unfaked calls to the standard io module.""" return getattr(self._io_module, name) if sys.platform != "win32": import fcntl class FakeFcntlModule: """Replaces the fcntl module. Only valid under Linux/MacOS, currently just mocks the functionality away. """ @staticmethod def dir() -> List[str]: """Return the list of patched function names. Used for patching functions imported from the module. """ return ["fcntl", "ioctl", "flock", "lockf"] def __init__(self, filesystem: "FakeFilesystem"): """ Args: filesystem: FakeFilesystem used to provide file system information (currently not used). """ self.filesystem = filesystem self._fcntl_module = fcntl def fcntl(self, fd: int, cmd: int, arg: int = 0) -> Union[int, bytes]: return 0 if isinstance(arg, int) else arg def ioctl( self, fd: int, request: int, arg: int = 0, mutate_flag: bool = True ) -> Union[int, bytes]: return 0 if isinstance(arg, int) else arg def flock(self, fd: int, operation: int) -> None: pass def lockf( self, fd: int, cmd: int, len: int = 0, start: int = 0, whence=0 ) -> Any: pass def __getattr__(self, name): """Forwards any unfaked calls to the standard fcntl module.""" return getattr(self._fcntl_module, name) fake_open.py000064400000032110150043321510007034 0ustar00# Copyright 2009 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """A fake open() function replacement. See ``fake_filesystem`` for usage. """ import errno import os import sys from collections import namedtuple from stat import ( S_ISDIR, ) from typing import ( Optional, Union, Any, Tuple, cast, AnyStr, TYPE_CHECKING, ) from pyfakefs import helpers from pyfakefs.fake_file import ( FakePipeWrapper, FakeFileWrapper, FakeFile, AnyFileWrapper, ) from pyfakefs.helpers import ( AnyString, is_root, PERM_READ, PERM_WRITE, ) if TYPE_CHECKING: from pyfakefs.fake_filesystem import FakeFilesystem _OpenModes = namedtuple( "_OpenModes", "must_exist can_read can_write truncate append must_not_exist", ) _OPEN_MODE_MAP = { # mode name:(file must exist, can read, can write, # truncate, append, must not exist) "r": (True, True, False, False, False, False), "w": (False, False, True, True, False, False), "a": (False, False, True, False, True, False), "r+": (True, True, True, False, False, False), "w+": (False, True, True, True, False, False), "a+": (False, True, True, False, True, False), "x": (False, False, True, False, False, True), "x+": (False, True, True, False, False, True), } class FakeFileOpen: """Faked `file()` and `open()` function replacements. Returns FakeFile objects in a FakeFilesystem in place of the `file()` or `open()` function. """ __name__ = "FakeFileOpen" def __init__( self, filesystem: "FakeFilesystem", delete_on_close: bool = False, raw_io: bool = False, ): """ Args: filesystem: FakeFilesystem used to provide file system information delete_on_close: optional boolean, deletes file on close() """ self.filesystem = filesystem self._delete_on_close = delete_on_close self.raw_io = raw_io def __call__(self, *args: Any, **kwargs: Any) -> AnyFileWrapper: """Redirects calls to file() or open() to appropriate method.""" return self.call(*args, **kwargs) def call( self, file_: Union[AnyStr, int], mode: str = "r", buffering: int = -1, encoding: Optional[str] = None, errors: Optional[str] = None, newline: Optional[str] = None, closefd: bool = True, opener: Any = None, open_modes: Optional[_OpenModes] = None, ) -> AnyFileWrapper: """Return 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: the buffer size used for writing. Data will only be flushed if buffer size is exceeded. The default (-1) uses a system specific default buffer size. Text line mode (e.g. buffering=1 in text mode) is not supported. 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: an optional function object that will be called with `file_` and the open flags (derived from `mode`) and returns a file descriptor. 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: 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 """ binary = "b" in mode if binary and encoding: raise ValueError("binary mode doesn't take an encoding argument") newline, open_modes = self._handle_file_mode(mode, newline, open_modes) # the pathlib opener is defined in a Path instance that may not be # patched under some circumstances; as it just calls standard open(), # we may ignore it, as it would not change the behavior if opener is not None and opener.__module__ != "pathlib": # opener shall return a file descriptor, which will be handled # here as if directly passed file_ = opener(file_, self._open_flags_from_open_modes(open_modes)) file_object, file_path, filedes, real_path = self._handle_file_arg(file_) if file_object is None and file_path is None: # file must be a fake pipe wrapper, find it... if ( filedes is None or len(self.filesystem.open_files) <= filedes or not self.filesystem.open_files[filedes] ): raise OSError(errno.EBADF, "invalid pipe file descriptor") wrappers = self.filesystem.open_files[filedes] assert wrappers is not None existing_wrapper = wrappers[0] assert isinstance(existing_wrapper, FakePipeWrapper) wrapper = FakePipeWrapper( self.filesystem, existing_wrapper.fd, existing_wrapper.can_write, mode, ) file_des = self.filesystem._add_open_file(wrapper) wrapper.filedes = file_des return wrapper assert file_path is not None if not filedes: closefd = True if ( not opener and open_modes.must_not_exist and ( file_object or self.filesystem.islink(file_path) and not self.filesystem.is_windows_fs ) ): self.filesystem.raise_os_error(errno.EEXIST, file_path) assert real_path is not None file_object = self._init_file_object( file_object, file_path, open_modes, real_path ) if S_ISDIR(file_object.st_mode): if self.filesystem.is_windows_fs: self.filesystem.raise_os_error(errno.EACCES, file_path) else: self.filesystem.raise_os_error(errno.EISDIR, file_path) # If you print obj.name, the argument to open() must be printed. # Not the abspath, not the filename, but the actual argument. file_object.opened_as = file_path if open_modes.truncate: current_time = helpers.now() file_object.st_mtime = current_time if not self.filesystem.is_windows_fs: file_object.st_ctime = current_time fakefile = FakeFileWrapper( file_object, file_path, update=open_modes.can_write, read=open_modes.can_read, append=open_modes.append, delete_on_close=self._delete_on_close, filesystem=self.filesystem, newline=newline, binary=binary, closefd=closefd, encoding=encoding, errors=errors, buffering=buffering, raw_io=self.raw_io, ) if filedes is not None: fakefile.filedes = filedes # replace the file wrapper open_files_list = self.filesystem.open_files[filedes] assert open_files_list is not None open_files_list.append(fakefile) else: fakefile.filedes = self.filesystem._add_open_file(fakefile) return fakefile @staticmethod def _open_flags_from_open_modes(open_modes: _OpenModes) -> int: flags = 0 if open_modes.can_read and open_modes.can_write: flags |= os.O_RDWR elif open_modes.can_read: flags |= os.O_RDONLY elif open_modes.can_write: flags |= os.O_WRONLY if open_modes.append: flags |= os.O_APPEND if open_modes.truncate: flags |= os.O_TRUNC if not open_modes.must_exist and open_modes.can_write: flags |= os.O_CREAT if open_modes.must_not_exist and open_modes.can_write: flags |= os.O_EXCL return flags def _init_file_object( self, file_object: Optional[FakeFile], file_path: AnyStr, open_modes: _OpenModes, real_path: AnyString, ) -> FakeFile: if file_object: if not is_root() and ( (open_modes.can_read and not file_object.st_mode & PERM_READ) or (open_modes.can_write and not file_object.st_mode & PERM_WRITE) ): self.filesystem.raise_os_error(errno.EACCES, file_path) if open_modes.can_write: if open_modes.truncate: file_object.set_contents("") else: if open_modes.must_exist: self.filesystem.raise_os_error(errno.ENOENT, file_path) if self.filesystem.islink(file_path): link_object = self.filesystem.resolve(file_path, follow_symlinks=False) assert link_object.contents is not None target_path = cast( AnyStr, link_object.contents ) # pytype: disable=invalid-annotation else: target_path = file_path if self.filesystem.ends_with_path_separator(target_path): error = ( errno.EINVAL if self.filesystem.is_windows_fs else errno.ENOENT if self.filesystem.is_macos else errno.EISDIR ) self.filesystem.raise_os_error(error, file_path) file_object = self.filesystem.create_file_internally( real_path, create_missing_dirs=False, apply_umask=True ) return file_object def _handle_file_arg( self, file_: Union[AnyStr, int] ) -> Tuple[Optional[FakeFile], Optional[AnyStr], Optional[int], Optional[AnyStr]]: file_object = None if isinstance(file_, int): # opening a file descriptor filedes: int = file_ wrapper = self.filesystem.get_open_file(filedes) if isinstance(wrapper, FakePipeWrapper): return None, None, filedes, None if isinstance(wrapper, FakeFileWrapper): self._delete_on_close = wrapper.delete_on_close file_object = cast( FakeFile, self.filesystem.get_open_file(filedes).get_object() ) assert file_object is not None path = file_object.name return ( file_object, cast(AnyStr, path), # pytype: disable=invalid-annotation filedes, cast(AnyStr, path), # pytype: disable=invalid-annotation ) # open a file file by path file_path = cast(AnyStr, file_) # pytype: disable=invalid-annotation if file_path == self.filesystem.dev_null.name: file_object = self.filesystem.dev_null real_path = file_path else: real_path = self.filesystem.resolve_path(file_path) if self.filesystem.exists(file_path): file_object = self.filesystem.get_object_from_normpath( real_path, check_read_perm=False ) return file_object, file_path, None, real_path def _handle_file_mode( self, mode: str, newline: Optional[str], open_modes: Optional[_OpenModes], ) -> Tuple[Optional[str], _OpenModes]: orig_modes = mode # Save original modes for error messages. # Normalize modes. Handle 't' and 'U'. if ("b" in mode and "t" in mode) or ( sys.version_info > (3, 10) and "U" in mode ): raise ValueError("Invalid mode: " + mode) mode = mode.replace("t", "").replace("b", "") mode = mode.replace("rU", "r").replace("U", "r") if not self.raw_io: if mode not in _OPEN_MODE_MAP: raise ValueError("Invalid mode: %r" % orig_modes) open_modes = _OpenModes(*_OPEN_MODE_MAP[mode]) assert open_modes is not None return newline, open_modes fake_os.py000064400000143156150043321510006531 0ustar00# Copyright 2009 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """ Uses :py:class:`FakeOsModule` to provide a fake :py:mod:`os` module replacement. """ import errno import functools import inspect import os import sys import uuid from contextlib import contextmanager from stat import ( S_IFREG, S_IFSOCK, ) from typing import ( List, Optional, Callable, Union, Any, Tuple, cast, AnyStr, TYPE_CHECKING, Set, ) from pyfakefs.extra_packages import use_scandir from pyfakefs.fake_file import ( FakeDirectory, FakeDirWrapper, StandardStreamWrapper, FakeFileWrapper, FakePipeWrapper, FakeFile, AnyFileWrapper, ) from pyfakefs.fake_open import FakeFileOpen, _OpenModes from pyfakefs.fake_path import FakePathModule from pyfakefs.fake_scandir import scandir, walk, ScanDirIter from pyfakefs.helpers import ( FakeStatResult, is_int_type, is_byte_string, make_string_path, IS_PYPY, to_string, matching_string, AnyString, to_bytes, PERM_EXE, PERM_DEF, is_root, get_uid, get_gid, ) if TYPE_CHECKING: from pyfakefs.fake_filesystem import FakeFilesystem NR_STD_STREAMS = 3 class FakeOsModule: """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_os.FakeOsModule(filesystem) """ use_original = False @staticmethod def dir() -> List[str]: """Return the list of patched function names. Used for patching functions imported from the module. """ _dir = [ "access", "chdir", "chmod", "chown", "close", "fstat", "fsync", "getcwd", "lchmod", "link", "listdir", "lstat", "makedirs", "mkdir", "mknod", "open", "read", "readlink", "remove", "removedirs", "rename", "rmdir", "stat", "symlink", "umask", "unlink", "utime", "walk", "write", "getcwdb", "replace", ] if sys.platform.startswith("linux"): _dir += [ "fdatasync", "getxattr", "listxattr", "removexattr", "setxattr", ] if sys.platform != "win32": _dir += [ "getgid", "getuid", ] if use_scandir: _dir += ["scandir"] return _dir def __init__(self, filesystem: "FakeFilesystem"): """Also exposes self.path (to fake os.path). Args: filesystem: FakeFilesystem used to provide file system information """ self.filesystem = filesystem self.os_module: Any = os self.path = FakePathModule(self.filesystem, self) self._supports_follow_symlinks: Optional[Set] = None self._supports_dir_fd: Optional[Set] = None self._supports_effective_ids: Optional[Set] = None self._supports_fd: Optional[Set] = None @property def devnull(self) -> str: return self.path.devnull @property def sep(self) -> str: return self.path.sep @property def altsep(self) -> Optional[str]: return self.path.altsep @property def linesep(self) -> str: return self.path.linesep @property def pathsep(self) -> str: return self.path.pathsep def fdopen(self, fd: int, *args: Any, **kwargs: Any) -> AnyFileWrapper: """Redirector to open() builtin function. Args: fd: The file descriptor of the file to open. *args: Pass through args. **kwargs: Pass through kwargs. Returns: File object corresponding to file_des. Raises: TypeError: if file descriptor is not an integer. """ if not is_int_type(fd): raise TypeError("an integer is required") return FakeFileOpen(self.filesystem)(fd, *args, **kwargs) def _umask(self) -> int: """Return the current umask.""" if self.filesystem.is_windows_fs: # windows always returns 0 - it has no real notion of umask return 0 if sys.platform == "win32": # if we are testing Unix under Windows we assume a default mask return 0o002 else: # under Unix, we return the real umask; # as there is no pure getter for umask, so we have to first # set a mode to get the previous one and then re-set that mask = os.umask(0) os.umask(mask) return mask def open( self, path: AnyStr, flags: int, mode: Optional[int] = None, *, dir_fd: Optional[int] = None ) -> int: """Return the file descriptor for a FakeFile. Args: 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. Returns: A file descriptor. Raises: OSError: if the path cannot be found ValueError: if invalid mode is given NotImplementedError: if `os.O_EXCL` is used without `os.O_CREAT` """ path = self._path_with_dir_fd(path, self.open, dir_fd) if mode is None: if self.filesystem.is_windows_fs: mode = 0o666 else: mode = 0o777 & ~self._umask() has_tmpfile_flag = ( hasattr(os, "O_TMPFILE") and flags & os.O_TMPFILE == os.O_TMPFILE ) open_modes = _OpenModes( must_exist=not flags & os.O_CREAT and not has_tmpfile_flag, can_read=not flags & os.O_WRONLY, can_write=flags & (os.O_RDWR | os.O_WRONLY) != 0, truncate=flags & os.O_TRUNC != 0, append=flags & os.O_APPEND != 0, must_not_exist=flags & os.O_EXCL != 0, ) if open_modes.must_not_exist and open_modes.must_exist: raise NotImplementedError("O_EXCL without O_CREAT mode is not supported") if has_tmpfile_flag: # this is a workaround for tempfiles that do not have a filename # as we do not support this directly, we just add a unique filename # and set the file to delete on close path = self.filesystem.joinpaths( path, matching_string(path, str(uuid.uuid4())) ) if not self.filesystem.is_windows_fs and self.filesystem.exists(path): # handle opening directory - only allowed under Posix # with read-only mode obj = self.filesystem.resolve(path) if isinstance(obj, FakeDirectory): if ( not open_modes.must_exist and not self.filesystem.is_macos ) or open_modes.can_write: self.filesystem.raise_os_error(errno.EISDIR, path) dir_wrapper = FakeDirWrapper(obj, path, self.filesystem) file_des = self.filesystem._add_open_file(dir_wrapper) dir_wrapper.filedes = file_des return file_des # low level open is always binary str_flags = "b" delete_on_close = has_tmpfile_flag if hasattr(os, "O_TEMPORARY"): delete_on_close = flags & os.O_TEMPORARY == os.O_TEMPORARY fake_file = FakeFileOpen( self.filesystem, delete_on_close=delete_on_close, raw_io=True )(path, str_flags, open_modes=open_modes) assert not isinstance(fake_file, StandardStreamWrapper) if fake_file.file_object != self.filesystem.dev_null: self.chmod(path, mode) return fake_file.fileno() def close(self, fd: int) -> None: """Close a file descriptor. Args: fd: An integer file descriptor for the file object requested. Raises: OSError: bad file descriptor. TypeError: if file descriptor is not an integer. """ file_handle = self.filesystem.get_open_file(fd) file_handle.close() def read(self, fd: int, n: int) -> bytes: """Read number of bytes from a file descriptor, returns bytes read. Args: fd: An integer file descriptor for the file object requested. n: 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. """ file_handle = self.filesystem.get_open_file(fd) if isinstance(file_handle, FakeFileWrapper): file_handle.raw_io = True if isinstance(file_handle, FakeDirWrapper): self.filesystem.raise_os_error(errno.EBADF, file_handle.file_path) return file_handle.read(n) def write(self, fd: int, contents: bytes) -> int: """Write string to file descriptor, returns number of bytes written. Args: fd: 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. """ file_handle = cast(FakeFileWrapper, self.filesystem.get_open_file(fd)) if isinstance(file_handle, FakeDirWrapper): self.filesystem.raise_os_error(errno.EBADF, file_handle.file_path) if isinstance(file_handle, FakePipeWrapper): return file_handle.write(contents) file_handle.raw_io = True file_handle._sync_io() file_handle.update_flush_pos() file_handle.write(contents) file_handle.flush() return len(contents) def pipe(self) -> Tuple[int, int]: read_fd, write_fd = os.pipe() read_wrapper = FakePipeWrapper(self.filesystem, read_fd, False) file_des = self.filesystem._add_open_file(read_wrapper) read_wrapper.filedes = file_des write_wrapper = FakePipeWrapper(self.filesystem, write_fd, True) file_des = self.filesystem._add_open_file(write_wrapper) write_wrapper.filedes = file_des return read_wrapper.filedes, write_wrapper.filedes def fstat(self, fd: int) -> FakeStatResult: """Return the os.stat-like tuple for the FakeFile object of file_des. Args: fd: 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. """ # stat should return the tuple representing return value of os.stat file_object = self.filesystem.get_open_file(fd).get_object() assert isinstance(file_object, FakeFile) return file_object.stat_result.copy() def umask(self, mask: int) -> int: """Change the current umask. Args: mask: (int) The new umask value. Returns: The old umask. Raises: TypeError: if new_mask is of an invalid type. """ if not is_int_type(mask): raise TypeError("an integer is required") old_umask = self.filesystem.umask self.filesystem.umask = mask return old_umask def chdir(self, path: AnyStr) -> None: """Change current working directory to target directory. Args: path: 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. """ try: path = self.filesystem.resolve_path(path, allow_fd=True) except OSError as exc: if self.filesystem.is_macos and exc.errno == errno.EBADF: raise OSError(errno.ENOTDIR, "Not a directory: " + str(path)) raise self.filesystem.confirmdir(path) directory = self.filesystem.resolve(path) # A full implementation would check permissions all the way # up the tree. if not is_root() and not directory.st_mode | PERM_EXE: self.filesystem.raise_os_error(errno.EACCES, directory.name) self.filesystem.cwd = path # type: ignore[assignment] def getcwd(self) -> str: """Return current working directory.""" return to_string(self.filesystem.cwd) def getcwdb(self) -> bytes: """Return current working directory as bytes.""" return to_bytes(self.filesystem.cwd) def listdir(self, path: AnyStr) -> List[AnyStr]: """Return a list of file names in target_directory. Args: path: 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. """ return self.filesystem.listdir(path) XATTR_CREATE = 1 XATTR_REPLACE = 2 def getxattr( self, path: AnyStr, attribute: AnyString, *, follow_symlinks: bool = True ) -> Optional[bytes]: """Return 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. """ if not self.filesystem.is_linux: raise AttributeError("module 'os' has no attribute 'getxattr'") if isinstance(attribute, bytes): attribute = attribute.decode(sys.getfilesystemencoding()) file_obj = self.filesystem.resolve(path, follow_symlinks, allow_fd=True) return file_obj.xattr.get(attribute) def listxattr( self, path: Optional[AnyStr] = None, *, follow_symlinks: bool = True ) -> List[str]: """Return 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. """ if not self.filesystem.is_linux: raise AttributeError("module 'os' has no attribute 'listxattr'") path_str = self.filesystem.cwd if path is None else path file_obj = self.filesystem.resolve( cast(AnyStr, path_str), # pytype: disable=invalid-annotation follow_symlinks, allow_fd=True, ) return list(file_obj.xattr.keys()) def removexattr( self, path: AnyStr, attribute: AnyString, *, follow_symlinks: bool = True ) -> None: """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. """ if not self.filesystem.is_linux: raise AttributeError("module 'os' has no attribute 'removexattr'") if isinstance(attribute, bytes): attribute = attribute.decode(sys.getfilesystemencoding()) file_obj = self.filesystem.resolve(path, follow_symlinks, allow_fd=True) if attribute in file_obj.xattr: del file_obj.xattr[attribute] def setxattr( self, path: AnyStr, attribute: AnyString, value: bytes, flags: int = 0, *, follow_symlinks: bool = True ) -> None: """Sets 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. """ if not self.filesystem.is_linux: raise AttributeError("module 'os' has no attribute 'setxattr'") if isinstance(attribute, bytes): attribute = attribute.decode(sys.getfilesystemencoding()) if not is_byte_string(value): raise TypeError("a bytes-like object is required") file_obj = self.filesystem.resolve(path, follow_symlinks, allow_fd=True) exists = attribute in file_obj.xattr if exists and flags == self.XATTR_CREATE: self.filesystem.raise_os_error(errno.ENODATA, file_obj.path) if not exists and flags == self.XATTR_REPLACE: self.filesystem.raise_os_error(errno.EEXIST, file_obj.path) file_obj.xattr[attribute] = value def scandir(self, path: str = ".") -> ScanDirIter: """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. """ return scandir(self.filesystem, path) def walk( self, top: AnyStr, topdown: bool = True, onerror: Optional[bool] = None, followlinks: bool = False, ): """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. """ return walk(self.filesystem, top, topdown, onerror, followlinks) def readlink(self, path: AnyStr, dir_fd: Optional[int] = None) -> str: """Read 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. 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 """ path = self._path_with_dir_fd(path, self.readlink, dir_fd) return self.filesystem.readlink(path) def stat( self, path: AnyStr, *, dir_fd: Optional[int] = None, follow_symlinks: bool = True ) -> FakeStatResult: """Return the os.stat-like tuple for the FakeFile object of entry_path. Args: 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. follow_symlinks: (bool) If `False` and `entry_path` points to a symlink, the link itself is changed instead of the linked object. Returns: The FakeStatResult object corresponding to entry_path. Raises: OSError: if the filesystem object doesn't exist. """ path = self._path_with_dir_fd(path, self.stat, dir_fd) return self.filesystem.stat(path, follow_symlinks) def lstat(self, path: AnyStr, *, dir_fd: Optional[int] = None) -> FakeStatResult: """Return the os.stat-like tuple for entry_path, not following symlinks. Args: path: path to filesystem object to retrieve. dir_fd: If not `None`, the file descriptor of a directory, with `path` being relative to this directory. Returns: the FakeStatResult object corresponding to `path`. Raises: OSError: if the filesystem object doesn't exist. """ # stat should return the tuple representing return value of os.stat path = self._path_with_dir_fd(path, self.lstat, dir_fd) return self.filesystem.stat(path, follow_symlinks=False) def remove(self, path: AnyStr, dir_fd: Optional[int] = None) -> None: """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. Raises: OSError: if path points to a directory. OSError: if path does not exist. OSError: if removal failed. """ path = self._path_with_dir_fd(path, self.remove, dir_fd) self.filesystem.remove(path) def unlink(self, path: AnyStr, *, dir_fd: Optional[int] = None) -> None: """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. Raises: OSError: if path points to a directory. OSError: if path does not exist. OSError: if removal failed. """ path = self._path_with_dir_fd(path, self.unlink, dir_fd) self.filesystem.remove(path) def rename( self, src: AnyStr, dst: AnyStr, *, src_dir_fd: Optional[int] = None, dst_dir_fd: Optional[int] = None ) -> None: """Rename 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: src: Path to filesystem object to rename. dst: Path to where the filesystem object will live after this call. src_dir_fd: If not `None`, the file descriptor of a directory, with `src` being relative to this directory. dst_dir_fd: If not `None`, the file descriptor of a directory, with `dst` being relative to this directory. 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) """ src = self._path_with_dir_fd(src, self.rename, src_dir_fd) dst = self._path_with_dir_fd(dst, self.rename, dst_dir_fd) self.filesystem.rename(src, dst) def renames(self, old: AnyStr, new: AnyStr): """Fakes `os.renames`, documentation taken from there. Super-rename; create directories as necessary and delete any left empty. Works like rename, except creation of any intermediate directories needed to make the new pathname good is attempted first. After the rename, directories corresponding to rightmost path segments of the old name will be pruned until either the whole path is consumed or a nonempty directory is found. Note: this function can fail with the new directory structure made if you lack permissions needed to unlink the leaf directory or file. """ head, tail = self.filesystem.splitpath(new) if head and tail and not self.filesystem.exists(head): self.makedirs(head) self.rename(old, new) head, tail = self.filesystem.splitpath(old) if head and tail: try: self.removedirs(head) except OSError: pass def replace( self, src: AnyStr, dst: AnyStr, *, src_dir_fd: Optional[int] = None, dst_dir_fd: Optional[int] = None ) -> None: """Renames a FakeFile object at old_file_path to new_file_path, preserving all properties. Also replaces existing new_file_path object, if one existed. Arg src: Path to filesystem object to rename. dst: Path to where the filesystem object will live after this call. src_dir_fd: If not `None`, the file descriptor of a directory, with `src` being relative to this directory. dst_dir_fd: If not `None`, the file descriptor of a directory, with `dst` being relative to this directory. 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) """ src = self._path_with_dir_fd(src, self.rename, src_dir_fd) dst = self._path_with_dir_fd(dst, self.rename, dst_dir_fd) self.filesystem.rename(src, dst, force_replace=True) def rmdir(self, path: AnyStr, *, dir_fd: Optional[int] = None) -> None: """Remove a leaf Fake directory. Args: path: (str) Name of directory to remove. dir_fd: If not `None`, the file descriptor of a directory, with `path` being relative to this directory. Raises: OSError: if `path` does not exist or is not a directory, or as per FakeFilesystem.remove_object. Cannot remove '.'. """ path = self._path_with_dir_fd(path, self.rmdir, dir_fd) self.filesystem.rmdir(path) def removedirs(self, name: AnyStr) -> None: """Remove a leaf fake directory and all empty intermediate ones. Args: name: 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. """ name = self.filesystem.absnormpath(name) directory = self.filesystem.confirmdir(name) if directory.entries: self.filesystem.raise_os_error(errno.ENOTEMPTY, self.path.basename(name)) else: self.rmdir(name) head, tail = self.path.split(name) if not tail: head, tail = self.path.split(head) while head and tail: head_dir = self.filesystem.confirmdir(head) if head_dir.entries: break # only the top-level dir may not be a symlink self.filesystem.rmdir(head, allow_symlink=True) head, tail = self.path.split(head) def mkdir( self, path: AnyStr, mode: int = PERM_DEF, *, dir_fd: Optional[int] = None ) -> None: """Create a leaf Fake directory. Args: path: (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 `path` being relative to this directory. Raises: OSError: if the directory name is invalid or parent directory is read only or as per FakeFilesystem.add_object. """ path = self._path_with_dir_fd(path, self.mkdir, dir_fd) try: self.filesystem.makedir(path, mode) except OSError as e: if e.errno == errno.EACCES: self.filesystem.raise_os_error(e.errno, path) raise def makedirs( self, name: AnyStr, mode: int = PERM_DEF, exist_ok: Optional[bool] = None ) -> None: """Create a leaf Fake directory + create any non-existent parent dirs. Args: 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. Raises: OSError: if the directory already exists and exist_ok=False, or as per :py:meth:`FakeFilesystem.create_dir`. """ if exist_ok is None: exist_ok = False self.filesystem.makedirs(name, mode, exist_ok) def _path_with_dir_fd( self, path: AnyStr, fct: Callable, dir_fd: Optional[int] ) -> AnyStr: """Return the path considering dir_fd. Raise on invalid parameters.""" try: path = make_string_path(path) except TypeError: # the error is handled later path = path if dir_fd is not None: # check if fd is supported for the built-in real function if fct not in self.supports_dir_fd: raise NotImplementedError("dir_fd unavailable on this platform") if isinstance(path, int): raise ValueError( "%s: Can't specify dir_fd without " "matching path_str" % fct.__name__ ) if not self.path.isabs(path): open_file = self.filesystem.get_open_file(dir_fd) return self.path.join( # type: ignore[type-var, return-value] cast(FakeFile, open_file.get_object()).path, path ) return path def truncate(self, path: AnyStr, length: int) -> None: """Truncate the file corresponding to path, so that it is length bytes in size. If length is larger than the current size, the file is filled up with zero bytes. Args: path: (str or int) Path to the file, or an integer file descriptor for the file object. length: (int) Length of the file after truncating it. Raises: OSError: if the file does not exist or the file descriptor is invalid. """ file_object = self.filesystem.resolve(path, allow_fd=True) file_object.size = length def ftruncate(self, fd: int, length: int) -> None: """Truncate the file corresponding to fd, so that it is length bytes in size. If length is larger than the current size, the file is filled up with zero bytes. Args: fd: (int) File descriptor for the file object. length: (int) Maximum length of the file after truncating it. Raises: OSError: if the file descriptor is invalid """ file_object = self.filesystem.get_open_file(fd).get_object() if isinstance(file_object, FakeFileWrapper): file_object.size = length else: raise OSError(errno.EBADF, "Invalid file descriptor") def access( self, path: AnyStr, mode: int, *, dir_fd: Optional[int] = None, effective_ids: bool = False, follow_symlinks: bool = True ) -> bool: """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. effective_ids: (bool) Unused. Only here to match the signature. follow_symlinks: (bool) If `False` and `path` points to a symlink, the link itself is queried instead of the linked object. Returns: bool, `True` if file is accessible, `False` otherwise. """ if effective_ids and self.filesystem.is_windows_fs: raise NotImplementedError( "access: effective_ids unavailable on this platform" ) path = self._path_with_dir_fd(path, self.access, dir_fd) try: stat_result = self.stat(path, follow_symlinks=follow_symlinks) except OSError as os_error: if os_error.errno == errno.ENOENT: return False raise if is_root(): mode &= ~os.W_OK return (mode & ((stat_result.st_mode >> 6) & 7)) == mode def chmod( self, path: AnyStr, mode: int, *, dir_fd: Optional[int] = None, follow_symlinks: bool = True ) -> None: """Change 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. follow_symlinks: (bool) If `False` and `path` points to a symlink, the link itself is queried instead of the linked object. """ if not follow_symlinks and ( self.chmod not in self.supports_follow_symlinks or IS_PYPY ): raise NotImplementedError( "`follow_symlinks` for chmod() is not available " "on this system" ) path = self._path_with_dir_fd(path, self.chmod, dir_fd) self.filesystem.chmod(path, mode, follow_symlinks) def lchmod(self, path: AnyStr, mode: int) -> None: """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. """ if self.filesystem.is_windows_fs: raise NameError("name 'lchmod' is not defined") self.filesystem.chmod(path, mode, follow_symlinks=False) def utime( self, path: AnyStr, times: Optional[Tuple[Union[int, float], Union[int, float]]] = None, ns: Optional[Tuple[int, int]] = None, dir_fd: Optional[int] = None, follow_symlinks: bool = True, ) -> None: """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. dir_fd: If not `None`, the file descriptor of a directory, with `path` being relative to this directory. follow_symlinks: (bool) If `False` and `path` points to a symlink, the link itself is queried instead of the linked object. 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. """ path = self._path_with_dir_fd(path, self.utime, dir_fd) self.filesystem.utime(path, times=times, ns=ns, follow_symlinks=follow_symlinks) def chown( self, path: AnyStr, uid: int, gid: int, *, dir_fd: Optional[int] = None, follow_symlinks: bool = True ) -> None: """Set 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. follow_symlinks: (bool) If `False` and path points to a symlink, the link itself is changed instead of the linked object. 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). """ path = self._path_with_dir_fd(path, self.chown, dir_fd) file_object = self.filesystem.resolve(path, follow_symlinks, allow_fd=True) if not isinstance(uid, int) or not isinstance(gid, int): raise TypeError("An integer is required") if uid != -1: file_object.st_uid = uid if gid != -1: file_object.st_gid = gid def mknod( self, path: AnyStr, mode: Optional[int] = None, device: int = 0, *, dir_fd: Optional[int] = None ) -> None: """Create a filesystem node named 'filename'. Does not support device special files or named pipes as the real os module does. Args: path: (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 `path` being relative to this directory. Raises: OSError: if called with unsupported options or the file can not be created. """ if self.filesystem.is_windows_fs: raise AttributeError("module 'os' has no attribute 'mknode'") if mode is None: # note that a default value of 0o600 without a device type is # documented - this is not how it seems to work mode = S_IFREG | 0o600 if device or not mode & S_IFREG and not is_root(): self.filesystem.raise_os_error(errno.EPERM) path = self._path_with_dir_fd(path, self.mknod, dir_fd) head, tail = self.path.split(path) if not tail: if self.filesystem.exists(head, check_link=True): self.filesystem.raise_os_error(errno.EEXIST, path) self.filesystem.raise_os_error(errno.ENOENT, path) if tail in (matching_string(tail, "."), matching_string(tail, "..")): self.filesystem.raise_os_error(errno.ENOENT, path) if self.filesystem.exists(path, check_link=True): self.filesystem.raise_os_error(errno.EEXIST, path) self.filesystem.add_object( head, FakeFile(tail, mode & ~self.filesystem.umask, filesystem=self.filesystem), ) def symlink( self, src: AnyStr, dst: AnyStr, target_is_directory: bool = False, *, dir_fd: Optional[int] = None ) -> None: """Creates the specified symlink, pointed at the specified link target. Args: src: The target of the symlink. dst: Path to the symlink to create. target_is_directory: Currently ignored. dir_fd: If not `None`, the file descriptor of a directory, with `src` being relative to this directory. Raises: OSError: if the file already exists. """ src = self._path_with_dir_fd(src, self.symlink, dir_fd) self.filesystem.create_symlink(dst, src, create_missing_dirs=False) def link( self, src: AnyStr, dst: AnyStr, *, src_dir_fd: Optional[int] = None, dst_dir_fd: Optional[int] = None ) -> None: """Create a hard link at new_path, pointing at old_path. Args: src: An existing path to the target file. dst: The destination path to create a new link at. src_dir_fd: If not `None`, the file descriptor of a directory, with `src` being relative to this directory. dst_dir_fd: If not `None`, the file descriptor of a directory, with `dst` being relative to this directory. Raises: OSError: if something already exists at new_path. OSError: if the parent directory doesn't exist. """ src = self._path_with_dir_fd(src, self.link, src_dir_fd) dst = self._path_with_dir_fd(dst, self.link, dst_dir_fd) self.filesystem.link(src, dst) def fsync(self, fd: int) -> None: """Perform fsync for a fake file (in other words, do nothing). Args: fd: The file descriptor of the open file. Raises: OSError: file_des is an invalid file descriptor. TypeError: file_des is not an integer. """ # Throw an error if file_des isn't valid if 0 <= fd < NR_STD_STREAMS: self.filesystem.raise_os_error(errno.EINVAL) file_object = cast(FakeFileWrapper, self.filesystem.get_open_file(fd)) if self.filesystem.is_windows_fs: if not hasattr(file_object, "allow_update") or not file_object.allow_update: self.filesystem.raise_os_error(errno.EBADF, file_object.file_path) def fdatasync(self, fd: int) -> None: """Perform fdatasync for a fake file (in other words, do nothing). Args: fd: The file descriptor of the open file. Raises: OSError: `fd` is an invalid file descriptor. TypeError: `fd` is not an integer. """ if self.filesystem.is_windows_fs or self.filesystem.is_macos: raise AttributeError("module 'os' has no attribute 'fdatasync'") # Throw an error if file_des isn't valid if 0 <= fd < NR_STD_STREAMS: self.filesystem.raise_os_error(errno.EINVAL) self.filesystem.get_open_file(fd) def sendfile(self, fd_out: int, fd_in: int, offset: int, count: int) -> int: """Copy count bytes from file descriptor fd_in to file descriptor fd_out starting at offset. Args: fd_out: The file descriptor of the destination file. fd_in: The file descriptor of the source file. offset: The offset in bytes where to start the copy in the source file. If `None` (Linux only), copying is started at the current position, and the position is updated. count: The number of bytes to copy. If 0, all remaining bytes are copied (MacOs only). Raises: OSError: If `fd_in` or `fd_out` is an invalid file descriptor. TypeError: If `fd_in` or `fd_out` is not an integer. TypeError: If `offset` is None under MacOs. """ if self.filesystem.is_windows_fs: raise AttributeError("module 'os' has no attribute 'sendfile'") if 0 <= fd_in < NR_STD_STREAMS: self.filesystem.raise_os_error(errno.EINVAL) if 0 <= fd_out < NR_STD_STREAMS: self.filesystem.raise_os_error(errno.EINVAL) source = cast(FakeFileWrapper, self.filesystem.get_open_file(fd_in)) dest = cast(FakeFileWrapper, self.filesystem.get_open_file(fd_out)) if self.filesystem.is_macos: if dest.get_object().stat_result.st_mode & 0o777000 != S_IFSOCK: raise OSError("Socket operation on non-socket") if offset is None: if self.filesystem.is_macos: raise TypeError("None is not a valid offset") contents = source.read(count) else: position = source.tell() source.seek(offset) if count == 0 and self.filesystem.is_macos: contents = source.read() else: contents = source.read(count) source.seek(position) if contents: written = dest.write(contents) dest.flush() return written return 0 def getuid(self) -> int: """Returns the user id set in the fake filesystem. If not changed using ``set_uid``, this is the uid of the real system. """ if self.filesystem.is_windows_fs: raise NameError("name 'getuid' is not defined") return get_uid() def getgid(self) -> int: """Returns the group id set in the fake filesystem. If not changed using ``set_gid``, this is the gid of the real system. """ if self.filesystem.is_windows_fs: raise NameError("name 'getgid' is not defined") return get_gid() def fake_functions(self, original_functions) -> Set: functions = set() for fn in original_functions: if hasattr(self, fn.__name__): functions.add(getattr(self, fn.__name__)) else: functions.add(fn) return functions @property def supports_follow_symlinks(self) -> Set[Callable]: if self._supports_follow_symlinks is None: self._supports_follow_symlinks = self.fake_functions( self.os_module.supports_follow_symlinks ) return self._supports_follow_symlinks @property def supports_dir_fd(self) -> Set[Callable]: if self._supports_dir_fd is None: self._supports_dir_fd = self.fake_functions(self.os_module.supports_dir_fd) return self._supports_dir_fd @property def supports_fd(self) -> Set[Callable]: if self._supports_fd is None: self._supports_fd = self.fake_functions(self.os_module.supports_fd) return self._supports_fd @property def supports_effective_ids(self) -> Set[Callable]: if self._supports_effective_ids is None: self._supports_effective_ids = self.fake_functions( self.os_module.supports_effective_ids ) return self._supports_effective_ids def __getattr__(self, name: str) -> Any: """Forwards any unfaked calls to the standard os module.""" return getattr(self.os_module, name) if sys.version_info > (3, 10): def handle_original_call(f: Callable) -> Callable: """Decorator used for real pathlib Path methods to ensure that real os functions instead of faked ones are used. Applied to all non-private methods of `FakeOsModule`.""" @functools.wraps(f) def wrapped(*args, **kwargs): if FakeOsModule.use_original: # remove the `self` argument for FakeOsModule methods if args and isinstance(args[0], FakeOsModule): args = args[1:] return getattr(os, f.__name__)(*args, **kwargs) return f(*args, **kwargs) return wrapped for name, fn in inspect.getmembers(FakeOsModule, inspect.isfunction): if not fn.__name__.startswith("_"): setattr(FakeOsModule, name, handle_original_call(fn)) @contextmanager def use_original_os(): """Temporarily use original os functions instead of faked ones. Used to ensure that skipped modules do not use faked calls. """ try: FakeOsModule.use_original = True yield finally: FakeOsModule.use_original = False fake_path.py000064400000042765150043321510007050 0ustar00# Copyright 2009 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """ Faked ``os.path`` module replacement. See ``fake_filesystem`` for usage. """ import errno import os import sys from stat import ( S_IFDIR, S_IFMT, ) from types import ModuleType from typing import ( List, Optional, Union, Any, Dict, Tuple, AnyStr, overload, ClassVar, TYPE_CHECKING, ) from pyfakefs.helpers import ( make_string_path, to_string, matching_string, ) if TYPE_CHECKING: from pyfakefs.fake_filesystem import FakeFilesystem from pyfakefs.fake_os import FakeOsModule def _copy_module(old: ModuleType) -> ModuleType: """Recompiles and creates new module object.""" saved = sys.modules.pop(old.__name__, None) new = __import__(old.__name__) if saved is not None: sys.modules[old.__name__] = saved return new class FakePathModule: """Faked os.path module replacement. FakePathModule should *only* be instantiated by FakeOsModule. See the FakeOsModule docstring for details. """ _OS_PATH_COPY: Any = _copy_module(os.path) devnull: ClassVar[str] = "" sep: ClassVar[str] = "" altsep: ClassVar[Optional[str]] = None linesep: ClassVar[str] = "" pathsep: ClassVar[str] = "" @staticmethod def dir() -> List[str]: """Return the list of patched function names. Used for patching functions imported from the module. """ dir_list = [ "abspath", "dirname", "exists", "expanduser", "getatime", "getctime", "getmtime", "getsize", "isabs", "isdir", "isfile", "islink", "ismount", "join", "lexists", "normcase", "normpath", "realpath", "relpath", "split", "splitdrive", "samefile", ] if sys.version_info >= (3, 12): dir_list += ["isjunction", "splitroot"] return dir_list def __init__(self, filesystem: "FakeFilesystem", os_module: "FakeOsModule"): """Init. Args: filesystem: FakeFilesystem used to provide file system information """ self.filesystem = filesystem self._os_path = self._OS_PATH_COPY self._os_path.os = self.os = os_module # type: ignore[attr-defined] self.reset(filesystem) @classmethod def reset(cls, filesystem: "FakeFilesystem") -> None: cls.sep = filesystem.path_separator cls.altsep = filesystem.alternative_path_separator cls.linesep = filesystem.line_separator() cls.devnull = "nul" if filesystem.is_windows_fs else "/dev/null" cls.pathsep = ";" if filesystem.is_windows_fs else ":" def exists(self, path: AnyStr) -> bool: """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. """ return self.filesystem.exists(path) def lexists(self, path: AnyStr) -> bool: """Test whether a path exists. Returns True for broken symbolic links. Args: path: path to the symlink object. Returns: bool (if file exists). """ return self.filesystem.exists(path, check_link=True) def getsize(self, path: AnyStr): """Return the file object size in bytes. Args: path: path to the file object. Returns: file size in bytes. """ file_obj = self.filesystem.resolve(path) if ( self.filesystem.ends_with_path_separator(path) and S_IFMT(file_obj.st_mode) != S_IFDIR ): error_nr = errno.EINVAL if self.filesystem.is_windows_fs else errno.ENOTDIR self.filesystem.raise_os_error(error_nr, path) return file_obj.st_size def isabs(self, path: AnyStr) -> bool: """Return True if path is an absolute pathname.""" if self.filesystem.is_windows_fs: path = self.splitdrive(path)[1] path = make_string_path(path) return self.filesystem.starts_with_sep(path) def isdir(self, path: AnyStr) -> bool: """Determine if path identifies a directory.""" return self.filesystem.isdir(path) def isfile(self, path: AnyStr) -> bool: """Determine if path identifies a regular file.""" return self.filesystem.isfile(path) def islink(self, path: AnyStr) -> bool: """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. """ return self.filesystem.islink(path) if sys.version_info >= (3, 12): def isjunction(self, path: AnyStr) -> bool: """Returns False. Junctions are never faked.""" return self.filesystem.isjunction(path) def splitroot(self, path: AnyStr): """Split a pathname into drive, root and tail. Implementation taken from ntpath and posixpath. """ return self.filesystem.splitroot(path) def getmtime(self, path: AnyStr) -> float: """Returns 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. """ try: file_obj = self.filesystem.resolve(path) return file_obj.st_mtime except OSError: self.filesystem.raise_os_error(errno.ENOENT, winerror=3) def getatime(self, path: AnyStr) -> float: """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. """ try: file_obj = self.filesystem.resolve(path) except OSError: self.filesystem.raise_os_error(errno.ENOENT) return file_obj.st_atime def getctime(self, path: AnyStr) -> float: """Returns 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. """ try: file_obj = self.filesystem.resolve(path) except OSError: self.filesystem.raise_os_error(errno.ENOENT) return file_obj.st_ctime def abspath(self, path: AnyStr) -> AnyStr: """Return the absolute version of a path.""" def getcwd(): """Return the current working directory.""" # pylint: disable=undefined-variable if isinstance(path, bytes): return self.os.getcwdb() else: return self.os.getcwd() path = make_string_path(path) if not self.isabs(path): path = self.join(getcwd(), path) elif self.filesystem.is_windows_fs and self.filesystem.starts_with_sep(path): cwd = getcwd() if self.filesystem.starts_with_drive_letter(cwd): path = self.join(cwd[:2], path) return self.normpath(path) def join(self, *p: AnyStr) -> AnyStr: """Return the completed path with a separator of the parts.""" return self.filesystem.joinpaths(*p) def split(self, path: AnyStr) -> Tuple[AnyStr, AnyStr]: """Split the path into the directory and the filename of the path.""" return self.filesystem.splitpath(path) def splitdrive(self, path: AnyStr) -> Tuple[AnyStr, AnyStr]: """Split the path into the drive part and the rest of the path, if supported.""" return self.filesystem.splitdrive(path) def normpath(self, path: AnyStr) -> AnyStr: """Normalize path, eliminating double slashes, etc.""" return self.filesystem.normpath(path) def normcase(self, path: AnyStr) -> AnyStr: """Convert to lower case under windows, replaces additional path separator.""" path = self.filesystem.normcase(path) if self.filesystem.is_windows_fs: path = path.lower() return path def relpath(self, path: AnyStr, start: Optional[AnyStr] = None) -> AnyStr: """We mostly rely on the native implementation and adapt the path separator.""" if not path: raise ValueError("no path specified") path = make_string_path(path) path = self.filesystem.replace_windows_root(path) sep = matching_string(path, self.filesystem.path_separator) if start is not None: start = make_string_path(start) else: start = matching_string(path, self.filesystem.cwd) start = self.filesystem.replace_windows_root(start) system_sep = matching_string(path, self._os_path.sep) if self.filesystem.alternative_path_separator is not None: altsep = matching_string(path, self.filesystem.alternative_path_separator) path = path.replace(altsep, system_sep) start = start.replace(altsep, system_sep) path = path.replace(sep, system_sep) start = start.replace(sep, system_sep) path = self._os_path.relpath(path, start) return path.replace(system_sep, sep) def realpath(self, filename: AnyStr, strict: Optional[bool] = None) -> AnyStr: """Return the canonical path of the specified filename, eliminating any symbolic links encountered in the path. """ if strict is not None and sys.version_info < (3, 10): raise TypeError("realpath() got an unexpected " "keyword argument 'strict'") if strict: # raises in strict mode if the file does not exist self.filesystem.resolve(filename) if self.filesystem.is_windows_fs: return self.abspath(filename) filename = make_string_path(filename) path, ok = self._join_real_path(filename[:0], filename, {}) path = self.abspath(path) return path def samefile(self, path1: AnyStr, path2: AnyStr) -> bool: """Return whether path1 and path2 point to the same file. 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. """ stat1 = self.filesystem.stat(path1) stat2 = self.filesystem.stat(path2) return stat1.st_ino == stat2.st_ino and stat1.st_dev == stat2.st_dev @overload def _join_real_path( self, path: str, rest: str, seen: Dict[str, Optional[str]] ) -> Tuple[str, bool]: ... @overload def _join_real_path( self, path: bytes, rest: bytes, seen: Dict[bytes, Optional[bytes]] ) -> Tuple[bytes, bool]: ... def _join_real_path( self, path: AnyStr, rest: AnyStr, seen: Dict[AnyStr, Optional[AnyStr]] ) -> Tuple[AnyStr, bool]: """Join two paths, normalizing and eliminating any symbolic links encountered in the second path. Taken from Python source and adapted. """ curdir = matching_string(path, ".") pardir = matching_string(path, "..") sep = self.filesystem.get_path_separator(path) if self.isabs(rest): rest = rest[1:] path = sep while rest: name, _, rest = rest.partition(sep) if not name or name == curdir: # current dir continue if name == pardir: # parent dir if path: path, name = self.filesystem.splitpath(path) if name == pardir: path = self.filesystem.joinpaths(path, pardir, pardir) else: path = pardir continue newpath = self.filesystem.joinpaths(path, name) if not self.filesystem.islink(newpath): path = newpath continue # Resolve the symbolic link if newpath in seen: # Already seen this path seen_path = seen[newpath] if seen_path is not None: # use cached value path = seen_path continue # The symlink is not resolved, so we must have a symlink loop. # Return already resolved part + rest of the path unchanged. return self.filesystem.joinpaths(newpath, rest), False seen[newpath] = None # not resolved symlink path, ok = self._join_real_path( path, matching_string(path, self.filesystem.readlink(newpath)), seen, ) if not ok: return self.filesystem.joinpaths(path, rest), False seen[newpath] = path # resolved symlink return path, True def dirname(self, path: AnyStr) -> AnyStr: """Returns the first part of the result of `split()`.""" return self.split(path)[0] def expanduser(self, path: AnyStr) -> AnyStr: """Return the argument with an initial component of ~ or ~user replaced by that user's home directory. """ path = self._os_path.expanduser(path) return path.replace( matching_string(path, self._os_path.sep), matching_string(path, self.sep), ) def ismount(self, path: AnyStr) -> bool: """Return 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). """ if not path: return False path_str = to_string(make_string_path(path)) normed_path = self.filesystem.absnormpath(path_str) sep = self.filesystem.path_separator if self.filesystem.is_windows_fs: path_seps: Union[Tuple[str, Optional[str]], Tuple[str]] if self.filesystem.alternative_path_separator is not None: path_seps = (sep, self.filesystem.alternative_path_separator) else: path_seps = (sep,) drive, rest = self.filesystem.splitdrive(normed_path) if drive and drive[:1] in path_seps: return (not rest) or (rest in path_seps) if rest in path_seps: return True for mount_point in self.filesystem.mount_points: if to_string(normed_path).rstrip(sep) == to_string(mount_point).rstrip(sep): return True return False def __getattr__(self, name: str) -> Any: """Forwards any non-faked calls to the real os.path.""" return getattr(self._os_path, name) if sys.platform == "win32": class FakeNtModule: """Under windows, a few function of `os.path` are taken from the `nt` module for performance reasons. These are patched here. """ @staticmethod def dir(): if sys.version_info >= (3, 12): return ["_path_exists", "_path_isfile", "_path_isdir", "_path_islink"] else: return ["_isdir"] def __init__(self, filesystem: "FakeFilesystem"): """Init. Args: filesystem: FakeFilesystem used to provide file system information """ import nt # type:ignore[import] self.filesystem = filesystem self.nt_module: Any = nt if sys.version_info >= (3, 12): def _path_isdir(self, path: AnyStr) -> bool: return self.filesystem.isdir(path) def _path_isfile(self, path: AnyStr) -> bool: return self.filesystem.isfile(path) def _path_islink(self, path: AnyStr) -> bool: return self.filesystem.islink(path) def _path_exists(self, path: AnyStr) -> bool: return self.filesystem.exists(path) else: def _isdir(self, path: AnyStr) -> bool: return self.filesystem.isdir(path) def __getattr__(self, name: str) -> Any: """Forwards any non-faked calls to the real nt module.""" return getattr(self.nt_module, name) fake_pathlib.py000064400000104101150043321510007516 0ustar00# Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """A fake implementation for pathlib working with FakeFilesystem. New in pyfakefs 3.0. Usage: * With fake_filesystem_unittest: If using fake_filesystem_unittest.TestCase, pathlib gets replaced by fake_pathlib together with other file system related modules. * Stand-alone with FakeFilesystem: `filesystem = fake_filesystem.FakeFilesystem()` `fake_pathlib_module = fake_filesystem.FakePathlibModule(filesystem)` `path = fake_pathlib_module.Path('/foo/bar')` Note: as the implementation is based on FakeFilesystem, all faked classes (including PurePosixPath, PosixPath, PureWindowsPath and WindowsPath) get the properties of the underlying fake filesystem. """ import errno import fnmatch import functools import inspect import ntpath import os import pathlib import posixpath import re import sys from pathlib import PurePath from typing import Callable from urllib.parse import quote_from_bytes as urlquote_from_bytes from pyfakefs import fake_scandir from pyfakefs.extra_packages import use_scandir from pyfakefs.fake_filesystem import FakeFilesystem from pyfakefs.fake_open import FakeFileOpen from pyfakefs.fake_os import FakeOsModule, use_original_os from pyfakefs.helpers import IS_PYPY def init_module(filesystem): """Initializes the fake module with the fake file system.""" # pylint: disable=protected-access FakePath.filesystem = filesystem if sys.version_info < (3, 12): FakePathlibModule.PureWindowsPath._flavour = _FakeWindowsFlavour(filesystem) FakePathlibModule.PurePosixPath._flavour = _FakePosixFlavour(filesystem) else: # in Python 3.12, the flavour is no longer an own class, # but points to the os-specific path module (posixpath/ntpath) fake_os = FakeOsModule(filesystem) fake_path = fake_os.path FakePathlibModule.PureWindowsPath._flavour = fake_path FakePathlibModule.PurePosixPath._flavour = fake_path def _wrap_strfunc(strfunc): @functools.wraps(strfunc) def _wrapped(pathobj, *args, **kwargs): return strfunc(pathobj.filesystem, str(pathobj), *args, **kwargs) return staticmethod(_wrapped) def _wrap_binary_strfunc(strfunc): @functools.wraps(strfunc) def _wrapped(pathobj1, pathobj2, *args): return strfunc(pathobj1.filesystem, str(pathobj1), str(pathobj2), *args) return staticmethod(_wrapped) def _wrap_binary_strfunc_reverse(strfunc): @functools.wraps(strfunc) def _wrapped(pathobj1, pathobj2, *args): return strfunc(pathobj2.filesystem, str(pathobj2), str(pathobj1), *args) return staticmethod(_wrapped) try: accessor = pathlib._Accessor # type: ignore[attr-defined] except AttributeError: accessor = object class _FakeAccessor(accessor): # type: ignore[valid-type, misc] """Accessor which forwards some of the functions to FakeFilesystem methods. """ stat = _wrap_strfunc(FakeFilesystem.stat) lstat = _wrap_strfunc( lambda fs, path: FakeFilesystem.stat(fs, path, follow_symlinks=False) ) listdir = _wrap_strfunc(FakeFilesystem.listdir) if use_scandir: scandir = _wrap_strfunc(fake_scandir.scandir) if hasattr(os, "lchmod"): lchmod = _wrap_strfunc( lambda fs, path, mode: FakeFilesystem.chmod( fs, path, mode, follow_symlinks=False ) ) else: def lchmod(self, pathobj, *args, **kwargs): """Raises not implemented for Windows systems.""" raise NotImplementedError("lchmod() not available on this system") def chmod(self, pathobj, *args, **kwargs): if "follow_symlinks" in kwargs: if sys.version_info < (3, 10): raise TypeError( "chmod() got an unexpected keyword " "argument 'follow_symlinks'" ) if not kwargs["follow_symlinks"] and ( os.chmod not in os.supports_follow_symlinks or IS_PYPY ): raise NotImplementedError( "`follow_symlinks` for chmod() is not available " "on this system" ) return pathobj.filesystem.chmod(str(pathobj), *args, **kwargs) mkdir = _wrap_strfunc(FakeFilesystem.makedir) unlink = _wrap_strfunc(FakeFilesystem.remove) rmdir = _wrap_strfunc(FakeFilesystem.rmdir) rename = _wrap_binary_strfunc(FakeFilesystem.rename) replace = _wrap_binary_strfunc( lambda fs, old_path, new_path: FakeFilesystem.rename( fs, old_path, new_path, force_replace=True ) ) symlink = _wrap_binary_strfunc_reverse( lambda fs, fpath, target, target_is_dir: FakeFilesystem.create_symlink( fs, fpath, target, create_missing_dirs=False ) ) if (3, 8) <= sys.version_info: link_to = _wrap_binary_strfunc( lambda fs, file_path, link_target: FakeFilesystem.link( fs, file_path, link_target ) ) if sys.version_info >= (3, 10): link = _wrap_binary_strfunc( lambda fs, file_path, link_target: FakeFilesystem.link( fs, file_path, link_target ) ) # this will use the fake filesystem because os is patched def getcwd(self): return os.getcwd() readlink = _wrap_strfunc(FakeFilesystem.readlink) utime = _wrap_strfunc(FakeFilesystem.utime) _fake_accessor = _FakeAccessor() if sys.version_info < (3, 12): flavour = pathlib._Flavour # type: ignore[attr-defined] class _FakeFlavour(flavour): # type: ignore[valid-type, misc] """Fake Flavour implementation used by PurePath and _Flavour""" filesystem = None sep = "/" altsep = None has_drv = False ext_namespace_prefix = "\\\\?\\" drive_letters = {chr(x) for x in range(ord("a"), ord("z") + 1)} | { chr(x) for x in range(ord("A"), ord("Z") + 1) } def __init__(self, filesystem): self.filesystem = filesystem self.sep = filesystem.path_separator self.altsep = filesystem.alternative_path_separator self.has_drv = filesystem.is_windows_fs super(_FakeFlavour, self).__init__() @staticmethod def _split_extended_path(path, ext_prefix=ext_namespace_prefix): prefix = "" if path.startswith(ext_prefix): prefix = path[:4] path = path[4:] if path.startswith("UNC\\"): prefix += path[:3] path = "\\" + path[3:] return prefix, path def _splitroot_with_drive(self, path, sep): first = path[0:1] second = path[1:2] if second == sep and first == sep: # extended paths should also disable the collapsing of "." # components (according to MSDN docs). prefix, path = self._split_extended_path(path) first = path[0:1] second = path[1:2] else: prefix = "" third = path[2:3] if second == sep and first == sep and third != sep: # is a UNC path: # vvvvvvvvvvvvvvvvvvvvv root # \\machine\mountpoint\directory\etc\... # directory ^^^^^^^^^^^^^^ index = path.find(sep, 2) if index != -1: index2 = path.find(sep, index + 1) # a UNC path can't have two slashes in a row # (after the initial two) if index2 != index + 1: if index2 == -1: index2 = len(path) if prefix: return prefix + path[1:index2], sep, path[index2 + 1 :] return path[:index2], sep, path[index2 + 1 :] drv = root = "" if second == ":" and first in self.drive_letters: drv = path[:2] path = path[2:] first = third if first == sep: root = first path = path.lstrip(sep) return prefix + drv, root, path @staticmethod def _splitroot_posix(path, sep): if path and path[0] == sep: stripped_part = path.lstrip(sep) if len(path) - len(stripped_part) == 2: return "", sep * 2, stripped_part return "", sep, stripped_part else: return "", "", path def splitroot(self, path, sep=None): """Split path into drive, root and rest.""" if sep is None: sep = self.filesystem.path_separator if self.filesystem.is_windows_fs: return self._splitroot_with_drive(path, sep) return self._splitroot_posix(path, sep) def casefold(self, path): """Return the lower-case version of s for a Windows filesystem.""" if self.filesystem.is_windows_fs: return path.lower() return path def casefold_parts(self, parts): """Return the lower-case version of parts for a Windows filesystem.""" if self.filesystem.is_windows_fs: return [p.lower() for p in parts] return parts def _resolve_posix(self, path, strict): sep = self.sep seen = {} def _resolve(path, rest): if rest.startswith(sep): path = "" for name in rest.split(sep): if not name or name == ".": # current dir continue if name == "..": # parent dir path, _, _ = path.rpartition(sep) continue newpath = path + sep + name if newpath in seen: # Already seen this path path = seen[newpath] if path is not None: # use cached value continue # The symlink is not resolved, so we must have # a symlink loop. raise RuntimeError("Symlink loop from %r" % newpath) # Resolve the symbolic link try: target = self.filesystem.readlink(newpath) except OSError as e: if e.errno != errno.EINVAL and strict: raise # Not a symlink, or non-strict mode. We just leave the path # untouched. path = newpath else: seen[newpath] = None # not resolved symlink path = _resolve(path, target) seen[newpath] = path # resolved symlink return path # NOTE: according to POSIX, getcwd() cannot contain path components # which are symlinks. base = "" if path.is_absolute() else self.filesystem.cwd return _resolve(base, str(path)) or sep def _resolve_windows(self, path, strict): path = str(path) if not path: return os.getcwd() previous_s = None if strict: if not self.filesystem.exists(path): self.filesystem.raise_os_error(errno.ENOENT, path) return self.filesystem.resolve_path(path) else: while True: try: path = self.filesystem.resolve_path(path) except OSError: previous_s = path path = self.filesystem.splitpath(path)[0] else: if previous_s is None: return path return self.filesystem.joinpaths( path, os.path.basename(previous_s) ) def resolve(self, path, strict): """Make the path absolute, resolving any symlinks.""" if self.filesystem.is_windows_fs: return self._resolve_windows(path, strict) return self._resolve_posix(path, strict) def gethomedir(self, username): """Return the home directory of the current user.""" if not username: try: return os.environ["HOME"] except KeyError: import pwd return pwd.getpwuid(os.getuid()).pw_dir else: import pwd try: return pwd.getpwnam(username).pw_dir except KeyError: raise RuntimeError( "Can't determine home directory " "for %r" % username ) class _FakeWindowsFlavour(_FakeFlavour): """Flavour used by PureWindowsPath with some Windows specific implementations independent of FakeFilesystem properties. """ reserved_names = ( {"CON", "PRN", "AUX", "NUL"} | {"COM%d" % i for i in range(1, 10)} | {"LPT%d" % i for i in range(1, 10)} ) pathmod = ntpath def is_reserved(self, parts): """Return True if the path is considered reserved under Windows.""" # NOTE: the rules for reserved names seem somewhat complicated # (e.g. r"..\NUL" is reserved but not r"foo\NUL"). # We err on the side of caution and return True for paths which are # not considered reserved by Windows. if not parts: return False if self.filesystem.is_windows_fs and parts[0].startswith("\\\\"): # UNC paths are never reserved return False return parts[-1].partition(".")[0].upper() in self.reserved_names def make_uri(self, path): """Return a file URI for the given path""" # Under Windows, file URIs use the UTF-8 encoding. # original version, not faked drive = path.drive if len(drive) == 2 and drive[1] == ":": # It's a path on a local drive => 'file:///c:/a/b' rest = path.as_posix()[2:].lstrip("/") return "file:///%s/%s" % ( drive, urlquote_from_bytes(rest.encode("utf-8")), ) else: # It's a path on a network drive => 'file://host/share/a/b' return "file:" + urlquote_from_bytes(path.as_posix().encode("utf-8")) def gethomedir(self, username): """Return the home directory of the current user.""" # original version, not faked if "HOME" in os.environ: userhome = os.environ["HOME"] elif "USERPROFILE" in os.environ: userhome = os.environ["USERPROFILE"] elif "HOMEPATH" in os.environ: try: drv = os.environ["HOMEDRIVE"] except KeyError: drv = "" userhome = drv + os.environ["HOMEPATH"] else: raise RuntimeError("Can't determine home directory") if username: # Try to guess user home directory. By default all users # directories are located in the same place and are named by # corresponding usernames. If current user home directory points # to nonstandard place, this guess is likely wrong. if os.environ["USERNAME"] != username: drv, root, parts = self.parse_parts((userhome,)) if parts[-1] != os.environ["USERNAME"]: raise RuntimeError( "Can't determine home directory " "for %r" % username ) parts[-1] = username if drv or root: userhome = drv + root + self.join(parts[1:]) else: userhome = self.join(parts) return userhome def compile_pattern(self, pattern): return re.compile(fnmatch.translate(pattern), re.IGNORECASE).fullmatch class _FakePosixFlavour(_FakeFlavour): """Flavour used by PurePosixPath with some Unix specific implementations independent of FakeFilesystem properties. """ pathmod = posixpath def is_reserved(self, parts): return False def make_uri(self, path): # We represent the path using the local filesystem encoding, # for portability to other applications. bpath = bytes(path) return "file://" + urlquote_from_bytes(bpath) def gethomedir(self, username): # original version, not faked if not username: try: return os.environ["HOME"] except KeyError: import pwd return pwd.getpwuid(os.getuid()).pw_dir else: import pwd try: return pwd.getpwnam(username).pw_dir except KeyError: raise RuntimeError( "Can't determine home directory " "for %r" % username ) def compile_pattern(self, pattern): return re.compile(fnmatch.translate(pattern)).fullmatch class FakePath(pathlib.Path): """Replacement for pathlib.Path. Reimplement some methods to use fake filesystem. The rest of the methods work as they are, as they will use the fake accessor. New in pyfakefs 3.0. """ # the underlying fake filesystem filesystem = None def __new__(cls, *args, **kwargs): """Creates the correct subclass based on OS.""" if cls is FakePathlibModule.Path: cls = ( FakePathlibModule.WindowsPath if cls.filesystem.is_windows_fs else FakePathlibModule.PosixPath ) if sys.version_info < (3, 12): return cls._from_parts(args) # pytype: disable=attribute-error else: return object.__new__(cls) if sys.version_info[:2] == (3, 10): # Overwritten class methods to call _init to set the fake accessor, # which is not done in Python 3.10, and not needed from Python 3.11 on @classmethod def _from_parts(cls, args): self = object.__new__(cls) self._init() drv, root, parts = self._parse_args(args) # pytype: disable=attribute-error self._drv = drv self._root = root self._parts = parts return self @classmethod def _from_parsed_parts(cls, drv, root, parts): self = object.__new__(cls) self._drv = drv self._root = root self._parts = parts self._init() return self if sys.version_info < (3, 11): def _init(self, template=None): """Initializer called from base class.""" # only needed until Python 3.10 self._accessor = _fake_accessor # only needed until Python 3.8 self._closed = False def _path(self): """Returns the underlying path string as used by the fake filesystem. """ return str(self) @classmethod def cwd(cls): """Return a new path pointing to the current working directory (as returned by os.getcwd()). """ return cls(cls.filesystem.cwd) if sys.version_info < (3, 12): # in 3.12, we can use the pathlib implementation def resolve(self, strict=None): """Make the path absolute, resolving all symlinks on the way and also normalizing it (for example turning slashes into backslashes under Windows). Args: strict: If False (default) no exception is raised if the path does not exist. New in Python 3.6. Raises: OSError: if the path doesn't exist (strict=True or Python < 3.6) """ if sys.version_info >= (3, 6): if strict is None: strict = False else: if strict is not None: raise TypeError( "resolve() got an unexpected keyword argument 'strict'" ) strict = True self._raise_on_closed() path = self._flavour.resolve( self, strict=strict ) # pytype: disable=attribute-error if path is None: self.stat() path = str(self.absolute()) path = self.filesystem.absnormpath(path) return FakePath(path) def open(self, mode="r", buffering=-1, encoding=None, errors=None, newline=None): """Open the file pointed by this path and return a fake file object. Raises: OSError: if the target object is a directory, the path is invalid or permission is denied. """ self._raise_on_closed() return FakeFileOpen(self.filesystem)( self._path(), mode, buffering, encoding, errors, newline ) def read_bytes(self): """Open the fake file in bytes mode, read it, and close the file. Raises: OSError: if the target object is a directory, the path is invalid or permission is denied. """ with FakeFileOpen(self.filesystem)( self._path(), mode="rb" ) as f: # pytype: disable=attribute-error return f.read() def read_text(self, encoding=None, errors=None): """ Open the fake file in text mode, read it, and close the file. """ with FakeFileOpen(self.filesystem)( # pytype: disable=attribute-error self._path(), mode="r", encoding=encoding, errors=errors ) as f: return f.read() def write_bytes(self, data): """Open the fake file in bytes mode, write to it, and close the file. Args: data: the bytes to be written Raises: OSError: if the target object is a directory, the path is invalid or permission is denied. """ # type-check for the buffer interface before truncating the file view = memoryview(data) with FakeFileOpen(self.filesystem)( self._path(), mode="wb" ) as f: # pytype: disable=attribute-error return f.write(view) def write_text(self, data, encoding=None, errors=None, newline=None): """Open the fake file in text mode, write to it, and close the file. Args: data: the string to be written encoding: the encoding used for the string; if not given, the default locale encoding is used errors: (str) Defines how encoding errors are handled. newline: Controls universal newlines, passed to stream object. New in Python 3.10. Raises: TypeError: if data is not of type 'str'. OSError: if the target object is a directory, the path is invalid or permission is denied. """ if not isinstance(data, str): raise TypeError("data must be str, not %s" % data.__class__.__name__) if newline is not None and sys.version_info < (3, 10): raise TypeError( "write_text() got an unexpected " "keyword argument 'newline'" ) with FakeFileOpen(self.filesystem)( # pytype: disable=attribute-error self._path(), mode="w", encoding=encoding, errors=errors, newline=newline, ) as f: return f.write(data) @classmethod def home(cls): """Return a new path pointing to the user's home directory (as returned by os.path.expanduser('~')). """ home = os.path.expanduser("~") if cls.filesystem.is_windows_fs != (os.name == "nt"): username = os.path.split(home)[1] if cls.filesystem.is_windows_fs: home = os.path.join("C:", "Users", username) else: home = os.path.join("home", username) if not cls.filesystem.exists(home): cls.filesystem.create_dir(home) return cls(home.replace(os.sep, cls.filesystem.path_separator)) def samefile(self, other_path): """Return whether other_path is the same or not as this file (as returned by os.path.samefile()). Args: other_path: A path object or string of the file object to be compared with Raises: OSError: if the filesystem object doesn't exist. """ st = self.stat() try: other_st = other_path.stat() except AttributeError: other_st = self.filesystem.stat(other_path) return st.st_ino == other_st.st_ino and st.st_dev == other_st.st_dev def expanduser(self): """Return a new path with expanded ~ and ~user constructs (as returned by os.path.expanduser) """ return FakePath( os.path.expanduser(self._path()).replace( os.path.sep, self.filesystem.path_separator ) ) def _raise_on_closed(self): if sys.version_info < (3, 9) and self._closed: self._raise_closed() def touch(self, mode=0o666, exist_ok=True): """Create a fake file for the path with the given access mode, if it doesn't exist. Args: mode: the file mode for the file if it does not exist exist_ok: if the file already exists and this is True, nothing happens, otherwise FileExistError is raised Raises: FileExistsError: if the file exists and exits_ok is False. """ self._raise_on_closed() if self.exists(): if exist_ok: self.filesystem.utime(self._path(), times=None) else: self.filesystem.raise_os_error(errno.EEXIST, self._path()) else: fake_file = self.open("w") fake_file.close() self.chmod(mode) if sys.version_info >= (3, 12): """These are reimplemented for now because the original implementation checks the flavour against ntpath/posixpath. """ def is_absolute(self): if self.filesystem.is_windows_fs: return self.drive and self.root return os.path.isabs(self._path()) def is_reserved(self): if not self.filesystem.is_windows_fs or not self._tail: return False if self._tail[0].startswith("\\\\"): # UNC paths are never reserved. return False name = self._tail[-1].partition(".")[0].partition(":")[0].rstrip(" ") return name.upper() in pathlib._WIN_RESERVED_NAMES class FakePathlibModule: """Uses FakeFilesystem to provide a fake pathlib module replacement. Can be used to replace both the standard `pathlib` module and the `pathlib2` package available on PyPi. You need a fake_filesystem to use this: `filesystem = fake_filesystem.FakeFilesystem()` `fake_pathlib_module = fake_filesystem.FakePathlibModule(filesystem)` """ def __init__(self, filesystem): """ Initializes the module with the given filesystem. Args: filesystem: FakeFilesystem used to provide file system information """ init_module(filesystem) self._pathlib_module = pathlib class PurePosixPath(PurePath): """A subclass of PurePath, that represents non-Windows filesystem paths""" __slots__ = () class PureWindowsPath(PurePath): """A subclass of PurePath, that represents Windows filesystem paths""" __slots__ = () class WindowsPath(FakePath, PureWindowsPath): """A subclass of Path and PureWindowsPath that represents concrete Windows filesystem paths. """ __slots__ = () def owner(self): raise NotImplementedError("Path.owner() is unsupported on this system") def group(self): raise NotImplementedError("Path.group() is unsupported on this system") def is_mount(self): raise NotImplementedError("Path.is_mount() is unsupported on this system") class PosixPath(FakePath, PurePosixPath): """A subclass of Path and PurePosixPath that represents concrete non-Windows filesystem paths. """ __slots__ = () def owner(self): """Return the username of the file owner. It is assumed that `st_uid` is related to a real user, otherwise `KeyError` is raised. """ import pwd return pwd.getpwuid(self.stat().st_uid).pw_name def group(self): """Return the group name of the file group. It is assumed that `st_gid` is related to a real group, otherwise `KeyError` is raised. """ import grp return grp.getgrgid(self.stat().st_gid).gr_name Path = FakePath def __getattr__(self, name): """Forwards any unfaked calls to the standard pathlib module.""" return getattr(self._pathlib_module, name) class FakePathlibPathModule: """Patches `pathlib.Path` by passing all calls to FakePathlibModule.""" fake_pathlib = None def __init__(self, filesystem=None): if self.fake_pathlib is None: self.__class__.fake_pathlib = FakePathlibModule(filesystem) def __call__(self, *args, **kwargs): return self.fake_pathlib.Path(*args, **kwargs) def __getattr__(self, name): return getattr(self.fake_pathlib.Path, name) @classmethod def __instancecheck__(cls, instance): # fake the inheritance to pass isinstance checks - see #666 return isinstance(instance, PurePath) class RealPath(pathlib.Path): """Replacement for `pathlib.Path` if it shall not be faked. Needed because `Path` in `pathlib` is always faked, even if `pathlib` itself is not. """ if sys.version_info < (3, 12): _flavour = ( pathlib._WindowsFlavour() # type:ignore if os.name == "nt" else pathlib._PosixFlavour() # type:ignore ) # type:ignore else: _flavour = ntpath if os.name == "nt" else posixpath def __new__(cls, *args, **kwargs): """Creates the correct subclass based on OS.""" if cls is RealPathlibModule.Path: cls = ( RealPathlibModule.WindowsPath # pytype: disable=attribute-error if os.name == "nt" else RealPathlibModule.PosixPath # pytype: disable=attribute-error ) if sys.version_info < (3, 12): return cls._from_parts(args) # pytype: disable=attribute-error else: return object.__new__(cls) if sys.version_info > (3, 10): def with_original_os(f: Callable) -> Callable: """Decorator used for real pathlib Path methods to ensure that real os functions instead of faked ones are used.""" @functools.wraps(f) def wrapped(*args, **kwargs): with use_original_os(): return f(*args, **kwargs) return wrapped for name, fn in inspect.getmembers(RealPath, inspect.isfunction): if not name.startswith("__"): setattr(RealPath, name, with_original_os(fn)) class RealPathlibPathModule: """Patches `pathlib.Path` by passing all calls to RealPathlibModule.""" real_pathlib = None @classmethod def __instancecheck__(cls, instance): # as we cannot derive from pathlib.Path, we fake # the inheritance to pass isinstance checks - see #666 return isinstance(instance, PurePath) def __init__(self): if self.real_pathlib is None: self.__class__.real_pathlib = RealPathlibModule() def __call__(self, *args, **kwargs): return RealPath(*args, **kwargs) def __getattr__(self, name): return getattr(self.real_pathlib.Path, name) class RealPathlibModule: """Used to replace `pathlib` for skipped modules. As the original `pathlib` is always patched to use the fake path, we need to provide a version which does not do this. """ def __init__(self): self._pathlib_module = pathlib class PurePosixPath(PurePath): """A subclass of PurePath, that represents Posix filesystem paths""" __slots__ = () class PureWindowsPath(PurePath): """A subclass of PurePath, that represents Windows filesystem paths""" __slots__ = () if sys.platform == "win32": class WindowsPath(RealPath, PureWindowsPath): """A subclass of Path and PureWindowsPath that represents concrete Windows filesystem paths. """ __slots__ = () else: class PosixPath(RealPath, PurePosixPath): """A subclass of Path and PurePosixPath that represents concrete non-Windows filesystem paths. """ __slots__ = () Path = RealPath def __getattr__(self, name): """Forwards any unfaked calls to the standard pathlib module.""" return getattr(self._pathlib_module, name) fake_scandir.py000064400000026073150043321510007531 0ustar00# Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """A fake implementation for the `scandir` function working with FakeFilesystem. Works with both the function integrated into the `os` module since Python 3.5 and the standalone function available in the standalone `scandir` python package. """ import os import sys from pyfakefs.extra_packages import use_scandir_package from pyfakefs.helpers import to_string, make_string_path if sys.version_info >= (3, 6): BaseClass = os.PathLike else: BaseClass = object class DirEntry(BaseClass): """Emulates os.DirEntry. Note that we did not enforce keyword only arguments.""" def __init__(self, filesystem): """Initialize the dir entry with unset values. Args: filesystem: the fake filesystem used for implementation. """ self._filesystem = filesystem self.name = "" self.path = "" self._abspath = "" self._inode = None self._islink = False self._isdir = False self._statresult = None self._statresult_symlink = None def inode(self): """Return the inode number of the entry.""" if self._inode is None: self.stat(follow_symlinks=False) return self._inode def is_dir(self, follow_symlinks=True): """Return True if this entry is a directory entry. Args: follow_symlinks: If True, also return True if this entry is a symlink pointing to a directory. Returns: True if this entry is an existing directory entry, or if follow_symlinks is set, and this entry points to an existing directory entry. """ return self._isdir and (follow_symlinks or not self._islink) def is_file(self, follow_symlinks=True): """Return True if this entry is a regular file entry. Args: follow_symlinks: If True, also return True if this entry is a symlink pointing to a regular file. Returns: True if this entry is an existing file entry, or if follow_symlinks is set, and this entry points to an existing file entry. """ return not self._isdir and (follow_symlinks or not self._islink) def is_symlink(self): """Return True if this entry is a symbolic link (even if broken).""" return self._islink def stat(self, follow_symlinks=True): """Return a stat_result object for this entry. Args: follow_symlinks: If False and the entry is a symlink, return the result for the symlink, otherwise for the object it points to. """ if follow_symlinks: if self._statresult_symlink is None: file_object = self._filesystem.resolve(self._abspath) self._statresult_symlink = file_object.stat_result.copy() if self._filesystem.is_windows_fs: self._statresult_symlink.st_nlink = 0 return self._statresult_symlink if self._statresult is None: file_object = self._filesystem.lresolve(self._abspath) self._inode = file_object.st_ino self._statresult = file_object.stat_result.copy() if self._filesystem.is_windows_fs: self._statresult.st_nlink = 0 return self._statresult if sys.version_info >= (3, 6): def __fspath__(self): return self.path if sys.version_info >= (3, 12): def is_junction(self) -> bool: """Return True if this entry is a junction. Junctions are not a part of posix semantic.""" if not self._filesystem.is_windows_fs: return False file_object = self._filesystem.resolve(self._abspath) return file_object.is_junction class ScanDirIter: """Iterator for DirEntry objects returned from `scandir()` function.""" def __init__(self, filesystem, path): self.filesystem = filesystem if isinstance(path, int): if not use_scandir_package and ( sys.version_info < (3, 7) or self.filesystem.is_windows_fs ): raise NotImplementedError( "scandir does not support file descriptor " "path argument" ) self.abspath = self.filesystem.absnormpath( self.filesystem.get_open_file(path).get_object().path ) self.path = "" else: path = make_string_path(path) self.abspath = self.filesystem.absnormpath(path) self.path = to_string(path) entries = self.filesystem.confirmdir(self.abspath).entries self.entry_iter = iter(entries) def __iter__(self): return self def __next__(self): entry = self.entry_iter.__next__() dir_entry = DirEntry(self.filesystem) dir_entry.name = entry dir_entry.path = self.filesystem.joinpaths(self.path, dir_entry.name) dir_entry._abspath = self.filesystem.joinpaths(self.abspath, dir_entry.name) dir_entry._isdir = self.filesystem.isdir(dir_entry._abspath) dir_entry._islink = self.filesystem.islink(dir_entry._abspath) return dir_entry if sys.version_info >= (3, 6): def __enter__(self): return self def __exit__(self, exc_type, exc_val, exc_tb): self.close() def close(self): pass def scandir(filesystem, path=""): """Return an iterator of DirEntry objects corresponding to the entries in the directory given by path. Args: filesystem: The fake filesystem used for implementation 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. """ return ScanDirIter(filesystem, path) def _classify_directory_contents(filesystem, root): """Classify contents of a directory as files/directories. Args: filesystem: The fake filesystem used for implementation root: (str) Directory to examine. Returns: (tuple) A tuple consisting of three values: the directory examined, a list containing all of the directory entries, and a list containing all of the non-directory entries. (This is the same format as returned by the `os.walk` generator.) Raises: Nothing on its own, but be ready to catch exceptions generated by underlying mechanisms like `os.listdir`. """ dirs = [] files = [] for entry in filesystem.listdir(root): if filesystem.isdir(filesystem.joinpaths(root, entry)): dirs.append(entry) else: files.append(entry) return root, dirs, files def walk(filesystem, top, topdown=True, onerror=None, followlinks=False): """Perform an os.walk operation over the fake filesystem. Args: filesystem: The fake filesystem used for implementation 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. """ def do_walk(top_dir, top_most=False): if not top_most and not followlinks and filesystem.islink(top_dir): return try: top_contents = _classify_directory_contents(filesystem, top_dir) except OSError as exc: top_contents = None if onerror is not None: onerror(exc) if top_contents is not None: if topdown: yield top_contents for directory in top_contents[1]: path = filesystem.joinpaths(top_dir, directory) if not followlinks and filesystem.islink(path): continue for contents in do_walk(path): yield contents if not topdown: yield top_contents return do_walk(to_string(top), top_most=True) class FakeScanDirModule: """Uses FakeFilesystem to provide a fake `scandir` module replacement. .. Note:: The ``scandir`` function is a part of the standard ``os`` module since Python 3.5. This class handles the separate ``scandir`` module that is available on pypi. You need a fake_filesystem to use this: `filesystem = fake_filesystem.FakeFilesystem()` `fake_scandir_module = fake_filesystem.FakeScanDirModule(filesystem)` """ @staticmethod def dir(): """Return the list of patched function names. Used for patching functions imported from the module. """ return "scandir", "walk" def __init__(self, filesystem): self.filesystem = filesystem def scandir(self, path="."): """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. """ return scandir(self.filesystem, path) def walk(self, top, topdown=True, onerror=None, followlinks=False): """Perform a 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. """ return walk(self.filesystem, top, topdown, onerror, followlinks) helpers.py000064400000031571150043321510006561 0ustar00# Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Helper classes use for fake file system implementation.""" import io import locale import os import platform import stat import sys import time from copy import copy from stat import S_IFLNK from typing import Union, Optional, Any, AnyStr, overload, cast AnyString = Union[str, bytes] AnyPath = Union[AnyStr, os.PathLike] IS_PYPY = platform.python_implementation() == "PyPy" IS_WIN = sys.platform == "win32" IN_DOCKER = os.path.exists("/.dockerenv") PERM_READ = 0o400 # Read permission bit. PERM_WRITE = 0o200 # Write permission bit. PERM_EXE = 0o100 # Execute permission bit. PERM_DEF = 0o777 # Default permission bits. PERM_DEF_FILE = 0o666 # Default permission bits (regular file) PERM_ALL = 0o7777 # All permission bits. if sys.platform == "win32": USER_ID = 1 GROUP_ID = 1 else: USER_ID = os.getuid() GROUP_ID = os.getgid() def get_uid() -> int: """Get the global user id. Same as ``os.getuid()``""" return USER_ID def set_uid(uid: int) -> None: """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. """ global USER_ID USER_ID = uid def get_gid() -> int: """Get the global group id. Same as ``os.getgid()``""" return GROUP_ID def set_gid(gid: int) -> None: """Set the global group id. This is only used to set st_gid for new files, no permission checks are performed. Args: gid: (int) the group ID of the user calling the file system functions. """ global GROUP_ID GROUP_ID = gid def reset_ids() -> None: """Set the global user ID and group ID back to default values.""" if sys.platform == "win32": set_uid(1) set_gid(1) else: set_uid(os.getuid()) set_gid(os.getgid()) def is_root() -> bool: """Return True if the current user is the root user.""" return USER_ID == 0 def is_int_type(val: Any) -> bool: """Return True if `val` is of integer type.""" return isinstance(val, int) def is_byte_string(val: Any) -> bool: """Return True if `val` is a bytes-like object, False for a unicode string.""" return not hasattr(val, "encode") def is_unicode_string(val: Any) -> bool: """Return True if `val` is a unicode string, False for a bytes-like object.""" return hasattr(val, "encode") @overload def make_string_path(dir_name: AnyStr) -> AnyStr: ... @overload def make_string_path(dir_name: os.PathLike) -> str: ... def make_string_path(dir_name: AnyPath) -> AnyStr: return cast(AnyStr, os.fspath(dir_name)) # pytype: disable=invalid-annotation def to_string(path: Union[AnyStr, Union[str, bytes]]) -> str: """Return the string representation of a byte string using the preferred encoding, or the string itself if path is a str.""" if isinstance(path, bytes): return path.decode(locale.getpreferredencoding(False)) return path def to_bytes(path: Union[AnyStr, Union[str, bytes]]) -> bytes: """Return the bytes representation of a string using the preferred encoding, or the byte string itself if path is a byte string.""" if isinstance(path, str): return bytes(path, locale.getpreferredencoding(False)) return path def join_strings(s1: AnyStr, s2: AnyStr) -> AnyStr: """This is a bit of a hack to satisfy mypy - may be refactored.""" return s1 + s2 def real_encoding(encoding: Optional[str]) -> Optional[str]: """Since Python 3.10, the new function ``io.text_encoding`` returns "locale" as the encoding if None is defined. This will be handled as no encoding in pyfakefs.""" if sys.version_info >= (3, 10): return encoding if encoding != "locale" else None return encoding def now(): return time.time() @overload def matching_string(matched: bytes, string: AnyStr) -> bytes: ... @overload def matching_string(matched: str, string: AnyStr) -> str: ... @overload def matching_string(matched: AnyStr, string: None) -> None: ... def matching_string( # type: ignore[misc] matched: AnyStr, string: Optional[AnyStr] ) -> Optional[AnyString]: """Return the string as byte or unicode depending on the type of matched, assuming string is an ASCII string. """ if string is None: return string if isinstance(matched, bytes) and isinstance(string, str): return string.encode(locale.getpreferredencoding(False)) return string # pytype: disable=bad-return-type class FakeStatResult: """Mimics os.stat_result for use as return type of `stat()` and similar. This is needed as `os.stat_result` has no possibility to set nanosecond times directly. """ def __init__( self, is_windows: bool, user_id: int, group_id: int, initial_time: Optional[float] = None, ): self.st_mode: int = 0 self.st_ino: Optional[int] = None self.st_dev: int = 0 self.st_nlink: int = 0 self.st_uid: int = user_id self.st_gid: int = group_id self._st_size: int = 0 self.is_windows: bool = is_windows self._st_atime_ns: int = int((initial_time or 0) * 1e9) self._st_mtime_ns: int = self._st_atime_ns self._st_ctime_ns: int = self._st_atime_ns def __eq__(self, other: Any) -> bool: return ( isinstance(other, FakeStatResult) and self._st_atime_ns == other._st_atime_ns and self._st_ctime_ns == other._st_ctime_ns and self._st_mtime_ns == other._st_mtime_ns and self.st_size == other.st_size and self.st_gid == other.st_gid and self.st_uid == other.st_uid and self.st_nlink == other.st_nlink and self.st_dev == other.st_dev and self.st_ino == other.st_ino and self.st_mode == other.st_mode ) def __ne__(self, other: Any) -> bool: return not self == other def copy(self) -> "FakeStatResult": """Return a copy where the float usage is hard-coded to mimic the behavior of the real os.stat_result. """ stat_result = copy(self) return stat_result def set_from_stat_result(self, stat_result: os.stat_result) -> None: """Set values from a real os.stat_result. Note: values that are controlled by the fake filesystem are not set. This includes st_ino, st_dev and st_nlink. """ self.st_mode = stat_result.st_mode self.st_uid = stat_result.st_uid self.st_gid = stat_result.st_gid self._st_size = stat_result.st_size self._st_atime_ns = stat_result.st_atime_ns self._st_mtime_ns = stat_result.st_mtime_ns self._st_ctime_ns = stat_result.st_ctime_ns @property def st_ctime(self) -> Union[int, float]: """Return the creation time in seconds.""" return self._st_ctime_ns / 1e9 @st_ctime.setter def st_ctime(self, val: Union[int, float]) -> None: """Set the creation time in seconds.""" self._st_ctime_ns = int(val * 1e9) @property def st_atime(self) -> Union[int, float]: """Return the access time in seconds.""" return self._st_atime_ns / 1e9 @st_atime.setter def st_atime(self, val: Union[int, float]) -> None: """Set the access time in seconds.""" self._st_atime_ns = int(val * 1e9) @property def st_mtime(self) -> Union[int, float]: """Return the modification time in seconds.""" return self._st_mtime_ns / 1e9 @st_mtime.setter def st_mtime(self, val: Union[int, float]) -> None: """Set the modification time in seconds.""" self._st_mtime_ns = int(val * 1e9) @property def st_size(self) -> int: if self.st_mode & S_IFLNK == S_IFLNK and self.is_windows: return 0 return self._st_size @st_size.setter def st_size(self, val: int) -> None: self._st_size = val @property def st_blocks(self) -> int: """Return the number of 512-byte blocks allocated for the file. Assumes a page size of 4096 (matches most systems). Ignores that this may not be available under some systems, and that the result may differ if the file has holes. """ if self.is_windows: raise AttributeError("'os.stat_result' object has no attribute 'st_blocks'") page_size = 4096 blocks_in_page = page_size // 512 pages = self._st_size // page_size if self._st_size % page_size: pages += 1 return pages * blocks_in_page @property def st_file_attributes(self) -> int: if not self.is_windows: raise AttributeError( "module 'os.stat_result' " "has no attribute 'st_file_attributes'" ) mode = 0 st_mode = self.st_mode if st_mode & stat.S_IFDIR: mode |= stat.FILE_ATTRIBUTE_DIRECTORY # type:ignore[attr-defined] if st_mode & stat.S_IFREG: mode |= stat.FILE_ATTRIBUTE_NORMAL # type:ignore[attr-defined] if st_mode & (stat.S_IFCHR | stat.S_IFBLK): mode |= stat.FILE_ATTRIBUTE_DEVICE # type:ignore[attr-defined] if st_mode & stat.S_IFLNK: mode |= stat.FILE_ATTRIBUTE_REPARSE_POINT # type:ignore return mode @property def st_reparse_tag(self) -> int: if not self.is_windows or sys.version_info < (3, 8): raise AttributeError( "module 'os.stat_result' " "has no attribute 'st_reparse_tag'" ) if self.st_mode & stat.S_IFLNK: return stat.IO_REPARSE_TAG_SYMLINK # type: ignore[attr-defined] return 0 def __getitem__(self, item: int) -> Optional[int]: """Implement item access to mimic `os.stat_result` behavior.""" import stat if item == stat.ST_MODE: return self.st_mode if item == stat.ST_INO: return self.st_ino if item == stat.ST_DEV: return self.st_dev if item == stat.ST_NLINK: return self.st_nlink if item == stat.ST_UID: return self.st_uid if item == stat.ST_GID: return self.st_gid if item == stat.ST_SIZE: return self.st_size if item == stat.ST_ATIME: # item access always returns int for backward compatibility return int(self.st_atime) if item == stat.ST_MTIME: return int(self.st_mtime) if item == stat.ST_CTIME: return int(self.st_ctime) raise ValueError("Invalid item") @property def st_atime_ns(self) -> int: """Return the access time in nanoseconds.""" return self._st_atime_ns @st_atime_ns.setter def st_atime_ns(self, val: int) -> None: """Set the access time in nanoseconds.""" self._st_atime_ns = val @property def st_mtime_ns(self) -> int: """Return the modification time in nanoseconds.""" return self._st_mtime_ns @st_mtime_ns.setter def st_mtime_ns(self, val: int) -> None: """Set the modification time of the fake file in nanoseconds.""" self._st_mtime_ns = val @property def st_ctime_ns(self) -> int: """Return the creation time in nanoseconds.""" return self._st_ctime_ns @st_ctime_ns.setter def st_ctime_ns(self, val: int) -> None: """Set the creation time of the fake file in nanoseconds.""" self._st_ctime_ns = val class BinaryBufferIO(io.BytesIO): """Stream class that handles byte contents for files.""" def __init__(self, contents: Optional[bytes]): super().__init__(contents or b"") def putvalue(self, value: bytes) -> None: self.write(value) class TextBufferIO(io.TextIOWrapper): """Stream class that handles Python string contents for files.""" def __init__( self, contents: Optional[bytes] = None, newline: Optional[str] = None, encoding: Optional[str] = None, errors: str = "strict", ): self._bytestream = io.BytesIO(contents or b"") super().__init__(self._bytestream, encoding, errors, newline) def getvalue(self) -> bytes: return self._bytestream.getvalue() def putvalue(self, value: bytes) -> None: self._bytestream.write(value) mox3_stubout.py000064400000013433150043321510007567 0ustar00# Copyright 2008 Google Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """ This is a fork of the pymox library intended to work with Python 3. The file was modified by quermit@gmail.com and dawid.fatyga@gmail.com Previously, pyfakefs used just this file from the mox3 library. However, mox3 will soon be decommissioned, yet standard mock cannot be used because of the problem described in pyfakefs #182 and mock issue 250 (https://github.com/testing-cabal/mock/issues/250). Therefore just this file was forked from mox3 and incorporated into pyfakefs. """ import inspect class StubOutForTesting: """Sample Usage: You want os.path.exists() to always return true during testing. stubs = StubOutForTesting() stubs.Set(os.path, 'exists', lambda x: 1) ... stubs.UnsetAll() The above changes os.path.exists into a lambda that returns 1. Once the ... part of the code finishes, the UnsetAll() looks up the old value of os.path.exists and restores it. """ def __init__(self): self.cache = [] self.stubs = [] def __del__(self): self.smart_unset_all() self.unset_all() def smart_set(self, obj, attr_name, new_attr): """Replace obj.attr_name with new_attr. This method is smart and works at the module, class, and instance level while preserving proper inheritance. It will not stub out C types however unless that has been explicitly allowed by the type. This method supports the case where attr_name is a staticmethod or a classmethod of obj. Notes: - If obj is an instance, then it is its class that will actually be stubbed. Note that the method Set() does not do that: if obj is an instance, it (and not its class) will be stubbed. - The stubbing is using the builtin getattr and setattr. So, the __get__ and __set__ will be called when stubbing (TODO: A better idea would probably be to manipulate obj.__dict__ instead of getattr() and setattr()). Raises AttributeError if the attribute cannot be found. """ if inspect.ismodule(obj) or ( not inspect.isclass(obj) and attr_name in obj.__dict__ ): orig_obj = obj orig_attr = getattr(obj, attr_name) else: if not inspect.isclass(obj): mro = list(inspect.getmro(obj.__class__)) else: mro = list(inspect.getmro(obj)) mro.reverse() orig_attr = None for cls in mro: try: orig_obj = cls orig_attr = getattr(obj, attr_name) except AttributeError: continue if orig_attr is None: raise AttributeError("Attribute not found.") # Calling getattr() on a staticmethod transforms it to a 'normal' # function. We need to ensure that we put it back as a staticmethod. old_attribute = obj.__dict__.get(attr_name) if old_attribute is not None and isinstance(old_attribute, staticmethod): orig_attr = staticmethod(orig_attr) # pytype: disable=not-callable self.stubs.append((orig_obj, attr_name, orig_attr)) setattr(orig_obj, attr_name, new_attr) def smart_unset_all(self): """Reverses all the SmartSet() calls. Restores things to their original definition. Its okay to call SmartUnsetAll() repeatedly, as later calls have no effect if no SmartSet() calls have been made. """ self.stubs.reverse() for args in self.stubs: setattr(*args) self.stubs = [] def set(self, parent, child_name, new_child): """Replace child_name's old definition with new_child. Replace definition in the context of the given parent. The parent could be a module when the child is a function at module scope. Or the parent could be a class when a class' method is being replaced. The named child is set to new_child, while the prior definition is saved away for later, when unset_all() is called. This method supports the case where child_name is a staticmethod or a classmethod of parent. """ old_child = getattr(parent, child_name) old_attribute = parent.__dict__.get(child_name) if old_attribute is not None: if isinstance(old_attribute, staticmethod): old_child = staticmethod(old_child) elif isinstance(old_attribute, classmethod): old_child = classmethod(old_child.__func__) self.cache.append((parent, old_child, child_name)) setattr(parent, child_name, new_child) def unset_all(self): """Reverses all the Set() calls. Restores things to their original definition. Its okay to call unset_all() repeatedly, as later calls have no effect if no Set() calls have been made. """ # Undo calls to set() in reverse order, in case set() was called on the # same arguments repeatedly (want the original call to be last one # undone) self.cache.reverse() for parent, old_child, child_name in self.cache: setattr(parent, child_name, old_child) self.cache = [] patched_packages.py000064400000010465150043321510010364 0ustar00# Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """ Provides patches for some commonly used modules that enable them to work with pyfakefs. """ import sys try: import pandas as pd import pandas.io.parsers as parsers except ImportError: parsers = None try: import xlrd except ImportError: xlrd = None try: from django.core.files import locks except ImportError: locks = None # From pandas v 1.2 onwards the python fs functions are used even when the engine # selected is "c". This means that we don't explicitly have to change the engine. patch_pandas = parsers is not None and [int(v) for v in pd.__version__.split(".")] < [ 1, 2, 0, ] def get_modules_to_patch(): modules_to_patch = {} if xlrd is not None: modules_to_patch["xlrd"] = XLRDModule if locks is not None: modules_to_patch["django.core.files.locks"] = FakeLocks return modules_to_patch def get_classes_to_patch(): classes_to_patch = {} if patch_pandas: classes_to_patch["TextFileReader"] = ["pandas.io.parsers"] return classes_to_patch def get_fake_module_classes(): fake_module_classes = {} if patch_pandas: fake_module_classes["TextFileReader"] = FakeTextFileReader return fake_module_classes if xlrd is not None: class XLRDModule: """Patches the xlrd module, which is used as the default Excel file reader by pandas. Disables using memory mapped files, which are implemented platform-specific on OS level.""" def __init__(self, _): self._xlrd_module = xlrd def open_workbook( self, filename=None, logfile=sys.stdout, verbosity=0, use_mmap=False, file_contents=None, encoding_override=None, formatting_info=False, on_demand=False, ragged_rows=False, ): return self._xlrd_module.open_workbook( filename, logfile, verbosity, False, file_contents, encoding_override, formatting_info, on_demand, ragged_rows, ) def __getattr__(self, name): """Forwards any unfaked calls to the standard xlrd module.""" return getattr(self._xlrd_module, name) if patch_pandas: # we currently need to add fake modules for both the parser module and # the contained text reader - maybe this can be simplified class FakeTextFileReader: fake_parsers = None def __init__(self, filesystem): if self.fake_parsers is None: self.__class__.fake_parsers = ParsersModule(filesystem) def __call__(self, *args, **kwargs): return self.fake_parsers.TextFileReader(*args, **kwargs) def __getattr__(self, name): return getattr(self.fake_parsers.TextFileReader, name) class ParsersModule: def __init__(self, _): self._parsers_module = parsers class TextFileReader(parsers.TextFileReader): def __init__(self, *args, **kwargs): kwargs["engine"] = "python" super().__init__(*args, **kwargs) def __getattr__(self, name): """Forwards any unfaked calls to the standard xlrd module.""" return getattr(self._parsers_module, name) if locks is not None: class FakeLocks: """django.core.files.locks uses low level OS functions, fake it.""" _locks_module = locks def __init__(self, _): pass @staticmethod def lock(f, flags): return True @staticmethod def unlock(f): return True def __getattr__(self, name): return getattr(self._locks_module, name) py.typed000064400000000104150043321510006230 0ustar00# Marker file for PEP 561. The pyfakefs package uses inline types. pytest_plugin.py000064400000003313150043321510010016 0ustar00"""A pytest plugin for using pyfakefs as a fixture When pyfakefs is installed, the "fs" fixture becomes available. :Usage: def my_fakefs_test(fs): fs.create_file('/var/data/xx1.txt') assert os.path.exists('/var/data/xx1.txt') """ import py import pytest from _pytest import capture from pyfakefs.fake_filesystem_unittest import Patcher try: from _pytest import pathlib except ImportError: pathlib = None Patcher.SKIPMODULES.add(py) Patcher.SKIPMODULES.add(pytest) Patcher.SKIPMODULES.add(capture) if pathlib is not None: Patcher.SKIPMODULES.add(pathlib) @pytest.fixture def fs(request): """Fake filesystem.""" if hasattr(request, "param"): # pass optional parameters via @pytest.mark.parametrize patcher = Patcher(*request.param) else: patcher = Patcher() patcher.setUp() yield patcher.fs patcher.tearDown() @pytest.fixture(scope="class") def fs_class(request): """Class-scoped fake filesystem fixture.""" if hasattr(request, "param"): patcher = Patcher(*request.param) else: patcher = Patcher() patcher.setUp() yield patcher.fs patcher.tearDown() @pytest.fixture(scope="module") def fs_module(request): """Module-scoped fake filesystem fixture.""" if hasattr(request, "param"): patcher = Patcher(*request.param) else: patcher = Patcher() patcher.setUp() yield patcher.fs patcher.tearDown() @pytest.fixture(scope="session") def fs_session(request): """Session-scoped fake filesystem fixture.""" if hasattr(request, "param"): patcher = Patcher(*request.param) else: patcher = Patcher() patcher.setUp() yield patcher.fs patcher.tearDown() pytest_tests/__init__.py000064400000000000150043321510011407 0ustar00pytest_tests/__pycache__/__init__.cpython-311.pyc000064400000000334150043321510015761 0ustar00 bgdS)Nro/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/pytest_tests/__init__.pyrsrpytest_tests/__pycache__/conftest.cpython-311.pyc000064400000002256150043321510016054 0ustar00 bg5vddlZddlmZddlmZmZddlmZejdZ ejdZ dS)N)Patcher)fs fs_module)examplec#Kttg}||jV|dS)zFake filesystem.)modules_to_reloadN)rrsetUprtearDown)patchers o/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/pytest_tests/conftest.pyfs_reload_exampler sM 222G MMOOO * c#K|VdS)z-Shows how to use an alias for the fs fixture.N)rs r fake_filesystemr%s HHHHHr) pytest!pyfakefs.fake_filesystem_unittestrpyfakefs.pytest_pluginrrpyfakefs.pytest_testsrfixturer rrrr rs$ 55555510000000))))))     rpytest_tests/__pycache__/example.cpython-311.pyc000064400000000526150043321510015660 0ustar00 bg.ddlmZeddz ZdS))Pathz/testfileN)pathlibr EXAMPLE_FILEn/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/pytest_tests/example.pyr s/tG}}v% rpytest_tests/__pycache__/io.cpython-311.pyc000064400000002303150043321510014627 0ustar00 bgZ$dZGddZdS)z This is a test case for pyfakefs issue #708. It tests the usage of an own module with the same name as a patched filesystem module, the content is taken from the issue. ceZdZdZdZdS) InputStreamc||_dS)N)name)selfrs i/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/pytest_tests/io.py__init__zInputStream.__init__ s  ct|jd5}|cdddS#1swxYwYdS)Nr)openrreadline)rfs rreadzInputStream.read s $)S ! ! Q::<<                  s 7;;N)__name__ __module__ __qualname__rrr rrrs2     r rN)__doc__rrr rrsA          r pytest_tests/__pycache__/pytest_check_failed_plugin_test.cpython-311.pyc000064400000002475150043321510022640 0ustar00 bgdZddlZddlZejejd ddZdS)zTests that a failed pytest properly displays the call stack. Uses the output from running pytest with pytest_plugin_failing_helper.py. Regression test for #381. Ntestresult.txtzOnly run in CI tests)reasonctd5}|}dddn #1swxYwY|sJtd|d|vsJd|vsJd|vsJdS)Nrcontentsz???AttributeErrorzdef test_fs(fs):)openreadprint)frs /builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/pytest_tests/pytest_check_failed_plugin_test.py!test_failed_testresult_stacktracer s   16688 OO8 *h  8 + + + +  ) ) ) ) ) )s 155)__doc__ospytestmarkskipifpathexistsr r rsr '7888AWXX * *YX * * *rpytest_tests/__pycache__/pytest_doctest_test.cpython-311.pyc000064400000004140150043321510020335 0ustar00 bgdZddlmZdZedddZedddZejd d e_ed ddZed ddZed ddZ dS)a This is a test case for pyfakefs issue #45. This problem is resolved by using PyTest version 2.8.6 or above. To run these doctests, install pytest and run: $ pytest --doctest-modules pytest_doctest_test.py Add `-s` option to enable print statements. )unicode_literalscPdd}d|rdnd|||_|S)z3Return a simple function with parametrized doctest.ct|d5}||ddddS#1swxYwYdS)Nw)openwrite)namecontentfs z/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/pytest_tests/pytest_doctest_test.py make_filez$make_file_factory..make_files $__  GGG                     s 488z >>> import os >>> {command} >>> name, content = 'foo', 'bar' >>> {func_name}(name, content) >>> open(name).read() == content {result} >>> os.remove(name) # Cleanup zgetfixture('fs')pass)command func_nameresult)r)format__doc__)rfakerrs r make_file_factoryrsU  F&*6""    passesFT)rr passes_tooz>>> os.remove(name)z>>> passfailscrashesz ) SyntaxErrorN) r __future__rrrrreplacerr crashes_toorr r s  ('''''0  8% = = =  |$t D D D '//0EzRR 'e<<<  ID ? ? ?d5III rpytest_tests/__pycache__/pytest_fixture_param_test.cpython-311.pyc000064400000005225150043321510021543 0ustar00 bgyddlZddlZddlmcmZejjdZejddegggddZ dZ dZ dS) Ncd|tjdtdS)zLTest fails because EXAMPLE_FILE is cached in the module and not patched. stuff herecontentsN create_fileexample EXAMPLE_FILE%check_that_example_file_is_in_fake_fsfss /builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/pytest_tests/pytest_fixture_param_test.pytest_example_file_failingr/NN7',N???)+++++r T)indirectcd|tjdtdS)zRTest passes if using a fixture that reloads the module containing EXAMPLE_FILErrNrr s r4test_example_file_passing_using_parametrized_fixturerrrcttj5}|dksJ dddn #1swxYwYtj5}|dksJ dddn #1swxYwYtjdksJtjsJdS)Nr)openr r read read_textis_file)files rr r &sE g" # #+tyy{{l*****+++++++++++++++   " " $ $+yy{{l*****+++++++++++++++   ) ) + +| ; ; ; ;   ' ' ) ))) )))s#AA A+BBBc|dtjdtjddS)Nz/absolute/path/to/directory) create_diroschdirr s rtest_twice_chdirr/s?MM/000H *+++H *+++++r) rpytestpyfakefs.pytest_tests.example pytest_testsr markxfailr parametrizerr rrrr's /////////,,,y 12TBB,,CB,***,,,,,rpytest_tests/__pycache__/pytest_fixture_test.cpython-311.pyc000064400000005646150043321510020372 0ustar00 bghddlZddlmcmZddlmZejjdZdZ dZ dZ dS)N)Patchercd|tjdtdS)zLTest fails because EXAMPLE_FILE is cached in the module and not patched. stuff herecontentsN create_fileexample EXAMPLE_FILE%check_that_example_file_is_in_fake_fs)fss z/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/pytest_tests/pytest_fixture_test.pytest_example_file_failingrs/NN7',N???)+++++cd|tjdtdS)zRTest passes if using a fixture that reloads the module containing EXAMPLE_FILErrNr)fs_reload_examples r'test_example_file_passing_using_fixturers2!!'"6!NNN)+++++rcttg5}|jtjdt ddddS#1swxYwYdS)z[Test passes if using a Patcher instance that reloads the module containing EXAMPLE_FILE)modules_to_reloadrrN)rr r r r r )patchers r'test_example_file_passing_using_patcherr%s G9 - - -0 w3lKKK-///000000000000000000s5AA Acttj5}|dksJ dddn #1swxYwYtj5}|dksJ dddn #1swxYwYtjdksJtjsJdS)Nr)openr r read read_textis_file)files rr r -sE g" # #+tyy{{l*****+++++++++++++++   " " $ $+yy{{l*****+++++++++++++++   ) ) + +| ; ; ; ;   ' ' ) ))) )))s#AA A+BBB) pytestpyfakefs.pytest_tests.example pytest_testsr !pyfakefs.fake_filesystem_unittestrmarkxfailrrrr rrr%s  /////////555555,,,,,,000*****rpytest_tests/__pycache__/pytest_module_fixture_test.cpython-311.pyc000064400000002215150043321520021725 0ustar00 bg~ddlZddlZejdddZejddZdS)NmoduleT)scopeautousec#xK|tjdd|VdSNfoobar) create_fileospathjoin) fs_modules /builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/pytest_tests/pytest_module_fixture_test.pyuse_fsrs7 "',,ue44555 OOOOOfsctjtjddsJdSr)r r existsr rrtest_fs_uses_fs_modulers4 7>>"',,ue44 5 555 555r)r pytestfixturermark usefixturesrrrrrs| h---.- 66666rpytest_tests/__pycache__/pytest_plugin_failing_helper.cpython-311.pyc000064400000000767150043321520022173 0ustar00 bgdZdZdS)zU Failing test to test stacktrace output - see ``pytest_check_failed_plugin_test.py``.cddksJdS)N)fss /builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/pytest_tests/pytest_plugin_failing_helper.pytest_fsrs 666666N)__doc__rrr rr s(++r pytest_tests/__pycache__/pytest_plugin_test.cpython-311.pyc000064400000013301150043321520020166 0ustar00 bgL pdZddlZddlZddlmZddlmZddlZdZ dZ dZ dZ d Z d Zd Zd Zd ZdS)z?Tests that the pytest plugin properly provides the "fs" fixtureN)OSType)Pausecr|dtjdsJdSN/var/data/xx1.txt create_fileospathexistsfss y/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/pytest_tests/pytest_plugin_test.pytest_fs_fixturer s6NN&''' 7>>- . ... ...cr|dtjdsJdSrr)fake_filesystems rtest_fs_fixture_aliasrs8 3444 7>>- . ... ...rc|d|dtjdsJtjdsJ||ksJdS)Nrz/var/data/xx2.txtr)rrs rtest_both_fixturesrsw 3444NN&''' 7>>- . ... . 7>>- . ... .  rctj}||jsJtj|jsJ|||jsJtj|jrJtj}||jrJtj|jsJ|tj|jrJtj|jsJdSN)tempfileNamedTemporaryFiler namer r pauseresumerfake_temp_filereal_temp_files rtest_pause_resumer!s 022N 99^( ) ))) ) 7>>.- . ... .HHJJJ 99^( ) ))) )w~~n12222 2022Nyy,---- - 7>>.- . ... .IIKKKw~~n12222 2 7>>.- . ... ...rctj}||jsJtj|jsJt |5||jsJtj|jrJtj}||jrJtj|jsJ dddn #1swxYwYtj|jrJtj|jsJdSr)rrr rr r rrs r test_pause_resume_contextmanagerr#+sl022N 99^( ) ))) ) 7>>.- . ... . r33yy,-----7>>."566666!46699^011111w~~n1222222 333333333333333 w~~n12222 2 7>>.- . ... ...s%BD  DDcd}t|d5}|ddddn #1swxYwYtjj|}|dksJdS)Nzfoo.txtwbar)openwritepyfakefs pytest_testsio InputStreamread)rfilepathfstreams rtest_use_own_io_moduler19sH h    " % 1 1( ; ;F ;;==E ! ! ! ! ! !s 599ctj|_tjt jsJdSr)rWINDOWSr r r r gettempdirr s rtest_switch_to_windowsr5Bs4 NBE 7>>(-// 0 000 000rctj|_tjt jsJdSr)rLINUXr r r rr4r s rtest_switch_to_linuxr8G4 LBE 7>>(-// 0 000 000rctj|_tjt jsJdSr)rMACOSr r r rr4r s rtest_switch_to_macosr<Lr9r)__doc__r rpyfakefs.fake_filesystemr!pyfakefs.fake_filesystem_unittestrpyfakefs.pytest_tests.ior)rrrr!r#r1r5r8r<rrrBsEE ++++++333333/// /// !!! / / / / / /"""111 111 11111rpytest_tests/conftest.py000064400000002465150043321520011517 0ustar00# Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Example for a custom pytest fixture with an argument to Patcher. # Use this as a template if you want to write your own pytest plugin # with specific Patcher arguments. # See `pytest_plugin.py` for more information. import pytest from pyfakefs.fake_filesystem_unittest import Patcher # import the fs fixture to be visible if pyfakefs is not installed from pyfakefs.pytest_plugin import fs, fs_module # noqa: F401 from pyfakefs.pytest_tests import example # noqa: E402 @pytest.fixture def fs_reload_example(): """Fake filesystem.""" patcher = Patcher(modules_to_reload=[example]) patcher.setUp() yield patcher.fs patcher.tearDown() @pytest.fixture def fake_filesystem(fs): # noqa: F811 """Shows how to use an alias for the fs fixture.""" yield fs pytest_tests/example.py000064400000001214150043321520011314 0ustar00# Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Used as SUT for pytest_fixture_test.py from pathlib import Path EXAMPLE_FILE = Path("/test") / "file" pytest_tests/io.py000064400000000532150043321520010272 0ustar00""" This is a test case for pyfakefs issue #708. It tests the usage of an own module with the same name as a patched filesystem module, the content is taken from the issue. """ class InputStream: def __init__(self, name): self.name = name def read(self): with open(self.name, "r") as f: return f.readline() pytest_tests/pytest_check_failed_plugin_test.py000064400000001222150043321520016266 0ustar00"""Tests that a failed pytest properly displays the call stack. Uses the output from running pytest with pytest_plugin_failing_helper.py. Regression test for #381. """ import os import pytest @pytest.mark.skipif(not os.path.exists("testresult.txt"), reason="Only run in CI tests") def test_failed_testresult_stacktrace(): with open("testresult.txt") as f: contents = f.read() # before the fix, a triple question mark has been displayed # instead of the stacktrace assert contents print("contents", contents) assert "???" not in contents assert "AttributeError" not in contents assert "def test_fs(fs):" in contents pytest_tests/pytest_doctest_test.py000064400000002624150043321520014003 0ustar00""" This is a test case for pyfakefs issue #45. This problem is resolved by using PyTest version 2.8.6 or above. To run these doctests, install pytest and run: $ pytest --doctest-modules pytest_doctest_test.py Add `-s` option to enable print statements. """ from __future__ import unicode_literals def make_file_factory(func_name, fake, result): """Return a simple function with parametrized doctest.""" def make_file(name, content=""): with open(name, "w") as f: f.write(content) make_file.__doc__ = """ >>> import os >>> {command} >>> name, content = 'foo', 'bar' >>> {func_name}(name, content) >>> open(name).read() == content {result} >>> os.remove(name) # Cleanup """.format( command="getfixture('fs')" if fake else "pass", func_name=func_name, result=result, ) return make_file passes = make_file_factory("passes", fake=False, result=True) passes_too = make_file_factory("passes_too", fake=True, result=True) passes_too.__doc__ = passes_too.__doc__.replace(">>> os.remove(name)", ">>> pass") fails = make_file_factory("fails", fake=False, result=False) # Pytest versions below 2.8.6 raise an internal error when running # these doctests: crashes = make_file_factory("crashes", fake=True, result=False) crashes_too = make_file_factory(") SyntaxError", fake=True, result=False) pytest_tests/pytest_fixture_param_test.py000064400000003571150043321520015206 0ustar00# Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Example for a test using a custom pytest fixture with an argument to Patcher # Needs Python >= 3.6 import os import pytest import pyfakefs.pytest_tests.example as example @pytest.mark.xfail def test_example_file_failing(fs): """Test fails because EXAMPLE_FILE is cached in the module and not patched.""" fs.create_file(example.EXAMPLE_FILE, contents="stuff here") check_that_example_file_is_in_fake_fs() @pytest.mark.parametrize("fs", [[None, [example]]], indirect=True) def test_example_file_passing_using_parametrized_fixture(fs): """Test passes if using a fixture that reloads the module containing EXAMPLE_FILE""" fs.create_file(example.EXAMPLE_FILE, contents="stuff here") check_that_example_file_is_in_fake_fs() def check_that_example_file_is_in_fake_fs(): with open(example.EXAMPLE_FILE) as file: assert file.read() == "stuff here" with example.EXAMPLE_FILE.open() as file: assert file.read() == "stuff here" assert example.EXAMPLE_FILE.read_text() == "stuff here" assert example.EXAMPLE_FILE.is_file() def test_twice_chdir(fs): # regression test for #530 - make sure that # alternative path separators are correctly handled under Windows fs.create_dir("/absolute/path/to/directory") os.chdir("/absolute/path/to/directory") os.chdir("/absolute/path/to/directory") pytest_tests/pytest_fixture_test.py000064400000003645150043321520014030 0ustar00# Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Example for a test using a custom pytest fixture with an argument to Patcher # Needs Python >= 3.6 import pytest import pyfakefs.pytest_tests.example as example from pyfakefs.fake_filesystem_unittest import Patcher @pytest.mark.xfail def test_example_file_failing(fs): """Test fails because EXAMPLE_FILE is cached in the module and not patched.""" fs.create_file(example.EXAMPLE_FILE, contents="stuff here") check_that_example_file_is_in_fake_fs() def test_example_file_passing_using_fixture(fs_reload_example): """Test passes if using a fixture that reloads the module containing EXAMPLE_FILE""" fs_reload_example.create_file(example.EXAMPLE_FILE, contents="stuff here") check_that_example_file_is_in_fake_fs() def test_example_file_passing_using_patcher(): """Test passes if using a Patcher instance that reloads the module containing EXAMPLE_FILE""" with Patcher(modules_to_reload=[example]) as patcher: patcher.fs.create_file(example.EXAMPLE_FILE, contents="stuff here") check_that_example_file_is_in_fake_fs() def check_that_example_file_is_in_fake_fs(): with open(example.EXAMPLE_FILE) as file: assert file.read() == "stuff here" with example.EXAMPLE_FILE.open() as file: assert file.read() == "stuff here" assert example.EXAMPLE_FILE.read_text() == "stuff here" assert example.EXAMPLE_FILE.is_file() pytest_tests/pytest_module_fixture_test.py000064400000001576150043321520015376 0ustar00# Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import os import pytest @pytest.fixture(scope="module", autouse=True) def use_fs(fs_module): fs_module.create_file(os.path.join("foo", "bar")) yield fs_module @pytest.mark.usefixtures("fs") def test_fs_uses_fs_module(): # check that `fs` uses the same filesystem as `fs_module` assert os.path.exists(os.path.join("foo", "bar")) pytest_tests/pytest_plugin_failing_helper.py000064400000000201150043321520015612 0ustar00""" Failing test to test stacktrace output - see ``pytest_check_failed_plugin_test.py``.""" def test_fs(fs): assert 1 == 2 pytest_tests/pytest_plugin_test.py000064400000004514150043321520013634 0ustar00"""Tests that the pytest plugin properly provides the "fs" fixture""" import os import tempfile from pyfakefs.fake_filesystem import OSType from pyfakefs.fake_filesystem_unittest import Pause import pyfakefs.pytest_tests.io def test_fs_fixture(fs): fs.create_file("/var/data/xx1.txt") assert os.path.exists("/var/data/xx1.txt") def test_fs_fixture_alias(fake_filesystem): fake_filesystem.create_file("/var/data/xx1.txt") assert os.path.exists("/var/data/xx1.txt") def test_both_fixtures(fs, fake_filesystem): fake_filesystem.create_file("/var/data/xx1.txt") fs.create_file("/var/data/xx2.txt") assert os.path.exists("/var/data/xx1.txt") assert os.path.exists("/var/data/xx2.txt") assert fs == fake_filesystem def test_pause_resume(fs): fake_temp_file = tempfile.NamedTemporaryFile() assert fs.exists(fake_temp_file.name) assert os.path.exists(fake_temp_file.name) fs.pause() assert fs.exists(fake_temp_file.name) assert not os.path.exists(fake_temp_file.name) real_temp_file = tempfile.NamedTemporaryFile() assert not fs.exists(real_temp_file.name) assert os.path.exists(real_temp_file.name) fs.resume() assert not os.path.exists(real_temp_file.name) assert os.path.exists(fake_temp_file.name) def test_pause_resume_contextmanager(fs): fake_temp_file = tempfile.NamedTemporaryFile() assert fs.exists(fake_temp_file.name) assert os.path.exists(fake_temp_file.name) with Pause(fs): assert fs.exists(fake_temp_file.name) assert not os.path.exists(fake_temp_file.name) real_temp_file = tempfile.NamedTemporaryFile() assert not fs.exists(real_temp_file.name) assert os.path.exists(real_temp_file.name) assert not os.path.exists(real_temp_file.name) assert os.path.exists(fake_temp_file.name) def test_use_own_io_module(fs): filepath = "foo.txt" with open(filepath, "w") as f: f.write("bar") stream = pyfakefs.pytest_tests.io.InputStream(filepath) assert stream.read() == "bar" def test_switch_to_windows(fs): fs.os = OSType.WINDOWS assert os.path.exists(tempfile.gettempdir()) def test_switch_to_linux(fs): fs.os = OSType.LINUX assert os.path.exists(tempfile.gettempdir()) def test_switch_to_macos(fs): fs.os = OSType.MACOS assert os.path.exists(tempfile.gettempdir()) tests/__init__.py000064400000000000150043321520010000 0ustar00tests/__pycache__/__init__.cpython-311.pyc000064400000000325150043321520014352 0ustar00 bgdS)Nrh/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/tests/__init__.pyrsrtests/__pycache__/all_tests.cpython-311.pyc000064400000006045150043321520014612 0ustar00 bg ddZddlZddlZddlmZmZmZmZmZm Z m Z m Z m Z m Z mZmZmZmZGddejZedkrlejdeZejee dSdS) zA test suite that runs all tests for pyfakefs at once. Includes tests with external pathlib2 and scandir packages if installed.N)dynamic_patch_testfake_stat_time_test example_testfake_filesystem_glob_testfake_filesystem_shutil_testfake_filesystem_testfake_filesystem_unittest_testfake_filesystem_vs_real_testfake_open_test fake_os_testfake_pathlib_testfake_tempfile_testpatched_packages_testmox3_stubout_testceZdZdZdZdS)AllTestsz6A test suite that runs all tests for pyfakefs at once.ctj}||t|t |t |t|t|t|t|t|t|t|t|t|t |t"g|S)N)unittestdefaultTestLoaderaddTestsloadTestsFromModulerrrr rr rr r rrrr r)selfloaders i/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/tests/all_tests.pysuitezAllTests.suite*s%+ **+?@@**+DEE**+FGG**<88**+>??**>::**+=>>**+GHH**+HII**<88**+<==**+=>>**+<==**+@AA    $ N)__name__ __module__ __qualname____doc__rrrrr's)@@rr__main__) verbosity)r sysrpyfakefs.testsrrrrrrr r r r r rrr TestSuiterrTextTestRunnerrunrresultexitint wasSuccessfulr!rrr.smLL $x!4 z $X $q 1 1 1 5 5hhjj6F6F6H6H I IF CHSSV))+++ , ,-----rtests/__pycache__/all_tests_without_extra_packages.cpython-311.pyc000064400000002362150043321520021434 0ustar00 bgxdZddlZddlZddlmZejr*de_ ddlmZn #e$rdZYnwxYwee_ee_ ddl m Z e dkrlej d e Zejee dSdS) zeA test suite that runs all tests for pyfakefs at once. Excludes tests using external scandir package.N)extra_packagesF)scandir)AllTests__main__) verbosity)__doc__sysunittestpyfakefsruse_scandir_packageosr ImportError use_scandirpyfakefs.tests.all_testsr__name__TextTestRunnerrunsuiteresultexitint wasSuccessful/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/tests/all_tests_without_extra_packages.pyrs!22 ######%)).N& $N!(N------ z $X $q 1 1 1 5 5hhjj6F6F6H6H I IF CHSSV))+++ , ,-----s '11tests/__pycache__/dynamic_patch_test.cpython-311.pyc000064400000010750150043321520016460 0ustar00 bg-dZddlZddlZddlmZGddejZGddeZedkrej dSdS) z< Tests for patching modules loaded after `setUpPyfakefs()`. N)fake_filesystem_unittestceZdZdZdS)TestPyfakefsUnittestBasec.|dS)zSet up the fake file systemN) setUpPyfakefs)selfs r/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/tests/dynamic_patch_test.pysetUpzTestPyfakefsUnittestBase.setUps N)__name__ __module__ __qualname__r r r rrs#r rc>eZdZdfd ZdZdZdZdZdZxZ S) DynamicImportPatchTestrunTestcXtt||dS)N)superr__init__)r methodName __class__s r rzDynamicImportPatchTest.__init__s( $d++44Z@@@@@r cddl}|d||jd||jddSNrtestosmkdir assertTruefsexistspathrrs r test_os_patchz$DynamicImportPatchTest.test_os_patch sc   v../// v../////r cddl}|d||jd||jddSrr)r_oss r test_os_import_as_patchz.DynamicImportPatchTest.test_os_import_as_patch'sf & v../// //00000r cddl}|d||jd||jddSr)os.pathrrrr r!r"s r test_os_path_patchz)DynamicImportPatchTest.test_os_path_patch.sc  v../// v../////r cddl}|jd|d|djdS)Nrd/)shutilrset_disk_usage assertEqual disk_usagetotal)rr-s r test_shutil_patchz(DynamicImportPatchTest.test_shutil_patch5sN  s### f//44:;;;;;r czd}tj|}|d5}|ddddn #1swxYwY||j||j|}|d|j dS)Nztest.txtwr) pathlibPathopenwriterrr get_objectr/contents)r file_pathr!f file_objects r test_pathlib_path_patchz.DynamicImportPatchTest.test_pathlib_path_patch;s |I&& YYs^^ q GGFOOO                y11222g((33  !566666sAAA)r) r r rrr#r&r)r2r> __classcell__)rs@r rrsAAAAAA000111000<<< 7777777r r__main__) __doc__r5unittestpyfakefsrTestCaserrr mainrr r rFs------7@ '7'7'7'7'75'7'7'7T zHMOOOOOr tests/__pycache__/example.cpython-311.pyc000064400000011746150043321520014257 0ustar00 bgzdZddlZddlZddlZ ddlZdZn#e$rdZdZYnwxYwdZdZdZ dZ d Z d Z d Z dS) aL Example module that is tested in :py:class`pyfakefs.example_test.TestExample`. This demonstrates the usage of the :py:class`pyfakefs.fake_filesystem_unittest.TestCase` base class. The modules related to file handling are bound to the respective fake modules: >>> os #doctest: +ELLIPSIS >>> os.path #doctest: +ELLIPSIS >>> shutil #doctest: +ELLIPSIS `open()` is an alias for `io.open()` and is bound to `FakeIoModule.open`. NTFct|d5}|d||dddddS#1swxYwYdS)aCreate the specified file and add some content to it. Use the `open()` built in function. For example, the following file operations occur in the fake file system. In the real file system, we would not even have permission to write `/test`: >>> os.path.isdir('/test') False >>> os.mkdir('/test') >>> os.path.isdir('/test') True >>> os.path.exists('/test/file.txt') False >>> create_file('/test/file.txt') >>> os.path.exists('/test/file.txt') True >>> with open('/test/file.txt') as f: ... f.readlines() ["This is test file '/test/file.txt'.\n", 'It was created using open().\n'] wzThis is test file '{0}'. zIt was created using open(). N)openwriteformatpathfs g/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/tests/example.py create_filer .s. dC2A ,33D99::: 0111222222222222222222s>AA #A c.tj|dS)a0Delete the specified file. For example: >>> os.mkdir('/test') >>> os.path.exists('/test/file.txt') False >>> create_file('/test/file.txt') >>> os.path.exists('/test/file.txt') True >>> delete_file('/test/file.txt') >>> os.path.exists('/test/file.txt') False N)osremover s r delete_filerJsIdOOOOOc@tj|S)a5Return True if the specified file exists. For example: >>> path_exists('/test') False >>> os.mkdir('/test') >>> path_exists('/test') True >>> >>> path_exists('/test/file.txt') False >>> create_file('/test/file.txt') >>> path_exists('/test/file.txt') True )rr existsrs r path_existsr\s" 7>>$  rc*tj|S)aReturn the list of paths matching the specified glob expression. For example: >>> os.mkdir('/test') >>> create_file('/test/file1.txt') >>> create_file('/test/file2.txt') >>> file_names = sorted(get_glob('/test/file*.txt')) >>> >>> import sys >>> if sys.platform.startswith('win'): ... # Windows style path ... file_names == [r'/test\file1.txt', r'/test\file2.txt'] ... else: ... # UNIX style path ... file_names == ['/test/file1.txt', '/test/file2.txt'] True )glob) glob_paths r get_globrps& 9Y  rc.tj|dS)z$Delete the specified file hierarchy.N)shutilrmtreers r rm_treers M$rctr!ttj|Sttj|S)z6Return a list of directory entries for the given path.) has_scandirlistscandirrrs r scan_dirr"s:+GOD))***  4  ! !!rc~t|d5}|cdddS#1swxYwYdS)z4Return the contents of the given path as byte array.rbN)rreadrs r file_contentsr&s~ dD  Qvvxxs 266)__doc__rrrr!r ImportErrorr rrrrr"r&rr r*s " NNNKKGKKK 2228$   (   , """s  ##tests/__pycache__/example_test.cpython-311.pyc000064400000027252150043321520015315 0ustar00 bg*dZddlZddlZddlZddlZddlmZddlmZddl m Z dZ Gddej Z ed krejdSdS) aV Test the :py:class`pyfakefs.example` module to demonstrate the usage of the :py:class`pyfakefs.fake_filesystem_unittest.TestCase` base class. Fake filesystem functions like `create_file()`, `create_dir()` or `create_symlink()` are often used to set up file structures at the beginning of a test. While you could also use the familiar `open()`, `os.mkdirs()` and similar functions, these functions can make the test code shorter and more readable. `create_file()` is particularly convenient because it creates all parent directories and allows you to specify the contents or the size of the file. N)fake_filesystem_unittest)use_scandir_package)examplec:tj|||tS)z9Load the pyfakefs/example.py doctest tests into unittest.)r load_doctestsr)loadertestsignores l/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/tests/example_test.py load_testsr 's # 1&% Q QQc~eZdZdZdZdZdZdZdZdZ dZ d Z e j e d d Zd Zd S) TestExamplezTest the example module. The os and shutil modules have been replaced with the fake modules, so that all of the calls to os and shutil in the tested example code occur in the fake filesystem. ctjt|_t j|jd5}||_dddn #1swxYwY| dS)aInvoke the :py:class:`pyfakefs.fake_filesystem_unittest.TestCase` `self.setUp()` method. This defines: * Attribute `self.fs`, an instance of :py:class:`pyfakefs.fake_filesystem.FakeFilesystem`. This is useful for creating test files. * Attribute `self.stubs`, an instance of :py:class:`pyfakefs.mox3_stubout.StubOutForTesting`. Use this if you need to define additional stubs. rbN) ospathrealpath__file__filepathioopenread real_contents setUpPyfakefs)selffs r setUpzTestExample.setUp3s((22 WT]D ) ) *Q!"D  * * * * * * * * * * * * * * * sA**A.1A.cdSNrs r tearDownzTestExample.tearDownFs r c|tjdtjd|tjd|tjdtjd|tjddS)zSTest example.create_file() which uses `open()` and `file.write()`. /testz/test/file.txtN) assertFalserrisdirmkdir assertTrueexistsr create_filer"s r test_create_filezTestExample.test_create_fileJs w//000   g../// (899:::,--- '78899999r c.|jdd|tjdt jd|tjddS)z4Test example.delete_file() which uses `os.remove()`.z/test/full.txtzFirst line Second Line )contentsN) fsr+r)rrr*r delete_filer&r"s r test_delete_filezTestExample.test_delete_fileVs{ ,7UVVV '788999,--- (899:::::r c|tjd|jd|tjddS)z9Test example.path_exists() which uses `os.path.exists()`.z/test/empty.txtN)r&r path_existsr/r+r)r"s r test_file_existszTestExample.test_file_exists]s] ,->??@@@ -... +,=>>?????r c|tjd|jd|tjdtjd|tjd|tj dgtj d}ttj d}|r||ddgd S||ddgd S) zTest example.get_glob().r%/test/dir1/dir2a/test/dir1/dir2bz/test/dir1/nonexistent*winz/test/dir1/dir*z/test/dir1\dir2az/test/dir1\dir2bN)r&rrr'r/ create_dirr)makedirs assertEqualrget_globsysplatform startswithsorted)r is_windowsmatching_pathss r test_get_globszTestExample.test_get_globscs- w//000 -...  &899::: &'''  &899::: )*CDDbIII\,,U33  01B C CDD  W   ^.ACV-W X X X X X   ^.@BT-U V V V V Vr c|jdtjd|tjd|tjdtjd| tj ddS)z/Test example.rm_tree() using `shutil.rmtree()`.r6r7z /test/dir1N) r/r9rr:r)rr'rrm_treer&r*r"s r test_rm_treezTestExample.test_rm_treets -... &'''  &899:::  &899::: %%%  5566666r c|jd|jd|jd|jddt t jdd}|dt||d |d j | |d  | |d  | |d  d S)zTest example.scandir() which uses `os.scandir()`. The os module has been replaced with the fake os module so the fake filesystem path entries are returned instead of `os.DirEntry` objects. /test/text.txt /test/dirz/linktest/linkedz/test/linked_filer%c|jSr namees r z-TestExample.test_os_scandir..!&r key linked_filerN)r/r+r9create_symlinkr@rscan_dirr;lenrLr)is_dir is_symlinkis_filerentriess r test_os_scandirzTestExample.test_os_scandirs' ,--- ;''' ./// 24FGGG)'228H8HIII CLL)))  888  ))++,,,  --//000  **,,-----r z+Testing only if scandir module is installedc|jd|jdtt jdd}|dt||d|dj| |d  | |d d S) zTest example.scandir() which uses `scandir.scandir()`. The scandir module has been replaced with the fake_scandir module so the fake filesystem path entries are returned instead of `scandir.DirEntry` objects. rHrIr%c|jSr rKrMs r rOz2TestExample.test_scandir_scandir..rPr rQrVztext.txtrUrN) r/r+r9r@rrXr;rYrLr)rZr\r]s r test_scandir_scandirz TestExample.test_scandir_scandirs ,--- ;''')'228H8HIII CLL))) WQZ_555  ))++,,,  **,,-----r c>|t5tj|jdddn #1swxYwY|j|j|tj|j|jdS)z_Test `example.file_contents()` for a real file after adding it using `add_real_file()`.N) assertRaisesOSErrorr file_contentsrr/ add_real_filer;rr"s r test_real_file_accessz!TestExample.test_real_file_accesss  w ' ' 1 1  !$- 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 dm,,, .t}==t?QRRRRRsAAAN)__name__ __module__ __qualname____doc__rr#r,r1r4rCrFr_unittestskipIfrrbrhr!r r rr,s &    : : :;;;@@@ WWW" 7 7 7...&X_ !N... SSSSSr r__main__)rlrrr=rmpyfakefsrpyfakefs.extra_packagesrpyfakefs.testsrr TestCaserrimainr!r r rus   ------777777""""""RRR SSSSS*3SSSD zHMOOOOOr tests/__pycache__/import_as_example.cpython-311.pyc000064400000012367150043321520016334 0ustar00 bgo ,dZddlZddlZddlZddlmZddlmZ ddlm Z ddlm Z ddlm Z ddl mZmZmZmZddl mZddlmZd Zd Zd Zej jfd Zd ZdZdZdZdZdZdZdZdZ dZ!dZ"dZ#dZ$dZ%GddZ&dS)zs Example module that is used for testing modules that import file system modules to be patched under another name. N)open)pathstat)existsisfileisdirislinkr)Pathc@tj|SN)my_osrrfilepaths q/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/tests/import_as_example.pycheck_if_exists1rs :  X & &&c*tj|Sr)rrrs rcheck_if_exists2r#s ;x  rcDt|Sr)r rrs rcheck_if_exists3r(s >> " ""rc||Sr)r file_existss rcheck_if_exists4r-s ;x  rc t|Srr rs rcheck_if_exists5r1 (  rc t|Sr) my_existsrs rcheck_if_exists6r"6s X  rcNtj|Sr)pathlibr rrs rcheck_if_exists7r%;s < ! ! ( ( * **rc t|Sr)rrs rcheck_if_isfiler'@rrc t|Sr)r rs rcheck_if_isdirr)Es ??rc t|Sr)r rs rcheck_if_islinkr+Jrrc t|Srrrs r file_stat1r-Os >>rc t|Sr)my_statrs r file_stat2r0Ts 8  rcRtjdkrddlm}nddlm}||S)Nwin32rr)sysplatformntrposix)r system_stats rr7r7YsF |w*******------ ;x  rc|t|5}|cdddS#1swxYwYdSr) bltn_openreadrfs rfile_contents1r=as| 8  vvxx 155c|t|5}|cdddS#1swxYwYdSr)io_openr:r;s rfile_contents2rAfs|   avvxxr>c*ttS)zReturns True in real fs only)r__file__rrrexists_this_filerDks (  rcbtt5 ddddS#1swxYwYdS)Works only in real fsN)rrCrrropen_this_filerGpsu h                     s $((c*ttS)rF)r rCrrrreturn_this_file_pathrIvs >>rc,eZdZejjfdZdS)TestDefaultArgc||Srr)selfrrs rcheck_if_existszTestDefaultArg.check_if_exists|s{8$$$rN)__name__ __module__ __qualname__rrrrNrrrrKrK{s049J4E%%%%%%rrK)'__doc__osrr$r3builtinsrr9ior@rrr/os.pathrrr r r!r rrrrrr"r%r'r)r+r-r0r7r=rArDrGrIrKrrrrWs  &&&&&&111111111111''''''''' !!! ### ,1:+<!!!!  +++      !!!       %%%%%%%%%%rtests/__pycache__/performance_test.cpython-311.pyc000064400000011003150043321520016146 0ustar00 bg< dZddlZddlZddlZddlmZddlmZej drGddeZ Gdd eZ ej ed Gd d eZ d ZedD]8ZdeezZee eedeezZee ee9edkrejdSdSdS)z>Shall provide tests to check performance overhead of pyfakefs.N)TestCase)IS_PYPYTEST_PERFORMANCEcFeZdZeddZeddZddZdS)SetupPerformanceTestreturnNc6tj|_dSNtime start_timeclss p/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/tests/performance_test.py setUpClasszSetupPerformanceTest.setUpClass!Y[[CNNNctj|jz |_td|jdzdS)Nz1Elapsed time per test for cached setup: {:.3f} ms r r elapsed_timeprintformatrs r tearDownClassz"SetupPerformanceTest.tearDownClasssQ#y{{S^;C  CJJ$r)     rc.|dSr  setUpPyfakefsselfs rsetUpzSetupPerformanceTest.setUp$s    rrN__name__ __module__ __qualname__ classmethodrrr rrrrsf  ) ) )  )       ! ! ! ! ! !rrcFeZdZeddZeddZddZdS)SetupNoCachePerformanceTestrNc6tj|_dSr r rs rrz&SetupNoCachePerformanceTest.setUpClass(rrctj|jz |_td|jdzdS)Nz3Elapsed time per test for uncached setup: {:.3f} msrrrs rrz)SetupNoCachePerformanceTest.tearDownClass,sQ#y{{S^;C  ELL$r)     rc2|ddS)NF) use_cacherrs rr z!SetupNoCachePerformanceTest.setUp5s     / / / / /rr!r"r'rrr)r)'sf  ) ) )  )       0 0 0 0 0 0rr)zPyPy times are not comparableceZdZdZdZdZdS)TimePerformanceTestzMake sure performance degradation in setup is noticed. The numbers are related to the CI builds and may fail in local builds. cF|tjddS)Ng?) assertLessrrrs rtest_cached_timez$TimePerformanceTest.test_cached_time>s OO0=s C C C C CrcF|tjddS)N)r1r)rrs rtest_uncached_timez&TimePerformanceTest.test_uncached_timeAs OO7Da H H H H HrN)r#r$r%__doc__r2r5r'rrr/r/8sD   D D D I I I I Irr/cdSr r'rs r test_setupr8Ds rdtest_ test_nocache__main__)r6osr unittest!pyfakefs.fake_filesystem_unittestrpyfakefs.helpersrenvirongetrr)skipIfr/r8rangenstr test_namesetattrr#mainr'rrrJsED 666666$$$$$$:>>$%%:!!!!!x!!!"00000h000"X_W=>> I I I I Ih I I?> I   U3ZZDDcc!ff$ $i<<<"SSVV+ +Y CCCC: u::rrtests/__pycache__/fake_filesystem_glob_test.cpython-311.pyc000064400000011661150043321520020034 0ustar00 bg dZddlZddlZddlZddlmZGddejZedkrej dSdS)z$Test for glob using fake_filesystem.N)fake_filesystem_unittestcJeZdZdZdZdZdZdZdZdZ dZ d Z d Z d S) FakeGlobUnitTestcH|d}|j||jd|z|jd|z|jd|z|jddS)Nz./xyzzyz %s/subdirz %s/subdir2z %s/subfile[Temp]) setUpPyfakefsfs create_dir create_file)self directorys y/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/tests/fake_filesystem_glob_test.pysetUpzFakeGlobUnitTest.setUps   9%%% ;2333 <)3444 L94555 H%%%%%cV|tjdgdS)N assertEqualglobr s rtest_glob_emptyz FakeGlobUnitTest.test_glob_empty"s& 2+++++rc.d}|tj|dtj|dtj|dgt t jddS)N/xyzzysubdirsubdir2subfilez/xyzzy/*rospathjoinsortedrr basedirs rtest_glob_starzFakeGlobUnitTest.test_glob_star%~  Wh// Wi00 Wi00  49Z(( ) )      rc|dgtjd|dgtjddS)Nrz/xyzzy/subfilerrs rtest_glob_exactz FakeGlobUnitTest.test_glob_exact0sO (TYx%8%8999 *+TY7G-H-HIIIIIrc.d}|tj|dtj|dtj|dgt t jddS)Nrrrrz/x?zz?/*rr"s rtest_glob_questionz#FakeGlobUnitTest.test_glob_question4r%rc|dgtjd|dgtjddS)Nrz /xyzzy/subdirrrs rtest_glob_no_magicz#FakeGlobUnitTest.test_glob_no_magic?sM (TYx%8%8999 /*DIo,F,FGGGGGrcV|gtjddS)N nonexistentrrs rtest_non_existent_pathz'FakeGlobUnitTest.test_non_existent_pathCs( TY}5566666rcX|dgtjddS)Nz/[Temp]z/*emp*rrs rtest_magic_dirzFakeGlobUnitTest.test_magic_dirFs* )di&9&9:::::rcZ|dgtjdddS)Nr/z*Tem*)rrglob1rs r test_glob1zFakeGlobUnitTest.test_glob1Is, (TZW%=%=>>>>>rc|tjd|tjddS)N[a) assertTruer has_magic assertFalsers rtest_has_magiczFakeGlobUnitTest.test_has_magicLsB s++,,, ,,-----rN) __name__ __module__ __qualname__rrr$r'r)r+r.r0r4r;rrrrs&&&,,,    JJJ    HHH777;;;???.....rr__main__) __doc__rrunittestpyfakefsrTestCaserr<mainr?rrrFs+* ------6.6.6.6.6./86.6.6.r zHMOOOOOrtests/__pycache__/fake_filesystem_shutil_test.cpython-311.pyc000064400000136030150043321520020417 0ustar00 bgVJdZddlZddlZddlZddlZddlZddlmZddlm Z ddl m Z m Z m Z mZddlmZejdkZGdd e jeZGd d eZGd d eZGddeZGddeZedkrejdSdS)zTests for `fake_filesystem_shutil` if used in `fake_filesystem_unittest.TestCase`. Note that almost all of the functionality is delegated to the real `shutil` and works correctly with the fake filesystem because of the faked `os` module. N)Path)fake_filesystem_unittest)get_uidset_uidis_rootIS_PYPY)RealFsTestMixinwin32c8eZdZddZdZdZedZdS)RealFsTestCaserunTestcntj||tj|dSN)rTestCase__init__r )self methodNames {/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/tests/fake_filesystem_shutil_test.pyrzRealFsTestCase.__init__#s2 )224DDD &&&&&ctj|tj|_t |_td|sn| |j |_ t|_t|_ | |j d|jdSdS)N)r setUposgetcwdcwdruidr use_real_fs setUpPyfakefsfs filesystemopencreate_basepathset_disk_usage base_pathrs rrzRealFsTestCase.setUp'sd###9;;99 !! 9    "gDODGDI  " " " G " "4 8 8 8 8 8  9 9rcVt|jtj|dSr)rrr tearDownr%s rr'zRealFsTestCase.tearDown4s) &&&&&rcb|rtjdkS|jjS)Nr )rsysplatformr is_windows_fsr%s rr+zRealFsTestCase.is_windows_fs8s.      +<7* *,,rN)r )__name__ __module__ __qualname__rrr'propertyr+rrr r "sa'''' 9 9 9'''--X---rr ceZdZejeddZdZdZeje ddZ ejeddZ ejeddZ eje dd Z d Z d Zd Zd ZdZejeddZdZdZdZdZdZdZdZdZdZdZdZdS)FakeShutilModuleTestPosix specific behaviorc|d}|||jj|d}|jj|d}|||j|d|||jj|d}|jj|d}|||t5tj ||ddddS#1swxYwYdS)Nrootpathdir1dir2mzf1.txt) make_path create_dirrpathjoinchmod create_file assertRaisesPermissionErrorshutilmove)r root_path dir1_path dir2_path old_file_path new_file_paths rtest_catch_permission_errorz0FakeShutilModuleTest.test_catch_permission_error@saNN:..   """GL%%i88 GL%%i88   """  i'''  """ )))X>>  )))X>>  '''    / / 6 6 K } 5 5 5 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6sEE Ec|d}tj|d}||tj|d}|||tj|tj || tj|| tj|| tj|dS)Nxyzzysubdirsubfile) r9rr;r<r:r> assertTrueexistsrArmtree assertFalser directorydir_path file_paths r test_rmtreez FakeShutilModuleTest.test_rmtreePsNN7++ 7<< 844 !!!GLLI66  ### y11222 i     22333 11222  2233333rc^|d}tj|d}||tj|d}||t j|dz|tj ||tj ||tj |dS)NrJrKrL/) r9rr;r<r:r>rArOrPrNrQs rtest_rmtree_with_trailing_slashz4FakeShutilModuleTest.test_rmtree_with_trailing_slash\sNN7++ 7<< 844 !!!GLLI66  ### i#o&&&  22333 11222  2233333rzWindows specific behaviorc||d}|tj|dtj|d}|||j|d|t5tj |dddn #1swxYwY| tj ||j|ddS)Nfoobarbazi$) check_windows_onlyr9r>rr;r<r=r?OSErrorrArOrMrNrrSrTs r4test_rmtree_without_permission_for_a_file_in_windowszIFakeShutilModuleTest.test_rmtree_without_permission_for_a_file_in_windowsgs= !!!>>%(( h66777GLL511  ###  i'''   w ' ' $ $ M( # # # $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ y11222  i'''''sC((C,/C,c0||d}|tj|dtj|d}|||j|dts|t5tj |dddn #1swxYwY| tj ||j|ddStj ||tj |dS)NrZr[r\r8i)check_posix_onlyr9r>rr;r<r=rr?r_rArOrMrNrPr`s r1test_rmtree_without_permission_for_a_dir_in_posixzFFakeShutilModuleTest.test_rmtree_without_permission_for_a_dir_in_posixts >>%(( h66777GLL511  ###  h&&&yy 8""7++ ( ( h''' ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( OOBGNN955 6 6 6 GMM(E * * * * * M( # # #   RW^^I66 7 7 7 7 7sC66C:=C:c||d}|tj|dtj|d}||t |5tj|dddn #1swxYwY| tj |dSNrZr[r\) rcr9r>rr;r<r!rArOrPrNr`s r test_rmtree_with_open_file_posixz5FakeShutilModuleTest.test_rmtree_with_open_file_posixs  >>%(( h66777GLL511  ### )__ $ $ M( # # # $ $ $ $ $ $ $ $ $ $ $ $ $ $ $  2233333s!CC Ccf||d}|tj|dtj|d}||t |5|t5tj |dddn #1swxYwYdddn #1swxYwY| tj |dSrf) r^r9r>rr;r<r!r?r_rArOrMrNr`s r.test_rmtree_with_open_file_fails_under_windowszCFakeShutilModuleTest.test_rmtree_with_open_file_fails_under_windowsst !!!>>%(( h66777GLL511  ### )__ ( (""7++ ( ( h''' ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( x0011111s6!C4<C C4C! !C4$C! %C44C8;C8cd}|t5tj|dddn #1swxYwY tj|ddS#t$r|dYdSwxYw)N nonexistingT) ignore_errorsz(rmtree raised despite ignore_errors True)r?r_rArOfail)rrRs rtest_rmtree_non_existing_dirz1FakeShutilModuleTest.test_rmtree_non_existing_dirs!   w ' ' % % M) $ $ $ % % % % % % % % % % % % % % % B M)4 8 8 8 8 8 8 B B B II@ A A A A A A Bs!>AA A""BBcXGddfd}|d}d_d_ tj||n%#t $r|dYnwxYw|j|j|d_d_ tj|d | n%#t $r|d YnwxYw| j|jddS) NceZdZdS)PFakeShutilModuleTest.test_rmtree_non_existing_dir_with_handler..NonLocalN)r,r-r.r0rrNonLocalrqs Drrrc$d_|_dSNT) errorHandled errorPath)_r; _error_inforrs r error_handlerzUFakeShutilModuleTest.test_rmtree_non_existing_dir_with_handler..error_handlers$(H !!%H   rrkF)onerrorz/rmtree raised exception despite onerror definedT)rlr{z2rmtree raised exception despite ignore_errors True) r9rurvrArOr_rmrM assertEqualrP)rryrRrrs @r)test_rmtree_non_existing_dir_with_handlerz>FakeShutilModuleTest.test_rmtree_non_existing_dir_with_handlers         & & & & &NN=11 % I M)] ; ; ; ; ; I I I IIG H H H H H I -... +Y777 % L M)4 O O O O O L L L IIJ K K K K K L ./// +R00000s#AA10A18CC21C2c|d}|d}||tj|d|tj||tj|tj |||tj|| tj |j tj |j dS)NrJ xyzzy_copy) r9r>rr=rMr;rNrPrAcopyr|statst_modersrc_filedst_files r test_copyzFakeShutilModuleTest.test_copys>>'**>>,// """ 5!!! x00111 11222 Hh''' x00111 **2BGH4E4E4MNNNNNrcZ|d}|d}tj|d}||||tj|d|tj||tj|| tj|tj |||tj|| tj |jtj |jdS)NrJparentr)r9rr;r<r>r:r=rMrNrPrArr|rr)rrparent_directoryrs rtest_copy_directoryz(FakeShutilModuleTest.test_copy_directorys@>>'**>>(337<< 0':: """ ())) 5!!! x00111 '788999 11222 H./// x00111 **2BGH4E4E4MNNNNNrc|d}||tj|d|d}|||tj||tj|tj||tj |}tj |}| |j |j | |j |j d| |j|jddSNrJrrplaces)r9r>rr=rMr;rNrAcopystatrr|rassertAlmostEqualst_atimest_mtimerrrsrc_statdst_stats r test_copystatz"FakeShutilModuleTest.test_copystats2>>'** """ 5!!!>>,// """ x00111 x00111(+++78$$78$$ )8+;<<< x0(2CANNN x0(2CANNNNNrz#Functionality not supported in PyPyc\||d}|||d}|d}||||||t j||ddS)zRegression test for #799rJsym1sym2F)follow_symlinksN)skip_if_symlink_not_supportedr9r>create_symlinkrAr)rfrrs rtest_copystat_symlinksz+FakeShutilModuleTest.test_copystat_symlinkss **,,, NN7 # # ~~f%%~~f%% D!$$$ D!$$$dE::::::rc|d}||tj|d|d}|tj||tj|tj |||tj|tj |}tj |}| |j |j | |j|jd| |j|jddSr)r9r>rr=rMr;rNrPrAcopy2rr|rrrrrs r test_copy2zFakeShutilModuleTest.test_copy2s@>>'** """ 5!!!>>,// x00111 11222 Xx((( x0011178$$78$$ )8+;<<< x0(2CANNN x0(2CANNNNNrc|d}|d}tj|d}||||tj|d|tj||tj|| tj|tj |||tj|tj |}tj |}| |j|j||j|jd||j|jddS)NrJrrrr)r9rr;r<r>r:r=rMrNrPrArrr|rrrr)rrrrrrs rtest_copy2_directoryz)FakeShutilModuleTest.test_copy2_directorys>>'**>>(337<< 0':: """ ())) 5!!! x00111 '788999 11222 X/000 x0011178$$78$$ )8+;<<< x0(2CANNN x0(2CANNNNNrc|d}|d}|||d|z|tj|d|tj||tj|tj |||tj||tjtj|d|tjtj|ddS)NrJrz %s/subdirrLrK) r9r:r>rr;r<rMrNrPrAcopytreer src_directory dst_directorys r test_copytreez"FakeShutilModuleTest.test_copytreesKw// |44   &&&  m3444 mY??@@@ }55666  66777 }555 }55666 rw||M8'L'LMMNNN rw||M9'M'MNNOOOOOrc|d}|d}|||tj||tj||t5tj ||ddddS#1swxYwYdSNrJr) r9r>rMrr;rNrPr?r_rAr)rrrs rtest_copytree_src_is_filez.FakeShutilModuleTest.test_copytree_src_is_file$s>>'**|44  """ x00111  66777   w ' ' 5 5 OHm 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5s>C!!C%(C%c|d}d}|j|}|j}|j}|t j|| t j|tj |||t j|| t j||j |}| ||j| ||jdS)Nz/original_xyzzyz /moved_xyzzy) skip_real_fsrr>st_inost_devrMrr;rNrPrArB get_objectr|)rrr src_objectsrc_inosrc_dev dst_objects r!test_move_file_in_same_filesystemz6FakeShutilModuleTest.test_move_file_in_same_filesystem-s& $!W((22 ## x00111 11222 Hh''' x00111 11222W''11  *"3444 *"344444rc||}|d}|jj|d}|j|}|j}|j }tj ||| tj ||tj ||j|}|||j|||j dS)Noriginal_xyzzy moved_xyzzy)rcreate_mount_pointr9rr;r<rr>rrrArBrMrNrPrassertNotEqual)r mount_pointrrrrrrs r$test_move_file_into_other_filesystemz9FakeShutilModuleTest.test_move_file_into_other_filesystem?s --// >>"2337<$$[-@@W((22 ## Hh''' x00111 11222W''11  GZ%6777 GZ%677777rc|d}|d}tj|d}|||||tj||tj|tj |||tj||tj|dS)NrJrR) r9rr;r<r>r:rMrNrPrArB)rrrrs rtest_move_file_into_directoryz2FakeShutilModuleTest.test_move_file_into_directoryQs>>'**{33 7<< w77 """  &&& x00111 11222 Hm,,, x00111 1122222rcJ|d}|d}|||tj|d|tj|d|tj||tj|tj |||tj||tjtj|d|tjtj|d|tj|dS)NrrrLrK) r9r:r>rr;r<rMrNrPrArBrs rtest_move_directoryz(FakeShutilModuleTest.test_move_directory]sy'788 }55   &&& mY??@@@  ]H==>>> }55666  66777 M=111 }55666 rw||M9'M'MNNOOO rw||M8'L'LMMNNN  6677777rc||dd}|j|dt j|}|d|j|d|j|d|j |d|| }|j j |d}|j j |d}|j|dt j|}|d|dS) NrZr[st_sizerXrrr)rd)rr9rr>rA disk_usager|totalusedfreerrr;r<)rrTrrrSs rtest_disk_usagez$FakeShutilModuleTest.test_disk_usageks< NN5%00  Is333&y11  z/000 jo... jo... ):666--// 7<$$[%88GL%%h66  Is333&x00  *55555rc||dd}|j|dt |}t j|}|d|j|d|j |d|j |d|dS)NrZr[rrrrr) rr9rr>rrArr|rrr)rrTr;rs rtest_disk_usage_with_pathz.FakeShutilModuleTest.test_disk_usage_with_path|s NN5%00  Is333I&t,,  z/000 jo... jo... ):66666rcT|jrdnd}|j|d|S)NzM:z/mountr) total_size)r+radd_mount_point)rrs rrz'FakeShutilModuleTest.create_mount_points4"0>ddh   <<<rN)r,r-r.unittestskipIf is_windowsrHrUrXrardrgrirnr}rrrrrrrrrrrrrrrrr0rrr2r2?s>X_Z!:;; 6 6<; 6 4 4 4 4 4 4X_^%@AA ( (BA (X_Z!:;;88<;8 X_Z!:;;44<;4X_^%@AA 2 2BA 2BBB111: O O O O O O O O OX_WCDD ; ;ED ; O O OOOO$ P P P555555$888$ 3 3 3 8 8 8666" 7 7 7rr2ceZdZdZdS)RealShutilModuleTestcdSrtr0r%s rrz RealShutilModuleTest.use_real_fstrNr,r-r.rr0rrrr#rrceZdZfdZdZdZdZdZdZe j e ddZ d Z e j e dd Zd Zd Zd ZxZS)FakeCopyFileTestcVtt|dSr)superrr')r __class__s rr'zFakeCopyFileTest.tearDowns& %%..00000rc|d}|d}d}||||tj||tj|tj|||tj|| ||dS)NrJrcontents of filecontents) r9r>rMrr;rNrPrAcopyfilecheck_contentsrrrrs rtest_common_casez!FakeCopyFileTest.test_common_cases>>'**>>,//% H555 x00111 11222(+++ x00111 Hh/////rcd|d}|}d}||||tj||tj5tj ||ddddS#1swxYwYdS)NrJrr) r9r>rMrr;rNr?rAErrorrrs r0test_raises_if_source_and_dest_are_the_same_filezAFakeCopyFileTest.test_raises_if_source_and_dest_are_the_same_files>>'**% H555 x00111   v| , , 0 0 OHh / / / 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0sB%%B),B)c||d}|d}d}|||||||t j||tj 5tj ||ddddS#1swxYwYdS)NrZr[rr) rr9r>rrMrr;rNr?rArrrs r'test_raises_if_dest_is_a_symlink_to_srcz8FakeCopyFileTest.test_raises_if_dest_is_a_symlink_to_srcs **,,,>>%((>>%((% H555 Hh/// x00111   v| , , 0 0 OHh / / / 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0s?C""C&)C&c@|d}|d}d}d}|||||||tj||tj|t j|||tj||||dS)NrJrcontents of source filecontents of dest filer) r9r>rMrr;rNrArr)rrr src_contents dst_contentss r,test_succeeds_if_dest_exists_and_is_writablez=FakeCopyFileTest.test_succeeds_if_dest_exists_and_is_writables>>'**>>,//0 .  L999 L999 x00111 x00111(+++ x00111 Hl33333rc|d}|d}d}d}||||||tj|d|tj||tj|trtj ||||jj|| |5}| d| dddn #1swxYwYnG| t5tj ||dddn #1swxYwYtj|ddS)NrJrrrrr])r9r>rr=rMr;rNrrArr!r|readr?r_)rrrrrrs r.test_raises_if_dest_exists_and_is_not_writablez?FakeCopyFileTest.test_raises_if_dest_exists_and_is_not_writables>>'**>>,//0 .  L999 L999 5!!! x00111 x00111 99 4 OHh / / / OODGL//99 : : :8$$ F  !:AFFHHEEE F F F F F F F F F F F F F F F""7++ 4 4(333 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5!!!!!s$)E55E9<E9F==GGr3c|||d}|dd}tj|d}d}|||||tj|d|tj ||tj |tsJ| t5tj||ddddS#1swxYwYdStj|||tj ||||dS)NrJtmprZrrr8)rcr9rr;r<r>r:r=rMrNrr?r_rArr)rrdst_dirrrs r3test_raises_if_dest_dir_is_not_writable_under_posixzDFakeCopyFileTest.test_raises_if_dest_dir_is_not_writable_under_posixs >>'**....7<<110  L999     %    x00111 w//000yy 8""7++ 4 4(333 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 OHh / / / OOBGNN844 5 5 5   , 7 7 7 7 7s/EEEcN|d}|d}|tj||t 5tj||ddddS#1swxYwYdSr) r9rPrr;rNr?r_rArrs rtest_raises_if_src_doesnt_existz0FakeCopyFileTest.test_raises_if_src_doesnt_exists>>'**>>,// 11222   w ' ' 0 0 OHh / / / 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0s7BB!Bc||d}|d}d}|||tj|d|tj|tsJ| t5tj ||ddddS#1swxYwYdStj |||tj|| ||dS)NrJrrrr)rcr9r>rr=rMr;rNrr?r_rArr)rrrrs rtest_raises_if_src_not_readablez0FakeCopyFileTest.test_raises_if_src_not_readablesl >>'**>>,//0  L999 5!!! x00111yy 8""7++ 4 4(333 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 OHh / / / OOBGNN844 5 5 5   , 7 7 7 7 7sC**C.1C.cx|d}|d}|||tj||t5tj ||ddddS#1swxYwYdSr) r9r:rMrr;rNr?r_rArrs r!test_raises_if_src_is_a_directoryz2FakeCopyFileTest.test_raises_if_src_is_a_directorys>>'**>>,// !!! x00111   w ' ' 0 0 OHh / / / 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0s B//B36B3c|d}|dd}d}||||||tj||tj||t5tj ||ddddS#1swxYwYdS)NrJrrZrr) r9r>r:rMrr;rNr?r_rAr)rrrrs r"test_raises_if_dest_is_a_directoryz3FakeCopyFileTest.test_raises_if_dest_is_a_directory s >>'**....0  L999     x00111 w//000   w ' ' / / OHg . . . / / / / / / / / / / / / / / / / / /sC;;C?C?c^tj}tj}d}ttj||d5}|ddddn #1swxYwYtj||tj |dS)Nzfoo.pdfwbsstub) tempfilemkdtempr!rr;r<writerArBrO)r source_dir target_dirfilenamefps rtest_moving_dir_into_dirz)FakeCopyFileTest.test_moving_dir_into_dirs%'' %''  "',,z844d ; ; r HHW                    J +++ j!!!!!sA99A=A=)r,r-r.r'rrrrrrrrrrrrrr __classcell__)rs@rrrs11111 0 0 0000 0 0 0 4 4 4""",X_Z!:;;88<;8&000X_Z!:;;88<;8 000 / / / " " " " " " "rrceZdZdZdS)RealCopyFileTestcdSrtr0r%s rrzRealCopyFileTest.use_real_fs$rrNrr0rrrr#rrr__main__)__doc__rrAr)r rpathlibrpyfakefsrpyfakefs.helpersrrrrpyfakefs.tests.test_utilsr r*rrr r2rrrr,mainr0rrrs  ------????????????555555 \W $ ------6---:KKKKK>KKK\ / N"N"N"N"N"~N"N"N"b'  zHMOOOOOrtests/__pycache__/test_utils.cpython-311.pyc000064400000064644150043321520015030 0ustar00 bgAdZddlZddlZddlZddlZddlZddlZddlZddlm Z ddlm Z ddl m Z m Z mZddlmZmZGddZGd d Zdd ZGddejZGddZGddeeZdS)z;Common helper classes used in tests, or as test class base.N)contextmanager)mock)fake_filesystem fake_openfake_os)is_byte_string to_stringceZdZdZdZdZdS) DummyTimezBMock replacement for time.time. Increases returned time on access.c"||_||_dSN current_time increment)self curr_timers j/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/tests/test_utils.py__init__zDummyTime.__init__#s%"c>|j}|xj|jz c_|Sr r)rargskwargsrs r__call__zDummyTime.__call__'s&(  T^+rN)__name__ __module__ __qualname____doc__rrrrr r s8LL###rr c&eZdZdZdZdZdZdS) DummyMockcdSr rrs rstartzDummyMock.start. rcdSr rr"s rstopzDummyMock.stop1r$rc|Sr rr"s r __enter__zDummyMock.__enter__4s rcdSr r)rexc_typeexc_valexc_tbs r__exit__zDummyMock.__exit__7r$rN)rrrr#r&r(r-rrrr r -sP           rr cHtjdt||S)Nzpyfakefs.helpers.now)rpatchr )r#steps r time_mockr3;s :,it.D.D E EErcteZdZdZejdkZejdkZejdkZdZ dZ e dZ dS)TestCasezz-RealFsTestMixin.make_path..1s///3 #///r)rErFtuplerXrWrejoinr )rrrers rrzRealFsTestMixin.make_path%s d1ge} - - >DAw ? ?w|((y~~>>K//$/// tw| 7$7777rcp|sdS|}g}|r|jj|s|jj|\}}|s<|r:|jj|s|j|n7|d||r|jj||D]W}|jj||}|j||j |dX|j ||dS)zCreate the directory at `dir_path`, including subdirectories. `dir_path` shall be composed using `make_path()`. Nrr) rWreexistssplitrUadd_mount_pointinsertrmkdirchmod)rdir_pathperm existing_path components components r create_dirzRealFsTestMixin.create_dir4sG  F   ,DGL$7$7 $F$F ,'+w|'9'9-'H'H $M9  w|**=99CO33MBBB   a + + + ,DGL$7$7 $F$F ,$ 0 0I GL--mYGGM GMM- ( ( ( GMM- / / / /  h%%%%%rNc||jj||t |rdnd}||||}|||5}|||dddn #1swxYwY|j||dS)zCreate the given file at `file_path` with optional contents, including subdirectories. `file_path` shall be composed using `make_path()`. Nwbw) rrWrerfrencoderVwriter)r file_pathcontentsencodingrmodefs r create_filezRealFsTestMixin.create_fileJs  ,,Y77888+~h/G/G+ttS  H$8x00H YYy$ ' ' "1#!!! " " " " " " " " " " " " " " "  i&&&&&s7BB"Bc||jj||j||dS)zCreate the path at `link_path`, and a symlink to this path at `target_path`. `link_path` shall be composed using `make_path()`. N)rrWrerfr)rr target_paths rcreate_symlinkzRealFsTestMixin.create_symlinkYsD  ,,Y77888  Y/////rct|rdnd}|||5}|||ddddS#1swxYwYdS)zcCompare `contents` with the contents of the file at `file_path`. Asserts equality. rbrN)rrVr:read)rrrrrs rcheck_contentszRealFsTestMixin.check_contents`s&h//8ttS YYy$ ' ' 11   Xqvvxx 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1s)A  A$'A$c|j|j}|jjdz|_|jjrd|jz|_||jkrs||j|j|js|j|j||dSdSdSdS)z1Create the path used as base path in `make_path`.NbasepathzC:)rUrXr~rlresetrrrz)r old_base_paths rrpzRealFsTestMixin.create_basepathhs ? & NM!_;jHDN, 7!%!6.. ,O))+++--dn==?O..t~>>> ,((***** ' & /. -,rc|jrt|dd}t|dd}tjdkrR|r>|||||dS|||dS|jrZ|t|ddt|dddS|||dS)Nz\\?\ntz /private/var/z/var/) rNstrreplacerWnamer^r:path_with_short_usernamerP)rr>r=s rassert_equal_pathsz"RealFsTestMixin.assert_equal_pathsws= ? /[[((B77F8}},,Y;;Hw$4#3#3#5#5  11&9911(;;   22222 ] /   F ##OW==H %%ow??        VX . . . . .rc|tj}t|dkr(|ddddz|d<tj|S)Nz~1)rrWr}lenupperr)rers rrz(RealFsTestMixin.path_with_short_usernamesaZZ'' z??a  &qM"1"-3355rs"BA  %%%%%%888888888866666666                 FFFF55555x 555.K5K5K5K5K5K5K5K5\ %(%(%(%(%(X%(%(%(%(%(rtests/__pycache__/fake_filesystem_test.cpython-311.pyc000064400000666350150043321520017044 0ustar00 bg dZddlZddlZddlZddlZddlZddlZddlmZm Z m Z ddl m Z m Z mZmZmZddlmZddlmZmZmZGddeZGd d eZGd d eZGd deZGddeZGddeZGddeZGddeZGddeZGddeZ Gdde Z!Gdde Z"Gdd e Z#Gd!d"eZ$Gd#d$eZ%Gd%d&eZ&Gd'd(eZ'Gd)d*eZ(Gd+d,eZ)Gd-d.eZ*Gd/d0eZ+Gd1d2eZ,e-d3krej.dSdS)4z$Unittest for fake_filesystem module.N)fake_filesystemfake_os fake_open)set_uidset_gidis_root reset_idsOSType)IS_WIN)TestCaseRealFsTestCase time_mockceZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZdZdZdZdZdZdZdZdZdZdS)FakeDirectoryUnitTestcTtjd|_tj|j|_t dd|_|jtj dd|j|_ tj d|j |_ dS) N/path_separator foobar dummy_file)contents filesystemsomedirr) rFakeFilesystemrr FakeOsModuleosrtimestartFakeFile fake_file FakeDirectoryfake_dirselfs t/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/tests/fake_filesystem_test.pysetUpzFakeDirectoryUnitTest.setUp%s)8LLL&t77b!$$  (1 |   (5 $/    c8|jdSN)r stopr&s r(tearDownzFakeDirectoryUnitTest.tearDown1s r*c|tj|jjz|tj|jjz|i|jjdSr,) assertTruestatS_IFREGr#st_modeS_IFDIRr% assertEqualentriesr&s r(test_new_file_and_directoryz1FakeDirectoryUnitTest.test_new_file_and_directory4s_  t~'==>>>  t}'<<=== T]233333r*c|j|j|d|ji|jjdSNr)r% add_entryr#r5r6r&s r(test_add_entryz$FakeDirectoryUnitTest.test_add_entry9sB /// (DN3T]5JKKKKKr*c|j|j||j|jddSr9)r%r:r#r5 get_entryr&s r(test_get_entryz$FakeDirectoryUnitTest.test_get_entry=sH /// )@)@)J)JKKKKKr*c0|jj}|jj|j|j|j||d|jj||d|jjdS)Nzsomedir/foobarr)r root_dir_namerootr:r%r#r5pathr'root_dirs r( test_pathzFakeDirectoryUnitTest.test_pathAs?0 &&t}555 /// H444dn6IJJJ H---t}/ABBBBBr*cd|j_d}|j||j|}|||jdSNTzC:/foo/bar/baz)r is_windows_fs create_dir get_objectr5rBr'dir_path dir_objects r(test_path_with_drivez*FakeDirectoryUnitTest.test_path_with_driveHsZ(,%# ""8,,,_//99  :?33333r*c|jj}d}|j||j||j|}||d|jdS)N /foo/bar/baz foo/bar/baz)rr@rIrchdirrJr5rB)r'rDrLrMs r(test_path_after_chdirz+FakeDirectoryUnitTest.test_path_after_chdirOsw?0! ""8,,,  h_//99  H111:?CCCCCr*cd|j_d}|j||j||j|}|||jdSrG)rrHrIrrRrJr5rBrKs r( test_path_after_chdir_with_drivez6FakeDirectoryUnitTest.test_path_after_chdir_with_driveWsn(,%# ""8,,,  h_//99  :?33333r*cx|j|j||j|jd|jd|t5|jdddddS#1swxYwYdSr9)r%r:r#r5r= remove_entry assertRaisesKeyErrorr&s r(test_remove_entryz'FakeDirectoryUnitTest.test_remove_entry_s /// )@)@)J)JKKK ""8,,,   x ( ( . . M # #H - - - . . . . . . . . . . . . . . . . . .sB//B36B3c|tj5d|j_ddddS#1swxYwYdSNg?raises_os_errorerrnoENOSPCr#sizer&s r(,test_should_throw_if_set_size_is_not_integerzBFakeDirectoryUnitTest.test_should_throw_if_set_size_is_not_integerfs  ! !%, / / & &"%DN  & & & & & & & & & & & & & & & & & & :>>c|tj5d|j_ddddS#1swxYwYdSNr]r&s r()test_should_throw_if_set_size_is_negativez?FakeDirectoryUnitTest.test_should_throw_if_set_size_is_negativejs  ! !%, / / % %"$DN  % % % % % % % % % % % % % % % % % %rcc^d|j_|d|jjdSNrr#rar5rr&s r(+test_produce_empty_file_if_set_size_is_zerozAFakeDirectoryUnitTest.test_produce_empty_file_if_set_size_is_zeron- T^455555r*c^d|j_|d|jjdSrirkr&s r(+test_sets_content_empty_if_set_size_is_zerozAFakeDirectoryUnitTest.test_sets_content_empty_if_set_size_is_zerorrmr*c^d|j_|d|jjdS)Ndummy_rkr&s r(7test_truncate_file_if_size_is_smaller_than_current_sizezMFakeDirectoryUnitTest.test_truncate_file_if_size_is_smaller_than_current_sizevs- 4>#:;;;;;r*c^d|j_|d|jjdS)Nrrrkr&s r(:test_leave_file_unchanged_if_size_is_equal_to_current_sizezPFakeDirectoryUnitTest.test_leave_file_unchanged_if_size_is_equal_to_current_sizezs-  t~'>?????r*c|d|j_|tj5|jddddn #1swxYwYd|j_|tj5|jdddddS#1swxYwYdS)NTaF)rrHr^r_EISDIRr% set_contentsr&s r(test_set_contents_to_dir_raisesz5FakeDirectoryUnitTest.test_set_contents_to_dir_raises~s'(,%  ! !%, / / , , M & &s + + + , , , , , , , , , , , , , , ,(-%  ! !%, / / , , M & &s + + + , , , , , , , , , , , , , , , , , ,s#AAA B11B58B5c^d|j_|d|jjdS)N z dummy_filerkr&s r(=test_pads_with_nullbytes_if_size_is_greater_than_current_sizezSFakeDirectoryUnitTest.test_pads_with_nullbytes_if_size_is_greater_than_current_sizes.  +T^-DEEEEEr*c|d|jjd|j_|d|jjd|j_|d|jjdS)Nr)r5r#st_mtimer&s r(test_set_m_timez%FakeDirectoryUnitTest.test_set_m_timesm T^4555"$ T^4555"% dn566666r*ctjd}tj|}d}||d|d||t j||}d|_ | d||t jdS)Nrr some_file1zcontents here1rr+) rrrr create_file assertLessr1ST_INOrJst_inor5)r'rfake_os_module file_pathfile_objs r(test_file_inodez%FakeDirectoryUnitTest.test_file_inodes$33GGG  -j99 y3CDDD >..y99$+FGGG((33 ^00;;DKHIIIIIr*ctjd}tj|}d}|||d||t j||}d|_ | d||t jdS)Nrrtestdirrr) rrrrrIrr1rrJrr5)r'rrdirpathdir_objs r(test_directory_inodez*FakeDirectoryUnitTest.test_directory_inodes$33GGG  -j99g&&& >..w77 DEEE''00 ^0099$+FGGGGGr*ctjd}|d}|dd|d}|dd |d d |d }|d d|dd|d|j|d|j|d|j|d|jj|tj 5d|_ddddS#1swxYwYdS)Nrr/fooz /foo/bar.txtst_sizez /foo/bar/z/foo/bar/baz1.txtz/foo/bar/baz2.txt(z/foo1z /foo1/bar.txt2z/foo1/bar/baz/file<ZFnd) rrrIrr5rarDr^r_rx)r'fsfoo_dirbar_dirfoo1_dirs r(test_directory_sizez)FakeDirectoryUnitTest.test_directory_sizes  +3 ? ? ?--'' ~r222-- ,, *B777 *B777==)) 333 +R888 W\*** W\*** hm,,, bk.///  ! !%, / /  HM                  sE--E14E1cftjd}|d|d|d|d|d|d}|gd|jdS) Nrrrz/foo/2z/foo/4z/foo/1z/foo/3)2413)rrrIrrJr5 ordered_dirs)r'rr%s r(test_ordered_dirsz'FakeDirectoryUnitTest.test_ordered_dirss$33GGG f%%%x(((x(((x(((x(((((00 ---x/DEEEEEr*N)__name__ __module__ __qualname__r)r.r7r;r>rErNrSrUrZrbrgrlrorsrurzr}rrrrrr*r(rr$s    444 LLLLLLCCC444DDD444...&&&%%%666666<<<@@@,,,FFF777 J J J H H H   "FFFFFr*rc&eZdZdZdZdZdZdS)SetLargeFileSizeTestcbtj}tjd||_dS)Nrr)rrr"r#r'rs r(r)zSetLargeFileSizeTest.setUps+$355 (1(zRRRr*c|tj5|jdddddS#1swxYwYdSr\r^r_r`r#set_large_file_sizer&s r((test_should_throw_if_size_is_not_integerz=SetLargeFileSizeTest.test_should_throw_if_size_is_not_integers  ! !%, / / 4 4 N . .s 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4AA A c|tj5|jdddddS#1swxYwYdSrerr&s r(%test_should_throw_if_size_is_negativez:SetLargeFileSizeTest.test_should_throw_if_size_is_negatives  ! !%, / / 3 3 N . .r 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3rc|jd|d|jj|d|jjdS)Niʚ;)r#rr5rrr&s r(6test_sets_content_none_if_size_is_non_negative_integerzKSetLargeFileSizeTest.test_sets_content_none_if_size_is_non_negative_integersT **:666 t~6777 T^%;<<<<GetPathComponentsTest.test_empty_path_should_return_empty_lists. T_==bAABBBBBr*cd|dg|jddSNfoorr&s r(=test_relative_path_with_one_component_should_return_componentzSGetPathComponentsTest.test_relative_path_with_one_component_should_return_components0 %$/"B"B5"I"IJJJJJr*cd|dg|jddS)Nrrrr&s r(=test_absolute_path_with_one_component_should_return_componentzSGetPathComponentsTest.test_absolute_path_with_one_component_should_return_component s0 %$/"B"B6"J"JKKKKKr*cf|ddg|jddS)Nrrrrr&s r(5test_two_level_relative_path_should_return_componentszKGetPathComponentsTest.test_two_level_relative_path_should_return_components s2 %)I)I))T)TUUUUUr*cf|ddg|jddS)Nrrrrr&s r(5test_two_level_absolute_path_should_return_componentszKGetPathComponentsTest.test_two_level_absolute_path_should_return_componentss2 %)I)I*)U)UVVVVVr*N) rrrr)rrrrrrrr*r(rrsOOOCCCKKKLLLVVVWWWWWr*rcLeZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZ dZ!d Z"d!Z#d"Z$d#Z%d$Z&d%Z'd&Z(d'Z)d(Z*d)Z+d*Z,d+Z-d,Z.d-Z/d.Z0d/Z1d0Z2d1Z3d2Z4d3Z5d4Z6d5Z7d6S)7FakeFilesystemUnitTestctjd|_|jj|_tjd|j|_tjd|j|_tjd|j|_ dS)Nrrrrfoobazquux) rrrr@rr"r#r$ fake_childfake_grandchildr&s r(r)zFakeFilesystemUnitTest.setUps)8LLL6(1(tWWW)7     /< t   r*c|d|jj|tj|jjjz|i|jjj dS)Nr) r5rrr0r1r4rAr3rDr6r&s r(test_new_filesystemz*FakeFilesystemUnitTest.test_new_filesystemsb do<===  t';'CCDDD T_5=>>>>>r*c|t5|jdddddS#1swxYwYdSr,)rX TypeErrorrexistsr&s r(test_none_raises_type_errorz2FakeFilesystemUnitTest.test_none_raises_type_error$s   y ) ) ) ) O " "4 ( ( ( ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) )sAA Ac`||jddSr) assertFalserrr&s r( test_empty_string_does_not_existz7FakeFilesystemUnitTest.test_empty_string_does_not_exist(s, //3344444r*cj||j|jdSr,)r0rrrr&s r(test_exists_rootz'FakeFilesystemUnitTest.test_exists_root+s, ..t~>>?????r*ct||j|jjdSr,)rrrr#namer&s r(test_exists_unadded_filez/FakeFilesystemUnitTest.test_exists_unadded_file.s1 //0CDDEEEEEr*cd}|j|d||j|dzdS)Nrbazr/baz)rrrrr'rs r(0test_not_exists_subpath_named_like_file_contentszGFakeFilesystemUnitTest.test_not_exists_subpath_named_like_file_contents1sQ  ##I#>>> // F0BCCDDDDDr*c||jj|j|jdSr,)r5rrDrJrr&s r(test_get_root_objectz+FakeFilesystemUnitTest.test_get_root_object7sA  O $ O & &t~ 6 6     r*c|j|j|j|d|ji|jjjdSr9)r add_objectrr#r5rDr6r&s r(test_add_object_to_rootz.FakeFilesystemUnitTest.test_add_object_to_root=sI ""4>4>BBB (DN3T_5M5UVVVVVr*cd|j_|d|jjd|j_|d|jjd|j_|d|jjdS)NTzC:/zE:/foozE:/z //foo/barz //foo/bar/)rrHr5r@rr&s r(test_windows_root_dir_namez1FakeFilesystemUnitTest.test_windows_root_dir_nameAsw(,%  =>>>&  =>>>) t'DEEEEEr*c|j|j|j||j|jjdSr,)rr rr#r0rrr&s r(test_exists_added_filez-FakeFilesystemUnitTest.test_exists_added_fileIsK ""4>4>BBB ..t~/BCCDDDDDr*c"d|j_|jd|jd||jd||jd||jd||jd||jdd |j_||jd ||jd ||jd ||jd ||jddS)NF /a/b/file_one /a/c/file_twoa/b/../c/file_two/a/c/../b/file_one/a/c/../../a/b/file_one a/b/../z/da/b/../z/../c/file_twoz/a/c ../b/file_one../../a/b/file_one../../a/b/../../a/c/file_two ../z/file_one../z/../c/file_two)rrHrr0rrrr&s r(test_exists_relative_path_posixz6FakeFilesystemUnitTest.test_exists_relative_path_posixMs(-% ##O444 ##O444 ../BCCDDD ../CDDEEE ../HIIJJJ // ==>>> //0HIIJJJ$ ..??@@@ ../CDDEEE ../MNNOOO //@@AAA //0DEEFFFFFr*c:d|j_d|j_|jd|jd||jd||jd||jd||jd||jd d |j_||jd ||jd ||jd ||jd||jddS)NTFrrrrrrrzC:/a/crrrrr)rrHis_macosrr0rrrr&s r(!test_exists_relative_path_windowsz8FakeFilesystemUnitTest.test_exists_relative_path_windows]s(,%#(  ##O444 ##O444 ../BCCDDD ../CDDEEE ../HIIJJJ // ==>>> ../GHHIII& ..??@@@ ../CDDEEE ../MNNOOO //@@AAA ../CDDEEEEEr*c|j|j|j||j|jddSr9)rr rr#r5rJr&s r(test_get_object_from_rootz0FakeFilesystemUnitTest.test_get_object_from_rootnsL ""4>4>BBB )C)CH)M)MNNNNNr*cZ|j|j|j||j|jd|tj5|jdddddS#1swxYwYdS)Nrsome_bogus_filename) rr rr#r5rJr^r_ENOENTr&s r(+test_get_nonexistent_object_from_root_errorzBFakeFilesystemUnitTest.test_get_nonexistent_object_from_root_errorrs ""4>4>BBB )C)CH)M)MNNN  ! !%, / / > > O & &'< = = = > > > > > > > > > > > > > > > > > >s8B  B$'B$cP|j|j|j|j|jj|tj5|j |jjddddS#1swxYwYdSr,) rr rr# remove_objectrr^r_r'rJr&s r(test_remove_object_from_rootz3FakeFilesystemUnitTest.test_remove_object_from_rootxs ""4>4>BBB %%dn&9:::  ! !%, / / < < O & &t~': ; ; ; < < < < < < < < < < < < < < < < < 4>BBB %%dn&9::: //0CDDEEEEEr*cJ|j|j|j|j|jj|j||jj|ji|jj|jjj dSr,) rr rrrr#r5rDr=r6r&s r(test_add_object_to_childz/FakeFilesystemUnitTest.test_add_object_to_childs ""4>4?CCC ""4?#7HHH  ^ $. 1 O $ . .t/C D D L     r*c6d|j_|j|jj|j|t j5|j|jj|jddddS#1swxYwYdSNF) rrHr r@r#r^r_ENOTDIRrr&s r(+test_add_object_to_regular_file_error_posixzBFakeFilesystemUnitTest.test_add_object_to_regular_file_error_posixs(-% ""4?#@$.QQQ  ! !%- 0 0 L L O & &t~':DN K K K L L L L L L L L L L L L L L L L L Ls+BBBc,d|j_|j|j|j|t j5|j|jj|jddddS#1swxYwYdSNT) rrHr rr#r^r_r'rr&s r(-test_add_object_to_regular_file_error_windowszDFakeFilesystemUnitTest.test_add_object_to_regular_file_error_windowss(,% ""4>4>BBB  ! !%, / / L L O & &t~':DN K K K L L L L L L L L L L L L L L L L L Ls+B  B B c\|j|j|j|j|jj|j|j|jj|jj}||j|dSr,) rr rrrr# joinpathsr0rrs r(test_exists_file_added_to_childz6FakeFilesystemUnitTest.test_exists_file_added_to_childs ""4>4?CCC ""4?#7HHH(()=t~?RSS ..t4455555r*c d|j|j|j|j|jj|j||j|j|j|jj|jjdSr,) rr rrrr#r5rJr;r&s r(test_get_object_from_childz1FakeFilesystemUnitTest.test_get_object_from_childs ""4>4?CCC ""4?#7HHH  N O & &))$/*>@STT       r*c|j|j|j|j|jj|j|tj5|j |j |jjdddddS#1swxYwYdSr-) rr rrrr#r^r_r'rJr;r&s r(,test_get_nonexistent_object_from_child_errorzCFakeFilesystemUnitTest.test_get_nonexistent_object_from_child_errors ""4>4?CCC ""4?#7HHH  ! !%, / /   O & &))$/*>@UVV                     s/>B::B>B>c|j|j|j|j|jj|j|j|jj|jj}|j||tj 5|j |ddddS#1swxYwYdSr,) rr rrrr#r;r*r^r_r'rJ)r' target_paths r(test_remove_object_from_childz4FakeFilesystemUnitTest.test_remove_object_from_childs  ""4>4?CCC ""4?#7HHHo// O $."5   %%k222  ! !%, / / 4 4 O & &{ 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4s8C  C$'C$c:|j|j|j|t j5|j|j|jj dddddS#1swxYwYdSr-) rr rrr^r_r'r*r;rr&s r(#test_remove_object_from_child_errorz:FakeFilesystemUnitTest.test_remove_object_from_child_errors ""4>4?CCC  ! !%, / /   O ) )))$/*>@UVV                     s>BBBc@|j|j|j|t j5|j|jd|jj zdddddS#1swxYwYdS)Nz%s1file_does_not_matter_since_parent_not_a_directory) rr rr#r^r_r5r*r;rr&s r(+test_remove_object_from_non_directory_errorzBFakeFilesystemUnitTest.test_remove_object_from_non_directory_errors ""4>4>BBB  ! !%- 0 0   O ) )))4>..G                     sABBBc|j|j|j|j|jj|j|j|jj|jj}|j|||j |dSr,) rr rrrr#r;r*rrrs r(#test_exists_file_removed_from_childz:FakeFilesystemUnitTest.test_exists_file_removed_from_childs ""4>4?CCC ""4?#7HHH(()=t~?RSS %%d+++ //5566666r*c |j|j|j|j|jj|j|j|jj|jj}|j||jj}|t5|j |dddn #1swxYwY|j||j| |j|j || |j ||j||t5|j |dddn #1swxYwY||j |dSr,)rr rrrrr;r#rXOSErrorrJr5r0rr*r)r'grandchild_directorygrandchild_files r($test_operate_on_grandchild_directoryz;FakeFilesystemUnitTest.test_operate_on_grandchild_directorys. ""4>4?CCC ""4?#79MNNN#88 O $"6";  /33 $."5    w ' ' 8 8 O & & 7 7 7 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 ""#7HHH )C)CO)T)TUUU ..??@@@ %%o666   w ' ' 8 8 O & & 7 7 7 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 //@@AAAAAs$>C%%C),C)$G  GGc0d}|j||j|}|tj||j|tj |j zdSr rrIrJr5rrBbasenamerr0r1r4r3r'rBnew_dirs r('test_create_directory_in_root_directoryz>FakeFilesystemUnitTest.test_create_directory_in_root_directorys{ ""4(((/,,T22 ))$//>>>  w677777r*cd}|j||tj5|j|ddddS#1swxYwYdSrrrIr^r_EEXISTrs r(>>  w67774 ""4(((/,,T22 ))$//>>>  w677777r*cd}|j||tj5|j|ddddS#1swxYwYdS)NrQrWrs r(*test_create_directory_already_exists_errorzAFakeFilesystemUnitTest.test_create_directory_already_exists_errors ""4(((  ! !%, / / - - O & &t , , , - - - - - - - - - - - - - - - - - -rZcd|j_d}|j|d|dz}tsT|t j5|j|ddddS#1swxYwYdS|j|||j |dS)NFrm perm_bitsr) rrHrIrr^r_EACCESrr0rr'rLrs r(7test_create_file_in_read_only_directory_raises_in_posixzNFakeFilesystemUnitTest.test_create_file_in_read_only_directory_raises_in_posix s(-% ""8u"===v% yy ?%%el33 7 7++I666 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 O ' ' 2 2 2 OODO229== > > > > >sBB  B cd|j_d}|j|d|dz}|j|||j|dS)NTz C:/foo/barr`rar)rrHrIrr0rrds r(;test_create_file_in_read_only_directory_possible_in_windowszRFakeFilesystemUnitTest.test_create_file_in_read_only_directory_possible_in_windowsst(,% ""8u"===v%  ##I... ..y99:::::r*cd}d}|j||||j|||jt j|d|z}||jt j|dS)Nr dummy datarz./%s)rrr0rrrrBdirname)r'rBrs r(%test_create_file_in_current_directoryz>>o%%i00 38,,, #,77777r*cTd}d}d}|jd|jd||j|||j|}|||j|||jdS)Nrrrrr)rrIrrlresolver5rrrs r(check_lresolve_objectz,FakeFilesystemUnitTest.check_lresolve_objects" ,  ""5))) ##L?#KKK &&y+>>>o&&y11 CH--- cl33333r*cFd|j_|dSr8rrHrr&s r(test_lresolve_object_windowsz3FakeFilesystemUnitTest.test_lresolve_object_windowss$(,% ""$$$$$r*cFd|j_|dSr4rr&s r(test_lresolve_object_posixz1FakeFilesystemUnitTest.test_lresolve_object_posixs$(-% ""$$$$$r*cX|jd||5|jddddn #1swxYwY||5|jdddddS#1swxYwYdS)N not_a_dirz not_a_dir/fooznot_a_dir/foo/bar)rrr^rr)r' error_subtypes r(check_directory_access_on_filez5FakeFilesystemUnitTest.check_directory_access_on_files& ##K000  ! !- 0 0 5 5 O # #O 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5  ! !- 0 0 : : O $ $%8 9 9 9 : : : : : : : : : : : : : : : : : :s#AAA7BB#&B#c\d|j_|tjdSr8)rrHrr_r'r&s r(%test_directory_access_on_file_windowszr@rCrErHrJrOrUrYr\r^rergrkrnrrrur}rrrrrrrrrrrrrrr*r(rrsa    ??? )))555@@@FFFEEE    WWWFFFEEEGGG FFF"OOO>>> <<< AAAFFF    LLL LLL 666    444777BBB&888--- 8 8 8--- ? ? ?;;;GGG 6 6 6666... + + +   +++666... === 8 8 8 4 4 4%%%%%%::::::;;;HHHHHr*rcVeZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd S)!CaseInsensitiveFakeFilesystemTestctjd|_d|j_t j|j|_|jj|_dSNrrFrrris_case_sensitiverrrrBr&s r(r)z'CaseInsensitiveFakeFilesystemTest.setUpsD)8LLL,1)&t77GL r*c|jd|jd||jddSNrrPz /Foo/Bar/Baz)rrIrr0rJr&s r(test_get_objectz1CaseInsensitiveFakeFilesystemTest.test_get_objectsV "":... ##N333 22>BBCCCCCr*c|jd|jd|jd||jddSr)rrIrr*rrr&s r(test_remove_objectz4CaseInsensitiveFakeFilesystemTest.test_remove_objectsn "":... ##N333 %%n555 //??@@@@@r*c|jd||jd||jd|jd||jd||jddSN/Foo/Barrz /foo/Bar/bazz /Foo/bar/BAZrP)rrIr0rrr&s r( test_existsz-CaseInsensitiveFakeFilesystemTest.test_existss "":... ..z::;;; ..z::;;; ##N333 ..~>>??? ..~>>?????r*c|jd|jd|jd}|jd}|||dSNrrPr)rrIrJr5r'dir1dir2s r(.test_create_directory_with_different_case_rootzPCaseInsensitiveFakeFilesystemTest.test_create_directory_with_different_case_rootst "":... "">222))*55))*55 t$$$$$r*c|jd|jd|jd}|jd}|||dSr)rrIrrJr5rs r((test_create_file_with_different_case_dirzJCaseInsensitiveFakeFilesystemTest.test_create_file_with_different_case_dirst "":... ##N333))*55))*55 t$$$$$r*c|jd|jdd||jjd|jddS)Nz/foo/bazrz ./baz/bipz foo/baz/bipr)rrIrr5r@ resolve_pathr&s r(test_resolve_pathz3CaseInsensitiveFakeFilesystemTest.test_resolve_pathsv "":... &&z;??? , 9 9 9 O ( ( 4 4     r*c|jd||jd||jd||jd||jddSNrFooFoo/Bar)rrr0rBisdirrisfiler&s r(test_isdir_isfilez3CaseInsensitiveFakeFilesystemTest.test_isdir_isfiles ##I...  ../// ))%00111  ((33444 3344444r*cd}|j|d|d|jddS)NrQ1234567r FOO/BAR/BAZrrr5rBgetsizers r( test_getsizez.CaseInsensitiveFakeFilesystemTest.test_getsizesN!  ##I #BBB DI--m<<=====r*cNd|j_d}|j||dz}|dz}|j|||t j5|jj |ddddS#1swxYwYdS)NFrz/link) rrHrIrsymlinkr^r_ELOOPrBr)r'rL link_path link_targets r(!test_getsize_with_looping_symlinkzCCaseInsensitiveFakeFilesystemTest.test_getsize_with_looping_symlinks(-% ""8,,,w& ')   Y///  ! !%+ . . , , GL  + + + , , , , , , , , , , , , , , , , , ,s- BB!Bc|jd}d|_|d|jddSNz foo/bar1.txtz Foo/Bar1.TXT)rrrr5rBgetmtimer' test_files r(test_get_mtimez0CaseInsensitiveFakeFilesystemTest.test_get_mtimesKO//??   TY//??@@@@@r*c|jdd||jddS)Nrrrr)rrr0rJr&s r(test_get_object_with_file_sizez@CaseInsensitiveFakeFilesystemTest.test_get_object_with_file_sizesE ##J#;;; 22:>>?????r*N)rrrr)rrrrrrrrrrrrr*r(rrs!!! DDD AAA @@@%%%%%%   555>>> ,,,AAA @@@@@r*rcDeZdZdZdZdZdZdZdZdZ dZ d Z d S) CaseSensitiveFakeFilesystemTestctjd|_d|j_t j|j|_|jj|_dS)NrrTrr&s r(r)z%CaseSensitiveFakeFilesystemTest.setUpsD)8LLL,0)&t77GL r*c|jd|jd|t5|jdddddS#1swxYwYdSr)rrIrrXrLrJr&s r(rz/CaseSensitiveFakeFilesystemTest.test_get_object s "":... ##N333   w ' ' 7 7 O & &~ 6 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7sA77A;>A;c`|jd|jd|t5|jddddn #1swxYwY||jddSr)rrIrrXrLr*r0rr&s r(rz2CaseSensitiveFakeFilesystemTest.test_remove_objects "":... ##N333   w ' ' : : O ) ). 9 9 9 : : : : : : : : : : : : : : : ..~>>?????sA66A:=A:c|jd||jd||jd|jd||jd||jddSr)rrIr0rrrr&s r(rz+CaseSensitiveFakeFilesystemTest.test_existss "":... ..z::;;; // ;;<<< ##N333 //??@@@ //??@@@@@r*c|jd|jd|jd}|jd}|||dSr)rrIrJassertNotEqualrs r(rzNCaseSensitiveFakeFilesystemTest.test_create_directory_with_different_case_root st "":... "">222))*55))*55 D$'''''r*c|jd|jd|jd}|jd}|||dSr)rrIrrJrrs r(rzHCaseSensitiveFakeFilesystemTest.test_create_file_with_different_case_dir'st "":... ##N333))*55))*55 D$'''''r*c|jd||jd||jd||jd||jddSr)rrrrBrrr&s r(rz1CaseSensitiveFakeFilesystemTest.test_isdir_isfile.s ##I... //000 ))%00111 )))44555 3344444r*cd}|j|d|tj5|jdddddS#1swxYwYdS)NrQrrr)rrrXrerrorrBrrs r(rz,CaseSensitiveFakeFilesystemTest.test_getsize5s!  ##I #BBB   rx ( ( - - I  m , , , - - - - - - - - - - - - - - - - - -rc|jd}d|_|tj5|jdddddS#1swxYwYdSr)rrrr^r_r'rBrrs r(rz.CaseSensitiveFakeFilesystemTest.test_get_mtime;sO//??    ! !%, / / / / I  ~ . . . / / / / / / / / / / / / / / / / / /A))A-0A-N) rrrr)rrrrrrrrrr*r(rrs!!! 777 @@@AAA((((((555--- /////r*rc$eZdZdZdZdZdZdS)OsPathInjectionRegressionTestzTest faking os.path before calling os.walk. Found when investigating a problem with gws/tools/labrat/rat_utils_unittest, which was faking out os.path before calling os.walk. ctjd|_tj|_t j|j|_dSr)rrrrrBos_pathrrr&s r(r)z#OsPathInjectionRegressionTest.setUpJs:)8LLLw &t77r*c(|jt_dSr,)rrrBr&s r(r.z&OsPathInjectionRegressionTest.tearDownRs,r*cd}||j||j|||jd||j||jd|z|jd|z|jd|z|jd|z|jd|zddggfdd d ggfd gd gfd gd dgfg}t d|jdDd}| t|t|t||D]\}}| |d|d| |dt |d| |dt |ddS)Nz/xrz%s/poz %s/po/controlz%s/po/experimentz%s/gvz %s/gv/controlrgvpoz/x/gvcontrolz/x/po experimentcg|]}|Srr).0steps r( zQOsPathInjectionRegressionTest.test_create_top_level_directory..hs<<<$<<zOOsPathInjectionRegressionTest.test_create_top_level_directory..hs AaDr*)keyrrr) rrrrIr0rsortedrwalkr5lenzip)r' top_level_direxpectedresultentryexpected_entrys r(test_create_top_level_directoryz=OsPathInjectionRegressionTest.test_create_top_level_directoryUs<  // >>??? ""=111 ..s33444 ..}==>>> ""7]#:;;; ##Om$CDDD ##$6$FGGG ""7]#:;;; ##Om$CDDD3%  D$< $ b9+ & b9l3 4  <<$',,s*;*;<<<..QQQ XF 444%(%:%: B B !E>   ^A.a 9 9 9   ^A.uQx0@0@ A A A   ^A.uQx0@0@ A A A A B Br*N)rrr__doc__r)r.rrr*r(rrBsP888BBBBBr*rceZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zejejd kddZdZdZdZdZdZdZdZdZdZejejpejddZ dZ!dZ"dZ#dZ$dZ%d Z&d!Z'd"Z(d#Z)d$Z*d%Z+d&Z,d'Z-d(Z.d)Z/d*Z0d+Z1d,Z2d-S).FakePathModuleTestctjd|_tj|j|_|jj|_dSN!r)rrrrrrrBr&s r(r)zFakePathModuleTest.setUpqs:)8LLL&t77GL r*c||j_d}|jj|z}|j||||j||||j||||jd|zdS)Nrz..!%s)rrHr@rr5rBabspathr' is_windowsfilenamers r( check_abspathz FakePathModuleTest.check_abspathvs(2%//(: ##G,,, $)"3"3G"<"<=== $)"3"3H"="=>>> $)"3"3Gh4F"G"GHHHHHr*c2|ddSNTr r"r&s r(test_abspath_windowsz'FakePathModuleTest.test_abspath_windowss d+++++r*c2|ddS)>> !2!2:!>!>??? ty0099::: $)"3"3K"@"@AAA  1 1( ; ;<<<  1 1) < <=====r*cld}|||jd|zdS)NrUz%s!baz)r5rBrj)r'rjs r( test_dirnamezFakePathModuleTest.test_dirnames8 $)"3"3Hw4F"G"GHHHHHr*cTgd}|d|jj|dS)N)rrrr]r5rBr:r' componentss r(test_join_stringsz$FakePathModuleTest.test_join_strings s4***    (CDDDDDr*cTgd}|d|jj|dS)N)r,barbazr^ryrzs r(test_join_bytesz"FakePathModuleTest.test_join_bytes$s4---  )DEEEEEr*c`|jrT||jd|jjddddS||jd|jjddddS)N~ USERPROFILE\rHOMEr)r r5rB expanduserrenvironreplacer&s r(test_expand_userz#FakePathModuleTest.test_expand_user(s ?     $$S)) .66tSAA         $$S))'//S99     r*zonly tested on unix systemsctjdkrd}nd}||jd|dS)Ndarwinz !var!rootz!rootz~root)sysplatformr5rBr)r'roothomes r(test_expand_rootz#FakePathModuleTest.test_expand_root4sI <8 # #"HHH --g66AAAAAr*cd}|tj5|j|ddddS#1swxYwYdS)Nr])rXrrrBrrs r(test_getsize_path_nonexistentz0FakePathModuleTest.test_getsize_path_nonexistent?s!   rx ( ( ) ) I  i ( ( ( ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) )sA  AAcd}|j||d|j|dS)Nr]rrrs r(test_getsize_file_emptyz*FakePathModuleTest.test_getsize_file_emptyDsI!  ##I... DI--i8899999r*cd}d}|j|d|d|j||d|j|dS)Nr]r^rrrrr_s r(test_getsize_file_non_zero_sizez2FakePathModuleTest.test_getsize_file_non_zero_sizeIsy! ( ##I #BBB DI--i88999 DI--o>>?????r*cd}|j||j|}|t |dkd|zdS)NrUr&expected non-negative size; actual: %s)rrIrBrrintr'rLras r(test_getsize_dir_emptyz)FakePathModuleTest.test_getsize_dir_emptyPs_ ""8,,,y  ** TQ(PSW(WXXXXXr*cd}|j|j|d|j|}|t |dkd|zdS)NrUrrr)rrr;rBrrrrs r(test_getsize_dir_non_zero_sizez1FakePathModuleTest.test_getsize_dir_non_zero_sizeWsq ##DO$=$=h$N$NOOOy  ** TQ(PSW(WXXXXXr*c|jd||jd||jd||jd||jddS)NrUrr, it_dont_exist)rrr0rBrrr&s r( test_isdirzFakePathModuleTest.test_isdir^s ##I...  ..///  //000 33444 99:::::r*c|jd||jd||jd||jd||jd|jjd|j_||jd||jd||jddS)Nr5rorArrUr)rrr0rBrr@rr&s r(test_isdir_with_cwd_changez-FakePathModuleTest.test_isdir_with_cwd_changees ##N333  //000   33444  ..///   22333!%!>CCC  //000   33444  ../////r*c|jd||jd||jd||jd||jddS)NrUrfoo!barr)rrrrBrr0r&s r( test_isfilezFakePathModuleTest.test_isfileps ##I... ))%00111  ((33444  ((44555 ))/::;;;;;r*c\|jd}|d|jdd|_|d|jd|d|jddS)Nz foo!bar1.txtrs foo!bar1.txt)rrrrBrrr5rs r(rz!FakePathModuleTest.test_get_mtimewsO//??  B 2 2> B BCCC  TY//??@@@ TY//@@AAAAAr*c||jd|tj5|jdddddS#1swxYwYdS)Ndoes_not_exist)rrBrr^r_r'rr&s r(test_get_mtime_raises_os_errorz1FakePathModuleTest.test_get_mtime_raises_os_error~s ))*:;;<<<  ! !%, / / 1 1 I  / 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1s A55A9<A9ct|jd|jd|jdd||jd||jd||jd||jd||jd||jd||jd||jddS)Nrzfoo!regular_filezfoo!link_to_file regular_filesfoo!link_to_filer) rrIrrrrBislinkr0rr&s r( test_islinkzFakePathModuleTest.test_islinksl ""5))) ##$6777 &&'9>JJJ ))%00111  (();<<===  (();<<===  (()<==>>>  (()<==>>>  (();<<=== ))*<==>>> ))/::;;;;;r*cd|j_|jd|jdd||jddS)NFrrUzfoo!Bar)rrrIrr0rBrr&s r(test_is_link_case_sensitivez.FakePathModuleTest.test_is_link_case_sensitivesb,1) ""5))) &&y%888  ((3344444r*c||jd||jd||jd||jd|jd||jd||jd||jddS)NrjrrD!mount!!mounts!mount)rrBismountr0rrdr&s r( test_ismountzFakePathModuleTest.test_ismounts **2..///  ))#..///  ))$//000 **955666 ''111  ))(33444  )))44555  )))4455555r*cnd|j_||jd||jd||jd||jd|jd||jd||jddS)NTrc:!c:zz:!rr)rrHr0rBrrrdr&s r(test_ismount_with_drive_lettersz2FakePathModuleTest.test_ismount_with_drive_letterss(,%  ))#..///  ))%00111 **400111  ))%00111 ''111  ))(33444  )))4455555r*cd|j_||jd||jd||jd||jd||jddS)NTz!!a!z!!a!bz!!a!b!z!a!b!z!!a!b!c)rrHr0rBrrr&s r(test_ismount_with_unc_pathsz.FakePathModuleTest.test_ismount_with_unc_pathss(,%  ))&11222  ))'22333  ))(33444 **733444 **95566666r*cd|j_|jd||jd||jd||jdd|j_||jddS)Nrrrz!mount!!TzZ:!)ralternative_path_separatorrdr0rBrrHr&s r(*test_ismount_with_alternate_path_separatorz=FakePathModuleTest.test_ismount_with_alternate_path_separators582 ''111  ))(33444  )))44555  ))*55666(,%  ))%0011111r*c:|t|jddd}tjdkr |jrd}nd}|r)|t|j|d|t|jddS) z(Forwards any non-faked calls to os.path.r8zGet a faked os.path functionN)rRrq _get_bothseps_join_real_pathz;Get a real os.path function not implemented in fake os.path nonexistent)r0hasattrrBr version_infor r)r'private_path_functions r($test_getattr_forward_to_real_os_pathz7FakePathModuleTest.test_getattr_forward_to_real_os_paths  5113QRRR $  f $ $ :(7%%(9%   OO #899P    M::;;;;;r*c2d|j_|d|jd|d|jd|d|jddS)NF)rjrjrUrU)rjrrUrA)rj!!zfoo!!bar !!foo!!bar)rrHr5 splitrootr&s r(test_splitroot_posixz'FakePathModuleTest.test_splitroot_posixs(-% ,do.G.G .R.RSSS -t/H/H/T/TUUU  "DO$=$=l$K$K     r*N)3rrrr)r"r'r*r.r1r3r=rBrFrMrQunittestskipIfrrrVr[rrerirurwr|rrr r  is_cygwinrrrrrrrrrrrrrrrrrrrrr*r(rrps!!! III,,,---HHH222333   (FFF / / / E E E W W WX_S%/1NOO   PO  WWWEEE333 5 5 5>>>IIIEEEFFF   X_1x1%BB B))) ::: @@@YYYYYY;;; 0 0 0<<<BBB111 <<<$555666666777222<<<      r*rceZdZdZdS)PathManipulationTestBasec:tjd|_dS)N|rrrrr&s r(r)zPathManipulationTestBase.setUps)8LLLr*N)rrrr)rr*r(rrs(MMMMMr*rcTeZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd S)CollapsePathPipeSeparatorTestzKTests CollapsePath (mimics os.path.normpath) using | as path separator.cb|d|jddS)Nrrjr5rnormpathr&s r( test_empty_path_becomes_dot_pathz>CollapsePathPipeSeparatorTest.test_empty_path_becomes_dot_paths. do66r::;;;;;r*cb|d|jddSrrr&s r(test_dot_path_unchangedz5CollapsePathPipeSeparatorTest.test_dot_path_unchanged. do66s;;<<<<%>t%D%DEEEEEr*cb|d|jddS)zMTests that '/' is not treated specially if the path separator is '|'.)rja/brNrr&s r(test_slashes_do_not_splitz'SplitPathTest.test_slashes_do_not_splits0 do&?&?&F&FGGGGGr*c|d|jd|d|jd|d|jd|d|jd|d|jd dS) N)rwba|bza|||b)|ar|a||b)rca|b|c)z|a|brz|a|b|crr&s r(,test_eliminate_trailing_separators_from_headz:SplitPathTest.test_eliminate_trailing_separators_from_heads T_%>%>u%E%EFFF T_%>%>w%G%GHHH do&?&?&H&HIII t'@'@'I'IJJJ (A(A((K(KLLLLLr*c|d|jd|d|jd|d|jddS)N)|||rjr)rrwr)rrwz|||arr&s r(#test_root_separator_is_not_strippedz1SplitPathTest.test_root_separator_is_not_stripped&sz do&?&?&F&FGGG T_%>%>t%D%DEEE t'@'@'H'HIIIIIr*cb|d|jddS)N)rrja|b|rr&s r()test_empty_tail_if_path_ends_in_separatorz7SplitPathTest.test_empty_tail_if_path_ends_in_separator+s. do&?&?&G&GHHHHHr*cb|d|jddS)N)rrz|a||b||crr&s r(0test_empty_path_components_are_preserved_in_headz>SplitPathTest.test_empty_path_components_are_preserved_in_head.s. )B)B:)N)NOOOOOr*N) rrrrrrrrrrrrr*r(rrs""BBBFFFHHH MMMJJJ IIIPPPPPr*rcHeZdZdZdZdZdZdZdZdZ dZ d Z d Z d S) JoinPathTestzETests JoinPath (which mimics os.path.join) using | as path separator.cb|d|jddSrr5rr;r&s r(test_one_empty_componentz%JoinPathTest.test_one_empty_component5s. T_66r::;;;;;r*cf|d|jddddSrr r&s r(test_multiple_empty_componentsz+JoinPathTest.test_multiple_empty_components8s2 T_66r2rBBCCCCCr*cb|d|jddS)Nz||a||r r&s r(2test_separators_not_stripped_from_single_componentz?JoinPathTest.test_separators_not_stripped_from_single_component;s. $/";";G"D"DEEEEEr*c h|d|jdddddS)Nza|b|c|drwrrdr r&s r(+test_one_separator_added_between_componentsz8JoinPathTest.test_one_separator_added_between_components>s4 DO$=$=c3S$Q$QRRRRRr*c|d|jddd|d|jddddS)Nra|b|rz a|||b|||cza|||zb|||r r&s r(:test_no_separator_added_for_components_ending_in_separatorzGJoinPathTest.test_no_separator_added_for_components_ending_in_separatorAs] $/";";D$"L"LMMM do&?&?PS&T&TUUUUUr*c h|d|jdddddS)Nz|c|drwz|bz|crr r&s r(8test_components_preceding_absolute_component_are_ignoredzEJoinPathTest.test_components_preceding_absolute_component_are_ignoredEs4 !:!:3dC!P!PQQQQQr*c|d|jdd|d|jddddS)Nrrwrjr r&s r(6test_one_separator_added_for_trailing_empty_componentszCJoinPathTest.test_one_separator_added_for_trailing_empty_componentsHsZ t88bAABBB t88b"EEFFFFFr*cd|d|jdddS)Nrwrjr r&s r(4test_no_separator_added_for_leading_empty_componentszAJoinPathTest.test_no_separator_added_for_leading_empty_componentsLs0 do77C@@AAAAAr*c|d|jddd|d|jddddS)Nrrwrjrrrrr r&s r(&test_internal_empty_components_ignoredz3JoinPathTest.test_internal_empty_components_ignoredOs\  9 9#r3 G GHHH !:!:4T!J!JKKKKKr*N) rrrrr rrrrrrrr rr*r(r r 2sOO<<<DDDFFFSSSVVVRRRGGGBBBLLLLLr*r ceZdZdZdS)PathSeparatorTestctjd}tj|}|d|j|d|jjdSr)rrrrr5r8rB)r'rrs r(2test_os_path_sep_matches_fake_filesystem_separatorzDPathSeparatorTest.test_os_path_sep_matches_fake_filesystem_separatorUs`$33GGG  -j99 n0111 n1566666r*N)rrrr$rr*r(r"r"Ts#77777r*r"cfeZdZdZdZdZdZeje j ddZ dS)NormalizeCaseTestcRtjd|_d|j_dSr)rrrrr&s r(r)zNormalizeCaseTest.setUp]s')8LLL,1)))r*c&|jd||jjd|jd||jjd|jddS)Nrrrz/FOO/BAR)rrr5r@_original_pathr&s r(test_normalize_casez%NormalizeCaseTest.test_normalize_caseas ##J/// , 5 5 5 O * *: 6 6    , 5 5 5 O * *: 6 6     r*c d|j_|jd|d|jd|d|jddS)NTz C:/Foo/Barz c:/foo/barz C:/FOO/BAR)rrHrr5r)r&s r(test_normalize_case_for_drivez/NormalizeCaseTest.test_normalize_case_for_drivelst(,% ##L111 t'E'El'S'STTT t'E'El'S'STTTTTr*c&|jd||jjd|jd||jjd|jddS)Nrz Foo/Bar/bazrPz Foo/Bar/BAZz /FOO/BAR/BAZ)rrIr5r@r)r&s r()test_normalize_case_for_non_existing_filez;NormalizeCaseTest.test_normalize_case_for_non_existing_filers "":... , 9 9 9 O * *> : :    , 9 9 9 O * *> : :     r*z(Regression test for Windows problem onlyctj}tjtjtjtd}||tj |d}| || | dS)Nr __init__.py) rrrrBr7rjr__file__add_real_directoryr:r5r)upper)r'r real_dir_path initPyPaths r(/test_normalize_case_for_lazily_added_empty_filezANormalizeCaseTest.test_normalize_case_for_lazily_added_empty_file}s %355  bgoobgooh6O6O&P&PQQRST %%m444W\\-??  Z%>%>z?O?O?Q?Q%R%RSSSSSr*N) rrrr)r*r,r.rrr r r6rr*r(r&r&\s222    UUU    X_  !KTTTTTr*r&c2eZdZdZdZdZdZdZdZdS)AlternativePathSeparatorTestcRtjd|_d|j_dS)Nrr?)rrrrr&s r(r)z"AlternativePathSeparatorTest.setUps')8LLL58222r*ctj}|jr|d|jn||jtjd}||jdSr)rrr r5r assertIsNoners r(test_initial_valuez/AlternativePathSeparatorTest.test_initial_values~$355 ? E   S*"G H H H H   jC D D D$33GGG  *?@@@@@r*ctj|j}|d|j|d|jjdS)Nr:)rrrr5altseprB)r'rs r( test_alt_sepz)AlternativePathSeparatorTest.test_alt_sepsO -do>> n3444 n1899999r*cb|d|jddS)NrAz !foo??barrr&s r((test_collapse_path_with_mixed_separatorszEAlternativePathSeparatorTest.test_collapse_path_with_mixed_separatorss. T_%=%=k%J%JKKKKKr*cd}||jjd|j|dS)Nz foo?..?barrrrs r()test_normalize_path_with_mixed_separatorszFAlternativePathSeparatorTest.test_normalize_path_with_mixed_separatorssM , 1 1 1 O ' ' - -     r*c"|jd|jd||jd||jddS)Nz ?foo?bar?bazz!foo!bar!xyzzy!plughr5z?foo?bar?xyzzy?plugh)rrr0rr&s r(!test_exists_with_mixed_separatorsz>AlternativePathSeparatorTest.test_exists_with_mixed_separatorssz ##N333 ##$:;;; ..~>>??? ../EFFGGGGGr*N) rrrr)r=r@rBrDrFrr*r(r8r8sy999AAA::: LLL   HHHHHr*r8ceZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZdZdZdZdZdZdZdZdZdZdZdS)DriveLetterSupportTestcjtjd|_d|j_d|j_dS)Nrr^T)rrrrrHr&s r(r)zDriveLetterSupportTest.setUps1)8LLL582(,%%%r*ctj}|jr||jdS||jdSr,)rrr r0rHrrs r(r=z)DriveLetterSupportTest.test_initial_valuesR$355 ? 7 OOJ4 5 5 5 5 5   Z5 6 6 6 6 6r*cb|d|jddS)Nrlz c:!!foo!!barrr&s r(test_collapse_pathz)DriveLetterSupportTest.test_collapse_paths. t'?'?'O'OPPPPPr*cb|d|jddS)N !!foo!bar!bazz!!foo!bar!!baz!!rr&s r(test_collapse_unc_pathz-DriveLetterSupportTest.test_collapse_unc_paths/ $/*B*BCU*V*VWWWWWr*cd|j_|d|jdd|j_|d|jddS)Nrjrlz c:!foo!!barrkrrr&s r(test_normalize_path_strz.DriveLetterSupportTest.test_normalize_path_strsh  t'B'B='Q'QRRR& t'B'B5'I'IJJJJJr*cd|j_|d|jdd|j_|d|jddS)Nr* c:!foo!bars c:!foo!!barrnr~rr&s r(test_normalize_path_bytesz0DriveLetterSupportTest.test_normalize_path_bytessh! (C(CN(S(STTT' (C(CF(K(KLLLLLr*c|d|jd|d|jd|d|jd|d|jd|d |jd |d |jd |d |jddS)N)rkrrl)rrrk)rorrA)rrro)rqrrr)rrrq)rrrUrr&s r(test_split_path_strz*DriveLetterSupportTest.test_split_path_strs *DO,E,El,S,STTT )B)B8)L)LMMM $/*C*CJ*O*OPPP t'@'@'H'HIII )4?+D+D[+Q+QRRR (A(A'(J(JKKK )B)B9)M)MNNNNNr*c.|d|jd|d|jd|d|jd|d|jd|d|jd |d|jd dS) N)za^brza^b^c)za^b!crza^b!c^dza^b!c!d)sa^bcsa^b^c)sa^b!cdsa^b!c^dsa^b!c!drr&s r(test_split_with_alt_separatorz4DriveLetterSupportTest.test_split_with_alt_separators t'@'@'I'IJJJ )B)B9)M)MNNN )B)B9)M)MNNN )B)B8)L)LMMM )4?+D+DZ+P+PQQQ )4?+D+DZ+P+PQQQQQr*c|d|jd|d|jd|d|jd|d|jd|d |jd |d |jd |d |jddS)N)rnr~rT)rmr,rn)rpr~!foo!bar)rDr,rp)rtr~s c:foo!bar)rsr,rt)r,r~rrr&s r(test_split_path_bytesz,DriveLetterSupportTest.test_split_path_bytess ,do.G.G .V.VWWW )4?+D+DY+O+OPPP *DO,E,Ek,R,RSSS )B)B7)K)KLLL +T_-F-F|-T-TUUU $/*C*CH*M*MNNN )4?+D+DZ+P+PQQQQQr*cf|d|jddddS)Nzc:drrrr r&s r(1test_characters_before_root_ignored_in_join_pathszHDriveLetterSupportTest.test_characters_before_root_ignored_in_join_pathss2  9 9#tS I IJJJJJr*cb|d|jddS)Nr@)r5rrr&s r(rz(DriveLetterSupportTest.test_resolve_paths. t'C'CL'Q'QRRRRRr*c|gd|jd|dg|jddS)N)rrrrlrrr&s r(test_get_path_componentsz/DriveLetterSupportTest.test_get_path_componentssf  O , ,\ : :    $!A!A$!G!GHHHHHr*cv|d|jd|d|jd|d|jd|d|jddS) N)rrArl)rjrArA)rrUrr)rjrUrUr5r splitdriver&s r(test_split_drive_strz+DriveLetterSupportTest.test_split_drive_strs +T_-G-G -U-UVVV )4?+E+Ej+Q+QRRR *DO,F,F{,S,STTT $/*D*DY*O*OPPPPPr*c|d|jd|d|jddS)N)rsr]rT)r*r]r]rer&s r(test_split_drive_bytesz-DriveLetterSupportTest.test_split_drive_bytess^  $/"<"<]"K"K    +T_-G-G -T-TUUUUUr*c.|d|jd|d|jd|d|jd|d|jd|d |jd |d |jd dS) N)rz^foo^barz c:^foo^bar)rjfoo^barrk)rj foo^bar!bazrl)rs^foo^bars c:^foo^bar)r*rmrm)r* ^foo^bar!bazrnrer&s r(test_split_drive_alt_sepz/DriveLetterSupportTest.test_split_drive_alt_seps +T_-G-G -U-UVVV $/*D*DY*O*OPPP ,do.H.H.W.WXXX  $/"<"<]"K"K    +T_-G-G -T-TUUU  "DO$>$>$O$O     r*cv|d|jd|d|jd|d|jd|d|jddS) N) !!foo!bar!bazrO)rj!!foors)rjrr)rqr !!foo!bar!!rer&s r(test_split_drive_with_unc_pathz5DriveLetterSupportTest.test_split_drive_with_unc_path   !4?#=#=o#N#N    (B(B7(K(KLLL +T_-G-G -U-UVVV ,do.H.H.W.WXXXXXr*cv|d|jd|d|jd|d|jd|d|jddS) N) ^^foo^barrrz ^^foo^bar!baz)rj^^foory)rj ^^foo^^barrz)rxz^^ ^^foo^bar^^rer&s r(&test_split_drive_with_unc_path_alt_sepz=DriveLetterSupportTest.test_split_drive_with_unc_path_alt_seprvr*c|d|jd|d|jd|d|jd|d|jd|d |jd dS) N)d:!foor d:!foo!baz)rrjz d:!foo!baz!rrjr)rrjr)c:!!rjrrr&s r(test_split_path_with_drivez1DriveLetterSupportTest.test_split_path_with_drive *DO,E,El,S,STTT +T_-F-F}-U-UVVV T_%>%>t%D%DEEE do&?&?&F&FGGG t'@'@'H'HIIIIIr*c|d|jd|d|jd|d|jd|d|jd|d |jd dS) N)zd:^foor d:^foo^baz)rrjz d:^foo^baz^rr)c:^rjr)c:^^rjrrr&s r("test_split_path_with_drive_alt_sepz9DriveLetterSupportTest.test_split_path_with_drive_alt_sep#rr*c|d|jd|d|jd|d|jddS)N) !!foo!bar!rrO)rqrjrq)rtrjrtrr&s r(test_split_path_with_unc_pathz4DriveLetterSupportTest.test_split_path_with_unc_path*  !4?#<#<_#M#M    *DO,E,Ek,R,RSSS ,do.G.G .V.VWWWWWr*c|d|jd|d|jd|d|jddS)N)z ^^foo^bar^r ^^foo^bar^baz)rxrjrx)r{rjr{rr&s r(%test_split_path_with_unc_path_alt_sepz.create_too_large_fileis=#.. 3$ 3*q.1222 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3sAAArrrrw) rrdrXrLr5get_disk_usageusedrr)r'rrrs` @r( test_disk_usage_on_file_creationz.DiskSpaceTest.test_disk_usage_on_file_creationes  *555 3 3 3 3 3 3  w ' ' $ $ ! ! # # # $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ DG228<<ABBB YY}c * * )d JJsZ' ( ( ( ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) TW%;%;H%E%E%JKKKKKs$ AAA+CCCcpd|j_|jd|jdd|d|jdjd |j_|d|jd jdS) NTrrrArrrzD:!zE:!fooro)rrHresetrr5rrrr&s r($test_disk_usage_on_automounted_drivez2DiskSpaceTest.test_disk_usage_on_automounted_drivews $   %%% J333 DG22599>???  DG226::?@@@@@r*c|jdd|jdd|jdd|jd d |jd d |d|jd j|d |jdj|d |jdj|d|jdjdS)NrorrrAirrrr!foo!bazrr5rr)rrdrr5rrtotalr&s r( test_disk_usage_on_mounted_pathsz.DiskSpaceTest.test_disk_usage_on_mounted_pathss3 3777  s;;; FB/// J333 NC888 TW33C88=>>> TW33F;;@AAA dg44Z@@EFFF dg44Z@@FGGGGGr*ctjdd}|dd|d|dS)Nrdrr r)rrlZ)rrrr5rrs r(/test_file_system_size_after_large_file_creationz=DiskSpaceTest.test_file_system_size_after_large_file_creationss$3+C    z3JKKK    % % ' '      r*c|jdd|d|jdS)NrAxyzzyr)r_rrr5rr&s r(0test_file_system_size_after_binary_file_creationz>DiskSpaceTest.test_file_system_size_after_binary_file_creationsG J::: tw'='='?'?@@@@@r*c|jdd|d|jdS)NrA complicatedr)r Yrr&s r(6test_file_system_size_after_ascii_string_file_creationzDDiskSpaceTest.test_file_system_size_after_ascii_string_file_creationsG J??? (>(>(@(@AAAAAr*c|jddd|d|jdS)NrAu сложноutf-8rencoding)r Xrr&s r(6test_filesystem_size_after_2byte_unicode_file_creationzDDiskSpaceTest.test_filesystem_size_after_2byte_unicode_file_creationsI J'RRR (>(>(@(@AAAAAr*c|jddd|d|jdS)NrAu複雑rr)rrq^rr&s r(6test_filesystem_size_after_3byte_unicode_file_creationzDDiskSpaceTest.test_filesystem_size_after_3byte_unicode_file_creationsI JGLLL tw'='='?'?@@@@@r*c|jdd|jdd|jd|d|jdS)NrArrrrr)rrPrrr*r5rr&s r()test_file_system_size_after_file_deletionz7DiskSpaceTest.test_file_system_size_after_file_deletionsx J::: J333 j))) (>(>(@(@AAAAAr*c<|jdd|jdd|jdd|jd|d |jdS) NrArrrr !foo1!barrro)rrrrr&s r(-test_file_system_size_after_directory_removalz;DiskSpaceTest.test_file_system_size_after_directory_removals J333 J333 K444 f%%% (>(>(@(@AAAAAr*c2|j} |jddn%#t$r|dYnwxYw||jdz|jjdS)NrAdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaar@File with contents fitting into disk space could not be written.rrrrrLfailr5rr' initial_usages r('test_creating_file_with_fitting_contentz5DiskSpaceTest.test_creating_file_with_fitting_contents..00   G   Z  @ @ @ @    IIU       +c1473I3I3K3K3PQQQQQ8AAcfd}j}t5|dddn #1swxYwY|jdS)Nc@jdddS)NrAseaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarrrr&sr(create_large_filezRDiskSpaceTest.test_creating_file_with_content_too_large..create_large_files$ G   Z  @ @ @ @ @r*rrrXrLr5)r'rrs` r()test_creating_file_with_content_too_largez7DiskSpaceTest.test_creating_file_with_content_too_larges A A A A A..00   w ' '                      (>(>(@(@AAAAA AAAc2|j} |jddn%#t$r|dYnwxYw||jdz|jjdS)NrArrz.create_large_files$ G   C  8 8 8 8 8r*r)r'rrs` r(&test_creating_file_with_size_too_largez4DiskSpaceTest.test_creating_file_with_size_too_larges..00  9 9 9 9 9  w ' '                      (>(>(@(@AAAAArc|jdd} |d|ddS#t$r|dYdSwxYw)NrArrrrz8Resizing file failed although disk space was sufficient.)rrrryrLrr' file_objects r("test_resize_file_with_fitting_sizez0DiskSpaceTest.test_resize_file_with_fitting_sizesg))*b)AA  R  + +C 0 0 0  $ $Z 0 0 0 0 0 R R R IIP Q Q Q Q Q Q Rs*A A-,A-cp|jdd}|tj5|ddddn #1swxYwY|tj5|dddddS#1swxYwYdS)NrArrrږaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)rrr^r_r`rryrs r($test_resize_file_with_size_too_largez2DiskSpaceTest.test_resize_file_with_size_too_larges)g))*b)AA  ! !%, / / 1 1  + +C 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1  ! !%, / / 0 0  $ $Y / / / 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0s#AA"%A"B++B/2B/c|jdd|jdd|d|jjdS)NrArrrorrrrrrenamer5rrr&s r(,test_file_system_size_after_directory_renamez:DiskSpaceTest.test_file_system_size_after_directory_renames` J333 vv&&& TW3355:;;;;;r*c|jdd|jdd|d|jjdS)NrArrrrr&s r('test_file_system_size_after_file_renamez5DiskSpaceTest.test_file_system_size_after_file_renames` J333 z:... TW3355:;;;;;r*ctd}d}|j|d|d|jj|j|||d|jj|j||d|jj|j||d|jjdS)N test_file1 test_file2rrr)rrr5rrrlinkunlink)r' file1_path file2_paths r(-test_that_hard_link_does_not_change_used_sizez;DiskSpaceTest.test_that_hard_link_does_not_change_used_sizes ! !  J333 TW3355:;;;  Z,,, TW3355:;;; z""" TW3355:;;; z""" DG22449:::::r*c|jdd|jd|tj5|jdddddn #1swxYwY|tj5|jdd dddn #1swxYwY |jd d|jdd |jd d dS#t $r|dYdSwxYw)Nz!mount_limitedrrz!mount_unlimitedz!mount_limited!foorr!barrrorz!mount_unlimited!fooi@Br)rrdr^r_r`rrLrr&s r(1test_that_the_size_of_correct_mount_point_is_usedz?DiskSpaceTest.test_that_the_size_of_correct_mount_point_is_used s  0R@@@  2333  ! !%, / / B B G   4b  A A A B B B B B B B B B B B B B B B  ! !%, / / 5 5 G    4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5  G    3 3 3 G   4b  A A A G   6  H H H H H    IIU       s7A??BB)CCCAD44EEcP|jdd|jdd|jdd|jd d|jd d|d |jd j|d|jd j|d|jdjdS)N!mount1rrz!mount1!bar!mount2rrArrz!mount1!foo!barz!mount1!bar!mount2!foo!barrro !mount1!foor)rrdrr5rfreer&s r(3test_that_disk_usage_of_correct_mount_point_is_usedzADiskSpaceTest.test_that_disk_usage_of_correct_mount_point_is_useds  b999  4DDD J333 -r::: 8"EEE TW33F;;@AAA TW33MBBGHHH TW334HIINOOOOOr*c|jdd|tj5|jdddddn #1swxYwY|jdd|jdd|d|jdj dS) NrrrrrrrrrB) rrdr^r_r`rset_disk_usager5rrr&s r(test_set_larger_disk_sizez'DiskSpaceTest.test_set_larger_disk_size's  b999  ! !%, / / < < G   s  ; ; ; < < < < < < < < < < < < < < < #I>>> M3777 dg44]CCHIIIIIsA%%A),A)c|jdd|jdd|tj5|jdddddn #1swxYwY|jd d|d|jdj dS) Nrrrrrrrr) rrdrr^r_r`rr5rrr&s r(test_set_smaller_disk_sizez(DiskSpaceTest.test_set_smaller_disk_size/s  c::: M3777  ! !%, / / B B G " "by " A A A B B B B B B B B B B B B B B B #I>>> TW33MBBGHHHHHsBBBc|jd|jdd|jdd|d|jdjdS)Nrrrrr)rrdrrr5rrr&s r( test_disk_size_on_unlimited_diskz.DiskSpaceTest.test_disk_size_on_unlimited_disk7s}  *** M3777 $Y??? dg44]CCHIIIIIr*cd|j_|jdd|jdd||jdjd dS) NT d:!foo!barrrr d:rr~r )rrHrrr5rrr&s r(5test_disk_size_on_auto_mounted_drive_on_file_creationzCDiskSpaceTest.test_disk_size_on_auto_mounted_drive_on_file_creation=sq $ L#666 $T::: //99>DDDDDr*c`d|j_|jd|jdd|jdd|jdd |d |jd jdS) NTrzd:!foo!bar!bazrrrr rri r~)rrHrIrrr5rrr&s r(:test_disk_size_on_auto_mounted_drive_on_directory_creationzHDiskSpaceTest.test_disk_size_on_auto_mounted_drive_on_directory_creationDs $ <((( ,c::: L#666 $T::: dg44X>>CDDDDDr*c|jdd}|jd}||j||j|jdS)Nrs somebytesrr)rrryrr5)r' source_file dest_files r($test_copying_preserves_byte_contentsz2DiskSpaceTest.test_copying_preserves_byte_contentsLsjg))%,)GG G''.. {3444 +[-ABBBBBr*c|dd5}|d|dddn #1swxYwY|d|jddS)Nbar.txtrD' D>'D+ +D>.D+ /D>2 E>E EE EEE5)F++F/2F/c|dd5}|ddddn #1swxYwY|d5}||ddddn #1swxYwY|t j5|dd5}|d|d|t j5|dddn #1swxYwYdddn #1swxYwYdddn #1swxYwY|d5}||dddddS#1swxYwYdS)Nrrrzr+r >ED> E E(E E(E E((E,/E,)F>>GGN)#rrrr)rrrrrrrrrrrrrrrrrrrrrrr rrrrrr"r%r)rr*r(rr_s3444 LLL$AAA H H H    AAABBBBBBAAABBB BBB R R R B B BRRR B B BRRR000<<< <<< ; ; ;$ P P PJJJIIIJJJ EEEEEECCC ::: + + + 1 1 1 1 1 1 1 1r*rcDeZdZdZdZdZdZdZdZdZ dZ d Z d S) MountPointTestc<tjdd|_dSrrr&s r(r)zMountPointTest.setUps$)83   r*c|jd|jd|jddS)Nrorr)rrdr&s r(add_mount_pointszMountPointTest.add_mount_pointssJ ''/// ''/// '' 33333r*c||d|jdj|d|jdj|d|jdj|d|jdjdS) NrrrrorRrr)r.r5rrJst_devr&s r(0test_that_new_mount_points_get_new_device_numberz?MountPointTest.test_that_new_mount_points_get_new_device_numbers  DO66s;;BCCC DO66v>>EFFF DO66v>>EFFF DO66zBBIJJJJJr*c`||d|jdj|d|jdj|d|jdjdSNrrrrAr0z!foo!baz!foo!bar)r.r5rrIr1r&s r(3test_that_new_directories_get_correct_device_numberzBMountPointTest.test_that_new_directories_get_correct_device_numbers  DO66{CCJKKK DO66zBBIJJJ DO667IJJQRRRRRr*c`||d|jdj|d|jdj|d|jdjdSr4)r.r5rrr1r&s r(-test_that_new_files_get_correct_device_numberzr@rr*r(r+r+s   444 KKKSSS TTT 555 M M M M M MTTTTTr*r+ceZdZdZdZdS)ConvenienceMethodTestc||d}|dd}|j|d||j|jd|j||||j|jd| |j |dS)Nrrrz link testrrr) skip_if_symlink_not_supported make_pathrrr5rr1st_nlink create_linkr0rr'rrs r()test_create_link_with_non_existent_parentz?ConvenienceMethodTest.test_create_link_with_non_existent_parents **,,,^^L11 NN=,??  ##J#EEE j11:A>>> ##J ::: j11:A>>> ..y99:::::r*c||d}|dd}|j|d|j||||j|||j|dS)Nrrrz symlink testr)rDrErrrr0rrrHs r(,test_create_symlink_with_non_existent_parentzBConvenienceMethodTest.test_create_symlink_with_non_existent_parents **,,,^^L11 NN=,??  ##J#HHH &&y*=== ..y99::: ..y99:::::r*N)rrrrIrKrr*r(rBrBs2 ; ; ;;;;;;r*rBceZdZdZdZdZdZdZddZdZ d Z d Z d Z d Z d ZdZdZdZejdZdZdZdZdZdZdZdZdZdZdZdZdS)RealFileSystemAccessTestctj|_tj|j|_t jt jt j td|_ t j|j d|_ dSr ) rrrrrrrBr7rjrr1 pyfakefs_path root_pathr&s r(r)zRealFileSystemAccessTest.setUps)8::(5doFFW]]27??27??8;T;T+U+UVV  t'9::1=r*c8tjdd}|t5|j|dddn #1swxYwY||j|dS)N nonexistingztest.txt) rrBr:rXrLr add_real_filerrr'nonexisting_paths r(&test_add_non_existing_real_file_raisesz?RealFileSystemAccessTest.test_add_non_existing_real_file_raisess7<< zBB   w ' ' < < O ) )*: ; ; ; < < < < < < < < < < < < < < < //0@AABBBBBsA""A&)A&cd}|tj5|j|dddn #1swxYwY||j|dS)Nz /nonexisting)r^r_r'rr2rrrTs r(+test_add_non_existing_real_directory_raiseszDRealFileSystemAccessTest.test_add_non_existing_real_directory_raisess)  ! !%, / / A A O . ./? @ @ @ A A A A A A A A A A A A A A A //0@AABBBBBsA  A A ct}|j||tj5|j|ddddS#1swxYwYdSr,)r1rrr^r_rXrSr'real_file_paths r(test_existing_fake_file_raisesz7RealFileSystemAccessTest.test_existing_fake_file_raisess! ##N333  ! !%, / / : : O ) ). 9 9 9 : : : : : : : : : : : : : : : : : :rc|j|j|tj5|j|jddddS#1swxYwYdSr,)rrIrPr^r_rXr2r&s r(#test_existing_fake_directory_raisesz222  ! !%, / / ? ? O . .t~ > > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?s A,,A03A0Nc|||kr.||j|nZ||j|||j|t j|}||j||j |j | |j |j d| |j |j d| |j |j d||j|j||j|jdS)Nr)places)r0rrrrr1r<_byte_contentsr5rassertAlmostEqualst_ctimest_atimerrxry)r'r#r[rB real_stats r(check_fake_file_statz-RealFileSystemAccessTest.check_fake_file_stats`  +"?"? OODO22>BB C C C C   T_33NCC D D D OODO22;?? @ @ @GN++  )2333 *I,=>>> y193EaPPP y193EaPPP y193EaPPP )9+;<<< )9+;<<<<RealFileSystemAccessTest.test_add_existing_real_file_read_only&sz22O11.AA  !!)^<<< *U2A666 !!)^<<<<>> ..t/ABBCCC  O " " T/1EFF      O " "27<<0BDU#V#V W W   GLL!35PQQ O++I66  !!)Y777 !!)Y77777r*c ,|j|j||jt j|jddd||jt j|jdd||jt j|jdddS)Npyfakefstestsfake_filesystem_test.pyrr0)rr2rPr0rrrBr:r&s r(%test_add_existing_real_directory_treez>RealFileSystemAccessTest.test_add_existing_real_directory_tree]s **4>:::  O " " N-      O " " T^Z9MNN      O " " T^ZGG       r*c#K|D]#}tj|d|d$dV|D]}tj|ddS)Nrr)rrr)r'symlinksrs r(create_symlinksz(RealFileSystemAccessTest.create_symlinkstsk ) )D JtAwQ ( ( ( (   D Id1g      r*c @ tj|j}tj|jdd}dtj|ddfdtj|ddf|tj|ddftj|d tj|dd fd tj|dd fg}|jd |d d 5}|ddddn #1swxYwY | |5|j |ddddn #1swxYwYn*#t$r|j rtjdwxYw|D]5}||j|d6||jtj|jddd||jtj|jddd||jtj|jddd||jtj|jddd||jtj|jddd||jtj|jddd||jtj|jddd||tj|jdddddS)Nrrr6fixturessymlink_dir_relative../all_tests.pysymlink_file_relativesymlink_dir_absolutez all_tests.pysymlink_file_absolutez/etc/somethingsymlink_file_absolute_outsiderz good morningF lazy_readz,Symlinks under Windows need admin privilegesrzfixtures/symlink_dir_relativez*fixtures/symlink_dir_relative/all_tests.pyzfixtures/symlink_file_relativezfixtures/symlink_dir_absolutez*fixtures/symlink_dir_absolute/all_tests.pyzfixtures/symlink_file_absolutez&fixtures/symlink_file_absolute_outside)rrrrrBr:rPrrrr2rLr rSkipTestr0rrr5r)r'rreal_directoryrrrs r((test_add_existing_real_directory_symlinkzARealFileSystemAccessTest.test_add_existing_real_directory_symlink~s #0AA dnj'JJ ^Z9OPP  " ^Z9PQQ   ^Z9OPP   ^^<< ^Z9PQQ  ! "J0O # 2 ##$4555 Y' - - $ GGN # # # $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ %%h// T T22>U2SSS T T T T T T T T T T T T T T T    X'(VWWW    = =D OODO2247;; < < < <  O " " N3      O " " N@      O " " N4      O " " N3      O " " N@      O " " N4      O " " N<      I N<   dff  sB0EEEF(3F F(F  F(#F $F(('Gc|dtj|jdd}dtj|ddfdtj|dd fg}||5|j|d d dddn #1swxYwY||j d ||j d||j ddS)NT force_real_fsrrr6rrrr/pathFrBr#/path/fixtures/symlink_dir_relative0/path/fixtures/symlink_dir_relative/all_tests.py$/path/fixtures/symlink_file_relative rDrrBr:rPrrr2r0rr'rrs r(4test_add_existing_real_directory_symlink_target_pathzMRealFileSystemAccessTest.test_add_existing_real_directory_symlink_target_path s ***>>>dnj'JJ ^Z9OPP  " ^Z9PQQ    ! !( + +   O . .Gu /                   ../TUUVVV  O " "#U V V    ../UVVWWWWWsCC Cc|dtj|jdd}dtj|ddfdtj|dd fg}||5|j|d d ||j d ||j d ||j dddddS#1swxYwYdS)NTrrrr6rrrrrrrrrrrs r(2test_add_existing_real_directory_symlink_lazy_readzKRealFileSystemAccessTest.test_add_existing_real_directory_symlink_lazy_read s ***>>>dnj'JJ ^Z9OPP  " ^Z9PQQ    ! !( + +   O . .Gt /    OO&&'LMM    OO&&F    OO&&'MNN                     sB%E  EEc|jd|tj5|j|jdddddS#1swxYwYdSrz)rrIr^r_rXr2rPr&s r(6test_add_existing_real_directory_tree_to_existing_pathzORealFileSystemAccessTest.test_add_existing_real_directory_tree_to_existing_path9 s "":...  ! !%, / / W W O . .t~: . V V V W W W W W W W W W W W W W W W W W Ws"A))A-0A-c |j|jd||jt j|jdd| |jt jddddd||jt j|jdd| |jt jdddd dS) Nrr{rrrrrrr0) rr2rPrrrrBr:rOr0r&s r(3test_add_existing_real_directory_tree_to_other_pathzLRealFileSystemAccessTest.test_add_existing_real_directory_tree_to_other_path> sI **4>z*RRR  O " " T/:STT      O " " -      O " " T^Z9MNN      O " " UE:}EE       r*c d|j_|j|j||jt j|jdd||jt j|jdddS)NTrrr0) rrr2rPr0rJrrBr:r&s r(0test_get_object_from_lazily_added_real_directoryzIRealFileSystemAccessTest.test_get_object_from_lazily_added_real_directory[ s,0) **4>:::  O & & T^Z9MNN      O & & T^ZGG       r*c d}tj|jd}|j|||j||||j|j | |j tj|d| ||j|j dS)N@rr) rrBr:rPrrr2r5rrr0rJ assertGreater)r' disk_sizer4s r('test_add_existing_real_directory_lazilyz@RealFileSystemAccessTest.test_add_existing_real_directory_lazilyi s&  T^Z@@  &&y-@@@ **=999 DO$B$B=$Q$Q$VWWW  O & & ],@AA      t55mDDI     r*cd}|j||j|j|jd|||j|jjdS)NrFr)rrrOr2rrr)r'rs r(+test_add_existing_real_directory_not_lazilyzDRealFileSystemAccessTest.test_add_existing_real_directory_not_lazily} s&  &&y$2DEEE **4+=*OOO  t55d6HIIN     r*c|j|jd||j|j||jt j|jd||jt j|jdt j|jd}|j|}| ||| ||dS)NFrvrrzpytest_plugin.py) rr2rOr0rrrBr:rrfrprs r(+test_add_existing_real_directory_read_writezDRealFileSystemAccessTest.test_add_existing_real_directory_read_write s( **4+=*OOO ..t/ABBCCC  O " " T/1EFF      O " "27<<0BDU#V#V W W   GLL!35GHH O++I66  !!)Y777   I66666r*c*tjt}tj|jdd}|j||g|j|}| ||| ||tj|d}|j|}| ||| ||dS)Nrrmodule_with_attributes.py) rrBrPr1r:rOradd_real_pathsrrfrkr'r[ fixture_pathr#s r(&test_add_existing_real_paths_read_onlyz?RealFileSystemAccessTest.test_add_existing_real_paths_read_only s))(33w||D$6LL  && 'EFFFO++N;;  !!)^<<< !!)^<<<l4OPPO++N;;  !!)^<<< !!)^<<<<>>CCC CCC ::: ??? ====    1 1 1===<<<RRR UUU///888"   .A A A FXXX2>WWW    :       (    777" = = = < < < < .__side_effect s+/I (8C8LI 5 5 5r*)r)r'!_FileSideEffectTests__side_effectrs @r( side_effectzFileSideEffectTests.side_effect s6 ', $ M M M M Mr*ctj|_|jd|dS)Nr)r)rrrrrr&s r(r)zFileSideEffectTests.setUp s?)8:: ##OAQAQASAS#TTTTTr*ctj|j}d|_|dd5}|ddddn #1swxYwY||jdSNFrrr)rrrrrr0r'rhandles r(test_side_effect_calledz+FileSideEffectTests.test_side_effect_called s#0AA "' Y , ,  LL                   /00000AAActj|j}d|_|dd5}|ddddn #1swxYwY||jddSr)rrrrrr5rrs r(test_side_effect_file_objectz0FileSideEffectTests.test_side_effect_file_object s#0AA "' Y , ,  LL                   =uEEEEErN)rrrrr)rrrr*r(rr sXUUU 111FFFFFr*r__main__)/rrr_rr1rrrrrrpyfakefs.fake_filesystemrrrr r pyfakefs.helpersr pyfakefs.tests.test_utilsr r rrrrrrrrrrrrrr r"r&r8rHrr+rBrMrrmainrr*r(rsi+* 8888888888$#####IIIIIIIIII]F]F]F]F]FH]F]F]F@=====8===&!L!L!L!L!L!L!L!LHWWWWWHWWW0\H\H\H\H\HX\H\H\H~ N@N@N@N@N@N@N@N@b</</</</</h</</</~+B+B+B+B+BH+B+B+B\g g g g g g g g T MMMMMxMMM .U.U.U.U.U$<.U.U.UbPPPPP,PPPDLLLLL+LLLD77777777*T*T*T*T*T*T*T*TZ"H"H"H"H"H8"H"H"HJnXnXnXnXnXXnXnXnXb`1`1`1`1`1H`1`1`1F ATATATATATXATATATH;;;;;N;;;.V<V<V<V<V<~V<V<V zHMOOOOOr*tests/__pycache__/logsio.cpython-311.pyc000064400000001456150043321520014115 0ustar00 bg@dZdZdS)z Example module that is used for a regression test where a module with a name ending with "io" was skipped from patching (see #569). c~t|d5}|cdddS#1swxYwYdS)z4Return the contents of the given path as byte array.rbN)openread)pathfs f/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/tests/logsio.py file_contentsr s~ dD  Qvvxxs 266N)__doc__r rr s( r tests/__pycache__/fake_filesystem_unittest_test.cpython-311.pyc000064400000226633150043321520020777 0ustar00 bgdZddlZddlZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl Z ddlm Z ddl m Z mZddlZddlZddlmZmZddlmZddlmZmZmZmZddlmZejd krdd lmZm Z Gd d e Z!Gd de Z"Gddej Z#Gdde#Z$Gdde#Z%Gddej Z&Gdde#Z'ddl(Z)Gdde#Z*Gdde#Z+Gddej Z,Gdd ej Z-Gd!d"ej Z.Gd#d$ej Z/Gd%d&Z0Gd'd(ej Z1Gd)d*e j Z2Gd+d,ej Z3Gd-d.ej Z4Gd/d0ej Z5Gd1d2e j Z6Gd3d4ej Z7Gd5d6e j Z8Gd7d8e j ej9Z:Gd9d:ej Z;ejd krGd;de Z=Gd?d@ej Z>dAZ?GdBdCej Z@GdDdEej ZAe jBejCdFkdGGdHdIej ZDe jBejdJkdKGdLdMej ZEeFdNkre jGdSdS)OzL Test the :py:class`pyfakefs.fake_filesystem_unittest.TestCase` base class. N)Path)TestCasemock)fake_filesystem_unittestfake_filesystem)OSType)PatcherPausepatchfs PatchMode)module_with_attributes ) copy_tree remove_treec*eZdZdZedZdS) TestPatcherc.t5}|jddtd5}|}dddn #1swxYwY|d|ddddS#1swxYwYdSN/foo/bartestcontents)r fs create_fileopenread assertEqual)selfpatcherfrs }/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/tests/fake_filesystem_unittest_test.pytest_context_managerz TestPatcher.test_context_manager4s  YY /' J " ": " ? ? ?j!! $Q6688 $ $ $ $ $ $ $ $ $ $ $ $ $ $ $   VX . . .  / / / / / / / / / / / / / / / / / /s4,B A B A B #A $B  BBc|ddtd5}|}dddn #1swxYwY|d|dSr)rrrr)r fake_fsr"rs r#test_context_decoratorz"TestPatcher.test_context_decorator;sJ888 *   vvxxH                *****AA A N)__name__ __module__ __qualname__r$r r'r#rr3s>/// ++ W+++r-rceZdZeejddZejdedZdS)TestPatchfsArgumentOrderz os.systemc(|ddtd5}|}dddn #1swxYwY|d|t jd|ddSNrrrfoorrrrossystemassert_called_with)r r&patched_systemr"rs r#test_argument_order1z-TestPatchfsArgumentOrder.test_argument_order1D J888 *   vvxxH                *** %))%00000r(c(|ddtd5}|}dddn #1swxYwY|d|t jd|ddSr1r3)r r7r&r"rs r#test_argument_order2z-TestPatchfsArgumentOrder.test_argument_order2Nr9r(N)r)r*r+r rpatchr8r;r,r-r#r/r/Csv TZ 11 W1TZ  11 W111r-r/ceZdZdZdS)TestPyfakefsUnittestBasec.|dS)Set up the fake file systemN setUpPyfakefsr s r#setUpzTestPyfakefsUnittestBase.setUpZs r-N)r)r*r+rDr,r-r#r>r>Ys#r-r>c6eZdZdZdZdZdZdZdZdZ dS) TestPyfakefsUnittestzATest the `pyfakefs.fake_filesystem_unittest.TestCase` base class.c|tjdt dd5}|ddddn #1swxYwY||jdt d5}|}dddn #1swxYwY| d|dS)zFake `open()` function is bound/fake_file.txtwz6This test file was created using the open() function. N) assertFalser4pathexistsrwrite assertTruerrrr r"contents r# test_openzTestPyfakefsUnittest.test_openbsb (899::: "C ( ( OA GGM N N N O O O O O O O O O O O O O O O '788999 " # # qffhhG                 H      s$A%%A),A),C  CCc|tjdt jdd5}|ddddn #1swxYwY||jdt d5}| }dddn #1swxYwY| d|dS)zFake io module is boundrHrIz9This test file was created using the io.open() function. N) rJr4rKrLiorrMrNrrrrOs r# test_io_openz!TestPyfakefsUnittest.test_io_openosd (899::: W%s + + Uq GGS T T T U U U U U U U U U U U U U U U '788999 " # # qffhhG                 K      s$A**A.1A.1CCCc||jdtjd||jddS)zFake os module is boundz/test/dir1/dir2N)rJrrLr4makedirsrNrCs r#test_oszTestPyfakefsUnittest.test_os|s] (9::;;; %&&& '899:::::r-c0tjd}|gt jd|jdt jd}|r|dg|n|dg||jdtt jd}|r|ddg|dS|ddg|dS)zFake glob module is boundwinz/test/dir1/dir*/test/dir1/dir2az/test/dir1\dir2a/test/dir1/dir2bz/test/dir1\dir2bN)sysplatform startswithrglobr create_dirsorted)r is_windowsmatching_pathss r# test_globzTestPyfakefsUnittest.test_globs\,,U33  TY'899::: -...#455  C   12N C C C C   01> B B B -... *; < <==  W   13FG X X X X X   02DE~ V V V V Vr-c|jd|jd||jd||jdt jd||jddS)zFake shutil module is boundrZr[z /test/dir1N)rr`rNrLshutilrmtreerJrCs r# test_shutilz TestPyfakefsUnittest.test_shutils -... -... '9::;;; '9::;;; l###  5566666r-ctjd}|d5}|ddddn #1swxYwYtjd}|r/||j ddS||j ddS)NrHrItextrYz\fake_file.txt) pathlibrrrMr\r]r^rNrrL)r pr"rbs r#test_fakepathlibz%TestPyfakefsUnittest.test_fakepathlibs L) * * VVC[[ A GGFOOO               \,,U33  > OODGNN+<== > > > > > OODGNN+;<< = = = = =sA  AAN) r)r*r+__doc__rQrTrWrdrhrmr,r-r#rFrF_swKK        ;;; WWW"777>>>>>r-rFceZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z ejejd kd dZejejd kd dZdS)TestPatchingImportscd}|j|||j||tjj|dS)N /foo/bar/baz)rrrNrLpyfakefstestsimport_as_examplecheck_if_exists1r file_paths r#test_import_as_other_namez-TestPatchingImports.test_import_as_other_namesh"  I&&& y11222 8II)TTUUUUUr-cd}|j|||j||tjj|dS)z/Make sure `from os import path` patches `path`.rrN)rrrNrLrsrtrucheck_if_exists2rws r#test_import_path_from_osz,TestPatchingImports.test_import_path_from_ossh"  I&&& y11222 8II)TTUUUUUr-cd}|j||tjj|dSNr)rr`rNrsrtrucheck_if_exists3rws r#test_import_path_from_pathlibz1TestPatchingImports.test_import_path_from_pathlibH  9%%% 8II)TTUUUUUr-cd}|j||tjj|dSr~)rr`rNrsrtrucheck_if_exists5rws r#test_import_exists_from_os_pathz3TestPatchingImports.test_import_exists_from_os_pathrr-cd}|j||tjj|dSr~)rrrNrsrtrucheck_if_isfilerws r#test_import_isfile_from_os_pathz3TestPatchingImports.test_import_isfile_from_os_pathsH  I&&& 8HHSSTTTTTr-cd}|j||tjj|dSr~)rr`rNrsrtrucheck_if_isdirrws r#test_import_isdir_from_os_pathz2TestPatchingImports.test_import_isdir_from_os_pathsH  9%%% 8GG RRSSSSSr-cd}d}|j||j|||tjj|dS)Nrz /foo/link)rrcreate_symlinkrNrsrtrucheck_if_islink)r rx link_paths r#test_import_islink_from_os_pathz3TestPatchingImports.test_import_islink_from_os_pathse   I&&& y)444 8HHSSTTTTTr-cd}|j||tjj|dSr~)rr`rNrsrtrucheck_if_exists6rws r#/test_import_function_from_os_path_as_other_namezCTestPatchingImports.test_import_function_from_os_path_as_other_namerr-cd}|j||tjj|dSr~)rr`rNrsrtrucheck_if_exists7rws r#test_import_pathlib_pathz,TestPatchingImports.test_import_pathlib_pathrr-cd}|j|dtjj|}|d|jdSNrabcrr)rrrsrtru file_stat1rst_sizer rx stat_results r#test_import_function_from_osz0TestPatchingImports.test_import_function_from_osY  I777n6AA)LL  K/00000r-cd}|j|dtjj|}|d|jdSr)rrrsrtru file_stat2rrrs r#*test_import_function_from_os_as_other_namez>TestPatchingImports.test_import_function_from_os_as_other_namerr-rzCurrently not working in 3.12cd}|j|dtjj|}|d|dSNrrrabc)rrrsrtrufile_contents1rr rxrs r#test_import_open_as_other_namez2TestPatchingImports.test_import_open_as_other_nameV  I777>3BB9MM )))))r-cd}|j|dtjj|}|d|dSr)rrrsrtrufile_contents2rrs r#!test_import_io_open_as_other_namez5TestPatchingImports.test_import_io_open_as_other_namerr-N)r)r*r+ryr|rrrrrrrrrunittestskipIfr\ version_inforrr,r-r#rprps<VVV VVVVVV VVV UUU TTT UUUVVV VVV 111 111 X_S%02QRR**SR* X_S%02QRR**SR***r-rpc&eZdZdZdZdZdZdS)TestPatchingDefaultArgsc2|ddS)NT)patch_default_argsrArCs r#rDzTestPatchingDefaultArgs.setUps d33333r-cd}|j||tjj|dSr~)rr`rNrsrtrucheck_if_exists4rws r#+test_path_exists_as_default_arg_in_functionzCTestPatchingDefaultArgs.test_path_exists_as_default_arg_in_functionrr-cd}|j|tjj}|||dSr~)rr`rsrtruTestDefaultArgrNcheck_if_exists)r rxsuts r#)test_path_exists_as_default_arg_in_methodzATestPatchingDefaultArgs.test_path_exists_as_default_arg_in_methodsY  9%%%n.==?? ++I6677777r-c|jd|tjjddSNr2)rrrNrsrtrurrCs r#test_fake_path_exists4z.TestPatchingDefaultArgs.test_fake_path_exists4C E""" 8II%PPQQQQQr-N)r)r*r+rDrrrr,r-r#rrsX444VVV 888 RRRRRr-rceZdZdZdZdS)!TestAttributesWithFakeModuleNameszXTest that module attributes with names like `path` or `io` are not stubbed out. cF|tjd|tjd|tjd|tjd|tjddS)z/Attributes of module under test are not patchedzos attribute valuezpath attribute valuezpathlib attribute valuezshutil attribute valuezio attribute valueN)rr r4rKrkrfrSrCs r#test_attributesz1TestAttributesWithFakeModuleNames.test_attributess /24HIII /46LMMM /79RSSS /68PQQQ /24HIIIIIr-N)r)r*r+rnrr,r-r#rr s2JJJJJr-rceZdZdZdZdS)TestPathNotPatchedIfNotOsPathzTests that `path` is not patched if it is not `os.path`. An own path module (in this case an alias to math) can be imported and used. cV|dtjddS)Ng@)rrKfloorrCs r#test_own_path_modulez2TestPathNotPatchedIfNotOsPath.test_own_path_module!s& DJsOO,,,,,r-N)r)r*r+rnrr,r-r#rrs- -----r-rc2eZdZdZejdZdS)FailedPatchingTestzNegative tests: make sure the tests for `modules_to_reload` and `modules_to_patch` fail if not providing the arguments. cd}|j|d|dtjj|jdSNrstestrrrrrsrtru system_statrrws r#test_system_statz#FailedPatchingTest.test_system_stat*s_  I888  x~/;;IFFN     r-N)r)r*r+rnrexpectedFailurerr,r-r#rr%s=     r-rceZdZdZdZdS)ReloadModuleTest`Make sure that reloading a module allows patching of classes not patched automatically. cR|tjjgdS)r@)modules_to_reloadNrBrsrtrurCs r#rDzReloadModuleTest.setUp8s' hn.N-OPPPPPr-N)r)r*r+rnrDr,r-r#rr3s2QQQQQr-rcNeZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d S) NoSkipNamesTestzdReference test for additional_skip_names tests: make sure that the module is patched by default.c.|dSNrArCs r#rDzNoSkipNamesTest.setUpA r-cr|tjjdSr)rJrsrtruexists_this_filerCs r#test_path_existsz NoSkipNamesTest.test_path_existsDs- 9JJLLMMMMMr-c|jd|tjjddSr)rrrNrsrtrurvrCs r#test_fake_path_exists1z&NoSkipNamesTest.test_fake_path_exists1Grr-c|jd|tjjddSr)rrrNrsrtrur{rCs r#test_fake_path_exists2z&NoSkipNamesTest.test_fake_path_exists2Krr-c|jd|tjjddSr)rrrNrsrtrurrCs r#test_fake_path_exists3z&NoSkipNamesTest.test_fake_path_exists3Orr-c|jd|tjjddSr)rrrNrsrtrurrCs r#test_fake_path_exists5z&NoSkipNamesTest.test_fake_path_exists5Srr-c|jd|tjjddSr)rrrNrsrtrurrCs r#test_fake_path_exists6z&NoSkipNamesTest.test_fake_path_exists6Wrr-c|jd|tjjddSr)rrrNrsrtrurrCs r#test_fake_path_exists7z&NoSkipNamesTest.test_fake_path_exists7[rr-c|t5tjjddddS#1swxYwYdSr) assertRaisesOSErrorrsrtruopen_this_filerCs r#test_open_failszNoSkipNamesTest.test_open_fails_s   w ' ' > > N , ; ; = = = > > > > > > > > > > > > > > > > > >s$A  AAcd}|j|dtjj|}|d|dS)Nrrr)rrrsrtlogsio file_contentsrrs r#*test_open_patched_in_module_ending_with_ioz:NoSkipNamesTest.test_open_patched_in_module_ending_with_iocsV  I777>(66yAA *****r-N)r)r*r+rnrDrrrrrrrrrr,r-r#rr=s88NNNRRRRRRRRRRRRRRRRRR>>>+++++r-rceZdZdZdZdZdZdZdZdZ dZ d Z d Z e jejd kd d ZdZdS)AdditionalSkipNamesTestzsMake sure that modules in additional_skip_names are not patched. Passes module name to `additional_skip_names`.c4|dgdS)N pyfakefs.tests.import_as_exampleadditional_skip_namesrArCs r#rDzAdditionalSkipNamesTest.setUpos# 2T1UVVVVVr-cr|tjjdSrrNrsrtrurrCs r#rz(AdditionalSkipNamesTest.test_path_existsr+ 8IIKKLLLLLr-c|jd|tjjddSrrrrJrsrtrurvrCs r#test_fake_path_does_not_exist1z6AdditionalSkipNamesTest.test_fake_path_does_not_exist1uE E""" 9JJ5QQRRRRRr-c|jd|tjjddSrrrrJrsrtrur{rCs r#test_fake_path_does_not_exist2z6AdditionalSkipNamesTest.test_fake_path_does_not_exist2yrr-c|jd|tjjddSrrrrJrsrtrurrCs r#test_fake_path_does_not_exist3z6AdditionalSkipNamesTest.test_fake_path_does_not_exist3}rr-c|jd|tjjddSrrrrJrsrtrurrCs r#test_fake_path_does_not_exist4z6AdditionalSkipNamesTest.test_fake_path_does_not_exist4rr-c|jd|tjjddSrrrrJrsrtrurrCs r#test_fake_path_does_not_exist5z6AdditionalSkipNamesTest.test_fake_path_does_not_exist5rr-c|jd|tjjddSrrrrJrsrtrurrCs r#test_fake_path_does_not_exist6z6AdditionalSkipNamesTest.test_fake_path_does_not_exist6rr-c|jd|tjjddSrrrrJrsrtrurrCs r#test_fake_path_does_not_exist7z6AdditionalSkipNamesTest.test_fake_path_does_not_exist7rr-r3Skip modules currently not working for open in 3.12cLtjjdSrrsrtrurrCs r#test_open_succeedsz*AdditionalSkipNamesTest.test_open_succeeds! (7799999r-cLtjjdSrrsrtrureturn_this_file_pathrCs r#test_path_succeedsz*AdditionalSkipNamesTest.test_path_succeeds(>>@@@@@r-Nr)r*r+rnrDrrrrr r rrrrr\rrrr,r-r#rrks66WWWMMMSSSSSSSSSSSSSSSSSSSSSX_ G#=:: :AAAAAr-rceZdZdZdZdZdZdZdZdZ dZ d Z d Z e jejd kd d ZdZdS)AdditionalSkipNamesModuleTestznMake sure that modules in additional_skip_names are not patched. Passes module to `additional_skip_names`.cR|tjjgdS)NrrrCs r#rDz#AdditionalSkipNamesModuleTest.setUps' (.2R1STTTTTr-cr|tjjdSrrrCs r#rz.AdditionalSkipNamesModuleTest.test_path_existsrr-c|jd|tjjddSrrrCs r#rz3L   !!!00000r-r-ceZdZdZdZdZdS)PatchModuleTestrc@|dtidS)r@rmodules_to_patchN)rBr-rCs r#rDzPatchModuleTest.setUps2 @BST      r-cd}|j|d|dtjj|jdSrrrws r#rz PatchModuleTest.test_system_stats_  I888  x~/;;IFFN     r-N)r)r*r+rnrDrr,r-r#r:r:s<        r-r:cpeZdZdZeejdZedeidZ dS)PatchModuleTestUsingDecoratorzMake sure that reloading a module allows patching of classes not patched automatically - use patchfs decorator with parameter. cd}||d|dtjj|jdSrrrrsrtrurrr r&rxs r#test_system_stat_failingz6PatchModuleTestUsingDecorator.test_system_stat_failings_ I888  x~/;;IFFN     r-rr<cd}||d|dtjj|jdSrrBrCs r#rz.PatchModuleTestUsingDecorator.test_system_stats] I888  x~/;;IFFN     r-N) r)r*r+rnr rrrDr-rr,r-r#r@r@sx     W  WACTUVVV  WV   r-r@ceZdZdZdZdZdS)NoRootUserTestz/Test allow_root_user argument to setUpPyfakefs.c2|ddS)NF)allow_root_userrArCs r#rDzNoRootUserTest.setUp s 511111r-cd|j_d}|j|d|dz}|t5|j|dddn #1swxYwYd}|j|t j|d|t5t|d ddddS#1swxYwYdS) zYCheck that fs behaves as non-root user regardless of actual user rights. Frim) perm_bitsbazNz/bazrI) r is_windows_fsr`rrrr4chmodr)r dir_pathrxs r#test_non_root_behaviorz%NoRootUserTest.test_non_root_behaviorsn!& 8u555u$   w ' ' + + G   * * * + + + + + + + + + + + + + + +  I&&& E"""   w ' ' ! ! C  ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !s$ A11A58A5C%%C),C)N)r)r*r+rnrDrQr,r-r#rGrGs899222!!!!!r-rGc8eZdZdZdZdZdZdZdZdZ dS) PauseResumeTestc<d|_|dSr)real_temp_filerBrCs r#rDzPauseResumeTest.setUp!s"" r-cJ|j|jdSdSr)rUcloserCs r#tearDownzPauseResumeTest.tearDown%s.   *   % % ' ' ' ' ' + *r-ctj}||j|j|t j|j|||j|j| t j|jtj|_ | |j|j j|t j|j j| | t j|j j|t j|jdSr) tempfileNamedTemporaryFilerNrrLr7r4rKpauserJrUresumer fake_temp_files r#test_pause_resumez!PauseResumeTest.test_pause_resume)sh!466 ~':;;<<< ~':;;<<<  ~':;;<<< (;<<===&9;; (;(@AABBB t':'?@@AAA  (;(@AABBB ~':;;<<<<+>?? @ @ @   RW^^N,?@@ A A A"*"="?"?D    TW^^D,?,DEE F F F OOBGNN4+>+CDD E E E  F F F F F F F F F F F F F F F (;(@AABBB ~':;;<<<<+>?? @ @ @   RW^^N,?@@ A A A"*"="?"?D    TW^^D,?,DEE F F F OOBGNN4+>+CDD E E E  F F F F F F F F F F F F F F F (;(@AABBB ~':;;<<<<+>?? @ @ @ GGIII OOADKK(;<< = = =   RW^^N,?@@ A A A%8::N   QT[[)<== > > > OOBGNN>+>?? @ @ @ HHJJJ   RW^^N,?@@ A A A OOBGNN>+>?? @ @ @ A A A A A A A A A A A A A A A sG8HHHcft5}tj}||j|j|tj|jt|5||j|j| tj|jtj}| |j|j|tj|jdddn #1swxYwY| tj|j|tj|jdddn #1swxYwY| dSr) r rZr[rNrrLr7r4rKr rJrWros r#rez7PauseResumePatcherTest.test_pause_resume_contextmanager}s6 YY A!%8::N OOADKK(;<< = = = OOBGNN>+>?? @ @ @q E E N,? @ @AAA  0C!D!DEEE!)!!>  ^-@!A!ABBB~/B C CDDD  E E E E E E E E E E E E E E E   RW^^N,?@@ A A A OOBGNN>+>?? @ @ @ A A A A A A A A A A A A A A A s8B HC&F  H F HF A1HHHN)r)r*r+r`rer,r-r#rmrmls2     r-rmceZdZdZdZdS)TestPyfakefsTestCasecVGddtj}|d|_dS)NceZdZdZdS)0TestPyfakefsTestCase.setUp..TestTestCasecdSrr,rCs r#runTestz8TestPyfakefsTestCase.setUp..TestTestCase.runTestsr-N)r)r*r+rwr,r-r# TestTestCaserus#     r-rxrw)rr test_case)r rxs r#rDzTestPyfakefsTestCase.setUpsG     3<   &i00r-c||jtj||jtjdSr)assertIsInstanceryrrr TestCaseMixinrCs r#test_test_case_typez(TestPyfakefsTestCase.test_test_case_types? dnh.?@@@ dn.F.TUUUUUr-N)r)r*r+rDr}r,r-r#rrrrs7111VVVVVr-rrcdeZdZdZdZdZejej dkddZ dS)TestTempDirCreationz2Test that the temp directory exists at test start.c.|dSrrArCs r#rDzTestTempDirCreation.setUprr-c|tjt jdSr)rNr4rKrLrZ gettempdirrCs r#test_tempdir_existsz'TestTempDirCreation.test_tempdir_existss1 x':'<'<==>>>>>r-win32zPOSIX only testcj|tjddS)Nz/tmp)rNr4rKrLrCs r#test_tmp_existsz#TestTempDirCreation.test_tmp_existss* v../////r-N) r)r*r+rnrDrrrr\r]rr,r-r#rrsk<<???X_S\W,.?@@00A@000r-rceZdZdZdZdZdS)TestTempFileReloadzbRegression test for #356 to make sure that reloading the tempfile does not affect other tests.ct5}|jddddddS#1swxYwYdS)Nz /mytempfileabcdr)r rr)r r!s r# test_fakefszTestTempFileReload.test_fakefss YY C' J " "=6 " B B B C C C C C C C C C C C C C C C C C Cs 9==cftjdd}||jddS)NIr)multiprocessingValuervalue)r vs r# test_valuezTestTempFileReload.test_values2  !#q ) ) !$$$$$r-N)r)r*r+rnrrr,r-r#rrs?$$CCC%%%%%r-rceZdZdZdS)TestPyfakefsTestCaseMixinc||t|d||jt jdS)Nr)rBrNhasattrr{rrrirCs r#test_set_up_pyfakefsz.TestPyfakefsTestCaseMixin.test_set_up_pyfakefssQ  d++,,, dg'EFFFFFr-N)r)r*r+rr,r-r#rrs(GGGGGr-rc$eZdZdZdZdZdZdS)TestShutilWithZipfilezRegression test for #427.cb||jddS)Nfoo/bar)rBrrrCs r#rDzTestShutilWithZipfile.setUps0  I&&&&&r-c4tjddddSNarchivezipr2)root_dirrf make_archiverCs r#test_azTestShutilWithZipfile.test_as Iuu======r-c4tjddddSrrrCs r#test_bzTestShutilWithZipfile.test_bs Iuu======r-N)r)r*r+rnrDrrr,r-r#rrsG##'''>>>>>>>>r-rc$eZdZdZdZdZdZdS)TestDistutilsCopyTreezRegression test for #501.c||jd|jd|jddS)Nz./test/subdir/z./test/subdir2/./test2/subdir/1.txt)rBrr`rrCs r#rDzTestDistutilsCopyTree.setUps_    G  / 0 0 0 G  0 1 1 1 G   6 7 7 7 7 7r-c tddtd|tjd|tjddS)N./test2/./test/./test/subdir/1.txt)rrrNr4rKisfilerJisdirrCs r#test_file_copiedz&TestDistutilsCopyTree.test_file_copiedsi j) , , ,  # # # OOBGNN+@AA B B B   RW]]:66 7 7 7 7 7r-cp|tjdt ddt d|tjd|tjddS)Nrrrr)rNr4rKrrrrJrrCs r#test_file_copied_againz,TestDistutilsCopyTree.test_file_copied_agains OOBGNN+ABB C C C j) , , ,  # # # OOBGNN+@AA B B B   RW]]:66 7 7 7 7 7r-N)r)r*r+rnrDrrr,r-r#rrsG'' 8 8 8  8 8 8 8 8 8 8 8r-rc(eZdZdZedZdS) PathlibTestzRegression test for #527ctjd}|rdtjjzntjj}||ttj tj d }||t|| | dS)z4Make sure fake file system is used for os in pathlibrYC:.N)r\r]r^r4rKseprstrrkrcwdabsoluterNrL)r rrbrdot_abss r#test_cwdzPathlibTest.test_cwds\,,U33 )3D4"'+%% 3w|'7'7'9'9#:#:;;;,s##,,.. 3w<<000 (()))))r-N)r)r*r+rnr rr,r-r#rrs3"" ** W***r-rc`eZdZejejddkddZdS)TestDeprecationSuppressionz,Test fails for Python 3.6 for unknown reasoncddlm}tjd5}tjdt ||dt|ddddS#1swxYwYdS)zaEnsures that deprecation warnings are suppressed during module lookup, see #542. r)DeprecationTestT)recorderrorN) +pyfakefs.tests.fixtures.deprecated_propertyrwarningscatch_warnings simplefilterDeprecationWarningrBrlen)r rrIs r#test_no_deprecation_warningz6TestDeprecationSuppression.test_no_deprecation_warnings       $D 1 1 1 (Q  !'+= > > >      QA ' ' ' ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (sAA;;A?A?N)r)r*r+rrr\rrr,r-r#rrsQX_ q 6 ( (  ( ( (r-rcg}|D]R}t|dkr&|dddkr|tj|z };|tj|z }S|S)z@Helper code for patching open_code in auto mode, see issue #554.rNz.py)rrunpyrun_path run_module)configsretvalconfigs r# load_configsrsi F// v;;??vbcc{e33 enV,, ,FF e&v.. .FF Mr-c*eZdZdZdZdZdZdZdS)AutoPatchOpenCodeTestCasez5Test patching open_code in auto mode, see issue #554.c|tjd|_|j|jdd|_dS)N)patch_open_codez configpy.pyzconfigurable_value='yup'rz%pyfakefs.tests.fixtures.config_module)rBr AUTOconfigpyrr config_modulerCs r#rDzAutoPatchOpenCodeTestCase.setUpsN 9>:::%  DM4NOOODr-c<t|j|jgdSr)rrrrCs r# test_bothz#AutoPatchOpenCodeTestCase.test_both$s dmT%7899999r-c0t|jgdSr)rrrCs r# test_run_pathz'AutoPatchOpenCodeTestCase.test_run_path'sdm_%%%%%r-c0t|jgdSr)rrrCs r#test_run_modulez)AutoPatchOpenCodeTestCase.test_run_module*sd()*****r-N)r)r*r+rnrDrrrr,r-r#rrsY??EEE:::&&&+++++r-rc2eZdZdZdZdZdZdZdZdS) TestOtherFSc.|dSrrArCs r#rDzTestOtherFS.setUp/rr-cDtjdk|j_|jjr d|j_|jt tt 5}|| dddn #1swxYwYtj }tj |tt 5}|| ddddS#1swxYwYdS)zRegression test for #558ntFN) r4r7rrNis_macos add_real_file__file__rrNrrhomechdir)r r"rs r#test_real_file_with_homez$TestOtherFS.test_real_file_with_home2sV "4 7  %$DG  h''' (^^ &q OOAFFHH % % % & & & & & & & & & & & & & & &y{{  (^^ &q OOAFFHH % % % & & & & & & & & & & & & & & & & & &s$&(BB!B (DDDcntj|j_d}||tjddd|dtj||j|| tj || tj |j | tj d| tj d|dtj |dtjj |d tj|d tj|d tj|d tjdS) Nz C:\foo\barzC:\r2bar)rz\foo\barz \\share\foor\/;z nul)rWINDOWSrr4rrKjoin splitdriverrNrLupperismountraltseppathseplinesepdevnullr rKs r# test_windowszTestOtherFS.test_windows?s^  rw||FE5AABBB ,bg.@.@.F.FGGG D!!! t,,--- ztz||44555 77888 ../// rv&&& rw{+++ bi((( bj))) ,,,  +++++r-cntj|j_d}||tjddd|dtjd|j|| tj || tj |j | tj d| tj d|dtj|dtjj|dtj|dtj|d tj|d tjdS Nrrr2r) C:/foo/barrz //share/foo: z /dev/null)rLINUXrr4rrKrrrrNrLrJrrrrrrrrs r# test_linuxzTestOtherFS.test_linuxPs\  rw||C>>??? +RW-?-? -M-MNNN D!!! t,,---   55666 ,,--- 77888 bf%%% bgk*** ry))) bj))) rz*** bj11111r-cntj|j_d}||tjddd|dtjd|j|| tj || tj |j | tj d| tj d|dtj|dtjj|dtj|dtj|d tj|d tjdSr)rMACOSrr4rrKrrrrNrLrrrJrrrrrrs r# test_macoszTestOtherFS.test_macosas\  rw||C>>??? +RW-?-? -M-MNNN D!!! t,,--- ztz||44555 ,,--- 77888 bf%%% bgk*** ry))) bj))) rz*** bj11111r-c tj|j_t d}|dz }|jd|tj|| tj t| |dS)Nz/testz C:/testfileT)parents)rrrr4rparentmkdirtouchrrNrKrLr relative_to)r folderrxs r#test_drivelike_pathzTestOtherFS.test_drivelike_pathrs\ g]* t,,,  s9+@+@+H+H'I'IJJKKKKKr-N) r)r*r+rDrrrr rr,r-r#rr.ss & & &,,,"222"222"LLLLLr-rrzWindows-specific behaviorc$eZdZedZdS)TestAbsolutePathOnWindowsc|tjddS)Nr)rNrkrr is_absoluter/s r#test_is_absolutez*TestAbsolutePathOnWindows.test_is_absolute~s>  S))2244@@BBCCCCCr-N)r)r*r+r rr,r-r#rr|s2 DD WDDDr-r)rzNot available before Python 3.8c0eZdZedZdZdZdS)TestClassSetupc||dddS)Nrrr)setUpClassPyfakefsr&r)clss r# setUpClasszTestClassSetup.setUpClasss;     !!)f!=====r-c |tjdt d5}|}dddn #1swxYwY|d|dSNrr)rNr4rKrLrrr)r r"rs r#test_using_fs_functionsz&TestClassSetup.test_using_fs_functionss y11222 )__ vvxxH                *****sA##A'*A'c||jd|jd}|d|jdSr)rNrrL get_objectrr)r r"s r#test_using_fakefsz TestClassSetup.test_using_fakefssU y11222 G  y ) ) ,,,,,r-N)r)r*r+ classmethodrr r#r,r-r#rrsK>>[>+++ -----r-r__main__)Hrnr_rSrr4rkrrfr\rZrrrrr pyfakefs.tests.import_as_examplerspyfakefs.tests.logsiorrpyfakefs.fake_filesystemr!pyfakefs.fake_filesystem_unittestr r r r pyfakefs.tests.fixturesr rdistutils.dir_utilrrrr/r>rFrprrmathrKrrrrrr r-r:r@rGrSrmrrrrr|rrrrrrrrrr]rrr)mainr,r-r#r.s"   ########''''>>>>>>>>++++++ ;:::::g99999999 + + + + +( + + + 11111x111,7@ F>F>F>F>F>3F>F>F>RK*K*K*K*K*2K*K*K*\RRRRR6?RRR( J J J J J(@ J J J-----$<---      1    QQQQQ/8QQQ++++++++++.7++++++\.A.A.A.A.A6?.A.A.Ab.A.A.A.A.A$<$E.A.A.Ab00000000"     .7   &     H$5   .!!!!!-6!!!0IIIII.7IIIX5>B V V V V V8, V V V 0 0 0 0 02; 0 0 0 % % % % %* % % %GGGGG /=GGG > > > > >4= > > >g88888 8 A8886 * * * * *( * * *(((((!9!B((((+++++ 8 A+++(KLKLKLKLKL*3KLKLKL\(*EFFDDDDD 8 ADDGFD!F*,MNN------6--ON-$ zHMOOOOOr-tests/__pycache__/mox3_stubout_example.cpython-311.pyc000064400000002135150043321520017002 0ustar00 bg|4dZddlZddlZddlZdZdZdZdS)zq Example module that is used for testing the functionality of :py:class`pyfakefs.mox_stubout.StubOutForTesting`. Nc@tj|SN)ospathexists)filepaths t/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/tests/mox3_stubout_example.pycheck_if_existsr s 7>>( # ##c*tj|Sr)mathfabs)xs r rrs 9Q<<r cjtjtjdzS)N)days)datetimedatetoday timedeltar r tomorrowrs) =   8#51#=#=#= ==r )__doc__rr rr rrrr r rsc $$$>>>>>r tests/__pycache__/fake_filesystem_vs_real_test.cpython-311.pyc000064400000120732150043321520020544 0ustar00 bgsdZddlZddlZddlZddlZddlZddlZddlmZm Z m Z ddl m Z dZ dZGddejZGd d eZd Zed krejdSdS) zETest that FakeFilesystem calls work identically to a real filesystem.N)fake_filesystemfake_os fake_open)IS_PYPYcpt|tr |dtjS|S)zBConverts slashes in the path to the architecture's path seperator./) isinstancestrreplaceosseppaths |/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/tests/fake_filesystem_vs_real_test.pyr r s/$)||C((( Kc<| |jS#t$rYdSwxYwdSN)errnoAttributeError) raised_errors r _get_errnor$s@ % %    DD  s  cNeZdZejdZerdndZdS)TestCasewinz C:\fakefsz/fakefsN)__name__ __module__ __qualname__sysplatform startswith is_windows _FAKE_FS_BASErrrr,s1((//J$.=LLIMMMrrcFeZdZdZd4dZdZdZ d5dZedZ ed Z d5d Z d6d Z d5d Z d5dZdZdZdZedZdZdZdZdZdZdZdZdZdZdZdZdZdZe j!e"j#d d!Z$e j!e"j#d d"Z%e j!e"j#d d#Z&e j!e"j#d d$Z'e j!e"j#d d%Z(d&Z)e j!e"j#d d'Z*e j!e"j#d d(Z+e j!e"j#d d)Z,e j!e"j#d d*Z-e j!e"j#d d+Z.e j!e"j#d d,Z/e j!e"j#d d-Z0e j!e"j#d d.Z1d/Z2d0Z3d1Z4d2Z5d3Z6dS)7FakeFilesystemVsRealTestc|sdStj|j|tj|j|fS)z@For a given path, return paths in the real and fake filesystems.)NN)r rjoin real_base fake_baseselfrs r_pathszFakeFilesystemVsRealTest._paths2sC : GLL . . GLL . .  rNcpt|}|j|||g||\}}|dkr.t j||j||dkr|t|d}||pd| | |d}||pd| |dkr|t|d}||pd| | |d}||pd| |dvr||}}| tjr ||dd \}}|d kr2t j |||j ||d S|d kr4t j |||j ||d Sd Sd S) z=Create a dir, file, or link in both the real fs and the fake.dfwbwb)lhNr4r5)r _created_filesappendr,r mkdirropenwritecloserr symlinklink) r+ file_typercontents real_path fake_pathfh real_target fake_targets r_create_test_filez*FakeFilesystemVsRealTest._create_test_file;s+4yy ""ItX#>???#{{400 9    HY    L  y ) ) )   i%%B HHX^ $ $ $ HHJJJ 3//B HHX^ $ $ $ HHJJJ   i&&B HHX^ $ $ $ HHJJJ 400B HHX^ $ $ $ HHJJJ  " "(0(K""26** E+/;;x|+D+D( [C ; 222 $$[)<<<<<c!! Y/// !!+y99999 # ""!rcdtjz}tj|_tjtjtj||_ tj tjtj |j rtj |j tj|j |j|_|tj|j tjt)j|_|j|jt/j|j|_t3j|j|_g|_tj |j |j |jdS)Nz fakefs.%s)timer getcwdcwdrrealpathr'tempfile gettempdirr(chdirisdirshutilrmtreer9r"r) assertTrueaccessW_OKrFakeFilesystem create_dirr FakeOsModuler FakeFileOpenr7)r+tsnames rsetUpzFakeFilesystemVsRealTest.setUp`s`ty{{*9;;))"',,x7J7L7Lf*U*UVV $&&''' 7== ( ( * M$. ) ) )    +  $."'::;;;.=?? ''777+D,@AA "/0DEE      4>*****rc Ptjtj |jdd}||D]}||d\}}|ddkr} tj|nM#t$r@}d|vr1| d|d|dtj |nYd}~nd}~wwxYw|j ||ddks |dd kr.tj ||j | tj|jtj|jdS#tj|jtj|jwxYw) Nr6rr.zDirectory not emptyz Real path z not empty: z : r/r4)r rNrLrMr7reverser,rmdirOSErrorfaillistdirrremoverPrQr(rJ)r+ rev_filesinforArBes rtearDownz!FakeFilesystemVsRealTest.tearDownzs $&&''' +AAA.I      ! 3 3'+{{47';';$ 97c>> "++++""""0A55 III#,99aaaI1F1F1F!H " "L&&y1117c>>T!W^^Ii(((L'' 222! 3$ M$. ) ) ) HTX      M$. ) ) ) HTX    s7AE19B E1 C6CE1CA$E114F%Fc d}||||\}}||||\} } |} | |dkrdndz } |||| krF|| d|d|| S| | d||d | S| d||d|| St|} t| } | | kr|d |d ||d | d |  S|rp|rn| rl||jrR| |jr8|t |jd}| t |jd} || kr | d|d | SdS)aInvoke an os method in both real and fake contexts and compare results. Invoke a real filesystem method with a path to a real file and invoke a fake filesystem method with a path to a fake file and compare the results. We expect some calls to throw Exceptions, so we catch those and compare them. Args: method_name: Name of method being tested, for use in error messages. path: potential path to a file in the real and fake file systems, passing an empty tuple indicates that no arguments to pass to method. real: built-in system library or method from the built-in system library which takes a path as an arg and returns some value. fake: fake_filsystem object or method from a fake_filesystem class which takes a path as an arg and returns some value. method_returns_path: True if the method returns a path, and thus we must compensate for expected difference between real and fake. Returns: A description of the difference in behavior, or None. c|rAt|dr%d|jj|jS|jjSdS)Nrz{}({})None)hasattrformat __class__rr)excs r _error_classzAFakeFilesystemVsRealTest._compare_behaviors.._error_classsH .3((N#??3=+A39MMM}--6rr#z()z({path})Nz: real version returned z, fake raised z: real version raised z, fake returned (z): both raised z , real errno z , fake errno z: real return )_get_real_value_get_fake_valuerr r(r)len)r+ method_namerrealfakemethod_returns_pathrmreal_err real_valuefake_err fake_value method_call real_errno fake_errnos r_compare_behaviorsz+FakeFilesystemVsRealTest._compare_behaviorss0:    $33KtLL*#33KtLL*$& trzzttz9  < ! !\\(%;%; ; ;KKJJ L*** KK L****J   X&&&& X&&&   )) ))  # #  X&&&&     ? ? ?))$.99 ?))$.99  ? (DN(;(;(=(=> 'DN(;(;(=(=>  # #     trcd}d} |}t|st||}|dkrgn|g}||}t|tr|}nt |}n#t $r }|}Yd}~nd}~wwxYw||fSNr#callablegetattrr bytesdecoder Exception) rrrrtryrx fake_methodargsresultrds rrpz(FakeFilesystemVsRealTest._get_fake_values  KD>> 9%dK88 22$D [$'F&%(( )#]]__  [[    HHHHHH ##A*A11 B;BBcd}d} |dkrgn|g}|}t|st||}||}t|tr|}nt |}n#t $r }|}Yd}~nd}~wwxYw||fSrr) rrrrsrwrvr real_methodrrds rroz(FakeFilesystemVsRealTest._get_real_values  22$DKD>> 9%dK88  [$'F&%(( )#]]__  [[    HHHHHH ##rcft|}|||t|j|S)aInvoke an os method in both real and fake contexts and compare. For a given method name (from the os module) and a path, compare the behavior of the system provided module against the fake_filesystem module. We expect results and/or Exceptions raised to be identical. Args: method_name: Name of method being tested. path: potential path to a file in the real and fake file systems. method_returns_path: True if the method returns a path, and thus we must compensate for expected difference between real and fake. Returns: A description of the difference in behavior, or None. )r r}r rr+rrrrus rassertOsMethodBehaviorMatchesz6FakeFilesystemVsRealTest.assertOsMethodBehaviorMatchess5&4yy&& r4<1D   rTc t||5}|||5}||||||cdddcdddS#1swxYwY ddddS#1swxYwYdS)aInvoke an open method in both real and fkae contexts and compare. Args: method_name: Name of method being tested. path: potential path to a file in the real and fake file systems. mode: how to open the file. data: any data to pass to the method. method_returns_data: True if a method returns some sort of data. For a given method name (from builtin open) and a path, compare the behavior of the system provided module against the fake_filesystem module. We expect results and/or Exceptions raised to be identical. Returns: A description of the difference in behavior, or None. N)r:rr})r+rrrmodedatamethod_returns_datareal_fhfake_fhs rdiff_open_method_behaviorz2FakeFilesystemVsRealTest.diff_open_method_behavior-s'($   d++ w..w9L                                          s4A3A A3A A3!A "A33A7:A7c\|||tj|jj|S)aInvoke an os.path method in both real and fake contexts and compare. For a given method name (from the os.path module) and a path, compare the behavior of the system provided module against the fake_filesytem module. We expect results and/or Exceptions raised to be identical. Args: method_name: Name of method being tested. path: potential path to a file in the real and fake file systems. method_returns_path: True if the method returns a path, and thus we must compensate for expected difference between real and fake. Returns: A description of the difference in behavior, or None. )r}r rrrs rdiff_os_path_method_behaviorz5FakeFilesystemVsRealTest.diff_os_path_method_behaviorGs/&&& rw (9;N   rct|}||||}|r||dSdS)aGAssert that an os.path behaves the same in both real and fake contexts. Wraps DiffOsPathMethodBehavior, raising AssertionError if any differences are reported. Args: method_name: Name of method being tested. path: potential path to a file in the real and fake file systems. method_returns_path: True if the method returns a path, and thus we must compensate for expected difference between real and fake. Raises: AssertionError if there is any difference in behavior. N)r rr_)r+rrrrudiffs r!assertOsPathMethodBehaviorMatchesz:FakeFilesystemVsRealTest.assertOsPathMethodBehaviorMatches^sL$4yy00dDWXX   IIdOOOOO  rc t|}|jrgndg}dg}ddg}|js|ddgz }|jrts|ddgz }d |j|jgd |j|jgd |j|jgg}g}|D]/}| ||}|r| |0|D]1}| |d d }|r| |2|D]/}| ||}|r| |0|D]C} | | d|| d| d}|r| |D|r0| d|dd|dSdS)NreadlinkrIisabsrOislinklexistsisfileexistsrSz stat.sizez lstat.sizer#T)rurr6Behaviors do not match for :  )r r!r _access_real _access_fake_stat_size_real_stat_size_fake_lstat_size_real_lstat_size_fakerr8rr}r_r') r+ros_method_namesos_method_names_no_argsos_path_method_nameswrapped_methods differencesrrrms rassertAllOsBehaviorsMatchz2FakeFilesystemVsRealTest.assertAllOsBehaviorsMatchus 4yy $A""j\#+* '1 : Xy$9 9  9g 9 Xx$8 8 t($*; < $.0D E 40$2G H   * ) )K55k4HHD )""4(((2 ) )K55RT6D )""4(((/ ) )K44[$GGD )""4(((  ) )A**1Q4qtQqTBBD )""4(((   III44{3335       rczt|}ddg}ddg}gd}g}|D]1}|||||} | r|| 2||zD]1}||||d} | r|| 2|r0|d|dd |dSdS) Nr; writelinesread readlines)truncateflushr<r#rrr)r rr8r_r') r+rrrwrite_method_namesread_method_namesother_method_namesrrrrs rassertFileHandleBehaviorsMatchz7FakeFilesystemVsRealTest.assertFileHandleBehaviorsMatchs4yy%|4#[1;;; - ) )K11+tT4PPD )""4(((,/AA ) )K11+tT2NND )""4(((   III44{3335       rcd}d} t|i|5 dddn #1swxYwYn#t$r }|}Yd}~nd}~wwxYw |j|i|5 dddn #1swxYwYn#t$r }|}Yd}~nd}~wwxYw||k}|r0|r.t|t|uo|j|jk}|sJd|d|d}dt |z}dt |z} |||z| zdSdS)awCompare open() function invocation between real and fake. Runs open(*args, **kwargs) on both real and fake. Args: *args: args to pass through to open() **kwargs: kwargs to pass through to open(). Returns: None. Raises: AssertionError if underlying open() behavior differs from fake. Nz(Behaviors don't match on open with args z & kwargs z. zReal open results in: %s zFake open results in: %s )r:rrtyperreprr_) r+rkwargsrvrxrdis_exception_equalmsg real_err_msg fake_err_msgs r"assertFileHandleOpenBehaviorsMatchz;FakeFilesystemVsRealTest.assertFileHandleOpenBehaviorsMatchs t&v&&                    HHHHHH  000                    HHHHHH &1   X$x..0SX]hm5S " 9 9C8$x..HL7$x..HL IIcL(<7 8 8 8 8 8 9 9sf ,  ,$,$, A=A A-A! A-!A%%A-(A%)A-- B7A>>Bc@tj|tjSr)r rSR_OKrs rrz%FakeFilesystemVsRealTest._access_realsyrw'''rcL|j|tjSr)rrSr rr*s rrz%FakeFilesystemVsRealTest._access_fakes|""4111rc||\}}tj|rdStj|jSr)r,r rrOstatst_size)r+rrAunused_fake_paths rrz(FakeFilesystemVsRealTest._stat_size_realsG&*kk$&7&7# # 7== # # 4wy!!))rc||\}}|jj|rdS|j|jSr)r,rrrOrr)r+runused_real_pathrBs rrz(FakeFilesystemVsRealTest._stat_size_fakesR&*kk$&7&7#) <  " "9 - - 4|  ++33rcx||\}}tj|rdStj|j}tj|rHtj|tj r|t|j z}|Sr) r,r rrOlstatrrrr r rqr()r+rrArsizes rrz)FakeFilesystemVsRealTest._lstat_size_reals&*kk$&7&7# # 7== # # 4x ""* 7>>) $ $ ,{9%%0088 ,DN+++ rc||\}}|jj|rdS|j|j}|jj|rN|j|tj r|t|j z}|Sr) r,rrrOrrrrr r r rqr))r+rrrBrs rrz)FakeFilesystemVsRealTest._lstat_size_fakes&*kk$&7&7#) <  " "9 - - 4|!!),,4 <  # #I . . ,|$$Y//::26BB ,DN+++ rc|dd|dd|dd|dd|dddS)Nrr1rz/aarr+s r test_isabsz#FakeFilesystemVsRealTest.test_isabs sv ..w=== ..w;;; ..w<<< ..w=== ..w<<<<>> &&w/////rzno symlink in Windowsc|dd|ddd|ddS)Nr/rr4 link_to_emptyrrs rtest_sym_link_to_empty_filez4FakeFilesystemVsRealTest.test_sym_link_to_empty_file-J sG,,, sOW=== &&77777rc|dd|ddd|ddS)Nr/rr5rrrs rtest_hard_link_to_empty_filez5FakeFilesystemVsRealTest.test_hard_link_to_empty_file3rrc|ddd|ddd|ddS)Nr/rrr4 link_to_filerrs rtest_sym_link_to_real_filez3FakeFilesystemVsRealTest.test_sym_link_to_real_file9L sG_=== sNG<<< &&~66666rc|ddd|ddd|ddS)Nr/rrr5rrrs rtest_hard_link_to_real_filez4FakeFilesystemVsRealTest.test_hard_link_to_real_file?rrc|ddd|ddd|ddS)Nr4 broken_linkbrokenloopz/a/looprrs rtest_broken_sym_linkz-FakeFilesystemVsRealTest.test_broken_sym_linkEsL sM8<<< sFI666 &&}55555rc|dd|dd|ddd|ddS)Nr.ra/br/a/b/filer@rrs rtest_file_in_a_folderz.FakeFilesystemVsRealTest.test_file_in_a_folderKs` sC((( sE*** sJ ;;; &&z22222rc|dd|dd|ddd|ddd |d dS) Nr.rrr/rr@r4a/link/a/b a/link/filerrs r test_absolute_sym_link_to_folderz9FakeFilesystemVsRealTest.test_absolute_sym_link_to_folderQsx sC((( sE*** sJ ;;; sHf555 &&}55555rcp|dd|dd|ddd|ddd |d\}}tj||j||d dS) Nr.rrr/rr@r4rrfile)rFr,r rNrr)r+real_dirfake_dirs rtest_link_to_folder_after_chdirz8FakeFilesystemVsRealTest.test_link_to_folder_after_chdirYs sC((( sE*** sJ ;;; sHf555![[//(  8$$$ &&v.....rc|dd|dd|ddd|ddd |d dS) Nr.rrr/rr@r4rr2rrrs r test_relative_sym_link_to_folderz9FakeFilesystemVsRealTest.test_relative_sym_link_to_folderesx sC((( sE*** sJ ;;; sHc222 &&}55555rctjddkrZ|dd|dd|ddd|ddSdS) NrDarwinr.rrr4a/b/c..)r unamerFrrs rtest_sym_link_to_parentz0FakeFilesystemVsRealTest.test_sym_link_to_parentms 8::a=H $ $  " "3 , , ,  " "3 . . .  " "3 6 6 6  * *7 3 3 3 3 3 % $rc|dd|ddd|dd|ddd |d dS) Nr.rr/a/targetr@rr4rr a/b/c/targetrrs r$test_path_through_sym_link_to_parentz=FakeFilesystemVsRealTest.test_path_through_sym_link_to_parentvsx sC((( sJ ;;; sE*** sGT222 &&~66666rc|dd|dd|dd|ddd|dd d |d dS) Nr.rra/sibling_of_br/a/sibling_of_b/targetr@r4r../sibling_of_brrrs r"test_sym_link_to_sibling_directoryz;FakeFilesystemVsRealTest.test_sym_link_to_sibling_directory~s sC((( sE*** s$4555 s$;ZHHH sG->??? &&~66666rc|dd|dd|dd|ddd|dd d |d dS) Nr.rrrr/rr@r4rrza/b/c/file_does_not_existrrs r4test_sym_link_to_sibling_directory_non_existant_filezMFakeFilesystemVsRealTest.test_sym_link_to_sibling_directory_non_existant_files sC((( sE*** s$4555 s$;ZHHH sG->??? &&'BCCCCCrc|dd|dd|dd|ddd|dd d |d dS) Nr.rrrr/rr@r4rz../broken_sibling_of_brrrs r)test_broken_sym_link_to_sibling_directoryzBFakeFilesystemVsRealTest.test_broken_sym_link_to_sibling_directorys sC((( sE*** s$4555 s$;ZHHH sG-EFFF &&~66666rc|dd|dd|dd|ddd|ddS) Nr.rrrr/rr@za/b/../sibling_of_b/targetrrs rtest_relative_pathz+FakeFilesystemVsRealTest.test_relative_pathsy sC((( sE*** s$4555 s$;ZHHH &&'CDDDDDrc|dd|dd|dd|ddd|ddS) Nr.rrrr/rr@za/b/../broken/targetrrs rtest_broken_relative_pathz2FakeFilesystemVsRealTest.test_broken_relative_pathsy sC((( sE*** s$4555 s$;ZHHH &&'=>>>>>rc|dd|ddd|dd|dd|ddd|d dS) Nr.rr/rr@rrrza/b/../broken/../targetrrs rtest_bad_relative_pathz/FakeFilesystemVsRealTest.test_bad_relative_paths sC((( sJ ;;; sE*** s$4555 s$;ZHHH &&'@AAAAArc2|dddS)Ngetmtimez no/such/pathrrs rtest_getmtime_nonexistant_pathz7FakeFilesystemVsRealTest.test_getmtime_nonexistant_paths ..z>JJJJJrc|ddd|ddd|ddd|ddd|ddd|dd d|dd d|dd d|d d d|d d d|ddd|ddd|ddd|ddd|ddd|ddd|ddd|ddd|ddd|ddd|ddd|ddd|ddd|ddd|dd ddS)Nr/rrr;r8rzother contentsr0rreadplus writepluszr+zw+r2 binaryreadr binarywrite binaryappendrbsother contentsr3abenc)encoding)rr3zutf-8)rFrrrs rtest_builtin_open_modesz0FakeFilesystemVsRealTest.test_builtin_open_modess sFO<<< sG_=== sHo>>> ++FC9IJJJ ++GS:JKKK ++Hc;KLLL sJ@@@ sKAAA ++J>NOOO ++K?OPPP sL2BCCC sM3CDDD sN4DEEE ++L$@QRRR ++M4ARSSS ++NDBSTTT ++FD:JKKK ++GT;KLLL ++Hdr?s1LK  8888888888$$$$$$>>>>>x >>> ^ Q^ Q^ Q^ Q^ Qx^ Q^ Q^ QB zHMOOOOOrtests/__pycache__/fake_open_test.cpython-311.pyc000064400000624435150043321520015617 0ustar00 bgeILdZddlZddlZddlZddlZddlZddlZddlZddlZddl m Z m Z ddl m Z mZddlmZddlmZddlmZGdd eZGd d eZGd d eZGddeZGddeZejejdkdGddeZGddeZejejdkdGddeZGddeZGddeZ Gdde Z!Gd d!eZ"Gd"d#e"Z#Gd$d%eZ$Gd&d'e$Z%Gd(d)eZ&Gd*d+e&Z'Gd,d-eZ(Gd.d/eZ)Gd0d1eZ*Gd2d3e*Z+Gd4d5e+Z,Gd6d7e*Z-Gd8d9e-Z.Gd:d;eZ/Gd<d=e/Z0Gd>d?eZ1Gd@dAe1Z2e3dBkrej4dSdS)Cz&Unit tests for fake_open.FakeOsModule.N)fake_filesystemhelpers)is_rootIS_PYPY) FakeIoModule) PatchMode)RealFsTestCasec$eZdZfdZdZxZS)FakeFileOpenTestBasectt||rtj|_dSt |j|_|jj|_dSN) superr setUp use_real_fsioopenr filesystemfake_io_moduleself __class__s n/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/tests/fake_open_test.pyrzFakeFileOpenTestBase.setUp#sd "D))//111      1DIII".t"?"?D +0DIIIcdS)N!rs rpath_separatorz#FakeFileOpenTestBase.path_separator+ssr)__name__ __module__ __qualname__rr __classcell__rs@rr r "sG11111rr ceZdZfdZfdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZ dZ!d Z"d!Z#d"Z$d#Z%d$Z&d%Z'd&Z(d'Z)d(Z*d)Z+d*Z,d+Z-d,Z.d-Z/d.Z0d/Z1d0Z2d1Z3d2Z4d3Z5d4Z6d5Z7d6Z8d7Z9d8Z:d9Z;d:Zd=Z?d>Z@d?ZAd@ZBdAZCdBZDdCZEdDZFdEZGdFZHdGZIdHZJdIZKdJZLdKZMdLZNdMZOxZPS)NFakeFileOpenTestcxtt|tj|_dSr )rr%rtime orig_timers rrzFakeFileOpenTest.setUp0s- %%++---rcxtt||jt_dSr )rr%tearDownr(r'rs rr*zFakeFileOpenTest.tearDown4s- %%..000N rc|dd}|tj|j|ddS)z8Expect raise when opening a file in a missing directory.foobar.txtwN) make_pathassert_raises_os_errorerrnoENOENTrr file_paths rtest_open_no_parent_dirz(FakeFileOpenTest.test_open_no_parent_dir8s9NN5)44  ##EL$)YLLLLLrc|d}d}|j|tj|jd|_||d5||j|dddn #1swxYwY| |j|dS)Nboozboo!farTdelete_on_closer.) skip_real_fsosmkdirr FakeFileOpenrr assertTrueexists assertFalserfile_dirr4s rtest_delete_on_closez%FakeFileOpenTest.test_delete_on_close=s    h#0RVWWW YYy# & & ? ? OODO229== > > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // ::;;;;;s).B##B'*B'cT|d}||d5||jj|dddn #1swxYwY||jj|dS)Nczarr.)r/rr>r;pathr?r3s r"test_no_delete_on_close_by_defaultz3FakeFileOpenTest.test_no_delete_on_close_by_defaultGsNN6** YYy# & & < < OODGL// :: ; ; ; < < < < < < < < < < < < < < <  ++I6677777s3A++A/2A/c|tj|jd|_d}||jj|||d5| |jj|dddn #1swxYwY||jj|dS)NTr8r,r.) r:rr=rrr@r;rFr?r>r3s r$test_compatibility_of_with_statementz5FakeFileOpenTest.test_compatibility_of_with_statementMs #0RVWWW   ,,Y77888 YYy# & & < < OODGL// :: ; ; ; < < < < < < < < < < < < < < < ,,Y7788888s?3B>>CCc|d}d} ||d5}||dddn #1swxYwYn%#t$r|dYnwxYw||5}|}dddn #1swxYwY|||dS)Nr,u Ümläütsr.,This test does not work with an ASCII locale)r/rwriteUnicodeEncodeErrorskipTestread assertEqual)rr4text_fractionsfcontentss rtest_unicode_contentsz&FakeFileOpenTest.test_unicode_contentsXs`NN5)) & J9c** (a''' ( ( ( ( ( ( ( ( ( ( ( ( ( ( (! J J J MMH I I I I I JYYy ! ! QvvxxH                >22222sFAA AAAAAA?>A?B88B<?B<c|d}d}||d5}||dddn #1swxYwY||d5}|}dddn #1swxYwY|||ddS)Nr,⅓ ⅔ ⅕ ⅖wbutf-8encoding)r/rrLrOrPdecode)rr4byte_fractionsrRrSs rtest_byte_contentsz#FakeFileOpenTest.test_byte_contentsis1NN5)) O YYy$ ' ' $1 GGN # # # $ $ $ $ $ $ $ $ $ $ $ $ $ $ $YYy7Y 3 3 qvvxxH                >#8#8#A#ABBBBBs#AAA2BBBc|d}d} ||d5}||dddn #1swxYwYn%#t$r|dYnwxYw||d5}|}dddn #1swxYwY|||tj ddS)Nr,uÄsgülr.rKrbF) r/rrLrMrNrOrPr[localegetpreferredencoding)rr4 str_contentsrRrSs rtest_write_str_read_bytesz*FakeFileOpenTest.test_write_str_read_bytestsNN5))   J9c** &a %%% & & & & & & & & & & & & & & &! J J J MMH I I I I I JYYy$ ' ' 1vvxxH                 (//&*Ee*L*LMM     sFAA AAAAAA?>A?B99B=B=c8gd}|d}||d|||5}|||ddddS#1swxYwYdSNz I am he as zyou are he as zyou are me and zwe are all together r-rS)r/ create_filejoinrrP readlines)rrSr4 fake_files rtest_open_valid_filez%FakeFileOpenTest.test_open_valid_files    NN9--  RWWX->->??? YYy ! ! >Y   Xy':':'<'< = = = > > > > > > > > > > > > > > > > > >s)BBBc<ddg}|dd}||d|||d5}|||dddn #1swxYwY||dd d d 5}|d dd |jjz|dg}|||ddddS#1swxYwYdS)Nz"Bang bang Maxwell's silver hammer Came down on her head abbey_roadmaxwellrgrh bufferingstrict )rterrorsnewlineopenerr)r/rirjrrPrkr;linesep)rrSr4rRexpected_contentss rtest_open_valid_argsz%FakeFileOpenTest.test_open_valid_argss 1 # NN<;;  RWWX->->??? YYyAY . . 6!   Xq{{}} 5 5 5 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 YY 8T$   ?  CRC 47?2 !    . > > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?s%)BBB6ADDDcvgd}|d}||d||j|j||5}|||ddddS#1swxYwYdSre) r/rirjr;chdir base_pathrrPrk)rrSr4rRs rtest_open_valid_file_with_cwdz.FakeFileOpenTest.test_open_valid_file_with_cwds    NN9--  RWWX->->???  dn%%% YYy ! ! 6Q   Xq{{}} 5 5 5 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6s8)B..B25B2c,ddg}|dd}||d|||5}d|D}dddn #1swxYwY|||dS)Nz!Bang bang Maxwell's silver hammerrorprqrvrhc6g|]}|Srrstrip.0lines r z;FakeFileOpenTest.test_iterate_over_file.. :::dkkmm:::r)r/rirjrrP)rrSr4rlresults rtest_iterate_over_filez'FakeFileOpenTest.test_iterate_over_files / # NN<;;  TYYx-@-@AAA YYy ! ! ;Y:: :::F ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; 6*****s A33A7:A7cddg}g}|d}||d|||5}|t ||t |dddn #1swxYwY|||dS)Nz Live long z and prosper zfoo.txtrgrh)r/rirjrappendnextrP)rrSrr4rls rtest_next_over_filez$FakeFileOpenTest.test_next_over_files!?3NN9--  RWWX->->??? YYy ! ! +Y MM$y// * * * MM$y// * * * + + + + + + + + + + + + + + + 6*****sAB,,B03B0c"|d}|j||jr-|t j|jj|dS|t j |jj|dSNr,) r/r;r< is_windowsr0r1EACCESr__call__EISDIR)rdirectory_paths rtest_open_directory_errorz*FakeFileOpenTest.test_open_directory_errors..  n%%% ?   ' ' di0.       ' ' di0.     rcgd}|d}|jj|d}|j|||d5}|D]}||dz dddn #1swxYwY||5}d|D}dddn #1swxYwY|||dS)Nz"Here comes the sun, little darlin'zHere comes the sun, and I say,z It's alrightrphere_comes_the_sunr.rvc6g|]}|Srrrs rrz@FakeFileOpenTest.test_create_file_with_write..rrr/r;rFrjr<rrLrPrrSrBr4rlrrs rtest_create_file_with_writez,FakeFileOpenTest.test_create_file_with_write|    >>,//GL%%h0DEE   h YYy# & & -)  - -t ,,,, - - - - - - - - - - - - - - - -YYy ! ! ;Y:: :::F ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; 6*****$*BBB5 CCCcgd}|d}|jj|d}|j|||d5}|D]}||dz dddn #1swxYwY||5}d|D}dddn #1swxYwY|||dS)Nrrprarvc6g|]}|Srrrs rrzAFakeFileOpenTest.test_create_file_with_append..rrrrs rtest_create_file_with_appendz-FakeFileOpenTest.test_create_file_with_appendrrc||d}|||tj|j|d|tj|j|ddS)Nbarxxb)skip_if_symlink_not_supportedr/rir0r1EEXISTrr3s r"test_exclusive_create_file_failurez3FakeFileOpenTest.test_exclusive_create_file_failures{ **,,,NN5))  ### ##EL$)YLLL ##EL$)YMMMMMrc|d}|jj|d}|j|d}||d5}||dddn #1swxYwY||5}|||ddddS#1swxYwYdS)Nr,rzString contentsr r/r;rFrjr<rrLrPrOrrBr4rSrls rtest_exclusive_create_filez+FakeFileOpenTest.test_exclusive_create_filesP>>%((GL%%h66   h$ YYy# & & &) OOH % % % & & & & & & & & & & & & & & & YYy ! ! 9Y   Xy~~'7'7 8 8 8 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9s$(B  BB*)C  C$'C$c|d}|jj|d}|j|d}||d5}||dddn #1swxYwY||d5}|||ddddS#1swxYwYdS)Nr,rsBinary contentsrr_rrs r!test_exclusive_create_binary_filez2FakeFileOpenTest.test_exclusive_create_binary_filesR>>%((GL%%h66   h% YYy$ ' ' &9 OOH % % % & & & & & & & & & & & & & & & YYy$ ' ' 99   Xy~~'7'7 8 8 8 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9s$(B  BB+)C!!C%(C%c|d}||dddg}||d5}|D]}||dz dddn #1swxYwY||5}d|D}dddn #1swxYwY|||dS) Noverwitez To disappearrhzOnly these lineszshould be in the file.r.rvc6g|]}|Srrrs rrzAFakeFileOpenTest.test_overwrite_existing_file..rrr/rirrLrP)rr4 new_contentsrlrrs rtest_overwrite_existing_filez-FakeFileOpenTest.test_overwrite_existing_file scNN:..  ^<<<  $ YYy# & & -)$ - -t ,,,, - - - - - - - - - - - - - - - -YYy ! ! ;Y:: :::F ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; v.....s$A22A69A6 B++B/2B/c|d}dg}|||d||d5}|ddD]}||dz dddn #1swxYwY||5}d|D}dddn #1swxYwY|||dS) N appendfilez*Contents of original fileAppended contentsrrhrrrrvc6g|]}|Srrrs rrz>FakeFileOpenTest.test_append_existing_file..$rrr)rr4rSrlrrs rtest_append_existing_filez*FakeFileOpenTest.test_append_existing_fileslNN<00 ;  Xa[999 YYy# & & -)   - -t ,,,, - - - - - - - - - - - - - - - -YYy ! ! ;Y:: :::F ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; 6*****s$ &A??BB B88B<?B<cp|d}||d||jj|||d5}|d|dddn #1swxYwY||d5}| d| d|d|ddddS#1swxYwYdS)N wplus_file old contentsrhrw+ new contentsr) r/rir>r;rFr?rrPrOrLseekrr4rls rtest_open_with_wplusz%FakeFileOpenTest.test_open_with_wplus'sNN<00  ^<<<  ++I66777 YYy# & & ?)   ^Y^^-=-= > > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?YYy$ ' ' >9 OON + + + NN1    OONINN,<,< = = = > > > > > > > > > > > > > > > > > >s%5)B**B.1B. AD++D/2D/cF|d}||d||jj|||d5}|d|dddn #1swxYwY||d5}| d|d|ddddS#1swxYwYdS)Nrrrhrrrrg) r/rir>r;rFr?rrPrOrrs rtest_open_with_wplus_truncationz0FakeFileOpenTest.test_open_with_wplus_truncation4sNN<00  ^<<<  ++I66777 YYy# & & ?)   ^Y^^-=-= > > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?YYy$ ' ' 39 NN1      R!1!1 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3s$5)B**B.1B. >DDDcfgd}ddg}|d}||d|||d5}|t j5|ddddn #1swxYwY|t j5|dddn #1swxYwYtd|}|t|t|j j d z zz }| || |d| d| ||dddn #1swxYwY||5}| ||z|ddddS#1swxYwYdS) NrfzThese new lines zlike you a lot. rrgrhrrrr)r/rirjr assertRaisesrUnsupportedOperationrOreadlinelenr;r{rPtellr writelinesrk)rrSadditional_contentsr4rl expected_lens rtest_open_with_append_flagz+FakeFileOpenTest.test_open_with_append_flag@s    34GHNN<00  RWWX->->??? YYy# & & 6)""2#:;; " "q!!! " " " " " " " " " " " " " " """2#:;; % %""$$$ % % % % % % % % % % % % % % %rwwx0011L CMMS-A-AA-EF FL   \9>>+;+; < < < NN1      Q  0 0 1 1 1  !4 5 5 5 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6YYy ! ! TY   X(;;Y=P=P=R=R S S S T T T T T T T T T T T T T T T T T Tsm G >B  G  B$ $G 'B$ ("G  C+ G +C/ /G 2C/ 3CG  GG-,H&&H*-H*c^|d}||d||jj|||d5}|d|dddn #1swxYwY|j r tj |j d|_||d5}|d| | d |d | |d |d |ddddS#1swxYwYdS) N aplus_filerrhrTr8a+ rrold contentsnew contents)r/rir>r;rFr?rrPrOrrr=rrLrrs rcheck_append_with_aplusz(FakeFileOpenTest.check_append_with_aplusXsNN<00  ^<<<  ++I66777 YYy# & & ?)   ^Y^^-=-= > > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? '4DIYYy$ ' ' K9   R!1!1 2 2 2 OON + + +   R!1!1 2 2 2 NN1      79I9I J J J  K K K K K K K K K K K K K K K K K Ks%5)B**B.1B.2B#F""F&)F&cV||dSr )check_macos_onlyrrs rtest_append_with_aplus_mac_osz.FakeFileOpenTest.test_append_with_aplus_mac_osks,  $$&&&&&rcV||dSr )check_linux_and_windowsrrs r$test_append_with_aplus_linux_windowsz5FakeFileOpenTest.test_append_with_aplus_linux_windowsos, $$&&& $$&&&&&rc|d}||d||jj|||d5}|d|dddn #1swxYwY||d5}| d| d| d|D]}|d| ddddS#1swxYwYdS) Nrrrhrrrrr r/rir>r;rFr?rrPrOrrL)rr4rlrs r%test_append_with_aplus_read_with_loopz6FakeFileOpenTest.test_append_with_aplus_read_with_loopssNN<00  ^<<<  ++I66777 YYy# & & ?)   ^Y^^-=-= > > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?YYy$ ' ' C9 NN1    OON + + + NN1   ! C C  !;TBBBB C  C C C C C C C C C C C C C C C C C Cs%5)B**B.1B. AD44D8;D8c|d}||d5}|d|ddddS#1swxYwYdS)Nrrrg)r/rrPrOrs rtest_read_empty_file_with_aplusz0FakeFileOpenTest.test_read_empty_file_with_aplussNN<00 YYy$ ' ' 39   R!1!1 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3s)A""A&)A&c|d}||d||jj|||d5}|d|dddn #1swxYwY||d5}|d|| d| d| d|d|ddddS#1swxYwYdS) N rplus_filezold contents hererhrr+rrznew contents hererrs rtest_read_with_rplusz%FakeFileOpenTest.test_read_with_rplussNN<00  -@AAA  ++I66777 YYy# & & D)   0)..2B2B C C C D D D D D D D D D D D D D D DYYy$ ' ' D9   0)..2B2B C C C NN1    OON + + + NN1      0)..2B2B C C C  D D D D D D D D D D D D D D D D D Ds%5)B**B.1B. BE((E,/E,c|||j|||tjzr|j|}|||j||jt j z| |jt j zdSdSr ) rir;chmodr PERM_READstatassert_mode_equalst_moder>S_IFREGr@S_IFDIR)rr4 perm_bitssts rcreate_with_permissionz'FakeFileOpenTest.create_with_permissions ###  i+++ w( ( 8i((B  " "9bj 9 9 9 OOBJ5 6 6 6   RZ$,6 7 7 7 7 7  8 8rc||d}||d||d||d||d|t 5||dddddS#1swxYwYdS)N target_fileirr.rINV)check_posix_onlyr/rrcloser ValueErrorr3s rtest_open_flags700z#FakeFileOpenTest.test_open_flags700s' NN=11  ##Iu555 )S!!''))) )S!!''))) )T""((***   z * * ( ( IIi ' ' ' ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (sC66C:=C:c0||d}||d||dt sP|tj|j|d|tj|j|ddS||d||ddS)Nrrr.r) rr/rrrrr0r1rr3s rtest_open_flags400z#FakeFileOpenTest.test_open_flags400s NN=11  ##Iu555 )S!!'')))yy /  ' ' diC P P P  ' ' diD Q Q Q Q Q IIi % % + + - - - IIi & & , , . . . . .rc||d}||d||dt s|t5||ddddn #1swxYwY|t5||dddddS#1swxYwYdS||d||ddS)Nrr.rr)rr/rrrrrOSErrorr3s rtest_open_flags200z#FakeFileOpenTest.test_open_flags200s NN=11  ##Iu555 )S!!'')))yy /""7++ * * )S))) * * * * * * * * * * * * * * *""7++ + + )T*** + + + + + + + + + + + + + + + + + + IIi % % + + - - - IIi & & , , . . . . .s$B33B7:B7C<<DDcF||d}||dts|t 5||ddddn #1swxYwY|t 5||ddddn #1swxYwY|t 5||dddddS#1swxYwYdS||d||d||ddS)Nr@rr.r)rr/rrrrrrr3s rtest_open_flags100z#FakeFileOpenTest.test_open_flags100s5 NN=11  ##Iu555yy /""7++ * * )S))) * * * * * * * * * * * * * * *""7++ * * )S))) * * * * * * * * * * * * * * *""7++ + + )T*** + + + + + + + + + + + + + + + + + + IIi % % + + - - - IIi % % + + - - - IIi & & , , . . . . .s6(B  BB0CCC8DD #D c||ddd}|d}d}|||||||||j|||d}|}| | ||dS)Nr,rbaztarJAYreal baz contentsrhr) rr/ricreate_symlinkassert_equal_pathsr;readlinkrrOrrPr link_pathtargettarget_contentsfh got_contentss rtest_follow_link_readz&FakeFileOpenTest.test_follow_link_reads **,,,NN5%77 ))- /::: Iv... (8(8(C(CDDD YYy# & &wwyy    ,77777rcP||ddd}|d}d}|||||jj|||d5}||dddn #1swxYwY||d5}| }dddn #1swxYwY| ||dS)Nr,rTBDrrr.r) rr/rr@r;rFr?rrLrOrPr s rtest_follow_link_writez'FakeFileOpenTest.test_follow_link_writes **,,,NN5%77 ))- Iv... ,,V44555 YYy# & & &" HH_ % % % & & & & & & & & & & & & & & & YYvs # # %r7799L % % % % % % % % % % % % % % % ,77777s$!CC C$DD  D c||jj|jddddd}|ddd}||dd||jj|jddd|d||jj |||jj |d}| |d5}| |dddn #1swxYwY| |d 5}| }dddn #1swxYwY| ||dS) Nr,build local_machineoutput1tmprr.r)rr;rFrjrr/ create_dirrr@r?rrLrOrPr s r!test_follow_intra_path_link_writez2FakeFileOpenTest.test_follow_intra_path_link_writes **,,,GL%% NE7OXs  x55 uh77888  GL  dneWo N N NN5 ! !   ,,Y77888 ,,V44555- YYy# & & &" HH_ % % % & & & & & & & & & & & & & & & YYvs # # %r7799L % % % % % % % % % % % % % % % ,77777s$E**E.1E. F,,F03F0cN||d}|j||jj|d}|j|||tj |j |dS)Nr,r) rr/r;r<rFrjsymlinkr0r1ELOOPrrAs r test_open_raises_on_symlink_loopz1FakeFileOpenTest.test_open_raises_on_symlink_loop s >>%((  hGL%%h66   9--- ##EKIFFFFFrc|d}||d|d}||d|d}||d||5}||5}||5}|}||||||dddn #1swxYwYdddn #1swxYwYddddS#1swxYwYdS)N some_file1contents here1rh some_file2contents here2 some_file3contents here3r/rirfileno assertGreater)r first_path second_path third_path fake_file1 fake_file2 fake_file3fileno2s r)test_file_descriptors_for_different_filesz:FakeFileOpenTest.test_file_descriptors_for_different_filessF^^L11  .>???nn\22  /?@@@^^L11  .>??? YYz " " Ej;'' E:YYz**Ej(//11G&&w 0A0A0C0CDDD&&z'8'8':':GDDDEEEEEEEEEEEEEEE E E E E E E E E E E E E E E E E E E E E E E E E E E E E E E E E Es[E&0EA%D7+ E7D; ;E>D; ?E E&E E&E E&&E*-E*c|d}||d|d}||d||5}||5}||5}|}||||||dddn #1swxYwYdddn #1swxYwYddddS#1swxYwYdS)Nr"r#rhr$r%r()rr+r,r.r/ fake_file1ar1s r5test_file_descriptors_for_the_same_file_are_differentzFFakeFileOpenTest.test_file_descriptors_for_the_same_file_are_different%s^^L11  .>???nn\22  /?@@@ YYz " " Fj;'' F:YYz**Fk(//11G&&w 0A0A0C0CDDD&&{'9'9';';WEEEFFFFFFFFFFFFFFF F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F Fs[.D:D"A%D ? D" D D"D D" D:"D& &D:)D& *D::D>D>c|d}||d|d}||d|d}||d||d5}||d5}||d}||d}|}|} |} |} dddn #1swxYwYdddn #1swxYwY||d5}||d5} ||||| | || ||| |dddn #1swxYwYdddn #1swxYwY||dS) Nr"r#rhr$r%r&r'r)r/rirr)rPr) rr+r,r-r.r/r0r4fileno1r1fileno3fileno4 fake_file1bs r1test_reused_file_descriptors_do_not_affect_otherszBFakeFileOpenTest.test_reused_file_descriptors_do_not_affect_others1s[^^L11  .>???nn\22  /?@@@^^L11  .>??? YYz3 ' ' /:;,, / !YYz377 "ii C88 $++--$++--$++--%,,..  / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /YY{C ( ( @J:s++ @{  **;*;*=*=>>>  +*<*<*>*>???  **;*;*=*=>>>  +*<*<*>*>???  @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ snE2A=D;/ E;D? ?ED? EEE3I B!H7+ I7H; ;I>H; ?IIIc|d}||||d5}||d5}gd}g}|D]f}||||||g|||gd}g}|D]>}||||?|d|D|dddn #1swxYwYddddS#1swxYwYdS)N some_filerr)hellozworld zsomewhere overzthe rainbow)nothingzto seeherecg|]}dSrgrr_s rrz@FakeFileOpenTest.test_intertwined_read_write..g!5!5!5"!5!5!5rr/rirrLflushrrOrPrr4writerreaderwritesreadsrLs rtest_intertwined_read_writez,FakeFileOpenTest.test_intertwined_read_writeKsNN;//  ### YYy# & & >&9c** >f###ELL'''LLNNNLL///LLNNNN  ///777$00ELL'''LL////  !5!5f!5!5!5u===/ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > >s7E)C-E E)E E)E E))E-0E-c|d}||||dd5}||dd5}gd}g}|D]f}||||||g|||ddg}g}|D]>}||||?|d |D|dddn #1swxYwYddddS#1swxYwYdS) Nr=rrXrYr)u приветuмир uгде-то заuрадугойu ничегоuне видноcg|]}dSrCrrDs rrzLFakeFileOpenTest.test_intertwined_read_write_python3_str..rFrrGrIs r'test_intertwined_read_write_python3_strz8FakeFileOpenTest.test_intertwined_read_write_python3_strisNN;//  ### YYy#Y 8 8 >F9cG<< >\\\###ELL'''LLNNNLL///LLNNNN  ///(*<=$00ELL'''LL////  !5!5f!5!5!5u===# > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > >s7E-C-E E-E E-E E--E14E1cPdd5}t5|dddn #1swxYwYt5|dddn #1swxYwYdddn #1swxYwYd5}t5|dddn #1swxYwYt5|dddn #1swxYwYdddn #1swxYwYd5}t5|dddn #1swxYwYt5|ddddn #1swxYwYt5| ddgdddn #1swxYwYdddn #1swxYwYfd}t5|ddddn #1swxYwYt5|dddddS#1swxYwYdS) Nr=rr.rrScontentscr|5}|D]} ddddS#1swxYwYdSr )r)moderRrEr4rs r_iterator_openz._iterator_opens9d++ qA                  s ,00) r/rirrrrOrktruncaterLr)rrrWr4s` @rtest_open_io_errorsz$FakeFileOpenTest.test_open_io_errorssNN;//  ### YYy# & & """7++                  ""7++                                  YYy# & & """7++                  ""7++                                  YYy# & & 0"""7++                  ""7++ % %$$$ % % % % % % % % % % % % % % %""7++ 0 0 ug./// 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0  0 0 0 0 0 0 0 0 0 0 0 0 0 0 0         w ' '  N3                    w ' '  N3                     sVCA?3 C?B CB C$C9 CC C C CC #C =FD9- F9D= =FD= FE?3 F?F FF FFF7JG3' J3G7 7J:G7 ;JH:. J:H> >JH> JJ7 JJ J J JJ!J KK!$K! LL"Lc||d}|||jj|d}|tj|j |ddSNrrr.) rr/rir;rFrjr0r1ENOTDIRrr3s r1test_open_raises_io_error_if_parent_is_file_posixzBFakeFileOpenTest.test_open_raises_io_error_if_parent_is_file_posixsv NN5))  ###GL%%i77  ##EM49iMMMMMrc||d}|||jj|d}|tj|j |ddSr[) check_windows_onlyr/rir;rFrjr0r1r2rr3s r3test_open_raises_io_error_if_parent_is_file_windowszDFakeFileOpenTest.test_open_raises_io_error_if_parent_is_file_windowssv !!!NN5))  ###GL%%i77  ##EL$)YLLLLLrc|d|jjjz}|||j|ddSNr,r.)r/r;rFsepr0r)rerror_nrrFs rcheck_open_with_trailing_sepz-FakeFileOpenTest.check_open_with_trailing_sepsA~~e$$tw|'77 ##HdisCCCCCrcl||tjdSr )check_linux_onlyrer1rrs r!test_open_with_trailing_sep_linuxz2FakeFileOpenTest.test_open_with_trailing_sep_linux0  ))%,77777rcl||tjdSr )rrer1r2rs r!test_open_with_trailing_sep_macosz2FakeFileOpenTest.test_open_with_trailing_sep_macosrircl||tjdSr )r_rer1EINVALrs r#test_open_with_trailing_sep_windowsz4FakeFileOpenTest.test_open_with_trailing_sep_windowss0 !!! ))%,77777rcD|d}|j|tjt jz||d5}|d| ddddS#1swxYwYdS)Ndevicerrg) r:rrirS_IFBLKrPERM_ALLrrPrO)r device_pathrs rtest_can_read_from_block_devicez0FakeFileOpenTest.test_can_read_from_block_devices   ##K@P1PQQQ YY{C ( ( ,B   R + + + , , , , , , , , , , , , , , , , , ,s)BBBcp|d}||||d5}|d||d|jj|ddddS#1swxYwYdSNrr.test) r/rirrLrXrPr;rFgetsizerr4f0s rtest_truncate_flushes_contentsz/FakeFileOpenTest.test_truncate_flushes_contentssNN5))  ### YYy# & & A" HHV    KKMMM   Q 4 4Y ? ? @ @ @ A A A A A A A A A A A A A A A A A AsAB++B/2B/c|d}||d5}||d5}|d|||d|jj|dddn #1swxYwYddddS#1swxYwYdSrv) r/rrLrXrHrPr;rFryrr4r{f1s r1test_update_other_instances_of_same_file_on_flushzBFakeFileOpenTest.test_update_other_instances_of_same_file_on_flushseNN5)) YYy# & & E"9c** Eb       DGL$8$8$C$CDDD  E E E E E E E E E E E E E E E E E E E E E E E E E E E E E E E E Es6CA1C4 CC CC CCCc(|d}||d5}|d|d||d||d|jj||d|j |j ddddS#1swxYwYdS)Nr,rrbrr) r/rrLrrXrPr;rFryrst_sizerr4rRs rtest_getsize_after_truncatez,FakeFileOpenTest.test_getsize_after_truncates1NN5)) YYy# & & A! GGCLLL FF1III JJLLL GGCLLL JJLLL   Q 4 4Y ? ? @ @ @   Q Y 7 7 ? @ @ @ A A A A A A A A A A A A A A A A A AsCDD D c|d}||d5}|d||d||d|j|jddddS#1swxYwYdS)Nr,rr)r/rrLrXrPr;rrrs rtest_st_size_after_truncatez,FakeFileOpenTest.test_st_size_after_truncatesNN5)) YYy# & & A! GGCLLL JJLLL GGCLLL JJLLL   Q Y 7 7 ? @ @ @  A A A A A A A A A A A A A A A A A AsBB??CCcX|d}||||5}|d||d|ddddS#1swxYwYdS)Nrr)r/rirrrOrPrrzs r/test_that_read_over_end_does_not_reset_positionz@FakeFileOpenTest.test_that_read_over_end_does_not_reset_positionsNN5))  ### YYy ! ! +R GGAJJJ GGIII   Q * * * + + + + + + + + + + + + + + + + + +sABB#&B#c|jrtjd|d}||d||d}||t5| ddddn #1swxYwY|t5| ddddn #1swxYwY|t5| dddn #1swxYwY|t5| dddn #1swxYwY|t5| dddn #1swxYwY|t5|ddddn #1swxYwY|t5|ddddS#1swxYwYdS)NDifferent exceptions with PyPyr,testrhrrrr)is_pypyunittestSkipTestr/rirrrrrOrLrrXrrrHrs r!test_accessing_closed_file_raisesz2FakeFileOpenTest.test_accessing_closed_file_raisess < F#$DEE ENN5))  W555IIi--    z * *   NN1                     z * * ! ! OOC  ! ! ! ! ! ! ! ! ! ! ! ! ! ! !   z * * ! !     ! ! ! ! ! ! ! ! ! ! ! ! ! ! !   z * * ! !     ! ! ! ! ! ! ! ! ! ! ! ! ! ! !   z * *   NN                     z * *   NN1                     z * *   OO                     s~ B..B25B2C55C9<C9D;;D?D? FFF&GG G ,HHH3IIIc|jrtjd|d}|j|tjtjztjz}||d}| | t5| ddddn #1swxYwY| t5| ddddn #1swxYwY|j |dS)Nrr,rrrr)rrrr/r;rO_CREATO_WRONLYO_TRUNCrrrrOrL)rr4r{rls r3test_accessing_open_file_with_another_handle_raiseszDFakeFileOpenTest.test_accessing_open_file_with_another_handle_raisess < F#$DEE ENN5)) W\\)RZ"+%= %J K KIIi--    z * *   NN1                     z * * ! ! OOC  ! ! ! ! ! ! ! ! ! ! ! ! ! ! !  bs$4CCC;DD!$D!c||d}||d5}|d|d||d|jj|ddddS#1swxYwYdSNr,r.rwrx) rr/rrLrPrr;rFryrzs rtest_tell_flushes_under_mac_osz/FakeFileOpenTest.test_tell_flushes_under_mac_oss NN5)) YYy# & & A" HHV      Q * * *   Q 4 4Y ? ? @ @ @ A A A A A A A A A A A A A A A A A AA1B>>CCc||d}||d5}|d|d||d|jj|ddddS#1swxYwYdSr) rr/rrLrPrr;rFryrzs rtest_tell_flushes_in_python3z-FakeFileOpenTest.test_tell_flushes_in_python3's $$&&&NN5)) YYy# & & A" HHV      Q * * *   Q 4 4Y ? ? @ @ @ A A A A A A A A A A A A A A A A A Arc||d}||d5}|d|d||d|jj|ddddS#1swxYwYdS)Nr,rrwrgrx) rr/rrLrPrOr;rFryrzs rtest_read_flushes_under_posixz.FakeFileOpenTest.test_read_flushes_under_posix0s NN5)) YYy$ ' ' A2 HHV      R + + +   Q 4 4Y ? ? @ @ @ A A A A A A A A A A A A A A A A A Arcn||d}||d5}|d||d|jj|ddddS#1swxYwYdS)Nr,rrwrx) r_r/rrLrOrPr;rFryrzs r*test_read_flushes_under_windows_in_python3z;FakeFileOpenTest.test_read_flushes_under_windows_in_python39s !!!NN5)) YYy$ ' ' A2 HHV    GGIII   Q 4 4Y ? ? @ @ @ A A A A A A A A A A A A A A A A A AsAB**B.1B.c|d}||d5}|d|d|jj||d|d|jj|ddddS#1swxYwYdS)Nr,r.rwrrx)r/rrLrPr;rFryrrzs rtest_seek_flushesz"FakeFileOpenTest.test_seek_flushesBs NN5)) YYy# & & A" HHV      Q 4 4Y ? ? @ @ @ GGAJJJ   Q 4 4Y ? ? @ @ @  A A A A A A A A A A A A A A A A A AsBC  CCc|d}||d5}|d|d|jj|||d|jj|ddddS#1swxYwYdS)Nr,rrwrrx)r/rrLrPr;rFryrXrzs rtest_truncate_flushesz&FakeFileOpenTest.test_truncate_flushesKs NN5)) YYy# & & A" HHV      Q 4 4Y ? ? @ @ @ KKMMM   Q 4 4Y ? ? @ @ @  A A A A A A A A A A A A A A A A A AsBC  C C c|d}|||5}|d||d||d|jj||d|d|jj|dddn #1swxYwY|d|jj|dS)Nrrr) r/rrrXrPrr;rFry)rrVr4r{s r)check_seek_outside_and_truncate_sets_sizez:FakeFileOpenTest.check_seek_outside_and_truncate_sets_sizeTsRNN5)) YYy$ ' ' A2 GGAJJJ KKMMM   Q * * *   Q 4 4Y ? ? @ @ @ GGAJJJ   Q 4 4Y ? ? @ @ @  A A A A A A A A A A A A A A A DGL00;;<<<<rs r test_closedzFakeFileOpenTest.test_closedhsNN5)) IIi % % """   !!! IIi  """   !!!!!rcX|d}||d}|||5}||d|ddddS#1swxYwYdS)Nrr.rg)r/rrrPrOr~s r%test_closing_closed_file_does_nothingz6FakeFileOpenTest.test_closing_closed_file_does_nothingssNN5)) YYy# & &  YYy ! ! ,R HHJJJ   R + + + , , , , , , , , , , , , , , , , , ,s=BB#&B#cb||d}|j|tjtjz}|j|}||dd5}|ddddn #1swxYwY| |j ||j || |j |dS)Nztest.txtrWFclosefdr) r:r/r;rrO_RDWRr get_objectrLr> has_open_filerr@)rfilenamefdfile_objfps r+test_closing_file_with_different_close_modez>*-- W\\(BJ$: ; ;?--h77 YYr4Y / / 2 HHW                   55h??@@@  b 66x@@AAAAAsB00B47B4c|d}||d5}||5}|d||d|dddn #1swxYwYddddS#1swxYwYdS)Nrr.rr)r/rrrXrPrOr~s rtest_truncate_flushes_zerosz,FakeFileOpenTest.test_truncate_flushes_zeross&NN5)) YYy# & & 2"9%% 2    rwwyy111 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2s6B8AB  B8 B$ $B8'B$ (B88B<?B<cd|d}||d5}|ddddn #1swxYwY||d5}|d|ddddS#1swxYwYdS)NrrWr_r/rrLrPrOrs rtest_byte_filenamez#FakeFileOpenTest.test_byte_filenamesNN7++ YYy$ ' ' 1 GGG                   YYy$ ' ' 01   Waffhh / / / 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0#AAA/)B%%B),B)cd|d}||d5}|ddddn #1swxYwY||d5}|d|ddddS#1swxYwYdS)NuтестrWrr_rrs rtest_unicode_filenamez&FakeFileOpenTest.test_unicode_filenamesNN:.. YYy$ ' ' 1 GGG                   YYy$ ' ' 01   Waffhh / / / 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0rchdD]}||jj|5}|ddddn #1swxYwY||jj5}|d|dddn #1swxYwYdS)N)rr.rrrrwrg)rr;devnullrLrPrO)rrVrRs rtest_write_devnullz#FakeFileOpenTest.test_write_devnulls0 / /D47?D11 Q               47?++ /q  QVVXX... / / / / / / / / / / / / / / / / /s#AA A 1)B&&B* -B* c|d}||dd5}|ddksJ dddn #1swxYwY||dd5}|ddksJ dddn #1swxYwY||d d5}|}|d ksJ ddddS#1swxYwYdS) Nr,r.zutf-16rYrrrr2r12)r/rrLrO)rr4rRtexts rtest_utf16_textz FakeFileOpenTest.test_utf16_textsNN5)) YYy#Y 9 9 %Q773<<1$$$$$ % % % % % % % % % % % % % % %YYy#Y 9 9 %Q773<<1$$$$$ % % % % % % % % % % % % % % %YYy#Y 9 9 Q6688D4<<<<<                  s5AAA:B##B'*B'C11C58C5)Qrr r!rr*r5rCrGrIrTr]rcrmr}rrrrrrrrrrrrrrrrrrrrrrrrrrrrr r2r5r;rNrQrYr]r`rerhrkrnrtr|rrrrrrrrrrrrrrrrrrrrrrrr"r#s@rr%r%/s##########MMM <<<888 9 9 9333" C C C     > > >???& 6 6 6 + + ++++   +++ +++ NNN999999 / / / + + + > > > 3 3 3TTT0KKK&'''''' C C C333 D D D888 ( ( ( / / //// ///$ 8 8 8 8 8 8888.GGG E E E F F F4>>><>>>0   @NNNMMMDDD 888888888,,,AAAEEE A A AAAA+++.   AAAAAAAAAAAAAAAAAA = = =<<<<<< " " ",,, B B B222000000///        rr%ceZdZdZdS)RealFileOpenTestcdSNTrrs rrzRealFileOpenTest.use_real_fstrNrr r!rrrrrr#rrcDeZdZdZdZdZdZdZdZdZ dZ d Z d S) FakeFileOpenWithOpenerTestc8|j||Sr )r;r)rrFflagss rryz!FakeFileOpenWithOpenerTest.openersw||D%(((rc|d}||d|||j5}|dksJ|t 5|ddddn #1swxYwYddddS#1swxYwYdS)Nr,rwrhry)r/rirryrOrrrLrs rtest_use_opener_with_readz4FakeFileOpenWithOpenerTest.test_use_opener_with_reads6NN5))  V444 YYyY 5 5 6688v%%%%""7++                                   s6 5B8>B  B8 B$ $B8'B$ (B88B<?B<c|d}||d||d|j5}|dksJ|ddksJ dddn #1swxYwY||5}|dksJ ddddS#1swxYwYdS) Nr,rwrhrrrrtestbarr/rirryrOrLrs rtest_use_opener_with_read_plusz9FakeFileOpenWithOpenerTest.test_use_opener_with_read_pluss`NN5))  V444 YYy$t{Y ; ; 'q6688v%%%%775>>Q&&&&& ' ' ' ' ' ' ' ' ' ' ' ' ' ' 'YYy ! ! )Q6688y((((( ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) )$ 6B  BB-CCCc|d}||d||d|j5}|t 5|dddn #1swxYwY|ddksJ dddn #1swxYwY||5}|dksJ ddddS#1swxYwYdS)Nr,rhr.rrr)r/rirryrrrOrLrs rtest_use_opener_with_writez5FakeFileOpenWithOpenerTest.test_use_opener_with_writesNN5))  U333 YYy#dkY : : 'a""7++                 775>>Q&&&&& ' ' ' ' ' ' ' ' ' ' ' ' ' ' 'YYy ! ! %Q6688u$$$$$ % % % % % % % % % % % % % % % % % %sH B9%B: B9B B9 B B99B=B=DD Dc|d}||d||d|j5}|dksJ|ddksJ dddn #1swxYwY||5}|dksJ ddddS#1swxYwYdS) Nr,rwrhrrrgrrrrs rtest_use_opener_with_write_plusz:FakeFileOpenWithOpenerTest.test_use_opener_with_write_pluss\NN5))  V444 YYy$t{Y ; ; 'q6688r>>>>775>>Q&&&&& ' ' ' ' ' ' ' ' ' ' ' ' ' ' 'YYy ! ! %Q6688u$$$$$ % % % % % % % % % % % % % % % % % %rc|d}||d||d|j5}|ddksJ|t 5|dddn #1swxYwYdddn #1swxYwY||5}|dksJ ddddS#1swxYwYdS)Nr,rhrrrrfoobar)r/rirryrLrrrOrs rtest_use_opener_with_appendz6FakeFileOpenWithOpenerTest.test_use_opener_with_appendsNN5))  U333 YYy#dkY : : a775>>Q&&&&""7++                                YYy ! ! (Q6688x''''' ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (sH 6B8B! B8!B% %B8(B% )B88B<?B<DDDc|d}||d||d|j5}|dksJ|ddksJ dddn #1swxYwY||5}|dksJ ddddS#1swxYwYdS) Nr,rhrrrgrrrrrs r test_use_opener_with_append_plusz;FakeFileOpenWithOpenerTest.test_use_opener_with_append_pluss\NN5))  U333 YYy$t{Y ; ; 'q6688r>>>>775>>Q&&&&& ' ' ' ' ' ' ' ' ' ' ' ' ' ' 'YYy ! ! (Q6688x''''' ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (rc|d}||d|t5||d|jdddn #1swxYwY|d}||d|j5}|ddksJ|t5|dddn #1swxYwYdddn #1swxYwY||5}|dksJ ddddS#1swxYwYdS)Nr,rwrhrrrrr/rirrrryrLrOrs r$test_use_opener_with_exclusive_writez?FakeFileOpenWithOpenerTest.test_use_opener_with_exclusive_writesPNN5))  V444   w ' ' : : IIiT[I 9 9 9 : : : : : : : : : : : : : : :NN5)) YYy#dkY : : a775>>Q&&&&""7++                                YYy ! ! %Q6688u$$$$$ % % % % % % % % % % % % % % % % % %sZA11A58A5.6D$D9 DD D D DD #D <E%%E),E)c|d}||d|t5||d|jdddn #1swxYwY|d}||d|j5}|ddksJ|dksJ dddn #1swxYwY||5}|dksJ ddddS#1swxYwYdS) Nr,rwrhzx+rrrrgrrs r#test_use_opener_with_exclusive_plusz>FakeFileOpenWithOpenerTest.test_use_opener_with_exclusive_plussNN5))  V444   w ' ' ; ; IIidkI : : : ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;NN5)) YYy$t{Y ; ; "q775>>Q&&&&6688r>>>>> " " " " " " " " " " " " " " "YYy ! ! %Q6688u$$$$$ % % % % % % % % % % % % % % % % % %s6A11A58A5.6C11C58C5D::D>D>N) rr r!ryrrrrrrrrrrrrrs))))))%%%%%%(((((( % % % % % % % %rrceZdZdZdS)RealFileOpenWithOpenerTestcdSrrrs rrz&RealFileOpenWithOpenerTest.use_real_fsrrNrrrrrrrrr)rz'open_code only present since Python 3.8ceZdZfdZfdZejeddZeje ddZ dZ dZ xZ S)FakeFilePatchedOpenCodeTestctt||rtj|_dSt j|j_ |j j|_dSr ) rrrrr open_coderONrpatch_open_coderrs rrz!FakeFilePatchedOpenCodeTest.setUps^ )40066888      ;\DNNN.7lDO +!0:DNNNrc|s d|j_tt|dS)NF)rrrrrr*rs rr*z$FakeFilePatchedOpenCodeTest.tearDownsD!! 4.3DO + )40099;;;;;rDifferent behavior in PyPyc|t5|dddddS#1swxYwYdSNrxr TypeErrorrrs rtest_invalid_pathz-FakeFilePatchedOpenCodeTest.test_invalid_path$   y ) )   NN1                     >AAc:|d}||d|j|tj}||5}|dksJ ddddS#1swxYwYdS)Nr,rwrhr)r/rir;rO_RDONLYrrO)rr4rrRs rtest_open_code_fd_pypyz2FakeFilePatchedOpenCodeTest.test_open_code_fd_pypy)sNN5))  V444 W\\)R[ 1 1 ^^B   '16688w&&&&& ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' 's'BBBcd}|d}|||||5}|}dddn #1swxYwY|||dSNrVr,rhr/rirrOrPrr\r4rRrSs rtest_byte_contents_open_codez8FakeFilePatchedOpenCodeTest.test_byte_contents_open_code1ONN5))  ^<<< ^^I & & !vvxxH                >22222A%%A),A)c|t}|t5||ddddS#1swxYwYdSr )r:__file__rrrr3s rtest_open_code_in_real_fsz5FakeFilePatchedOpenCodeTest.test_open_code_in_real_fs9s    w ' ' & & NN9 % % % & & & & & & & & & & & & & & & & & &sAA A) rr r!rr*rskipIfrrrr rr"r#s@rrrs;;;;;<<<<< X_W:;;<;X_[">??''@?'333&&&&&&&rrceZdZdZdS)RealPatchedFileOpenCodeTestcdSrrrs rrz'RealPatchedFileOpenCodeTest.use_real_fsArrNrrrrrr@rrrcXeZdZfdZejeddZdZxZ S)FakeFileUnpatchedOpenCodeTestctt||rtj|_dS|jj|_dSr )rrrrrrrrs rrz#FakeFileUnpatchedOpenCodeTest.setUpGsR +T2288:::      ;\DNNN!0:DNNNrrc|t5|dddddS#1swxYwYdSrrrs rrz/FakeFileUnpatchedOpenCodeTest.test_invalid_pathNrrct}||5}|}dddn #1swxYwY|t |dkdS)Nd)rrrOr>r)rr4rRrSs rrz7FakeFileUnpatchedOpenCodeTest.test_open_code_in_real_fsSs ^^I & & !vvxxH                H +,,,,,s>AA) rr r!rrrrrrr"r#s@rrrEsr;;;;;X_W:;;<;-------rrceZdZdZdZdS)RealUnpatchedFileOpenCodeTestcdSrrrs rrz)RealUnpatchedFileOpenCodeTest.use_real_fs\rrcd}|d}|||||5}|}dddn #1swxYwY|||dSrr r s rr z:RealUnpatchedFileOpenCodeTest.test_byte_contents_open_code_r r N)rr r!rr rrrrr[s233333rrcVeZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd S)BufferingModeTestcl|d}||dd5}|d||d5}|}|d|dddn #1swxYwYddddS#1swxYwYdS)Nbuffertest.binrWrrssaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaar_r/rrLrOrPrr4rRrrs rtest_no_bufferingz#BufferingModeTest.test_no_bufferingis(NN#344 YYy$!Y 4 4 0 GGJ   9d++ 0qFFHH  Q/// 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0s5,B)+B B)B B)B B))B-0B-c|d}|t5||ddddddS#1swxYwYdS)Nbuffertest.txtr.rrs)r/rrrr3s r)test_no_buffering_not_allowed_in_textmodez;BufferingModeTest.test_no_buffering_not_allowed_in_textmodeqsNN#344   z * * 3 3 IIiI 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3sAAAc|d}||d5}|d||d5}|}|d|dddn #1swxYwYdddn #1swxYwY||d5}|}|d|ddddS#1swxYwYdS)Nr"rWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaar_rr#r$s rtest_default_buffering_no_flushz1BufferingModeTest.test_default_buffering_no_flushvsNN#344 YYy$ ' ' )1 GGK 9d++ )qFFHH  a((( ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) YYy$ ' ' -1A   [! , , , - - - - - - - - - - - - - - - - - -sG,B&+B B&B B&B B&&B*-B*+C??DDc|d}||d5}|d|||d5}|}|d|dddn #1swxYwYddddS#1swxYwYdS)Nr"rWr*r_)r/rrLrHrOrPr$s rtest_default_buffering_flushz.BufferingModeTest.test_default_buffering_flushs1NN#344 YYy$ ' ' 11 GGK GGIII9d++ 1qFFHH  a000 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1s6AB;,+B# B;#B' 'B;*B' +B;;B?B?cV|d}||dd5}|d||d5}|}|dt |dddn #1swxYwY|d||d5}|}|d t |dddn #1swxYwY|d ||d5}|}|d t |dddn #1swxYwY|d ||d5}|}|d t |dddn #1swxYwY|d ||d5}|}|d t |dddn #1swxYwYddddS#1swxYwYdS)Nr"rWrsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaar_raaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaair/rrLrOrPrr$s r!test_writing_with_specific_bufferz3BufferingModeTest.test_writing_with_specific_buffersNN#344 YYy$#Y 6 6 /! GGJ   9d++ ,qFFHH  CFF+++ , , , , , , , , , , , , , , , GGJ   9d++ .qFFHH  c!ff--- . . . . . . . . . . . . . . . GGJ   9d++ .qFFHH  c!ff--- . . . . . . . . . . . . . . . GGJ   9d++ /qFFHH  s1vv...  / / / / / / / / / / / / / / / GGJ   9d++ /qFFHH  s1vv... / / / / / / / / / / / / / / // / / / / / / / / / / / / / / / / / /s,J8B JB" "J%B" &.J8D JD JD .J8F JF JF .J8H  J H JH .J8J: JJ J J JJ"%J"cb|d}||dd5}|d||d5}|}|dt |dddn #1swxYwY|d||d5}|}|d t |dddn #1swxYwY|d ||d5}|}|d t |dddn #1swxYwY|d||d5}|}|d t |dddn #1swxYwYddddS#1swxYwYdS) Nr"r.rrrstesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttestrr testi(testtesttesttesttesttesttesttesttesttestir6r$s r"test_writing_text_with_line_bufferz4BufferingModeTest.test_writing_text_with_line_buffersNN#344 YYy#Y 3 3 .q GGL ! ! !9c** ,aFFHH  CFF+++ , , , , , , , , , , , , , , , GGH   9c** .aFFHH  c!ff--- . . . . . . . . . . . . . . . GGK 9c** .aFFHH  c!ff--- . . . . . . . . . . . . . . . GGH   9c** .aFFHH  c!ff--- . . . . . . . . . . . . . . .# . . . . . . . . . . . . . . . . . .s,H$8B H$B" "H$%B" &.H$8D H$D H$D .H$8F H$F H$F .H$8H  H$ H H$H H$$H(+H(ch|d}||dd5}|ddz||d5}|}|dt |dddn #1swxYwY|d||d5}|}|dt |dddn #1swxYwY|d ||d5}|}|d t |dddn #1swxYwY|d ||d5}|}|d t |dddn #1swxYwYddddS#1swxYwYdS) Nr"r.rrrsrwiri>r:i>i>r6r$s r(test_writing_large_text_with_line_bufferz:BufferingModeTest.test_writing_large_text_with_line_buffersNN#344 YYy#Y 3 3 0q GGFTM " " "9c** 0aFFHH  A/// 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 GGFOOO9c** 0aFFHH  A/// 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 GGH   9c** 0aFFHH  A/// 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 GGH   9c** 0aFFHH  A/// 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0# 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0/H'8B! H'!B% %H'(B% ).H'8D H'D H'"D #.H'8F H'F H'F .H' 8H H'H H'H H''H+.H+c^|d}||d5}|d||d5}|}|dt |dddn #1swxYwY|d||d5}|}|dt |dddn #1swxYwY|d||d5}|}|dt |dddn #1swxYwY|d||d5}|}|dt |dddn #1swxYwYddddS#1swxYwYdS)Nr'r.testtesttesttesttestrrr:r;r6r$s r%test_writing_text_with_default_bufferz7BufferingModeTest.test_writing_text_with_default_buffersNN#344 YYy# & & ,! GGJ   9c** ,aFFHH  CFF+++ , , , , , , , , , , , , , , , GGH   9c** ,aFFHH  CFF+++ , , , , , , , , , , , , , , , GGK 9c** ,aFFHH  CFF+++ , , , , , , , , , , , , , , , GGH   9c** ,aFFHH  CFF+++ , , , , , , , , , , , , , , ,# , , , , , , , , , , , , , , , , , ,s,H"8B H"B H"#B $.H"8D H"D H"D .H" 8F H"F H"F .H"8H > H" H H"H H""H&)H&ch|d}||dd5}|ddz||d5}|}|dt |dddn #1swxYwY|d ||d5}|}|dt |dddn #1swxYwY|d ||d5}|}|dt |dddn #1swxYwY|d ||d5}|}|dt |dddn #1swxYwYddddS#1swxYwYdS) Nr'r.rrsri@rrrwr6r$s r&test_writing_text_with_specific_bufferz8BufferingModeTest.test_writing_text_with_specific_buffersNN#344 YYy#Y 3 3 ,q GGC$J   9c** ,aFFHH  CFF+++ , , , , , , , , , , , , , , , GGFOOO9c** ,aFFHH  CFF+++ , , , , , , , , , , , , , , , GGFOOO9c** ,aFFHH  CFF+++ , , , , , , , , , , , , , , , GGFOOO9c** ,aFFHH  CFF+++ , , , , , , , , , , , , , , ,# , , , , , , , , , , , , , , , , , ,r?c|d}||dd5}|ddddn #1swxYwY||dd5}|d||d5}|}|dt |dddn #1swxYwY|d ||d5}|}|d t |dddn #1swxYwY|d ||d5}|}|d t |dddn #1swxYwY|d ||d5}|}|d t |dddn #1swxYwY|d ||d5}|}|dt |dddn #1swxYwYddddS#1swxYwYdS)Nr"rWr/rsr0abr_r2r1r4r3ir5ir6r$s r test_append_with_specific_bufferz2BufferingModeTest.test_append_with_specific_buffer s8NN#344 YYy$#Y 6 6 ! GGJ                  YYy$#Y 6 6 /! GGJ   9d++ .qFFHH  c!ff--- . . . . . . . . . . . . . . . GGJ   9d++ /qFFHH  s1vv... / / / / / / / / / / / / / / / GGJ   9d++ /qFFHH  s1vv... / / / / / / / / / / / / / / / GGJ   9d++ /qFFHH  s1vv...  / / / / / / / / / / / / / / / GGJ   9d++ /qFFHH  s1vv... / / / / / / / / / / / / / / // / / / / / / / / / / / / / / / / / /sAAA3,K#8C# K##C' 'K#*C' +.K#8E K#E! !K#$E! %.K#8G K#G K#G .K# 8I K#I K#I .K#8K ? K# K K#K K##K'*K'c||jd|jd|jjdd}||d5}|d| ||d5}| }| | ddddn #1swxYwY| t5|d| dddn #1swxYwY||d5}| }| | ddddn #1swxYwY|dddddS#1swxYwYdS) Nrr,r-rW2aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaar_bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb2)r:rset_disk_usager;makedirsrFrjrrLrHrOr> startswithrrrXr$s r(test_failed_flush_does_not_truncate_filez:BufferingModeTest.test_failed_flush_does_not_truncate_file)s  &&s+++ GL%%eY77 YYy$ ' ' 1 GGI    GGIII9d++ 9qFFHH Y 7 7888 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9""7++   ###                9d++ 9qFFHH Y 7 7888 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 JJrNNN                  s?AG:?=D< G:D G:D G:-*E# G:#E' 'G:*E' +G:=G  G: G G:G G::G>G>cP||jd|jd|jjdd}||dd5}|d||d5}| }| d|dddn #1swxYwY| t5|d dddn #1swxYwY||d5}| }| d|dddn #1swxYwYddddS#1swxYwYdS) Nrr,r-rWrrsrIr_rJ) r:rrLr;rMrFrjrrLrOrPrrr$s r(test_failed_write_does_not_truncate_filez:BufferingModeTest.test_failed_write_does_not_truncate_file=ss  &&s+++ GL%%eY77 YYy$!Y 4 4 / GGI   9d++ /qFFHH  A... / / / / / / / / / / / / / / /""7++ $ $ ### $ $ $ $ $ $ $ $ $ $ $ $ $ $ $9d++ /qFFHH  A... / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /s~,F-+C$ F$C( (F+C( ,F D+ F+D/ /F2D/ 3F +F7 FF F F FF"FN)rr r!r%r(r+r-r7r<r>rBrDrGrOrQrrrr r hs000333 - - -111///<...00000,,,.,,,4///@(/////rr ceZdZdZdS)RealBufferingTestcdSrrrs rrzRealBufferingTest.use_real_fsPrrNrrrrrSrSOrrrSc^eZdZdZfdZdZdZdZdZdZ dZ d Z d Z d Z d ZxZS) OpenFileWithEncodingTestz]Tests that are similar to some open file tests above but using an explicit text encoding.ctt||d|_dSr)rrVrr/r4rs rrzOpenFileWithEncodingTest.setUpXs7 &--33555..rc~d}||jdd5}||dddn #1swxYwY||jd5}|}dddn #1swxYwY|||ddS)Nعلي باباr.arabicrYr_)rr4rLrOrPr[rrbrRrSs rrcz2OpenFileWithEncodingTest.test_write_str_read_bytes\s"( YYt~sXY > > "! GGL ! ! ! " " " " " " " " " " " " " " " YYt~t , , vvxxH                xx'@'@AAAAAs#AA A(B  B B cd}||jdd5}|t5||dddn #1swxYwYdddn #1swxYwY||jddd5}||dddn #1swxYwY||jdd5}|}dddn #1swxYwY|d |||jddd 5}||dddn #1swxYwY||jdd5}|}dddn #1swxYwY|d |dS) NrYr.cyrillicrYasciixmlcharrefreplacerZrwrz2علي بابا namereplacez\N{ARABIC LETTER AIN}\N{ARABIC LETTER LAM}\N{ARABIC LETTER YEH} \N{ARABIC LETTER BEH}\N{ARABIC LETTER ALEF}\N{ARABIC LETTER BEH}\N{ARABIC LETTER ALEF})rr4rrMrLrOrPr[s rtest_write_str_error_modesz3OpenFileWithEncodingTest.test_write_str_error_modesds=( YYt~sZY @ @ &A""#566 & & %%% & & & & & & & & & & & & & & & & & & & & & & & & & & & & & &YY NC':M   "  GGL ! ! ! " " " " " " " " " " " " " " "YYt~sWY = = vvxxH                MxXXX YY NC'-   "  GGL ! ! ! " " " " " " " " " " " " " " "YYt~sWY = = vvxxH                 &       s|A4A A4A! !A4$A! %A44A8;A8B??CC'DD D E))E-0E-F22F69F6cd}||jdd5}||dddn #1swxYwY||jd5}|t5|dddn #1swxYwYdddn #1swxYwY||jdd5}|}dddn #1swxYwY|||||jdd5}|}dddn #1swxYwY|d |dS) NrYr.rZrYr^replacer`backslashreplacez\xd9\xe4\xea \xc8\xc7\xc8\xc7)rr4rLrUnicodeDecodeErrorrOassertNotEqualrPr[s rtest_read_str_error_modesz2OpenFileWithEncodingTest.test_read_str_error_modess( YYt~sXY > > "! GGL ! ! ! " " " " " " " " " " " " " " "YYt~Y 8 8 A""#566                                YYt~ Y J J avvxxH                L(333 YY NW5G   vvxxH                98DDDDDskAA A)B<B% B<%B) )B<,B) -B<<CC$DD  D E$$E(+E(c\d}||jdd5}||dddn #1swxYwY||jdd5}|}dddn #1swxYwY|||dS)NrYr.rZrYr)rr4rLrOrPr[s rtest_write_and_read_strz0OpenFileWithEncodingTest.test_write_and_read_strs( YYt~sXY > > "! GGL ! ! ! " " " " " " " " " " " " " " " YYt~sXY > > !vvxxH                x00000s#AA A*B  BBc`gd}||jdd5}|D]}||dz dddn #1swxYwY||jd5}d|D}dddn #1swxYwY|||dS)N)u:Allons enfants de la Patrie,Le jour de gloire est arrivé!zContre nous de la tyrannie,u!L’étendard sanglant est levé.rrXrYrvc6g|]}|Srrrs rrzIOpenFileWithEncodingTest.test_create_file_with_append..rr)rr4rLrPrrSrlrrs rrz5OpenFileWithEncodingTest.test_create_file_with_appendsI    YYt~sWY = = -  - -t ,,,, - - - - - - - - - - - - - - - -YYt~Y 8 8 ;I:: :::F ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; 6*****s#A  AA4 B  BBcdg}||j|dd||jdd5}|ddD]}||dz dddn #1swxYwY||jd5}d |D}dddn #1swxYwY|||dS) Nu^Оригинальное содержаниеДополнительное содержаниеrr]rSrZrrYrrrvc6g|]}|Srrrs rrzFOpenFileWithEncodingTest.test_append_existing_file..rr)rir4rrLrPrms rrz2OpenFileWithEncodingTest.test_append_existing_filesk o  (1+ SSS YYt~sZY @ @ -I   - -t ,,,, - - - - - - - - - - - - - - - -YYt~ Y ; ; ;y:: :::F ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; 6*****s$&A77A;>A; B77B;>B;c ||jdd||jdd5}|d|dddn #1swxYwY||jdd5}|d|d|d|ddddS#1swxYwYdS) N!старое содержаниеr]rorrYrновое содержаниеr)rir4rrPrOrLrr>rrls rrz-OpenFileWithEncodingTest.test_open_with_wpluss  N%HS]    YYt~sZY @ @ TI   @)..BRBR S S S T T T T T T T T T T T T T T TYYt~tjY A A QY OO= > > > NN1    OO=y~~?O?O P P P Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Qs$)A00A47A4AC88C<?C<cgd}ddg}||jd|d||jdd5}|t j5|d dddn #1swxYwY|t j5|dddn #1swxYwY| td|| | d | d | | |dddn #1swxYwY||jd5}| ||z|ddddS#1swxYwYdS) N)uКалинка, uкалинка, uкалинка моя, u'В саду ягода-малинка, uмалинка моя. rgr]rorrYr)rir4rjrrrrrOrrPrrrrrk)rrSrrls rrz3OpenFileWithEncodingTest.test_open_with_append_flagsYYYIKef  NRWWX%6%6    YYt~sZY @ @ 6I""2#:;; " "q!!! " " " " " " " " " " " " " " """2#:;; % %""$$$ % % % % % % % % % % % % % % %   S!2!233Y^^5E5E F F F NN1      Q  0 0 1 1 1  !4 5 5 5 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6YYt~ Y ; ; Ty   X(;;Y=P=P=R=R S S S T T T T T T T T T T T T T T T T T Tsm F6B FB FB "FC# F#C' 'F*C' +BFFF;,G44G8;G8cR||jdd||jdd}|||jdd5}|d||d|d ||d |d |ddddS#1swxYwYdS) Nrrr]rorrYrrs!ru@старое содержаниеновое содержание) rir4rrrPrrLrrOrts rtest_append_with_aplusz/OpenFileWithEncodingTest.test_append_with_aplussl  N%HS]    IIdncJIGG  YYt~tjY A A sY   R!1!1 2 2 2 OO= > > >   R!1!1 2 2 2 NN1      _ajaoaoaqaq r r r  s s s s s s s s s s s s s s s s s ss,B#DD #D c,||jdd||jdd}|||jdd5}|d||d|d|d|d |ddddS#1swxYwYdS) Nu,старое содержание здесьr]rorrYrru новое содержаниеu+новое содержание здесь)rir4rrrPrOrrLrts rrz-OpenFileWithEncodingTest.test_read_with_rpluss\  NC    IIdncJIGG  YYt~tjY A A ^Y   KY^^M]M] ^ ^ ^ NN1    OO> ? ? ? NN1      JINNL\L\ ] ] ]  ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^s,BD  D D )rr r!__doc__rrcrbrhrjrrrrryrr"r#s@rrVrVTs""/////BBB   8EEE&111 + + + + + + Q Q QTTT$ s s s^^^^^^^rrVceZdZdZdS)OpenRealFileWithEncodingTestcdSrrrs rrz(OpenRealFileWithEncodingTest.use_real_fsrrNrrrrr}r}rrr}ceZdZfdZdZdZdZdZej e j dkddZ ej e j d kd d Z d Zd ZxZS)FakeFileOpenLineEndingTestcVtt|dSr )rrrrs rrz FakeFileOpenLineEndingTest.setUps& ($//5577777rcz|d}dD]!}|||||d5}|ddg|dddn #1swxYwY||d5}|d|dddn #1swxYwY||d 5}|||dddn #1swxYwY#dS) Nr=)s1 2s1 2s1 2rhrrVz1 r1 2r_r/rirrPrkrO)rr4rSrRs rtest_read_default_newline_modez9FakeFileOpenLineEndingTest.test_read_default_newline_modesNN;// 5 5 5H   Y  : : :93// >1  %q{{}}=== > > > > > > > > > > > > > > >93// 31  222 3 3 3 3 3 3 3 3 3 3 3 3 3 3 39400 5A  16688444 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5  5 5s6 +BB B ")CC C 9)D..D2 5D2 c"|d}||d5}|ddddn #1swxYwY||d5}|d|jjzdz|dddn #1swxYwY||d5}|ddddn #1swxYwY||d5}|d |jjzdz|ddddS#1swxYwYdS) Nr=r.rr_r12z1 2s1 )r/rrLrPr;r{encoderOrs r!test_write_universal_newline_modez&>>Eqvvxx P P P Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q QsIAAA0A CC C (D  DD,A FF Fc$|d}d}|||||dd5}|d|dddn #1swxYwY||dd5}|d|dddn #1swxYwY||dd 5}|d|dddn #1swxYwY||dd 5}|d|ddddS#1swxYwYdS) Nr=1 2 3 4rhrrgrVrx1 2 3 4 rv r/rirrPrOrr4 file_contentsrRs rtest_read_with_newline_argz5FakeFileOpenLineEndingTest.test_read_with_newline_args`NN;// '  ];;; YYysBY 7 7 71   ^QVVXX 6 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 YYysDY 9 9 7Q   ^QVVXX 6 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 YYysDY 9 9 7Q   ^QVVXX 6 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 YYysFY ; ; 7q   ^QVVXX 6 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7sH)A<<BB)CCC7)D,,D03D0)FF  F c4|d}d}|||||dd5}|gd|dddn #1swxYwY||dd5}|gd |dddn #1swxYwY||dd 5}|gd |dddn #1swxYwY||dd 5}|d dg|ddddS#1swxYwYdS)Nr=rrhrrgr)1 2 z3 4r)z1 z 2 3 rrv)rrz3 4rrz2 3 4r/rirrPrkrs rtest_readlines_with_newline_argz:FakeFileOpenLineEndingTest.test_readlines_with_newline_argsNN;// '  ];;; YYysBY 7 7 J1   9991;;== I I I J J J J J J J J J J J J J J J YYysDY 9 9 FQ   555q{{}} E E E F F F F F F F F F F F F F F F YYysDY 9 9 FQ   555q{{}} E E E F F F F F F F F F F F F F F F YYysFY ; ; Bq   gy11;;== A A A B B B B B B B B B B B B B B B B B BsH+A>>BB!+CCC;+D22D69D6+F  FF)r zU flag no longer supportedct|d}d}|||||dd5}|d|dddn #1swxYwY||dd5}|d|dddn #1swxYwY||dd5}|d|ddddS#1swxYwYdS) Nr=rrhrrrrUrrs r.test_read_with_ignored_universal_newlines_flagzIFakeFileOpenLineEndingTest.test_read_with_ignored_universal_newlines_flag+sNN;// '  ];;; YYysDY 9 9 7Q   ^QVVXX 6 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 YYysDY 9 9 7Q   ^QVVXX 6 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 YYysDY 9 9 7Q   ^QVVXX 6 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7s6)A<<BB)CCC7)D--D14D1)r zU flag still supportedc|d}d}||||t5||ddddddS#1swxYwYdS)Nr=rrhrrr)r/rirrr)rr4rs r*test_universal_newlines_flag_not_supportedzEFakeFileOpenLineEndingTest.test_universal_newlines_flag_not_supported7sNN;// '  ];;;   z * * 9 9 IIic4I 8 8 8 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9s A//A36A3c|d}||dd5}|ddddn #1swxYwY||d5}|d|dddn #1swxYwY||dd 5}|ddddn #1swxYwY||d5}|d|dddn #1swxYwY||dd 5}|ddddn #1swxYwY||d5}|d |dddn #1swxYwY||dd 5}|ddddn #1swxYwY||d5}|d |ddddS#1swxYwYdS)Nr=r.rg)rxrr_rrrvrs 1 2 3 4rs1 2 3 4rrs rtest_write_with_newline_argz6FakeFileOpenLineEndingTest.test_write_with_newline_arg?s1NN;// YYy#rY 2 2 $a GGN # # # $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ YYytY , , 8   _affhh 7 7 7 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8YYy#tY 4 4 $ GGN # # # $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ YYytY , , 8   _affhh 7 7 7 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8YYy#vY 6 6 $! GGN # # # $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ YYytY , , <   0!&&(( ; ; ; < < < < < < < < < < < < < < <YYy#tY 4 4 $ GGN # # # $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ YYytY , , 8   _affhh 7 7 7 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8sAAA2)B''B+.B+ C,,C03C0)EE E&FF F *)GG#&G#H$$H(+H()I<<JJcB|d}dfd}t|}||||d5}||t|ddddS#1swxYwYdS)Nr=s c3Kd}|tkrSd|}|dkr|dVdS||dzV|dz}|tkQdSdS)Nr rzrr)rfind)pxixrs r chunk_linezCFakeFileOpenLineEndingTest.test_binary_readline..chunk_lineYsBs=))))"''r2288',,,,F#BaK0000!V s=))))))))rrhr_r)r/listrirrP)rr4rchunked_contentsrRrs @rtest_binary_readlinez/FakeFileOpenLineEndingTest.test_binary_readlineUsNN;// 3       -- ];;; YYytY , , 8   -tAww 7 7 7 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8s#$BBB)rr r!rrrrrrrsys version_inforrrrr"r#s@rrrs88888 5 5 5 Q Q Q 7 7 7 B B BX_S%02NOO 7 7PO 7X_S%/1IJJ99KJ9888,8888888rrceZdZdZdS)RealFileOpenLineEndingTestcdSrrrs rrz&RealFileOpenLineEndingTest.use_real_fsjrrNrrrrrrirrrc<eZdZfdZdZdZdZdZdZxZ S)&FakeFileOpenLineEndingWithEncodingTestcVtt|dSr )rrrrs rrz,FakeFileOpenLineEndingWithEncodingTest.setUpos& 4d;;AACCCCCrc|d}dD]}|||d||dd5}|ddg|dddn #1swxYwY||dd5}|d |dddn #1swxYwYdS) Nr=) раз двараз дваu раз дваr]rorrVrZuраз дваrr)rr4rSrls rtest_read_standard_newline_modezFFakeFileOpenLineEndingWithEncodingTest.test_read_standard_newline_modersNN;// P E EH   YJ  O O O93DD P   *h!79L9L9N9NOOO P P P P P P P P P P P P P P P93DD E   !19>>3C3CDDD E E E E E E E E E E E E E E E  E Es$ +BB B $)CC C c|d}||dd5}|ddddn #1swxYwY||d5}|dd|jjzd dz|dddn #1swxYwY||dd5}|d dddn #1swxYwY||d5}|d d|jjzd dz|ddddS#1swxYwYdS) Nr=r.r]rYrr_ruразrrраз )r/rrLrPrr;r{rOrs rrzHFakeFileOpenLineEndingWithEncodingTest.test_write_universal_newline_mode{sNN;// YYy# Y ; ; &q GG$ % % % & & & & & & & & & & & & & & & YYytY , ,     ++'/((**+//*--.                   YYy# Y ; ; (q GG& ' ' ' ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( YYytY , ,    !!*--'/((**+//*--.                      sIAAA2A1C//C36C3D44D8;D8A1GGGc.|d}d}|||d||ddd5}|d|dddn #1swxYwY||ddd5}|d|dddn #1swxYwY||dd d5}|d|dddn #1swxYwY||dd d5}|d|ddddS#1swxYwYdS) Nr="раз два три четыреr]rorrgrVrxrZrrvrrrs rrzAFakeFileOpenLineEndingWithEncodingTest.test_read_with_newline_argsNN;// @  ]ZPPP YYysBY L L QPQ   Eqvvxx P P P Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q YYysD:Y N N QRS   Eqvvxx P P P Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q YYysD:Y N N QRS   Eqvvxx P P P Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q YYysFZY P P QTU   Eqvvxx P P P Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q QsH )A>>BB")CCC;)D00D47D4)F  FFc>|d}d}|||d||ddd5}|gd|dddn #1swxYwY||dd d5}|gd |dddn #1swxYwY||dd d5}|gd |dddn #1swxYwY||dd d5}|ddg|ddddS#1swxYwYdS)Nr=rr]rorrgr)раз два uтри четыреr)ru два три rrv)rruтри четыреrruдва три четыреrrs rrzFFakeFileOpenLineEndingWithEncodingTest.test_readlines_with_newline_argsNN;// @  ]ZPPP YYysBY L L dPQ   SSSUVU`U`UbUb c c c d d d d d d d d d d d d d d d YYysD:Y N N `RS   OOOQRQ\Q\Q^Q^ _ _ _ ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` YYysD:Y N N `RS   OOOQRQ\Q\Q^Q^ _ _ _ ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` YYysFZY P P \TU   l,JKQ[[]] [ [ [ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \sH +BBB$+CC"C?+D66D:=D:+FFFc|d}||ddd5}|ddddn #1swxYwY||d5}|dd|dddn #1swxYwY||dd d5}|ddddn #1swxYwY||d5}|dd|dddn #1swxYwY||dd d5}|ddddn #1swxYwY||d5}|d d|dddn #1swxYwY||dd d5}|ddddn #1swxYwY||d5}|d d|ddddS#1swxYwYdS)Nr=r.rgr])rxrZrr_rrvru$раз два три четыреru"раз два три четыре)r/rrLrPrrOrs rrzBFakeFileOpenLineEndingWithEncodingTest.test_write_with_newline_argsNN;// YYy#rJY G G >1 GG< = = = > > > > > > > > > > > > > > > YYytY , , d   ELLZXXZ[Z`Z`ZbZb c c c d d d d d d d d d d d d d d dYYy#tjY I I >Q GG< = = = > > > > > > > > > > > > > > > YYytY , , d   ELLZXXZ[Z`Z`ZbZb c c c d d d d d d d d d d d d d d dYYy#v Y K K >q GG< = = = > > > > > > > > > > > > > > > YYytY , , h   IPPQ[\\^_^d^d^f^f g g g h h h h h h h h h h h h h h hYYy#tjY I I >Q GG< = = = > > > > > > > > > > > > > > > YYytY , , d   ELLZXXZ[Z`Z`ZbZb c c c d d d d d d d d d d d d d d d d d dsAAA3 $2DEEEEErc|d5}||j|ddddS#1swxYwYdS)Nr_)rrPrrOrts rtest_read_binaryz(OpenWithBinaryFlagsTest.test_read_binarys ^^D ! ! CY   T/1A1A B B B C C C C C C C C C C C C C C C C C Cs.AAAc |d5}|d|||d5}||j||d5}||dd5}|t5|dddn #1swxYwYdddn #1swxYwYdddn #1swxYwYdddn #1swxYwYddddS#1swxYwYdS)NrWrr_rrr^r) rrPrrrrOrrrf)rrRrf2f3s rtest_write_binaryz)OpenWithBinaryFlagsTest.test_write_binarysq  $ $T * * &a   Q ) ) )++AD+99 &R  !3RWWYY???^^D))&R33w4&!../ABB&&GGIII&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & &sAE AD3D2D C. " D .C22D 5C26D 9 DD D D D D3D D3#D $D3' E 3D7 7E :D7 ;E  EEcj|d5}|d|||d5}||j|dddn #1swxYwYddddS#1swxYwYdS)Nzw+brr_r)rrPrrrrO)rrRrs rtest_write_and_read_binaryz2OpenWithBinaryFlagsTest.test_write_and_read_binary sD  $ $U + + @q   Q ) ) )++AD+99 @R  !3RWWYY??? @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @s6AB(.B B(B B(B B((B,/B,)rr r!rrrrr"r#s@rrrstFFFFF CCC & & &@@@@@@@rrceZdZdZdS)RealOpenWithBinaryFlagsTestcdSrrrs rrz'RealOpenWithBinaryFlagsTest.use_real_fsrrNrrrrrrrrrc0eZdZfdZdZdZdZxZS)OpenWithTextModeFlagsTestc~tt||dSr )rrrsetUpFileSystemrs rrzOpenWithTextModeFlagsTest.setUps8 '..44666 rc|d|_d|_d|_d|_||j|jdS)Nr=s two linesz two linesz two linesrh)r/r4roriginal_contentsconverted_contentsrirs rrz)OpenWithTextModeFlagsTest.setUpFileSystemsQ 44,!/". $2DEEEEErc||d5}||j|dddn #1swxYwY|d5}||j|ddddS#1swxYwYdS)z#Test that text mode flag is ignoredrNrt)r_rrPrrO)rrRs rtest_read_textz(OpenWithTextModeFlagsTest.test_read_text%sP !!! ^^C  @A   T4affhh ? ? ? @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ^^D ! ! @Q   T4affhh ? ? ? @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @s#.A$$A(+A(.B??CCc|t5|dddddS#1swxYwYdS)Nzw+bt)rrrrs r test_mixed_text_and_binary_flagsz:OpenWithTextModeFlagsTest.test_mixed_text_and_binary_flags-s   z * * , ,  # #F + + + , , , , , , , , , , , , , , , , , ,r)rr r!rrrrr"r#s@rrrskFFF@@@,,,,,,,rrceZdZdZdS)RealOpenWithTextModeFlagsTestcdSrrrs rrz)RealOpenWithTextModeFlagsTest.use_real_fs3rrNrrrrrr2rrrc,eZdZdZdZdZdZdZdS)OpenWithInvalidFlagsTestc|t5|ddddddS#1swxYwYdS)Nr=Rrrrrs rtest_capital_rz'OpenWithInvalidFlagsTest.test_capital_r8   z * * ( ( IIk3 ' ' ' ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (?AAc|t5|ddddddS#1swxYwYdS)Nr=Wrrs rtest_capital_wz'OpenWithInvalidFlagsTest.test_capital_w<rrc|t5|ddddddS#1swxYwYdS)Nr=Arrs rtest_capital_az'OpenWithInvalidFlagsTest.test_capital_a@rrc|t5|ddddddS#1swxYwYdS)Nr=urrs r test_lower_uz%OpenWithInvalidFlagsTest.test_lower_uDrrc|t5|ddddddS#1swxYwYdS)Nr=rwrrs r test_lower_rwz&OpenWithInvalidFlagsTest.test_lower_rwHs   z * * ) ) IIk4 ( ( ( ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) )rN)rr r!rr r rrrrrrr7s_(((((((((((()))))rrceZdZdZdS)OpenWithInvalidFlagsRealFsTestcdSrrrs rrz*OpenWithInvalidFlagsRealFsTest.use_real_fsNrrNrrrrrrMrrrceZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZdZdZdZdZdZdS)ResolvePathTestc||d5}|dddddS#1swxYwYdS)Nr.r)rrL)r file_namers r write_to_filezResolvePathTest.write_to_fileSs YYy# & & " HHSMMM                  s :>>c|t5|ddddddS#1swxYwYdSr)rrrrs r$test_none_filepath_raises_type_errorz4ResolvePathTest.test_none_filepath_raises_type_errorWs   y ) ) ! ! IIdC  ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !rc|t5|ddddddS#1swxYwYdS)Nrgr.)rrrrs r#test_empty_filepath_raises_io_errorz3ResolvePathTest.test_empty_filepath_raises_io_error[s   w ' '   IIb#                     rc|d}||||jj|dSr)r/rr>r;rFr?r3s rtest_normal_pathz ResolvePathTest.test_normal_path_sQNN5))  9%%%  ++I6677777rc||dd}|dd}||d||||jj||d|j |tj dS)Nr,rrrr) rr/rrr>r;rFr?rPrST_SIZEr final_targetr s rtest_link_within_same_directoryz/ResolvePathTest.test_link_within_same_directoryds **,,,~~eU33 NN5%00  Iu--- 9%%%  ++L99::: DGLL66t|DEEEEErcL||ddd}|dd}|||dd}|jjdd}|||||||jj || d|j |tj ||jj |||j |tj tjzdS)Nr,rbiprrr)rr/rr;rFrjrrr>r?rPrr"ST_MODEr)rr$dir_pathr  target_paths rtest_link_to_sub_directoryz*ResolvePathTest.test_link_to_sub_directorymsK **,,,~~eUE:: >>%// !!!NN5%00 gl''u55  I{333 9%%%  ++L99::: DGLL66t|DEEE  ++H55666  X..t|r?rPrr"r#s rtest_link_to_parent_directoryz-ResolvePathTest.test_link_to_parent_directory|s= **,,,~~eU33  u--... u--...NN5%00  Itw|'8'8u'E'EFFF 4>>%>>???  ++L99::: DGLL66t|DEEE  ++I6677777rc||ddd}||dd|dd}|||||||jj|dSNr,rr'r) rr/rrrr>r;rFr?r#s rtest_link_to_absolute_pathz*ResolvePathTest.test_link_to_absolute_paths **,,,~~eUE::  ue44555NN5%00  I|444 9%%%  ++L99:::::rc\||ddd}||dd|dd}|||jjddd|js3|||jj || |jj ||j |d||d|j | |jj d|js3|||jj d||| |jj|dS)Nr,rr'r.)rr/rrr;rFrjrr realpathr>islinkrgetcwdrr?r#s r$test_relative_links_work_after_chdirz4ResolvePathTest.test_relative_links_work_after_chdirs **,,,~~eUE::  ue44555NN5%00  Itw|'8'8eU'K'KLLL T  # #L$',2G2G 2R2R S S S  ++I66777  dnnU++,,, u 5 5tw~~7G7GHHH  ++E22333 P  # #L$',2G2G2N2N O O O 9%%%  ++L99:::::rc||ddd}||dd|dd}||||js3|||jj|| |jj ||j |d||d|j | |jj d|js3|||jjd| || |jj|dSr0)rr/rrrr r;rFr4r>r5rr6rr?r#s r$test_absolute_links_work_after_chdirz4ResolvePathTest.test_absolute_links_work_after_chdirs **,,,~~eUE::  ue44555NN5%00  I|444 T  # #L$',2G2G 2R2R S S S  ++I66777  dnnU++,,, u 5 5tw~~7G7GHHH  ++E22333 P  # #L$',2G2G2N2N O O O 9%%%  ++L99:::::rcX||dd}|dd}|||||ddd}|||jjdd|||jj||j ||||j |||jjd|j d|||j dS)Nrr,rr-) rr/rrr;rFrjr r4rr6)r dir1_path dir2_pathr s r test_chdir_through_relative_linkz0ResolvePathTest.test_chdir_through_relative_links_ NN3.. NN3..   """  """NN3u55  Itw|'8'8u'E'EFFF  47<+@+@+K+KLLL  i     47>>+;+;<<<  47<+@+@+G+GHHH  e  47>>+;+;<<<<>%// !!!7<<"+66  h  h $'..*:*:;;;;;rc||dd}||d||ddd||dd||d}|d|dS)Nr,rlinkrrr)rr/rrrrPrO)rr rs rtest_read_link_to_linkz&ResolvePathTest.test_read_link_to_links **,,,NN5%00  Iv... DNN5&995AAA 4>>%77888 YYy# & & bggii(((((rc||dd}|dd}||d||ddd||||jj|dS)Nr,rrrC)rr/rrr>r;rFr?r#s rtest_write_link_to_linkz'ResolvePathTest.test_write_link_to_links **,,,~~eU33 NN5%00  Iv... DNN5&995AAA 9%%%  ++L99:::::rc ||j|dddd||ddd|js||dd|jj|dd||ddd|jj|ddd|dddd}||d| |jj || |jj |dddd|ddddd}| |jj || |ddddd| |jj |dS)Nrlink1clink2rde) rr;rMr/rrr rFr4r>r?r@r)rr r$s rtest_multiple_linksz#ResolvePathTest.test_multiple_linkss" **,,, Wc7CCDDD DNN344g>>>   # #sG,, %%dnnS#&>&>??     # #sGS11 %%dnnS#s&C&CDD    NN3c::  Iw///  ++I66777  ++DNN3S#,N,NOOPPP~~c7C#FF  ,,\::;;; 4>>#sCcBBCCC  ++L99:::::rc|||dd|ddd}|||dd}||||j|d|j|}|d|j |d|j |j|d|j|}|d |j |d |j d S) z6os.utime() and os.stat() via symbolic link (issue #49)r,rr'r)rrrrrr)rrxrrxN) rrr/rrr;utimerrPst_atimest_mtime)rr* link_namers rtest_utime_linkzResolvePathTest.test_utime_links> **,,, ue44555nnUE599  ;'''NN5%00  I{333  i((( W\\) $ $ BK((( BK(((  i((( W\\) $ $ BK((( BK(((((rc||dd}||d||jj|dS)Nrloop)rr/rr@r;rFr?)rr s rtest_too_many_linksz#ResolvePathTest.test_too_many_linkssi NN3//  Iv... ,,Y7788888rc|||d|jddS)Nz C:!foo!barz C:!foo!!barr_r:rPr resolve_pathrs r%test_that_drive_letters_are_preservedz5ResolvePathTest.test_that_drive_letters_are_preservedsR !!!  t'C'CM'R'RSSSSSrc|||d|jddS)Nz !!foo!bar!bazz!!foo!bar!baz!!rXrs r!test_that_unc_paths_are_preservedz1ResolvePathTest.test_that_unc_paths_are_preserved!s^ !!!   T_99:KLL     rN)rr r!rrrr r%r+r.r1r7r9r=rArDrFrMrSrVrZr\rrrrrRs:!!!888 FFF M M M 8 8 8;;;;;;&;;;&===" < < < ) ) );;;;;;4)))$999 TTT      rrceZdZdZdS)RealResolvePathTestcdSrrrs rrzRealResolvePathTest.use_real_fs*rrNrrrrr^r^)rrr^__main__)5r{r1rr`r;rrr'rpyfakefsrrpyfakefs.helpersrrpyfakefs.fake_ior!pyfakefs.fake_filesystem_unittestrpyfakefs.tests.test_utilsr r r%rrrrrrrrrr rSrVr}rrrrrrrrrrrrrrr^rmainrrrrgs5 -, ----------------))))))777777444444     >   B B B B B +B B B J' T%T%T%T%T%!5T%T%T%n!; !F*,UVV'&'&'&'&'&"6'&'&WV'&T"= !F*,UVV-----$8--WV-* 3 3 3 3 3$A 3 3 3d/d/d/d/d/,d/d/d/N) Z^Z^Z^Z^Z^3Z^Z^Z^z#; p8p8p8p8p8!5p8p8p8f!; QdQdQdQdQd-AQdQdQdh-S :::::!5:::&%9 111110111.@@@@@3@@@<"9 ,,,,, 5,,,2$= )))))3))),%= T T T T T *T T T n/  zHMOOOOOrtests/__pycache__/fake_os_test.cpython-311.pyc000064400001655234150043321520015301 0ustar00 bg2dZddlZddlZddlZddlZddlZddlmZmZm Z m Z ddl m Z m Z mZmZddlmZmZmZmZddlmZmZmZddlmZmZGdd eZGd d eZGd d eZGddeZGddeZ GddeZ!GddeZ"Gdde"Z#GddeZ$Gdde$Z%GddeZ&GddeZ'ej(e d Gd!d"eZ)Gd#d$e)Z*Gd%d&e)Z+Gd'd(e+Z,ej(ej-d)ej(ed*Gd+d,e)Z.Gd-d.e.Z/Gd/d0e.Z0Gd1d2e0Z1Gd3d4eZ2Gd5d6eZ3Gd7d8e3Z4dS)9z$Unit tests for fake_os.FakeOsModule.N) IN_DOCKERIS_PYPYget_uidget_gid)fake_filesystemfake_os fake_open fake_file) FakeFileOpenis_rootset_uidset_gid) use_scandiruse_scandir_packageuse_builtin_scandir)TestCaseRealFsTestCaseceZdZdZdZdS)FakeOsModuleTestBasec||||jj||j|}|dt j|j||jt j z| |jt j zdS)N) create_file assertTrueospathexistsstat assertEqualS_IMODEst_modeS_IFREG assertFalseS_IFDIRselfrsts l/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/tests/fake_os_test.pycreateTestFilez#FakeOsModuleTestBase.createTestFile+s   ++D11222 W\\$    RZ 8 8999  T\1222 dl233333c||||jj||j|}|dt j|j| |jt j z||jt j zdS)N) create_dirrrrrrrrr r"r!r#r$s r'createTestDirectoryz(FakeOsModuleTestBase.createTestDirectory3s   ++D11222 W\\$    RZ 8 8999 dl2333  T\122222r)N)__name__ __module__ __qualname__r(r-r)r'rr*s244433333r)rc^eZdZfdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZ dZ!d Z"d!Z#d"Z$d#Z%d$Z&d%Z'd&Z(d'Z)d(Z*d)Z+d*Z,d+Z-d,Z.d-Z/d.Z0d/Z1d0Z2d1Z3d2Z4d3Z5d4Z6d5Z7d6Z8d7Z9d8Z:d9Z;d:Zd=Z?d>Z@d?ZAd@ZBdAZCdBZDdCZEdDZFdEZGdFZHdGZIdHZJdIZKdJZLdKZMdLZNdMZOdNZPdOZQdPZRdQZSdRZTdSZUdTZVdUZWdVZXdWZYdXZZdYZ[dZZ\d[Z]d\Z^d]Z_d^Z`d_Zad`ZbdaZcdbZddcZeddZfdeZgdfZhdgZidhZjdiZkdjZldkZmdlZndmZodnZpdoZqdpZrdqZsdrZtdsZudtZvduZwdvZxdwZydxZzdyZ{dzZ|d{Z}d|Z~d}Zd~ZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZd„ZdÄZdĄZdńZdƄZdDŽZdȄZdɄZdʄZd˄Zd̄Zd̈́Zd΄ZdτZdЄZdфZd҄ZdӄZdԄZdՄZdքZdׄZd؄ZdلZdڄZdۄZd܄Zd݄ZdބZd߄ZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZ dZ!d Z"d!Z#d"Z$d#Z%d$Z&d%Z'd&Z(d'Z)d(Z*d)Z+d*Z,d+Z-e.j/e0j1d,vd-d.Z2d/Z3d0Z4d1Z5d2Z6d3Z7d4Z8xZ9S(5FakeOsModuleTestctt||jj|jjz|jjz|_|jj|jjz|_dSN) superr3setUprR_OKW_OKX_OKrwxrwr% __class__s r'r7zFakeOsModuleTest.setUp=sU %%++---7<$',.=',-r)c|d}|||j|dS)z!chdir should work on a directory.fooN) make_pathr,rchdirr% directorys r' test_chdirzFakeOsModuleTest.test_chdirBs?NN5))   """  i     r)c|ddd}|tj|jj|dS)z8chdir should raise OSError if the target does not exist.nosuchrDN)rAassert_raises_os_errorerrnoENOENTrrBrCs r'test_chdir_fails_non_existz+FakeOsModuleTest.test_chdir_fails_non_existHs;NN4==  ##EL$'-KKKKKr)c|dd}|||tj|jj|dS)>%// """ ##EM47=(KKKKKr)c|d}d}|jj||}|||j||j||tj|jtj|dS)z-Consecutive relative chdir calls should work.r@rON) rArrjoinr,rBrrealpathgetcwd)r%dir1dir2 full_dirnames r'test_consecutive_chdirz'FakeOsModuleTest.test_consecutive_chdirSs~~e$$w|((t44   %%%  d  d  G  TW^^-- . .0@0@0N0N     r)c||j}d}|jj|}|j||j||||j|jd|||j|j|jj |d|||jdS)z,chdir into '..' should behave appropriately.r@..N) skip_real_fsrrXrabspath filesystemr,rBrrV)r%rootdirdirname abs_dirnames r'test_backwards_chdirz%FakeOsModuleTest.test_backwards_chdir`s '..""gl**733  ""7+++  g dgnn&6&6777  d $'.."2"2333  dgl''66777 $'.."2"233333r)c||dd}||||jj|j|j||||jdSNr@rO) r_rAr,rra root_dir_namerrXrB)r%rcs r' test_get_cwdzFakeOsModuleTest.test_get_cwdos ....     68H8HIII  g $'.."2"233333r)c|tj|jjd|dd}gd}|D]5}||jj||6| | |t|j|dS)Nnon_existing/fake_dirxyzzyplughr@rObaz) rIrJrKrlistdirrArrrVsortrsortedr%rDfilesfs r' test_listdirzFakeOsModuleTest.test_listdirxs ## L$'/+B   NN7G44 %%% > >A   TW\..y!<< = = = =  twy'A'A B BCCCCCr)ch|tjtjvr||t j|jjd|dd}gd}|D]5}| |jj ||6| |j |tj}||t!|j|dS)Nrlrmrn)check_posix_onlyrrp supports_fdr_rIrJEBADFrArrrVrqopenO_RDONLYrrr)r%dir_pathrtrupath_dess r'!test_listdir_uses_open_fd_as_pathz2FakeOsModuleTest.test_listdir_uses_open_fd_as_paths  :R^ + +       ##EK#FFF>>'733%%% = =A   TW\..x;; < < < < 7<<"+66 twx'@'@ A ABBBBBr)c|d}|j||jj|d}|j||||d|dg|j|dS)Nrlbugr@rArmkdirrrVrrrp)r%directory_rootrDs r'test_listdir_returns_listz*FakeOsModuleTest.test_listdir_returns_lists00  n%%%GL%%ne<<   i     599::: %$'//)"<"<=====r)c ||d}gd}|D]+}||||,||d|d|||t |j|ddS)Nrlrnsymlink skip_if_symlink_not_supportedrArcreate_symlinkrqrrrrrprss r'test_listdir_on_symlinkz(FakeOsModuleTest.test_listdir_on_symlink **,,,NN7++ %%% ; ;A   T^^Iq99 : : : : DNN955t~~g7N7NOOO  twt~~i7P7P'Q'Q R RSSSSSr)c|ddd}|||tj|jj|dS)Nr@rOro)rArrIrJrQrrpr% file_paths r'test_listdir_errorz#FakeOsModuleTest.test_listdir_errorsONN5%77  ### ##EM47?INNNNNr)cj||jjddSN.)rrrrr%s r'test_exists_current_dirz(FakeOsModuleTest.test_exists_current_dirs,  ++C0011111r)cgd}|D]*}|||+|||t |j|jdS)Nrn)rrArqrrrrrp base_path)r%rtrus r'test_listdir_currentz%FakeOsModuleTest.test_listdir_currents%%% 0 0A   T^^A.. / / / /  twt~'F'F G GHHHHHr)ct|d}||d||d5}|}|j|}|||dddn #1swxYwY|t5|jddddn #1swxYwY|t5|jdddddS#1swxYwYdS)N some_file1contents here1contentsrza string) rArr|filenorfdopenassertNotEqual assertRaises TypeError)r% file_path1 fake_file1r fake_file2s r' test_fdopenzFakeOsModuleTest.test_fdopens^^L11  .>??? YYz3 ' ' 8:&&((F//J    J 7 7 7 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8   y ) ) ! ! GNN4  ! ! ! ! ! ! ! ! ! ! ! ! ! ! !   y ) ) ' ' GNN: & & & ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' 's7ABBB9C  C$'C$D--D14D1c\|tj|jjddSNrx)rIrJr{rrrs r'test_out_of_range_fdopenz)FakeOsModuleTest.test_out_of_range_fdopens& ##EKEEEEEr)c|d}|d}|d}||d||d||d||d}||d}||d}|}|}|} |j||tj|jj|| ||| | ||j |5} | | |udddn #1swxYwY|j | 5} | | |udddn #1swxYwY|tj|jj |dS) Nr some_file2 some_file3rrzcontents here2zcontents here3r) rArr|rrcloserIrJr{rrr") r% first_path second_path third_pathrr fake_file3fileno1fileno2fileno3rus r'test_closed_file_descriptorz,FakeOsModuleTest.test_closed_file_descriptors^^L11 nn\22 ^^L11  .>??? /?@@@ .>???YYz3// YY{C00 YYz3// ##%%##%%##%%  g ##EKHHH *"3"3"5"5666 *"3"3"5"5666 W^^G $ $ .   Q*_ - - - . . . . . . . . . . . . . . . W^^G $ $ .   Q*_ - - - . . . . . . . . . . . . . . . ##EKIIIIIs$2GGG;HH#&H#c||d}||d|j|t jdzt jz ||d}| }|j ||j |dtsP| t5|j |dddddS#1swxYwYdS|j |d|j|dS)Nrrrrrw)r_rArrchmodrr!S_IWRITEr|rrr rOSErrorr)r%rrrs r'test_fdopen_modez!FakeOsModuleTest.test_fdopen_modes} ^^L11  .>???  j4<%#74="HIIIYYz3// ##%% w w$$$yy #""7++ - -w,,, - - - - - - - - - - - - - - - - - - GNN7C ( ( ( GMM' " " " " "s=D&&D*-D*c|d}|jj|d}||d||5}|}|tj |j |tj z|tj |j |j z| d|j |tjddddS#1swxYwYdSNrlrmABCDEr)rArrrVrr|rrrr!fstatST_MODEr rST_SIZE)r%rDrfile_objrs r' test_fstatzFakeOsModuleTest.test_fstats]NN7++ GL%%i99  W555 YYy ! ! EX__&&F OODL47==+@+@+NN O O O OODL47==+@+@+HH I I I   Q f 5 5dl C D D D  E E E E E E E E E E E E E E E E E Es"CE  EEc|d}|jj|d}||d|t j|j|t jz|t j |j|t jz|t j |j|j z| d|j|t j dSr rArrrVrrrr#rr!r rrr%rDrs r' test_statzFakeOsModuleTest.test_statsNN7++ GL%%i99  W555  tw||I'>'>t|'LLMMM  tw||I'>'>t|'LLMMM  tw||I'>'>'FFGGG DGLL33DLABBBBBr)c||d}||d|d|j|j|d}||d|d|j|j|d}||d |d|j|j|d }||d |d|j|j|d }||dd z|d|j|jdS)Nfoo1r)rrfoo2tfoo3stttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttfoo4sttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttfoo5i)ryrArrrr st_blocksrs r'test_st_blockszFakeOsModuleTest.test_st_blockss NN6**  S111 DGLL33=>>>NN6**  T222 DGLL33=>>>NN6**  [999 DGLL33=>>>NN6**  [999 DGLL33=>>>NN6**  TD[999 TW\\)44>?????r)c*||d}||d|t5|j|jddddS#1swxYwYdS)Nr@r)r)check_windows_onlyrArrAttributeErrorrrrrs r'test_no_st_blocks_in_windowsz-FakeOsModuleTest.test_no_st_blocks_in_windowss !!!NN5))  S111   ~ . . . . GLL # # - - . . . . . . . . . . . . . . . . . .s BB B c||d}|jj|d}||d|tj|j|tj z|tj |j|tj z|tj |j|j z| d|j|tj dS)Nz//root/share/dirrmrrrr_rrrrVrrrr#rr!r rrrs r'test_stat_with_unc_pathz(FakeOsModuleTest.test_stat_with_unc_paths  !!!& GL%%i99  W555  tw||I'>'>t|'LLMMM  tw||I'>'>t|'LLMMM  tw||I'>'>'FFGGG DGLL33DLABBBBBr)c||d}|jj|d}||d|tj|j|tj z|tj |j|tj z|tj |j|j z| d|j|tj dS)Nz C:/foo/dirrmrrrrrs r'test_stat_with_drivez%FakeOsModuleTest.test_stat_with_drive%s  !!! GL%%i99  W555  tw||I'>'>t|'LLMMM  tw||I'>'>t|'LLMMM  tw||I'>'>'FFGGG DGLL33DLABBBBBr)c||tj|jjd|dd}||||5}| t j |j|j t j zddddS#1swxYwYdS)Nrr@rO) r_rIrJr{rrrArr|rr!filedesrr%rrus r'test_stat_uses_open_fd_as_pathz/FakeOsModuleTest.test_stat_uses_open_fd_as_path0s  ##EKqAAANN5%00  ### YYy ! ! RQ OODL47<< +B+B4<+PP Q Q Q R R R R R R R R R R R R R R R R R RsACC!$C!c||d}d}d}|t|t||jj||}|jj|d}||||||| t||j |dtj | t||j |dtj dS =Test that stat with follow_symlinks=False behaves like lstat.rlrmfrobozzlinkrFfollow_symlinksN) ryrArlenrrrVrrrrrr%rD base_name file_contentsr link_paths r'"test_stat_no_follow_symlinks_posixz3FakeOsModuleTest.test_stat_no_follow_symlinks_posix9s< NN7++  !  C NNC ,>,>???GL%%i;; GL%%i88  ];;; Iy111     GLLEL : :4< H      NN GLLEL : :4< H     r)c|||d}d}d}|t |t ||jj||}|jj|d}|||| ||| t ||j |dtj | d|j |dtj d S) rrlrmrrrFrrN) rrrArrrrrVrrrrrrs r'$test_stat_no_follow_symlinks_windowsz5FakeOsModuleTest.test_stat_no_follow_symlinks_windowsNsG !!! **,,,NN7++  !  C NNC ,>,>???GL%%i;; GL%%i88  ];;; Iy111     GLLEL : :4< H     tw||Iu|==dlK     r)c||d}d}d}|t|t||jj||}|jj|d}||||||| t||j |tj | t||j |tj dSNrlrmrrr) ryrArrrrrVrrrlstatrrrs r'test_lstat_size_posixz&FakeOsModuleTest.test_lstat_size_posixcs NN7++  !  C NNC ,>,>???GL%%i;; GL%%i88  ];;; Iy111 ]++TW]]9-E-Edl-STTT Yy)A)A$,)OPPPPPr)c|||d}d}d}|t |t ||jj||}|jj|d}|||| ||| t ||j |tj | d|j |tj dS)Nrlrmrrrr)rrrArrrrrVrrrrrrrs r'test_lstat_size_windowsz(FakeOsModuleTest.test_lstat_size_windowsqs* !!! **,,,NN7++  !  C NNC ,>,>???GL%%i;; GL%%i88  ];;; Iy111 ]++TW]]9-E-Edl-STTT DGMM)44T\BCCCCCr)c|j|j}|||j|j|z|||j|j|z|zdSr5)rrrrpath_separator)r% stat_results r'test_lstat_trailing_sepz(FakeOsModuleTest.test_lstat_trailing_sepsgmmDN33   t~8K8K8M8M'MNN      GMM!4!4!6!669L9L9N9NN       r)c|j|j}|jd}|j|}|||dSNutf8)rrrencoderr%stat_strbase_path_bytes stat_bytess r'test_stat_with_byte_stringz+FakeOsModuleTest.test_stat_with_byte_strings[7<<//.//77W\\/22  X.....r)c|j|j}|jd}|j|}|||dSr)rrrrrrs r'test_lstat_with_byte_stringz,FakeOsModuleTest.test_lstat_with_byte_strings[7==00.//77W]]?33  X.....r)c|jd}|jd}|||dSr)rrrr)r%r lstat_results r'test_stat_with_current_dirz+FakeOsModuleTest.test_stat_with_current_dirsDgll3'' w}}S))  l33333r)c|d}||||jj||jjzdSNalpha)rArr"rrrseprs r'test_exists_with_trailing_sepz.FakeOsModuleTest.test_exists_with_trailing_seps\NN7++  ### ,,Y-DEEFFFFFr)c|d}|j||jjz|jjz||jj|dSNr@)rArrr rrrr%r~s r'test_mkdir_with_trailing_sepz-FakeOsModuleTest.test_mkdir_with_trailing_sepsc>>%((  h,tw{:;;;  ++H5566666r)c||tj|jjddSN)ryrIrJrKrreadlinkrs r'test_readlink_empty_pathz)FakeOsModuleTest.test_readlink_empty_paths9  ##EL$'2BBGGGGGr)c||d}|j|j||t j|jj||jj zdSr) ryrArrrrIrJEINVALrr r%rs r'#test_readlink_ending_with_sep_posixz4FakeOsModuleTest.test_readlink_ending_with_sep_posixsv NN5))   222 ## L$'*I ,C     r)c>|||d}|j|j|||j||jjzj dSr) check_linux_onlyrrArrrrrr r rs r'*test_lstat_symlink_with_trailing_sep_linuxz;FakeOsModuleTest.test_lstat_symlink_with_trailing_sep_linux  **,,,NN5))   222  i$'+&=>>FGGGGGr)c>|||d}|j|j|||j||jjzj dSr) check_macos_onlyrrArrrrrr r rs r'*test_lstat_symlink_with_trailing_sep_macosz;FakeOsModuleTest.test_lstat_symlink_with_trailing_sep_macosrr)c@|||d}|j|j|||j|j||jjzdSr) rrrArrrassert_equal_pathsrr rs r'%test_readlink_ending_with_sep_windowsz6FakeOsModuleTest.test_readlink_ending_with_sep_windowss !!! **,,,NN5))   222  NDG,,Y-DEE     r)cH|||d}|j|j|||jj||jjj zdSr) rrrArrrrrislinkr rs r'%test_islink_with_trailing_sep_windowsz6FakeOsModuleTest.test_islink_with_trailing_sep_windowss !!! **,,,NN5))   222  ++I 8H,HIIJJJJJr)c||d}|j|j|||jj||jjzdSr) rrArrrr"rr'r rs r'#test_islink_with_trailing_sep_linuxz4FakeOsModuleTest.test_islink_with_trailing_sep_linuxr NN5))   222 ,,Y-DEEFFFFFr)c||d}|j|j|||jj||jjzdSr) r!rArrrr"rr'r rs r'#test_islink_with_trailing_sep_macosz4FakeOsModuleTest.test_islink_with_trailing_sep_macosr+r)c|d}|||||jjj||jjzdSNrO)rArrIrrgetsizer r%error_nrrs r',check_getsize_raises_with_trailing_separatorz=FakeOsModuleTest.check_getsize_raises_with_trailing_separators`NN5))  ### ## dgl*I ,C     r)cl||tjdSr5)ryr3rJrQrs r'1test_getsize_raises_with_trailing_separator_posixzBFakeOsModuleTest.test_getsize_raises_with_trailing_separator_posixs0  99%-HHHHHr)cl||tjdSr5)rr3rJrrs r'3test_getsize_raises_with_trailing_separator_windowszDFakeOsModuleTest.test_getsize_raises_with_trailing_separator_windowss0 !!! 99%,GGGGGr)c|d}|j|j||||jj||jjzdSr)rArrrrIremover )r%r2rs r'!check_remove_link_ending_with_sepz2FakeOsModuleTest.check_remove_link_ending_with_sepsVNN5))   222 ##Hdgni$'+>UVVVVVr)cl||tjdSr5)rr:rJrQrs r'&test_remove_link_ending_with_sep_linuxz7FakeOsModuleTest.test_remove_link_ending_with_sep_linuxs0  ..u}=====r)cl||tjdSr5)r!r:rJEPERMrs r'&test_remove_link_ending_with_sep_macosz7FakeOsModuleTest.test_remove_link_ending_with_sep_macoss0  ..u{;;;;;r)c|||tjdSr5)rrr:rJEACCESrs r'(test_remove_link_ending_with_sep_windowsz9FakeOsModuleTest.test_remove_link_ending_with_sep_windowssB !!! **,,, ..u|<<<< ) )       ##EKBBBNN5%00 NN5&11 #  ];;; Iy111 YYy ! ! YQ   S//qy1I1I$,1W X X X Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y YsAD::D>D>c|ddd}||jj| |j||ddS#t$rK}|tj |j |||j Yd}~dSd}~wwxYw)NnonexistentfileException is expected.) rAr"rrrrfailrrrJrKrS)r%ros_errors r'test_stat_non_existent_filez,FakeOsModuleTest.test_stat_non_existent_filesNN5*f==  ,,Y77888 ; GLL # # # II. / / / / / ; ; ;   U\8> : : :   Y(9 : : : : : : : : : ;s /A<< CAC  Cc|d|jjz}|||jj|tjtjztjzdSr/)rArr rIr|O_CREATO_WRONLYO_TRUNCr1s r')check_open_raises_with_trailing_separatorz:FakeOsModuleTest.check_open_raises_with_trailing_separator#s^NN5))DGK7  ##  GL  J $rz 1      r)cl||tjdSr5)rrRrJEISDIRrs r'.test_open_raises_with_trailing_separator_linuxz?FakeOsModuleTest.test_open_raises_with_trailing_separator_linux,0  66u|DDDDDr)cl||tjdSr5)r!rRrJrKrs r'.test_open_raises_with_trailing_separator_macosz?FakeOsModuleTest.test_open_raises_with_trailing_separator_macos0rVr)cl||tjdSr5)rrRrJrrs r'0test_open_raises_with_trailing_separator_windowszAFakeOsModuleTest.test_open_raises_with_trailing_separator_windows4s0 !!! 66u|DDDDDr)c4|||d}|j||||jj||jjzdSr) check_linux_and_windowsrrArrr"rlexistsr rs r'2test_lexists_with_trailing_separator_linux_windowszCFakeOsModuleTest.test_lexists_with_trailing_separator_linux_windows8s $$&&& **,,,NN5))   9--- --i$'+.EFFGGGGGr)c ||d}|j||||jj||jjzdSr)r!rArrrrr]r rs r'*test_lexists_with_trailing_separator_macosz;FakeOsModuleTest.test_lexists_with_trailing_separator_macos?sn NN5))   9---  ,,Y-DEEFFFFFr)c4|||d}|j||||jj||jjzdSr) r\rrArrr"rr'r rs r'1test_islink_with_trailing_separator_linux_windowszBFakeOsModuleTest.test_islink_with_trailing_separator_linux_windowsFs $$&&& **,,,NN5))   9--- ,,Y-DEEFFFFFr)c ||d}|j||||jj||jjzdSr)r!rArrrrr'r rs r')test_islink_with_trailing_separator_macosz:FakeOsModuleTest.test_islink_with_trailing_separator_macosMsn NN5))   9---  ++I ,CDDEEEEEr)c||d}||||jj||jjzdSr)r\rArr"rrisfiler rs r'1test_isfile_with_trailing_separator_linux_windowszBFakeOsModuleTest.test_isfile_with_trailing_separator_linux_windowsTsn $$&&&NN5))  ### ,,Y-DEEFFFFFr)c||d}||||jj||jjzdSr)r!rArr"rrrfr rs r')test_isfile_with_trailing_separator_macosz:FakeOsModuleTest.test_isfile_with_trailing_separator_macosZsn NN5))  ### ,,Y-DEEFFFFFr)c|d}||d||jj|dS)Nr@rperm)rArrrrrfrs r'test_isfile_not_readable_filez.FakeOsModuleTest.test_isfile_not_readable_fileasVNN5))  +++  ++I6677777r)c|d}|||||jj||jjzdSr)rArrIrrr r1s r'"check_stat_with_trailing_separatorz3FakeOsModuleTest.check_stat_with_trailing_separatorfsRNN5))  ### ##HdglI >>>>r)cl||tjdSr5)rrorJrrs r')test_stat_with_trailing_separator_windowsz:FakeOsModuleTest.test_stat_with_trailing_separator_windowsp0 !!! // =====r)c|d}|||||jj||jjzdSr)rArrIrr9r r1s r'$check_remove_with_trailing_separatorz5FakeOsModuleTest.check_remove_with_trailing_separatortsRNN5))  ### ##Hdgni$'+>UVVVVVr)cl||tjdSr5)ryrvrJrQrs r')test_remove_with_trailing_separator_posixz:FakeOsModuleTest.test_remove_with_trailing_separator_posixz0  11%-@@@@@r)cl||tjdSr5)rrvrJrrs r'+test_remove_with_trailing_separator_windowsz !!! **,,, 88:::::r)cV||dSr5)ryrrs r'0test_readlink_raises_if_path_is_not_a_link_posixzAFakeOsModuleTest.test_readlink_raises_if_path_is_not_a_link_posixs,  88:::::r)c4||d|dd}|||jj||ddd}|||jj|dSNa_filer@rO)rrArIrrr% error_subtypers r'&check_readlink_raises_if_path_has_filez7FakeOsModuleTest.check_readlink_raises_if_path_has_files 11222NN8U33  ##M473CYOOONN8UE::  ##M473CYOOOOOr)c|||tjdSr5rrrrJrKrs r'-test_readlink_raises_if_path_has_file_windowsz>FakeOsModuleTest.test_readlink_raises_if_path_has_file_windowsB !!! **,,, 33ELAAAAAr)cl||tjdSr5ryrrJrQrs r'+test_readlink_raises_if_path_has_file_posixzrs r'test_remove_dir_mac_osz'FakeOsModuleTest.test_remove_dir_mac_os0  ek*****r)cl||tjdSr5rrrJrArs r'test_remove_dir_windowsz(FakeOsModuleTest.test_remove_dir_windows0 !!! el+++++r)c |||jjdd}|j||tj |jj |dS)NzC:test) rr_rrrVrar,rIrJrAr9rs r'test_remove_dir_with_drivez+FakeOsModuleTest.test_remove_dir_with_drive!sy !!! 7<$$T622 ""8,,, ##EL$'.(KKKKKr)c|d}|jj|d}||||jj||j|||jj|dSNzzyrm) rArrrVrrrr9r"rs r'test_remove_filez!FakeOsModuleTest.test_remove_file)sNN5)) GL%%i99  ###  ++I66777 y!!! ,,Y7788888r)c|d}d}|jj||}||||jj||j||j|| |jj|dSr) rArrrVrrrrBr9r"r%rD file_namers r'test_remove_file_no_directoryz.FakeOsModuleTest.test_remove_file_no_directory1sNN5))  GL%%i;;  ###  ++I66777  i    y!!! ,,Y7788888r)cF||dd}|||j|d|t j|jj||j|ddS)Nr@rO$r) rrArrrrIrJrAr9r%rs r'7test_remove_file_with_read_permission_raises_in_windowszHFakeOsModuleTest.test_remove_file_with_read_permission_raises_in_windows;s !!!~~eU++   dE""" ##EL$'.$GGG  dE"""""r)cR||dd}|||j|d|j|||jj|dS)Nr@rOr) ryrArrrr9r"rrrs r'rs r'#test_remove_dir_raises_error_mac_osz4FakeOsModuleTest.test_remove_dir_raises_error_mac_os0  **5;77777r)cl||tjdSr5rrrJrArs r'$test_remove_dir_raises_error_windowsz5FakeOsModuleTest.test_remove_dir_raises_error_windows0 !!! **5<88888r)c||d}|d}|||j||||jj|||jj||j|||jj|| |jj|dSNr link_to_dir) rrAr,rrrrrr9r"r%rDrs r'test_remove_symlink_to_dirz+FakeOsModuleTest.test_remove_symlink_to_dirs  **,,,NN5)) ~~m,,  """  4(((  ++I66777  ++D11222 t  ++I66777 ,,T2233333r)c|dddd}||jj||t j|jj|dS)NrIdoesnotexist) rAr"rrrrIrJrKunlinkrs r'test_unlink_raises_if_not_existz0FakeOsModuleTest.test_unlink_raises_if_not_existscNN665'BB  ,,Y77888 ##EL$'.)LLLLLr)c|d}|jj|d}|jj|d}||d||jj|||jj||j||||jj|||jj|| |ddS)z$Can rename a file to an unused name.rl plugh_old plugh_new test contentsrN) rArrrVrrrr"renamecheck_contentsr%rD old_file_path new_file_paths r'test_rename_to_nonexistent_filez0FakeOsModuleTest.test_rename_to_nonexistent_files$NN7++  )))[AA  )))[AA  AAA  ++M::;;; ,,];;<<< }m444 ,,];;<<<  ++M::;;; M?;;;;;r)cz||d}|d}|jj|d}|||j|||tj |jj ||dSNrdir link_target) ryrArrrVr,rrIrJrQrr%rr~rs r' test_rename_dir_to_symlink_posixz1FakeOsModuleTest.test_rename_dir_to_symlink_posixs NN6** >>%((gl''-@@  !!!  Y/// ##EM47>8YWWWWWr)c|||d}|d}|jj|d}|||j|||tj |jj ||dSr) rrrArrrVr,rrIrJrrrs r'"test_rename_dir_to_symlink_windowsz3FakeOsModuleTest.test_rename_dir_to_symlink_windowss !!! **,,,NN6** >>%((gl''-@@  !!!  Y/// ##EL$'.(IVVVVVr)cD||d}|d}|j|||||j||||jj|| |jj|| |jj |dSN file_linkrI) ryrArrrrr"rrrrfr%rrs r'test_rename_file_to_symlinkz,FakeOsModuleTest.test_rename_file_to_symlinks NN;// NN6**   9--- ### y),,, ,,Y77888  ++I66777  ++I6677777r)cn||dd}|||jj|d}|jj|d}|j|||j|||j||||jj || |jj |dSNr@rOlink1link2) ryrAr,rrrVrrr"rrr%r link_path1 link_path2s r'test_rename_symlink_to_symlinkz/FakeOsModuleTest.test_rename_symlink_to_symlinks NN5%00   """W\&&y':: W\&&y'::   :...  :... z:... ,,Z88999  ++J7788888r)c||d}|d}|jj|d}|||j|||||tj |jj ||dSNdir_linkr inner_dir) ryrArrrVr,rrIrJrrr%r-r~dir_in_dir_paths r'0test_rename_symlink_to_symlink_for_parent_raiseszAFakeOsModuleTest.test_rename_symlink_to_symlink_for_parent_raisess >>*-->>%((',++HkBB !!! (+++ ((( ## L$'.(O     r)c4|||d}|||d}|j|j||jj|d}|d}|j ||| |t|j |jdS)NbetabBeta) rcheck_case_insensitive_fsrAr,rrrrrVrrrrrp)r%resultdir_path_lowerrpath1dir_path_uppers r'check_rename_case_with_symlinkz/FakeOsModuleTest.check_rename_case_with_symlinks **,,, &&(((// '''NN3''   222 !!)V44// un--- (G(G!H!HIIIIIr)c\||ddgdS)Nr4r3)r!r;rs r'!test_rename_case_with_symlink_macz2FakeOsModuleTest.test_rename_case_with_symlink_macs2  ++S&M:::::r)c\||ddgdS)Nr5r4)rr;rs r'%test_rename_case_with_symlink_windowsz6FakeOsModuleTest.test_rename_case_with_symlink_windowss2 !!! ++VSM:::::r)c||dd}|||jj|d}|tj|jj ||dSNr@rOnew_dir) ryrAr,rrrVrIrJrrr%rnew_paths r'test_recursive_rename_raisesz-FakeOsModuleTest.test_recursive_rename_raisessx NN5%00   """7<$$Y :: ##EL$'.)XVVVVVr)c$|d}|||d}|jj|d}|||j||dS)Nrold_filenew_file)rAr,rrrVrr)r%r~rrs r'#test_rename_file_to_parent_dir_filez4FakeOsModuleTest.test_rename_file_to_parent_dir_files>>%(( !!!NN:..  ))(J??  ### y-00000r)c||dd}|||tj|jj||dzdSNr@roz/new)ryrArrIrJrQrrrs r'0test_rename_with_target_parent_file_raises_posixzAFakeOsModuleTest.test_rename_with_target_parent_file_raises_posixsq NN5%00  ### ## M47>9i&6H     r)c ||dd}|||tj|jj||jj |ddSNr@ronew) rrArrIrJrArrrrVrs r'2test_rename_with_target_parent_file_raises_windowszCFakeOsModuleTest.test_rename_with_target_parent_file_raises_windowss !!!NN5%00  ### ## L GN  GL  i / /      r)c||d}|jj|d}|jj|d}|||j|||j||||jj |dSNr@slinkrI) ryrArrrVrrrr"rr%rrrs r'test_rename_symlink_to_sourcez.FakeOsModuleTest.test_rename_symlink_to_source!s NN5)) GL%%i99 GL%%i88  ###  9--- y),,, ,,Y7788888r)c||dd}|jj|d}|jj|d}|||j|||tj |jj ||dSNr@rOr-r) ryrArrrVr,rrIrJrTrr%rrr~s r'!test_rename_symlink_to_dir_raisesz2FakeOsModuleTest.test_rename_symlink_to_dir_raises+s NN5%00 GL%%i<< 7<$$Y66 !!! ),,, ##EL$'.)XVVVVVr)c||d}|||jj|d}|jj|d}|j|||j||||jj || |jj |||jj |dSrR) ryrAr,rrrVrrr"rrr]rTs r'test_rename_broken_symlinkz+FakeOsModuleTest.test_rename_broken_symlink4s  NN5))   """GL%%i99 GL%%i88   9--- y),,, ,,Y77888  ,,Y77888 ,,Y7788888r)cdD]\}}||}||}||jj|dd||jj|||jj||j||||jj|||jj|| |jj|dd| s3| d|j |jdSz)Can rename a directory to an unused name.))wxyywrl)abccbcdeedrmrrN)rArrrrVrrr"rr use_real_fsrra get_objectst_nlinkr%old_pathrDs r'test_rename_directoryz&FakeOsModuleTest.test_rename_directory@s"J S S Hh~~h//H~~h//H   TW\..xAAF  S S S OODGL//99 : : :   TW\00:: ; ; ; GNN8X . . .   TW\00:: ; ; ; OODGL//99 : : :    1 1(G D Df M M M##%% S  DO$>$>x$H$H$QRRR S Sr)c|d}|d}|||||||jj||dSNrrI)rAr,rrIrrr%r2r~rs r'.check_rename_directory_to_existing_file_raisesz?FakeOsModuleTest.check_rename_directory_to_existing_file_raisesOsn>>%((NN6**  !!! ### ##Hdgnh RRRRRr)cl||tjdSr5ryrkrJrQrs r'3test_rename_directory_to_existing_file_raises_posixzDFakeOsModuleTest.test_rename_directory_to_existing_file_raises_posixV0  ;;EMJJJJJr)cl||tjdSr5rrkrJrrs r'5test_rename_directory_to_existing_file_raises_windowszFFakeOsModuleTest.test_rename_directory_to_existing_file_raises_windowsZ0 !!! ;;ELIIIIIr)c2||dd}|dd}|||||tj|jj||dSz?Renaming to an existing directory raises OSError under Windows.r@rOroN)rrAr,rIrJrrrres r'>%//>>%// !!! !!! ##EL$'.(HUUUUUr)c|d||dd}|||d}|j|||j||||jj |||jj |dSNF) skip_posixrrIr) skip_real_fs_failurerrArrrrrrrrs r'8test_rename_to_a_hardlink_of_same_file_should_do_nothingzIFakeOsModuleTest.test_rename_to_a_hardlink_of_same_file_should_do_nothinggs !!U!333 **,,,NN5&11  ###NN6**   Y *** y),,,  ++I66777  ++I6677777r)c||d}|||jj|d}|j|||jj|dd}|||jj|dd}|j||| |jj || |jj |dS)Nr@rSr3gamma) rrAr,rrrVrrrrrr"r'r%r symlink_pathrrs r' test_hardlink_works_with_symlinkz1FakeOsModuleTest.test_hardlink_works_with_symlinkrs **,,,NN5))   """w|((G<<   <000GL%%i&AA  ###GL%%i'BB   Y ***  ++I66777 ,,Y7788888r)c2||dd}|dd}|||||tj|jj||dSru)rrAr,rIrJrArreplaceres r':test_replace_existing_directory_should_raise_under_windowszKFakeOsModuleTest.test_replace_existing_directory_should_raise_under_windowss !!!>>%//>>%// !!! !!! ##EL$'/8XVVVVVr)cN||dd}|d}||jj|d|||j||||jj|jj|d| |jj|dSURenaming to an existing directory changes the existing directory under Posix.r@rOrlsubN) ryrAr,rrrVrrrr"res r'-test_rename_to_existing_directory_under_posixz>FakeOsModuleTest.test_rename_to_existing_directory_under_posixs >>%//>>'**  ))(E::;;; !!! x***  ++DGL,=,=h,N,NOOPPP ,,X6677777r)c2||ddd}|d}|||||t j|jj||dSNr@rOrorl) ryrArr,rIrJrTrrr%rrDs r'9test_rename_file_to_existing_directory_raises_under_posixzJFakeOsModuleTest.test_rename_file_to_existing_directory_raises_under_posixs NN5%77 >>'** ### !!! ##EL$'.)XVVVVVr)c||dd}|dd}||jj|d||jj|d|t5|j||ddddS#1swxYwYdS)rr@rOrorN) ryrAr,rrrVrrrres r';test_rename_to_existing_dir_under_posix_raises_if_not_emptyzLFakeOsModuleTest.test_rename_to_existing_dir_under_posix_raises_if_not_emptys >>%//>>%//  ))(E::;;;  ))(E::;;;   w ' ' / / GNN8X . . . / / / / / / / / / / / / / / / / / /sC**C.1C.c||jdd}d}|j||t j|jj||dS)z5Renaming to another filesystem device raises OSError.z/mount/foo/barz /mount/barN) r_raadd_mount_pointrrIrJEXDEVrrres r'*test_rename_to_another_device_should_raisez;FakeOsModuleTest.test_rename_to_another_device_should_raisesp  ''111 ##H--- ##EK8TTTTTr)c&||d}|jj|d}|jj|d}||d||d||jj|||jj||j||| |jj|||jj|| |ddSz,Can rename a file to a used name under Unix.rlr rtest contents 1rtest contents 2N) ryrArrrVrrrrr"rrs r'"test_rename_to_existent_file_posixz3FakeOsModuleTest.test_rename_to_existent_file_posixsP NN7++  )))[AA  )))[AA  1BCCC 1BCCC  ++M::;;;  ++M::;;; }m444 ,,];;<<<  ++M::;;; M+<=====r)cT||d}|jj|d}|jj|d}||d||d||jj|||jj||tj |jj ||dSzC  CC/)D%%D),D)cX||ddSN)r\rrs r'#test_append_mode_tell_linux_windowsz4FakeOsModuleTest.test_append_mode_tell_linux_windowss. $$&&& 22155555r)cX||ddSr)r!rrs r'test_append_mode_tell_macosz,FakeOsModuleTest.test_append_mode_tell_macos!s.  22155555r)c|d}||d5}|d|d|ddddS#1swxYwYdS)Nr@r)rAr|rrrrs r'#test_tell_after_seek_in_append_modez4FakeOsModuleTest.test_tell_after_seek_in_append_mode&sNN5)) YYy# & & *! FF1III   Q ) ) ) * * * * * * * * * * * * * * * * * *s>A77A;>A;c2|d}||d5}|d|d|d|ddddS#1swxYwYdS)Nr@raar)rAr|rrrrrs r''test_tell_after_seekback_in_append_modez8FakeOsModuleTest.test_tell_after_seekback_in_append_mode-sNN5)) YYy# & & *! GGDMMM FF1III   Q ) ) ) * * * * * * * * * * * * * * * * * *sAB  BBc|||jj|j|jjzdSr5)rrrisdirrr rs r'!test_dir_with_trailing_sep_is_dirz2FakeOsModuleTest.test_dir_with_trailing_sep_is_dir5s9 dgl00$'+1MNNOOOOOr)c|d|jjz}|j||||jj||jdSNr)rArr rrIrr)r%errorr~s r'"check_rename_dir_with_trailing_sepz3FakeOsModuleTest.check_rename_dir_with_trailing_sep9sV>>%((47;6  h ##E47>8T^TTTTTr)cl||tjdSr5)ryrrJ ENOTEMPTYrs r''test_rename_dir_with_trailing_sep_posixz8FakeOsModuleTest.test_rename_dir_with_trailing_sep_posix>s0  //@@@@@r)cl||tjdSr5)rrrJrrs r')test_rename_dir_with_trailing_sep_windowsz:FakeOsModuleTest.test_rename_dir_with_trailing_sep_windowsCrtr)c|d}|jj|d}|jj|dd}|jj|d}|jj|dd}||||d||jj|||jj|||jj|||jj||j ||||jj|||jj|||jj|||jj|| |ddSzTest a rename of a directory.rlbeforerIafterpayloadrN) rArrrVr,rrrr"rrr%rDr before_filer after_files r'test_rename_dirz FakeOsModuleTest.test_rename_dirGsNN7++ W\&&y(;; gl'' 8VDD GL%%i99 W\&&y'6BB   ### y999  ++J77888  ++K88999 ,,Y77888 ,,Z88999 z9--- ,,Z88999 ,,[99:::  ++I66777  ++J77888 J 22222r)c|||d}|jj|d}|jj|d}|||j|}|j dz |_ |j |dd|j |d|||j|}| |j |j |j |||j|d}||j |j ||j|j||j|j||j|jd S) zTest if rename preserves mtime.rlr riF)check_read_permN)ryr_rArrrVrrarcst_mtimechownrrrrr st_uidst_gid)r%rDrrrGrHs r'test_rename_preserves_statz+FakeOsModuleTest.test_rename_preserves_stat[s  NN7++  )))[AA  )))[AA  '''?--m<<$-4  mS#...  mU+++ '''?--m<< H-x/@AAA }m444?--mU-SS *H,=>>> )8+;<<< (/::: (/:::::r)c|d}d}|jj|d}||||j|||||dSz2Test renaming when old and new names are the same.rlz Spam eggseggsrN)rArrrVrrrr%rDrrs r'test_rename_same_filenamesz+FakeOsModuleTest.test_rename_same_filenamesqs|NN7++ # GL%%i88  ];;; y),,, I}55555r)c|d}|dd}|dd}||||jj||j|||jj||||||j||jd||jj||jd|jd||jj|dS)Can remove a directory.rlabccdr`z../cdeedr^N rAr,rrrrrmdirr"rBr%rDsub_dir other_dirs r' test_rmdirzFakeOsModuleTest.test_rmdirzoNN7++ ..'22NN7G44   """  ++I66777  i    ,,Y77888      """  g  j!!! ,,Y77888  d  g ,,W5566666r)cT|d}|jj|d}||||jj||tj |jj |dS)z9Raises an exception if the target directory is not empty.rlrmN) rArrrVrrrrIrJrrrs r'test_rmdir_raises_if_not_emptyz/FakeOsModuleTest.test_rmdir_raises_if_not_emptysNN7++ GL%%i99  ###  ++I66777 ##EOTW]INNNNNr)c|d}|jj|d}||||jj||tj |jj ||||jj ddS)z5Raises an exception if the target is not a directory.rlrmrN) rArrrVrrrrIrJrQr)r%r2rDrs r'#check_rmdir_raises_if_not_directoryz4FakeOsModuleTest.check_rmdir_raises_if_not_directorysNN7++ GL%%i99  ###  ++I66777 ##EM47=)LLL ##HdgmSAAAAAr)cl||tjdSr5)ryrrJrrs r'(test_rmdir_raises_if_not_directory_posixz9FakeOsModuleTest.test_rmdir_raises_if_not_directory_posixs0  00>>>>>r)cl||tjdSr5)rrrJrArs r'*test_rmdir_raises_if_not_directory_windowsz;FakeOsModuleTest.test_rmdir_raises_if_not_directory_windowss0 !!! 00>>>>>r)c|d}||jj||t j|jj|dS)z1Raises an exception if the target does not exist.rlN) rAr"rrrrIrJrKrrCs r'test_rmdir_raises_if_not_existz/FakeOsModuleTest.test_rmdir_raises_if_not_exists]NN7++  ,,Y77888 ##EL$'-KKKKKr)c|||dd}|jj|d}|||jj|d}|j|||j|dz| |jj |dS)Nr@rOr r3z/alpha rrrArrrVr,rrr"rr%rr~rs r'test_rmdir_via_symlinkz'FakeOsModuleTest.test_rmdir_via_symlink !!! **,,,NN5%00 7<$$Y88 !!!GL%%i88   9---  i(*+++ ,,X6677777r)c||jj||j||jj| Sr5)rrrr removedirsrCs r'remove_dirs_checkz"FakeOsModuleTest.remove_dirs_checksW  ++I66777 9%%%7<&&y1111r)c|gd}|D]o}|||||jj||p|tj |j ||d|tj |j ||d|| ||d||jj||d| |jj||d||jj||d|tj |j ||d| |jj||d||dd|j |d|| |dd| |jj|dd| |jj|ddS) N)test1)r test2)r extra)r r test3rrrarr r r )r_r,rArrrrrIrJrrr"EBUSYra)r%datarDs r'test_removedirsz FakeOsModuleTest.test_removedirss       L LI OODNN955 6 6 6 OODGL//y0I0IJJ K K K K ## OT3T^^DG5L5L    ## OT3T^^DG5L5L    ..t~~d1g/F/FGGHHH  ++DNN47,C,CDDEEE ,,T^^DG-D-DEEFFF  ++DNN47,C,CDDEEE ## K/Q1H1H   ,,T^^DG-D-DEEFFF w88999 ""4>>'#:#:;;; ..t~~gw/O/OPPQQQ ,,T^^GW-M-MNNOOO ,,T^^G-D-DEEFFFFFr)c||j|j|jj|jd|jjjz}||jj|| tj |jj |dS)z(Raises exception if asked to remove '/'.rN) r_rrrr splitdriver rrrIrJr rrCs r''test_removedirs_raises_if_removing_rootz8FakeOsModuleTest.test_removedirs_raises_if_removing_roots   dn%%%GL++DN;;A>AQQ   ++I66777 ##EK1CYOOOOOr)c||dd}||||jj||tj |jj ||jj |\}}|jj |d|jjj kr||jj||jj |\}}|jj |d|jjj kdSdS)zRaises exception if asked to remove '/' as part of a larger operation. All of other directories should still be removed, though. r@rOrN)r_rAr,rrrrrIrJr rsplitrr r")r%rDhead unused_tails r'/test_removedirs_raises_if_cascade_removing_rootz@FakeOsModuleTest.test_removedirs_raises_if_cascade_removing_roots< NN5%00   """  ++I66777 ##EK1CYOOO GL..y99kgl%%d++A.$',2BBB   TW\00;; < < < $ 2 24 8 8 D+gl%%d++A.$',2BBBBBBBr)c||d|dd}||||jj||j|||jj|dS)z:removedirs works on directory names with trailing slashes.ror@rON)r,rArrrrrr"rCs r'#test_removedirs_with_trailing_slashz4FakeOsModuleTest.test_removedirs_with_trailing_slashs u--...NN5%00   """  ++I66777 9%%% ,,Y7788888r)c8||d}|d}|||j|||t j|jj|dS)Nrr-) ryrAr,rrrIrJrQr)r%r~r-s r''test_remove_dirs_with_top_symlink_failsz8FakeOsModuleTest.test_remove_dirs_with_top_symlink_failss >>%((>>*-- !!! (+++ ##EM473ExPPPPPr)cH||d}|d}|||j|||jj|d}|||j|||jj || |jj |dSNrr-rZ) ryrAr,rrrrVrr"rrr%r~r- dir_in_dirs r'.test_remove_dirs_with_non_top_symlink_succeedsz?FakeOsModuleTest.test_remove_dirs_with_non_top_symlink_succeeds s >>%((>>*-- !!! (+++W\&&x88   ### :&&& ,,Z88999  ++H5566666r)c|d}||j||j|||jd|z|j||j|||jd|d||j||jd||jjd|zdS)z&mkdir can create a relative directory.rlz/%s/z../abccbz /%s/abccbN) r_r"rarrrrrBrrCs r' test_mkdirzFakeOsModuleTest.test_mkdirs'   // ::;;;  i    ..uy/@AABBB  i     i    ...999ii/PQQRRR  i     j!!!  ++K),CDDEEEEEr)c|d}||jj||j|||jj|||jj|ddS)z9mkdir can create a directory named with a trailing slash.r@N)rAr"rrrrrrCs r'test_mkdir_with_trailing_slashz/FakeOsModuleTest.test_mkdir_with_trailing_slash(sNN5))  ,,Y77888  i     ++I66777  ++DNN5,A,ABBCCCCCr)c`d}|tj|jj|dS)z5mkdir raises exeption if creating directory named ''.rN)rIrJrKrrrCs r')test_mkdir_raises_if_empty_directory_namez:FakeOsModuleTest.test_mkdir_raises_if_empty_directory_name0s+  ##EL$'-KKKKKr)cd}|d}||jj||t j|jj|dS)z:mkdir raises exception if parent directory does not exist.rl/fooN)r"rrrrIrJrKrr%parentrDs r'test_mkdir_raises_if_no_parentz/FakeOsModuleTest.test_mkdir_raises_if_no_parent5s] &(  ,,V44555 ##EL$'-KKKKKr)c||dd}|jj|d}|jj|d}|||j|||tj |jj |dSNr@rOrr) ryrArrrVr,rrIrJrQrrXs r'%test_mkdir_raises_on_symlink_in_posixz6FakeOsModuleTest.test_mkdir_raises_on_symlink_in_posix<s NN5%00 GL%%i?? 7<$$Y66 !!! ),,, ##EM47=)LLLLLr)c^|||dd}|jj|d}|jj|d}|||j|||j|| |jj || |jj |dSr.) rrrArrrVr,rrr"rrrXs r'%test_mkdir_removes_symlink_in_windowsz6FakeOsModuleTest.test_mkdir_removes_symlink_in_windowsEs !!! **,,,NN5%00 GL%%i?? 7<$$Y66 !!! ),,,  i    ,,Y77888  ++H5566666r)c|d}||||jj||tj|jj |dSz3mkdir raises exception if directory already exists.rlN) rAr,rrrrrIrJrrrCs r'%test_mkdir_raises_if_directory_existsz6FakeOsModuleTest.test_mkdir_raises_if_directory_existsQsmNN7++   """  ++I66777 ##EL$'-KKKKKr)cT|d}|jj|d}||||jj||tj |jj |dS8mkdir raises exception if name already exists as a file.rlrmN) rArrrVrrrrIrJrrrs r' test_mkdir_raises_if_file_existsz1FakeOsModuleTest.test_mkdir_raises_if_file_existsXsNN7++ GL%%i99  ###  ++I66777 ##EL$'-KKKKKr)c|d}|jj|d}|||||jj|jj|ddSr7rlrmffN)rArrrVrrIrr% error_typerDrs r'$check_mkdir_raises_if_parent_is_filez5FakeOsModuleTest.check_mkdir_raises_if_parent_is_file`sNN7++ GL%%i99  ### ##  tw|'8'8D'I'I     r)cl||tjdSr5ryr>rJrQrs r')test_mkdir_raises_if_parent_is_file_posixz:FakeOsModuleTest.test_mkdir_raises_if_parent_is_file_posixiryr)cl||tjdSr5rr>rJrKrs r'+test_mkdir_raises_if_parent_is_file_windowsz>%// !!!NN5&11  ),,,',##Iy99  g  ++G4455555r)cl|d}|jj|d}||jj||j|||jj|dSz>makedirs can create a directory even if parent does not exist.rlr@N)rArrrVr"rmakedirsrr*s r' test_makedirszFakeOsModuleTest.test_makedirss((GL%%fe44  ,,V44555 ###  ++I6677777r)c@|d}|jj|d}||||jj||||jj|dSzAmakedirs raises exception if a parent component exists as a file.rlrmN) rArrrVrrrrIrWr%r=rrDs r''check_makedirs_raises_if_parent_is_filez8FakeOsModuleTest.check_makedirs_raises_if_parent_is_filesNN7++ GL%%i99  ###  ++I66777 ##J0@)LLLLLr)cl||tjdSr5ryr\rJrQrs r',test_makedirs_raises_if_parent_is_file_posixz=FakeOsModuleTest.test_makedirs_raises_if_parent_is_file_posix0  44U]CCCCCr)cl||tjdSr5rr\rJrKrs r'.test_makedirs_raises_if_parent_is_file_windowsz?FakeOsModuleTest.test_makedirs_raises_if_parent_is_file_windows0 !!! 44U\BBBBBr)cF||d}|j|d||t j|jj|jj |ddSN broken_linkbogusnewdir) ryrArrrIrJrKrWrrVrs r'-test_makedirs_raises_if_parent_is_broken_linkz>FakeOsModuleTest.test_makedirs_raises_if_parent_is_broken_links NN=11  w//;;; ## L G  GL  i 2 2     r)c$||d}|jj|d}|j|||tj|jj |dS)Nr) rrArrrVrrIrJrrWr%rrs r'.test_makedirs_raises_if_parent_is_looping_linkz?FakeOsModuleTest.test_makedirs_raises_if_parent_is_looping_linksy **,,,NN6** gl'' 6::   Y/// ##EL$'2BINNNNNr)c||dd}|||jj|d}|j|||jj|d}|j|||jj |dS)Nr@rOlinkedruname) ryrAr,rrrVrrWrr)r%base_dirlink_dirrBs r'"test_makedirs_if_parent_is_symlinkz3FakeOsModuleTest.test_makedirs_if_parent_is_symlinks >>%// !!!7<$$Xx88 (+++',##Hc22 g&&&  ++G4455555r)c@||d}|j||j|d|dd}t sO|t5|j|ddddS#1swxYwYdS|j|| |jj |dS)z+makedirs raises exception if access denied.rrQr4N) ryrArrrr rrrWrrrrCs r'%test_makedirs_raises_if_access_deniedz6FakeOsModuleTest.test_makedirs_raises_if_access_denieds@ NN3''   i     i'''NN3,, yy <""7++ , ,  +++ , , , , , , , , , , , , , , , , , , G  Y ' ' ' OODGL// :: ; ; ; ; ;sCC  C c|dd}||||jj||tj|jj ||j |d||jj|dSz#makedirs uses the exist_ok argumentrlr@Texist_okN) rAr,rrrrrIrJrrWrCs r'test_makedirs_exist_okz'FakeOsModuleTest.test_makedirs_exist_oksNN7E22   """  ++I66777 ##EL$'2BINNN T222  ++I6677777r)c<||d}|j|d|jj|d}t s\|tj |jj |d|tj |jj |ddS|j || |jj |dS)Nr@rrrOTryF) ryrArrrrVr rIrJrArWrr)r%rDsubdirs r'$test_makedirs_in_write_protected_dirz5FakeOsModuleTest.test_makedirs_in_write_protected_dirs  NN5))   ie ,,,""9e44yy 9  ' ' dg. (     ' ' dg. (      G  V $ $ $ OODGL//77 8 8 8 8 8r)c|tj|jjdd|tj|jjdddS)NrFryT)rIrJrKrrWrs r'"test_makedirs_raises_on_empty_pathz3FakeOsModuleTest.test_makedirs_raises_on_empty_pathsR ##EL$'2BBQV#WWW ##EL$'2BBQU#VVVVVr)c|t5|jdddddS#1swxYwYdSNzero)rrrfsyncrs r'test_fsync_raises_on_non_intz-FakeOsModuleTest.test_fsync_raises_on_non_ints   y ) ) " " GMM& ! ! ! " " " " " " " " " " " " " " " " " "sAA Acz||t|jjddSr)rrrr fdatasyncrs r' test_fdatasync_raises_on_non_intz1FakeOsModuleTest.test_fdatasync_raises_on_non_int s7  )TW%6?????r)c\|tj|jjddSr)rIrJr{rrrs r'test_fsync_raises_on_invalid_fdz0FakeOsModuleTest.test_fsync_raises_on_invalid_fd$s& ##EKDDDDDr)c||tj|jjd|tj|jjddS)Nrrx)rrIrJrrrr{rs r'#test_fdatasync_raises_on_invalid_fdz4FakeOsModuleTest.test_fdatasync_raises_on_invalid_fd'sX  ##EL$'2CQGGG ##EK1BCHHHHHr)c||d}||d||d5}|}|j||tj |jj|dzddddS#1swxYwYdSN test_filedummy file contentsrrrx) ryrArr|rrrrIrJr{r%test_file_pathrtest_fds r'test_fsync_pass_posixz&FakeOsModuleTest.test_fsync_pass_posix-s  44 2GHHH YY~s + + Sy&&((G GMM' " " "  ' ' TW]GcM R R R  S S S S S S S S S S S S S S S S S SsACCCcv||d}||d||d5}|}|j||tj |jj|dzdddn #1swxYwY||d5}|}|tj |jj|ddddS#1swxYwYdS)Nrrrr+rxr) rrArr|rrrrIrJr{rs r'test_fsync_pass_windowsz(FakeOsModuleTest.test_fsync_pass_windows8s !!! 44 2GHHH YY~t , , S &&((G GMM' " " "  ' ' TW]GcM R R R  S S S S S S S S S S S S S S S YY~s + + My&&((G  ' ' TW]G L L L M M M M M M M M M M M M M M M M M Ms&ACCC!AD..D25D2cj||d}||d||d}|}|j||tj |jj|dzdSr) rrArr|rrrrIrJr{rs r'test_fdatasync_passz$FakeOsModuleTest.test_fdatasync_passFs  44 2GHHHIInc22 ""$$ '""" ##EK1BGcMRRRRRr)cD||d}|||j|d|d|j|j||j ||jj ||j ||jj ||j ||jj ||j ||jj ||j ||jdS)N some_file)ryrAr(rrassert_mode_equalrr raccessF_OKr8r9r:r;rs r'test_access700zFakeOsModuleTest.test_access700Rs8 ~~k** D!!!  dE""" udgll4&8&8&@AAA tTW\::;;; tTW\::;;; tTW\::;;; tTW\::;;; tTX6677777r)c||d}|||j|d|d|j|j||j ||jj ||j ||jj ||j ||jj | |j ||jj| |j ||j||j ||jdS)Nr)ryrAr(rrrrr rrrr8r9r"r:r;r<rs r'test_access600zFakeOsModuleTest.test_access600`s` ~~k** D!!!  dE""" udgll4&8&8&@AAA tTW\::;;; tTW\::;;; tTW\::;;; dgl;;<<< dh77888 tTW5566666r)c||d}|||j|d|d|j|j||j ||jj ||j ||jj | |j ||jj | |j ||jtrm||j ||jj||j ||jdS| |j ||jj| |j ||jdS)NrrQ)ryrAr(rrrrr rrrr8r"r:r;r r9r<rs r'test_access400zFakeOsModuleTest.test_access400os ~~k** D!!!  dE""" udgll4&8&8&@AAA tTW\::;;; tTW\::;;; dgl;;<<< dh77888 99 < OODGNN4>> ? ? ? OODGNN499 : : : : :   TW^^D$',?? @ @ @   TW^^D$':: ; ; ; ; ;r)cZ|||d}|||d}||||j|d||j||jj ||j||jj trl||j||jj ||j||j nk||j||jj ||j||j ||j||jj||j||j||j||jj d||j||jj d||j||jj d||j||jjd||j||jd||j||j ddS)Nrlink_to_some_filerQFr)rr_rAr(rrrrrrr8r r9r<r"r:r;)r%rrs r'test_access_symlinkz$FakeOsModuleTest.test_access_symlinks **,,, ~~k** D!!!NN#677  It,,,  i''' y$',??@@@ y$',??@@@ 99 A OODGNN9dglCC D D D OODGNN9dg>> ? ? ? ?   TW^^Itw|DD E E E   TW^^Itw?? @ @ @  47<@@AAA  48<<=== y$',PUVVWWW y$',PUVVWWW y$',PUVVWWW y$',PUVVWWW y$(ERRSSS y$'5QQRRRRRr)c$|ddd}||jj|||j||jj||j||jj||j||jj||j||jj ||j||j ||j||j dS)NrGrHrI) rAr"rrrrrr8r9r:r;r<rs r'test_access_non_existent_filez.FakeOsModuleTest.test_access_non_existent_files/~~eZ88 ,,T22333 dgl;;<<< dgl;;<<< dgl;;<<< dgl;;<<< dh77888 dg6677777r)c||dd}|t5|j||jjdddddS#1swxYwYdS)Nr@rOT) effective_ids)rrArNotImplementedErrorrrrrs r'.test_effective_ids_not_supported_under_windowsz?FakeOsModuleTest.test_effective_ids_not_supported_under_windowss !!!~~eU++   2 3 3 C C GNN4TN B B B C C C C C C C C C C C C C C C C C Cs(A::A>A>c|||d}|||j|d|j|}|d|j| |jt j z| |jt j zdSNrc ) ryr_rAr(rrrrr rr!r"r#r$s r' test_chmodzFakeOsModuleTest.test_chmods  ~~k** D!!!  dF### W\\$   vrz222  T\1222 dl233333r)c|||tj|jjdd|d}||| |5}|j|j d|j |}| d|j ddddS#1swxYwYdS)Nrrr)ryr_rIrJr{rrrAr(r|rrrr r%rrur&s r'test_chmod_uses_open_fd_as_pathz0FakeOsModuleTest.test_chmod_uses_open_fd_as_paths   ##EK6JJJ~~k** D!!! YYt__ 7 GMM!)V , , ,d##B  " "62: 6 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7sAC77C;>C;c4||d}|||d}||||j|d|j|}|d|j|j|d}| t j dt j |jdzdS)NrrrFrr) ryrAr(rrrrrr rrr%rrr&s r'test_chmod_follow_symlinkz*FakeOsModuleTest.test_chmod_follow_symlinks ~~k** D!!!NN#677  It,,,  i((( W\\) $ $ vrz222 W\\)U\ ; ; e,,dl2:.F.F.NOOOOOr)c||d}|||d}||||jj|jjvstrR|t5|j|ddddddS#1swxYwYdS|j|dd|j |}| d|j |j |d}| d|j dS)NrrrFrr) ryrAr(rrrsupports_follow_symlinksrrrrrr rs r'test_chmod_no_follow_symlinkz-FakeOsModuleTest.test_chmod_no_follow_symlinks ~~k** D!!!NN#677  It,,, 7= @ @ @G @""#677 H H i GGG H H H H H H H H H H H H H H H H H H GMM)VUM C C Ci((B  " "5"* 5 5 5i??B  " "62: 6 6 6 6 6s#CCCc |||d}|||d}||||j|d|j|}|d|j |j |}|d|j dS)z9lchmod shall behave like chmod with follow_symlinks=True.rrrrN) ryr_rAr(rrlchmodrrr rrs r' test_lchmodzFakeOsModuleTest.test_lchmods  ~~k** D!!!NN#677  It,,, y&))) W\\) $ $ ubj111 W]]9 % % vrz22222r)c|||d}|||j|d|j|}|d|j| |jt j z| |jt j zdS)Nsome_diri) ryr_rAr-rrrrr r"r!rr#r$s r'test_chmod_dirzFakeOsModuleTest.test_chmod_dirs  ~~j))   &&&  dF### W\\$   vrz222 dl2333  T\122222r)c|ddd}||jj| |j|d|ddS#t$rK}|tj |j |||j Yd}~dSd}~wwxYw)NrGrHrIr+rJ) rAr"rrrrrKrrrJrKrS)r%rrLs r'test_chmod_non_existentz(FakeOsModuleTest.test_chmod_non_existents~~eZ88 ,,T22333 6 GMM$ & & & II. / / / / / 6 6 6   U\8> : : :   T8#4 5 5 5 5 5 5 5 5 5 6s 0A== CAC  Cc||d}|||j|dd|j|}||t jd||t jd|j|dd|j|}||t jd||t jd|j|dd|j|}||t jd||t jddS)Nrder) r_rArrrrrST_UIDST_GIDr%rr&s r'test_chown_existing_filez)FakeOsModuleTest.test_chown_existing_filesh NN;//  ###  ic*** W\\) $ $ DK#... DK#...  ic*** W\\) $ $ DK#... DK#...  iR((( W\\) $ $ DK#... DK#.....r)c$|||tj|jjddd|dd}||| |5}|j|j dd|j |}| |tj dddddS#1swxYwYdS)Nrrrr@rO)ryr_rIrJr{rrrArr|rrrr)r%rrur&s r'test_chown_uses_open_fd_as_pathz0FakeOsModuleTest.test_chown_uses_open_fd_as_path&s+   ##EK3LLLNN5%00  ### YYy ! ! 3Q GMM!)S# . . .i((B   R _c 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3sA"DD  D c||d}|||d}||||j|dd|j|}||t jd||t j d|j|d}| |t jd| |t j ddSNrrrrFr) r_rArrrrrrrrrr%rrr&s r'test_chown_follow_symlinkz*FakeOsModuleTest.test_chown_follow_symlink2s NN;//  ###NN#677  Iy111  ic*** W\\) $ $ DK#... DK#... W\\)U\ ; ; Bt{OS111 Bt{OS11111r)c||d}|||d}||||j|ddd|j|}||t jd||t j d|j|d}| |t jd| |t j ddSr) r_rArrrrrrrrrrs r'test_chown_no_follow_symlinkz-FakeOsModuleTest.test_chown_no_follow_symlinkAs NN;//  ###NN#677  Iy111  ic5 AAA W\\) $ $ Bt{OS111 Bt{OS111 W\\)U\ ; ; DK#... DK#.....r)c"||d}|||t|jj|dd|t|jj|dddS)z$os.chown() with bad args (Issue #30)rusernamer groupnameN)ryrArrrrrrs r'test_chown_bad_argumentsz)FakeOsModuleTest.test_chown_bad_argumentsPs NN;//  ### )TW]Iz2NNN )TW]Ir;OOOOOr)c||d}||jj||tj|jj |dddS)Nrr) ryrAr"rrrrIrJrKrrs r'1test_chown_nonexisting_file_should_raise_os_errorzBFakeOsModuleTest.test_chown_nonexisting_file_should_raise_os_errorXst NN;//  ,,Y77888 ##EL$'-CQTUUUUUr)c|d}ddg}gd}|||D]7}|jj||}||8|D]7}|jj||}||8|||j|}t|\}}} || | ||| ||| || dS)z/Directory classification should work correctly.r@bar1baz2)baz1bar2baz3N) rAr,rrrVrrqwalknextr) r%root_directorytest_directories test_filesrDr generatorrootdirsrts r' test_classify_directory_contentsz1FakeOsModuleTest.test_classify_directory_contents^sa.."F+---  ''') ' 'I )).)DDI OOI & & & &# ( (I )).)DDI   Y ' ' ' 'GLL00  OOdE   ... )4000 U+++++r)c||d}||jj||j|||jj||tj dz|j |j dS)Nr@r) rrAr"rrrmknodrrrr!r rRs r'test_mk_nod_can_create_a_filez.FakeOsModuleTest.test_mk_nod_can_create_a_filews >>%(( ,,X66777  h  ++H55666 -tw||H/E/E/MNNNNNr)c|d}|tj|jj|dSrrrIrJrKrrrRs r'%test_mk_nod_raises_if_empty_file_namez6FakeOsModuleTest.test_mk_nod_raises_if_empty_file_name=  ##EL$'-JJJJJr)cR||d}|jj|d}||jj||tj |jj |dS)Nrlr@) rrArrrVr"rrIrJrKr)r%r+rSs r'-test_mk_nod_raises_if_parent_dir_doesnt_existz>FakeOsModuleTest.test_mk_nod_raises_if_parent_dir_doesnt_exists ((7<$$VU33 ,,V44555 ##EL$'-JJJJJr)c>||dd}||||jj||tj |jj |dSNtmpr@ rrArrrrrrIrJrrrRs r'!test_mk_nod_raises_if_file_existsz2FakeOsModuleTest.test_mk_nod_raises_if_file_existss >>%// """  ++H55666 ##EL$'-JJJJJr)c||dd}|tj|jj|dS)NrrrrArIrJrKrrrRs r'%test_mk_nod_raises_if_filename_is_dotz6FakeOsModuleTest.test_mk_nod_raises_if_filename_is_dotsK >>%-- ##EL$'-JJJJJr)c||dd}|tj|jj|dS)Nrr^rrRs r',test_mk_nod_raises_if_filename_is_double_dotz=FakeOsModuleTest.test_mk_nod_raises_if_filename_is_double_dotsK >>%.. ##EL$'-JJJJJr)c<||d}||||jj||tj |jj |dSrrrRs r'.test_mknod_empty_tail_for_existing_file_raisesz?FakeOsModuleTest.test_mknod_empty_tail_for_existing_file_raisess >>%(( """  ++H55666 ##EL$'-JJJJJr)c||dd}|tj|jj|dSrrrRs r'1test_mknod_empty_tail_for_nonexistent_file_raiseszBFakeOsModuleTest.test_mknod_empty_tail_for_nonexistent_file_raisessK >>%// ##EL$'-JJJJJr)c|d}|tj|jj|dSrrrRs r'-test_mknod_raises_if_filename_is_empty_stringz>FakeOsModuleTest.test_mknod_raises_if_filename_is_empty_stringrr)cd||d}ts8|tj|jj|tj dS|j|tj |j |dS)Nr) ryr_r rIrJr>rrrS_IFCHRr9rRs r'(test_mknod_raises_if_unsupported_optionsz9FakeOsModuleTest.test_mknod_raises_if_unsupported_optionss  yy %  ' ' TW]Hdl      GMM(DL 1 1 1 GNN8 $ $ $ $ $r)ch||d}||||jj||dd}|tj |jj |dSrg) rrArrrrrrIrJrQr)r% filename1 filename2s r'.test_mknod_raises_if_parent_is_not_a_directoryz?FakeOsModuleTest.test_mknod_raises_if_parent_is_not_a_directorys NN5))  ###  ++I66777NN5%00  ##EM47=)LLLLLr)c||ddd}||dd|jd|||jj|||jj || |ddd||jj|||jj |dS)Nr@rOrorh) rrAr,rrrrr]r"rrrs r' test_symlinkzFakeOsModuleTest.test_symlinks **,,,NN5%77  ue44555 +++  ,,Y77888 ,,Y77888 ug>>???  ,,Y77888  ++I6677777r)cH||d}|jj|d}|t j|jj|||t j|jj||dSr/) ryrArrrVrIrJrKrr%r~rs r''test_symlink_on_nonexisting_path_raisesz8FakeOsModuleTest.test_symlink_on_nonexisting_path_raisess >>%((GL%%h66  ##EL$'/9iXXX ##EL$'/8YWWWWWr)c||d}|||tj|jj|j||jj z|d}|tj |jj|j||jj zdSNrrO) ryrAr,rIrJrrrrr rKrs r'/test_symlink_with_path_ending_with_sep_in_posixz@FakeOsModuleTest.test_symlink_with_path_ending_with_sep_in_posixs >>%(( !!! ## L GO N tw{ "    >>%(( ## L GO N tw{ "      r)c|||d}|||t j|jj|j ||jj z|d}|j|j ||jj zdSr) rrrAr,rIrJrrrrr rs r'1test_symlink_with_path_ending_with_sep_in_windowszBFakeOsModuleTest.test_symlink_with_path_ending_with_sep_in_windowss !!! **,,,>>%(( !!! ## L GO N tw{ "    >>%(( 47;(>?????r)c||d|jjz}|t j|jj||dSr)rrArr rIrJrKrr%path0s r'+test_broken_symlink_with_trailing_sep_posixzFakeOsModuleTest.test_broken_symlink_with_trailing_sep_windowssf !!! **,,,u%% 3 ##EL$'/5%PPPPPr)c||d}|j|j||t j|jj||jj z|jdSr) rrArrrrIrJrQrr rs r'+test_rename_symlink_with_trailing_sep_linuxz4$'++=t~     r)c||d}|j|j||j||jjz|jdSr)r!rArrrrr rs r'+test_rename_symlink_with_trailing_sep_macosz:::::r)c<|||d}|j|j||tj|jj ||jj z|jdSr) rrrArrrrIrJrrr rs r'-test_rename_symlink_with_trailing_sep_windowsz>FakeOsModuleTest.test_rename_symlink_with_trailing_sep_windows s !!! **,,,~~e$$ --- ## L$'.$*9MMMMMr)c||}|tj|jj|dSr5)r!r'rIrJrKrr9rs r'/test_remove_broken_link_with_trailing_sep_macosz@FakeOsModuleTest.test_remove_broken_link_with_trailing_sep_macosU sI BBDD  ##EL$'.)LLLLLr)c||}|tj|jj|dSr5)rr'rIrJrrr9rs r'1test_remove_broken_link_with_trailing_sep_windowszBFakeOsModuleTest.test_remove_broken_link_with_trailing_sep_windowsZ sI !!!BBDD  ##EL$'.)LLLLLr)c||}|tj|jj||ddSNr)rr'rIrJrQrrrArs r'/test_rename_broken_link_with_trailing_sep_linuxz@FakeOsModuleTest.test_rename_broken_link_with_trailing_sep_linux_ sb BBDD  ## M47>9dnnX6N6N     r)c||}|tj|jj||ddSr<)r!r'rIrJrKrrrArs r'/test_rename_broken_link_with_trailing_sep_macosz@FakeOsModuleTest.test_rename_broken_link_with_trailing_sep_macosf sb BBDD  ## L$'.)T^^H5M5M     r)c||}|tj|jj||ddSr<)rr'rIrJrrrrArs r'1test_rename_broken_link_with_trailing_sep_windowszBFakeOsModuleTest.test_rename_broken_link_with_trailing_sep_windowsm sb !!!BBDD  ## L$'.)T^^H5M5M     r)c||}|tj|jj|dSr5)ryr'rIrJrKrrrs r'1test_readlink_broken_link_with_trailing_sep_posixzBFakeOsModuleTest.test_readlink_broken_link_with_trailing_sep_posixt sJ BBDD  ##EL$'2BINNNNNr)c||}|tj|jj|dSr5)rr'rIrJrrrrs r'3test_readlink_broken_link_with_trailing_sep_windowszDFakeOsModuleTest.test_readlink_broken_link_with_trailing_sep_windowsy sJ !!!BBDD  ##EL$'2BINNNNNr)c|}||jj|dSr5)r'r"rrr'rs r')test_islink_broken_link_with_trailing_sepz:FakeOsModuleTest.test_islink_broken_link_with_trailing_sep~ s?BBDD  ,,Y7788888r)c|}||jj|dSr5)r'r"rrr]rs r'*test_lexists_broken_link_with_trailing_sepz;FakeOsModuleTest.test_lexists_broken_link_with_trailing_sep s?BBDD  --i8899999r)c|||d}|j|j||j||jjz|dSr)rrrArrrrr rs r'2test_rename_link_with_trailing_sep_to_self_windowszCFakeOsModuleTest.test_rename_link_with_trailing_sep_to_self_windows st !!! **,,,~~e$$ --- tdgk)400000r)c ||d}|j|j||t j|jj||jj z|dSr) ryrArrrrIrJrQrr rs r'0test_rename_link_with_trailing_sep_to_self_posixzAFakeOsModuleTest.test_rename_link_with_trailing_sep_to_self_posix sw ~~e$$ --- ## M47>4$'++=t     r)cF||d|jjz}|d}|j|||||j|d|||j|ddS)Nrrrr)rrArr rrIr|)r%rr&rs r'3check_open_broken_symlink_to_path_with_trailing_sepzDFakeOsModuleTest.check_open_broken_symlink_to_path_with_trailing_sep s **,,,nnX..< NN6**   Y/// ##E49iEEE ##E49iEEEEEr)cl||tjdSr5)rrOrJrTrs r'8test_open_broken_symlink_to_path_with_trailing_sep_linuxzIFakeOsModuleTest.test_open_broken_symlink_to_path_with_trailing_sep_linux 0  @@NNNNNr)cl||tjdSr5)r!rOrJrKrs r'8test_open_broken_symlink_to_path_with_trailing_sep_macoszIFakeOsModuleTest.test_open_broken_symlink_to_path_with_trailing_sep_macos rRr)cl||tjdSr5)rrOrJrrs r':test_open_broken_symlink_to_path_with_trailing_sep_windowszKFakeOsModuleTest.test_open_broken_symlink_to_path_with_trailing_sep_windows s0 !!! @@NNNNNr)c>||d}|d}||d5|||jj||jjz|ddddS#1swxYwYdS)Nr@rr)rrAr|rIrrr )r%rrrs r'check_link_path_ending_with_sepz0FakeOsModuleTest.check_link_path_ending_with_sep s **,,,NN5)) NN6** YYy# & &    ' 'tw|Y%                      s0A))A-0A-cl||tjdSr5)ryrdrJrQrs r')test_rename_to_path_ending_with_sep_posixz:FakeOsModuleTest.test_rename_to_path_ending_with_sep_posix ryr)cl||tjdSr5)rrdrJrrs r'+test_rename_to_path_ending_with_sep_windowsz>%((  hNN6**  ),,, ## M47=)dgk*A     r)c||d}|j||d}|j|||j||jjz||jj |dSr) r!rArrrrr r"rrr s r''test_rmdir_link_with_trailing_sep_macosz8FakeOsModuleTest.test_rmdir_link_with_trailing_sep_macos s >>%((  hNN6**  ),,,  i$'+-... ,,Y7788888r)c|||d}|j||d}|j|||j||jjz||jj |dSr) rrrArrrrr r"rrr s r')test_rmdir_link_with_trailing_sep_windowsz:FakeOsModuleTest.test_rmdir_link_with_trailing_sep_windows s !!! **,,,>>%((  hNN6**  ),,,  i$'+-... ,,Y7788888r)c^||d}|d}|j|||j|||t j|jj||jjzdSrgrr%r9rs r'3test_readlink_circular_link_with_trailing_sep_linuxzDFakeOsModuleTest.test_readlink_circular_link_with_trailing_sep_linux s u%%u%% u%%% u%%% ##EK1A547;CVWWWWWr)cd||d}|d}|j|||j|||||j||jjzdSrg)r!rArrrrr rps r'3test_readlink_circular_link_with_trailing_sep_macoszDFakeOsModuleTest.test_readlink_circular_link_with_trailing_sep_macos s u%%u%% u%%% u%%%  0 01D E EFFFFFr)c|||d}|d}|j|||j|||t j|jj||jj zdSrgrrps r'5test_readlink_circular_link_with_trailing_sep_windowszFFakeOsModuleTest.test_readlink_circular_link_with_trailing_sep_windows s !!! **,,,u%%u%% u%%% u%%% ##EL$'2BEDGKDWXXXXXr)c||tj|jjdddS)Nz/nonexistent_sourcez /link_dest)rrIrJrKrrrs r'test_link_bogusz FakeOsModuleTest.test_link_bogus sF **,,, ## L$',(=|     r)c.||d}|d}d}||||j|||j|||jj|| |5}| | |ddddS#1swxYwYdSN test_file1 test_file2abcdefr) rrArrrr rrrr|rrr% file1_path file2_path contents1rus r'test_link_deletez!FakeOsModuleTest.test_link_delete s3 **,,,^^L11 ^^L11   i888  Z,,, z"""  ++J77888 YYz " " 2a   QVVXXy 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2s)D  DDc||d}|d}d}d}||||j||||5}|||dddn #1swxYwY||d5}||dddn #1swxYwY||5}|||ddddS#1swxYwYdS)Nrzr{r|ghijklrr) rrArrrr|rrr)r%r~rr contents2rus r'test_link_updatez!FakeOsModuleTest.test_link_update/ s **,,,^^L11 ^^L11    i888  Z,,, YYz " " 2a   QVVXXy 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2YYz3 ' ' 1 GGI                  YYz " " 2a   QVVXXy 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2s6 )B??CC DD D")EEEc||d}|dd}d}||||tj|jj||dS)Nrz nonexistentr{r|r)rrArrIrJrKrr)r%r~breaking_link_pathrs r'test_link_non_existent_parentz.FakeOsModuleTest.test_link_non_existent_parentC s **,,,^^L11 !^^M<HH  i888 ## L$', 4F     r)c||dd}|||tj|jj||dSrg)rrArrIrJrrrrs r'test_link_is_existing_filez+FakeOsModuleTest.test_link_is_existing_fileP sa **,,,NN5%00  ### ##EL$', 9UUUUUr)cD|||dd}|jj|d}|||tj |jj ||dSNr@rOr) rrrArrrVr,rIrJrArr s r'test_link_target_is_dir_windowsz0FakeOsModuleTest.test_link_target_is_dir_windowsV s !!! **,,,>>%//GL%%h77  !!! ##EL$',)TTTTTr)c||dd}|jj|d}|||tj|jj ||dSr) ryrArrrVr,rIrJr>rr s r'test_link_target_is_dir_posixz.FakeOsModuleTest.test_link_target_is_dir_posix^ sx >>%//GL%%h77  !!! ##EKxSSSSSr)c@||d}|d}|d}||||j|jd|j||||j|jd||j|jd|j||||j|jd||j|jd||j|jd|j|||j|jd||j|jd|j|||j|jddS)z1Test that hard link counts are updated correctly.rzr{ test_file3rrraN) rrArrrrrdrr )r%r~r file3_paths r'test_link_count1z!FakeOsModuleTest.test_link_count1e s **,,,^^L11 ^^L11 ^^L11  $$$ j11:A>>>  Z,,, j11:A>>> j11:A>>>  Z,,, j11:A>>> j11:A>>> j11:A>>> z""" j11:A>>> j11:A>>> z""" j11:A>>>>>r)c |||dd||dd|d|j|ddj|d|j|dj||dd|d|j|djdS)Nr@rOrorrr)r_r,rArrrarcrdrs r'test_nlink_for_directoriesz+FakeOsModuleTest.test_nlink_for_directories s)  ue44555 u55666  O & &t~~eU'C'C D D M    DO66t~~e7L7LMMVWWW v66777 DO66t~~e7L7LMMVWWWWWr)c|tjd}tj||||jddSN)ryrumaskr)r%rs r' test_umaskzFakeOsModuleTest.test_umask sX    d 3 344444r)c||jd|d}|j||d|j|j|jd|d}|j||d|j|jdS)z-mkdir creates a directory with umask applied.rrY7rZN)ryrrrArrrr )r%rYrZs r'test_mkdir_umask_appliedz)FakeOsModuleTest.test_mkdir_umask_applied s   d~~f%%  d udgll4&8&8&@AAA  d~~f%%  d udgll4&8&8&@AAAAAr)c ||jd|j|dd|d|j|dj|d|j|ddj|jd|j|dd|d|j|dj|d|j|ddjd S) z2makedirs creates a directories with umask applied.rp1rYrrp2rZrN)ryrrrWrArrr rs r'test_makedirs_umask_appliedz,FakeOsModuleTest.test_makedirs_umask_applied sn   d f55666 udgll4>>$3G3G&H&H&PQQQ  47<<tV < <==E     d f55666 udgll4>>$3G3G&H&H&PQQQ  47<<tV < <==E     r)cV||jd|d}|j|t jdz|d|j|j|jd|d}|j|t jdz|d|j|jdS) z*mkdir creates a device with umask applied.rnod1rnod2N) rrrrArrr!rr )r%node1node2s r'test_mknod_umask_appliedz)FakeOsModuleTest.test_mknod_umask_applied s   dv&&  eT\E1222 udgll5&9&9&ABBB  dv&&  eT\E1222 udgll5&9&9&ABBBBBr)cV||jd|d}||d|d|j|j|jd|d}||d|d|j|jdS) z'open creates a file with umask applied.rfile1rrrfile2rN) ryrrrAr|rrrr )r%rrs r'test_open_umask_appliedz(FakeOsModuleTest.test_open_umask_applied s   dw'' %##%%% udgll5&9&9&ABBB  dw'' %##%%% udgll5&9&9&ABBBBBr)c|j\}}|j||j|dSr5)rpiperr%read_fdwrite_fds r'test_open_pipezFakeOsModuleTest.test_open_pipe sD GLLNN  g  hr)cz|d}|j|tj}|j\}}||||j||j||j|dSNr)rArr|rOr assertGreaterr)r%rfdrrs r'test_open_pipe_with_existing_fdz0FakeOsModuleTest.test_open_pipe_with_existing_fd sw'' W\\% , , GLLNN 7B'''  b  g  hr)cz|j\}}|d}|j|tj}||||j||j||j|dSr)rrrAr|rOrr)r%rrrrs r'!test_open_file_with_existing_pipez2FakeOsModuleTest.test_open_file_with_existing_pipe s GLLNNw'' W\\% , , 2x(((  g  h  br)cb|j\}}|d|j|d|d|j|d|j||j|dS)Nrtest)rrrrrrrs r'test_read_write_pipez%FakeOsModuleTest.test_read_write_pipe s GLLNN DGMM(G<<=== $',,w":":;;;  g  hr)cfg}tdD]_}|dt|z}||j|tj`|d}||||5|j\}}||d5}| d| ddddn #1swxYwY||d5}| d| dddn #1swxYwYdddn #1swxYwY|D]}|j |dS)NrrIzfile.txtwbrrr) rangerAstrappendrr|rOrrrrrr) r%fdsirrrrrurs r'test_open_existing_pipez(FakeOsModuleTest.test_open_existing_pipe s>q 7 7A>>&3q66/22D JJtw||D"*55 6 6 6 6NN:..  ### YYy ! ! 4 4 $  GX8T** 6a  AGGG$4$4555 6 6 6 6 6 6 6 6 6 6 6 6 6 6 67D)) 4Q  !&&((333 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4  4 4 4 4 4 4 4 4 4 4 4 4 4 4 4   B GMM"      sZ13F$*D FD F!D "F;)E0$ F0E4 4F7E4 8FF F c:|j\}}|j|d|d|j|d|j||j|dS)Nrr)rrrrrrrs r'test_write_to_pipez#FakeOsModuleTest.test_write_to_pipe s GLLNN  h((( $',,w":":;;;  g  hr))win32darwinlinuxz1Pipe implementation may differ on other platformsc|j\}}|tj|jj|d|j||j|dS)Nr)rrrIrJr{rrrs r'test_write_to_read_fdz&FakeOsModuleTest.test_write_to_read_fd sf !GLLNN ##EKQQQ  g  hr)cB|dd}||d|j|d||5}|d|ddddS#1swxYwYdS)Nr@rO012345678901234567r 0123456789)rArrrr|rrrs r' test_truncatezFakeOsModuleTest.test_truncate sNN5%00  -ABBB B''' YYy ! ! 5Q   \16688 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5s)BBBc^|tj|jjdddS)Nr@r)rIrJrKrrrs r'test_truncate_non_existingz+FakeOsModuleTest.test_truncate_non_existing s) ##EL$'2BE2NNNNNr)c|dd}||d|j|tj}|j|d|d|j|j||5}|d| ddddS#1swxYwYdS)Nr@rOrrz0123456789) rArrr|O_RDWRrrrst_sizerr%rrrus r'test_truncate_to_largerz(FakeOsModuleTest.test_truncate_to_larger s)NN5%00  \::: W\\)RY / / R    TW\\)44<=== YYy ! ! AQ   5qvvxx @ @ @ A A A A A A A A A A A A A A A A A As6)C,,C03C0ctjtjvr||t j|jjdd|d}| |d|j |tj }|j|d| d|j |j| |5}| d|ddddS#1swxYwYdS)N2rr01234567890123456789rr)rrrzr_rIrJr{ ftruncaterArr|rrrrrrs r'test_truncate_with_fdz&FakeOsModuleTest.test_truncate_with_fd sV ;bn , ,       ##EK1BBKKKNN;//  -CDDD W\\)RY / / R    TW\\)44<=== YYy ! ! 5Q   \16688 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5s )EE Ec~|jr||tj|jjdd|d}||d|j |t j }|j |d| d|j |j| |5}| d|ddddS#1swxYwYdS)Nrrr0123456789012345rr)is_pypyr_rIrJr{rrrArr|rrrrrrrs r'test_ftruncatezFakeOsModuleTest.test_ftruncate' sQ <       ##EK1BBKKKNN;//  -?@@@ W\\)RY / / R    TW\\)44<=== YYy ! ! 5Q   \16688 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5s<)D22D69D6c||jj|jjvtjtjv||jj|jjvtjtjv||jj|jjvtjtjv||jj|jjvtjtjvdS)zCMake sure that the fake capabilities are the same as the real ones.N)rrrrrzsupports_dir_fdsupports_effective_idsrs r'test_capabilitiesz"FakeOsModuleTest.test_capabilities5 s  GLDG< < Gr2 2    )<WXXX  GLDG3 3RW@R5R     GLDG: : Gr0 0     r)(:r.r/r0r7rErLrTr\rerirvrrrrrrrrrrrrrrrrrrrrrrrrr rrrrrr"r%r(r*r-r3r5r7r:r<r?rBrErMrRrUrXrZr^r`rbrdrgrirmrorqrsrvrxr{rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr rrrr"r*r1r;r=r?rErIrLrPrUrYr[rgrkrnrrrvr{rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr r#r%r'r,r/r1r4r8r>rArDrGrIrMrOrRrTrXr\r_rcrjrmrtrvr{r~rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr r rrrrrrrrr$r'r)r,r.r0r2r4r6r8r:r=r?rArCrErGrIrKrMrOrQrTrVrXrZr\r`rbrdrfrhrjrlrnrqrsrurwrrrrrrrrrrrrrrrrrrrunittestskipIfsysplatformrrrrrrr __classcell__r>s@r'r3r3<s..... !!! LLL LLL     4 4 4444 D D D C C C>>>TTTOOO 222III ' ' 'FFFJJJ4###"EEECCC@@@$... C C C C C CRRR   *   * Q Q Q D D D    /// /// 444 GGG 777 HHH   HHHHHH   KKKGGG GGG    IIIHHHWWW >>><<<=== Y Y Y ; ; ;   EEEEEEEEEHHHGGGGGGFFFGGG GGG888 UUU ???>>>WWW AAA@@@EEEOOO ;;; ;;;PPPBBB CCC   ###    JJJ       222          " L L L,,,+++,,,LLL999999###444444.333444999$JJJ 999888999 4 4 4MMM < < <XXXWWW 8 8 8 9 9 9     J J J;;; ;;;WWW111       999WWW 9 9 9 S S SSSSKKKJJJVVV 8 8 8 9 9 9WWW 8 8 8WWW / / /UUU > > >     > > > < < <    P P P < < < 5 5 5666 666 ******PPPUUU AAA >>>333(;;;,666777$OOOBBB??????LLL 8 8 8222 &G&G&GPPPP999 999QQQ 7 7 7 F F FDDDLLL LLLMMM 7 7 7LLLLLL   AAA@@@LLLLLLLLL L L L<<< 666888MMMDDDCCC   OOO666<<<"888999 WWW """@@@EEEIII S S S M M M S S S 8 8 8 7 7 7<<<&SSS: 8 8 8CCC 4 4 4 7 7 7 P P P777 3 3 3 3 3 3 6 6 6///* 3 3 3 2 2 2 / / /PPPVVV ,,,2OOOKKK KKKKKKKKK KKK KKKKKK KKK % % %MMM 8 8 8XXX   &@@@ QQQ QQQ    ;;;    Y Y YLLL LLL LLL OOO !!! $$$ NNN MMM MMM          OOO OOO 999:::111   FFFOOOOOOOOO<<<;;;RRR888AAA@@@   999999XXXGGGYYY   222"222(    VVV UUUTTT???4 X X X555 B B B   C C C C C C         $   X_ 88;   555OOOAAA 5 5 5 5 5 5        r)r3ceZdZdZdS)RealOsModuleTestcdSNTr1rs r'rbzRealOsModuleTest.use_real_fsF tr)Nr.r/r0rbr1r)r'rrE #r)rcLeZdZfdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZ dZ!d Z"d!Z#d"Z$d#Z%d$Z&d%Z'd&Z(d'Z)d(Z*d)Z+d*Z,d+Z-d,Z.d-Z/d.Z0d/Z1d0Z2d1Z3d2Z4d3Z5d4Z6d5Z7d6Z8d7Z9d8Z:d9Z;d:Zd=Z?d>Z@d?ZAd@ZBdAZCdBZDdCZEdDZFdEZGdFZHdGZIdHZJdIZKdJZLdKZMdLZNdMZOdNZPdOZQdPZRdQZSdRZTdSZUdTZVdUZWdVZXdWZYdXZZdYZ[dZZ\d[Z]d\Z^d]Z_d^Z`xZaS)_!FakeOsModuleTestCaseInsensitiveFSctt|||jj|jjz|jjz|_|jj|jjz|_ dSr5) r6rr7r6rr8r9r:r;r<r=s r'r7z'FakeOsModuleTestCaseInsensitiveFS.setUpK sg /66<<>>> &&(((7<$',.=',-r)c|dd}|||dd}|tj|jj|dS)rNr@rOFooBarNrP)r%rSrs r'rTz@FakeOsModuleTestCaseInsensitiveFS.test_chdir_fails_non_directoryQ s`>>%// """NN5%00  ##EM47=)LLLLLr)c|d}|j||jj|d}|j||dd}|||d|dg|j|dS)NrlrXYZZYBUGr@r)r%rrDdirectory_uppers r'rz;FakeOsModuleTestCaseInsensitiveFS.test_listdir_returns_listX s00  n%%%GL%%ne<<   i   ..%88  599::: %$'///"B"BCCCCCr)c ||d}gd}|D]+}||||,||d|d|||t |j|ddS)NrlrnrSymLinkrrss r'rz9FakeOsModuleTestCaseInsensitiveFS.test_listdir_on_symlinka rr)c||d}|d}|d}||d|j|t jdzt jz ||d}| }|j ||j |dts)| t|jj |ddS|j |ddS) Nr Some_File1 SOME_file1rrrrr)r_rArrrrr!rr|rrr rr)r%r file_path2 file_path3rrs r'rz2FakeOsModuleTestCaseInsensitiveFS.test_fdopen_modek s ^^L11 ^^L11 ^^L11  .>???  j4<%#74="HIIIYYz3// ##%% w w$$$yy )   gtw~w D D D D D GNN7C ( ( ( ( (r)c*|d}|d}|jj|d}||d|t j|j|t jz|jj|d}|t j |j|t jz|t j |j|j z| d|j|t j dS)NrlrrmrrPlughrr)r%rD directory1rrs r'rz+FakeOsModuleTestCaseInsensitiveFS.test_stat| s&NN7++ ^^G,, GL%%i99  W555  tw||J'?'? 'MMNNNW\&&z7;;   tw||J'?'? 'MMNNN  tw||J'?'?'GGHHH DGLL44T\BCCCCCr)c||d}d}d}|t|t||jj||}|jj|d}||||||| t||j | dtj | t||j | dtj dSr) ryrArrrrrVrrrrupperrrs r'rzDFakeOsModuleTestCaseInsensitiveFS.test_stat_no_follow_symlinks_posix sP NN7++  !  C NNC ,>,>???GL%%i;; GL%%i88  ];;; Iy111     GLL**EL B B4< P      NN GLL**EL B B4< P     r)c||d}d}d}|t|t||jj||}|jj|d}||||||| t||j | tj | t||j | tj dSr)ryrArrrrrVrrrrrrrrs r'test_lstat_posixz2FakeOsModuleTestCaseInsensitiveFS.test_lstat_posix s; NN7++  !  C NNC ,>,>???GL%%i;; GL%%i88  ];;; Iy111     ioo.?.? @ @ N    Yy7H7H)I)I$,)WXXXXXr)c2||ddd}|d}|||||j||dSr~)rrArr$rrrrs r'rz/FakeOsModuleTestCaseInsensitiveFS.test_readlink s **,,,NN5%77 )) Iv...  0 01B1B C CVLLLLLr)c|ddd}|||tj|jj|dSr)rArrIrJrrrrrs r'(check_readlink_raises_if_path_not_a_linkzJFakeOsModuleTestCaseInsensitiveFS.check_readlink_raises_if_path_not_a_link sZNN5%??  ### ##EL$'2BIOODUDUVVVVVr)c~|||dSr5)rrrrs r'/test_readlink_raises_if_path_not_a_link_windowszQFakeOsModuleTestCaseInsensitiveFS.test_readlink_raises_if_path_not_a_link_windows s> !!! **,,, 5577777r)cV||dSr5)ryrrs r'-test_readlink_raises_if_path_not_a_link_posixzOFakeOsModuleTestCaseInsensitiveFS.test_readlink_raises_if_path_not_a_link_posix s,  5577777r)c|||d|dd}|||jj||ddd}|||jj|dSr)rrArIrrrrs r'rzHFakeOsModuleTestCaseInsensitiveFS.check_readlink_raises_if_path_has_file s 11222NN8U33  ##M473CY__EVEVWWWNN8UE::  ##M473CY__EVEVWWWWWr)c|||tjdSr5rrs r'rzOFakeOsModuleTestCaseInsensitiveFS.test_readlink_raises_if_path_has_file_windows rr)cl||tjdSr5rrs r'rzMFakeOsModuleTestCaseInsensitiveFS.test_readlink_raises_if_path_has_file_posix rr)c |||ddd|d||dd|d||d|j|dd d d dS) NrrrrrrMeyerGeoMetroLemonPierrs r'rzBFakeOsModuleTestCaseInsensitiveFS.test_readlink_with_links_in_path rr)c J|||dddd|d||d|dd||d |d d ||d|j|d d dS)NrrrrrrEasternEuropeanrRussian WolfhoundsDOGSChaserrs r'rzJFakeOsModuleTestCaseInsensitiveFS.test_readlink_with_chained_links_in_path rr)c |d}|jj|d}|||}||jj||||jj |||jj||j ||||jj |||jj||tj |jj ddS)Nrlrmz/Plugh) rArrrVr,rrrrIr9rBrJrKrs r'rz2FakeOsModuleTestCaseInsensitiveFS.check_remove_dir s3NN7++ 7<$$Y88 !!!>>##  ++HNN,<,<==>>> ##Itw~xHHH  ++H55666  i    ##Itw~xHHH  ++H55666 ##EL$'.(KKKKKr)cl||tjdSr5rrs r'rz8FakeOsModuleTestCaseInsensitiveFS.test_remove_dir_mac_os rr)cl||tjdSr5rrs r'rz9FakeOsModuleTestCaseInsensitiveFS.test_remove_dir_windows rr)c|d}|jj|d}||||jj||j|| |jj|dSr) rArrrVrrrrr9r"rs r'rz2FakeOsModuleTestCaseInsensitiveFS.test_remove_file sNN5)) GL%%i99  ###  ++IOO,=,=>>??? y(())) ,,Y7788888r)c|d}d}|jj||}||||jj||j||j || |jj|dSr) rArrrVrrrrBrr9r"rs r'rz?FakeOsModuleTestCaseInsensitiveFS.test_remove_file_no_directory sNN5))  GL%%i;;  ###  ++I66777  ioo''((( y(())) ,,Y7788888r)c||dd}||||d5|t j|jj| dddn #1swxYwY| |jj |dSr) rrArr|rIrJrArr9rrrrrs r'rzKFakeOsModuleTestCaseInsensitiveFS.test_remove_open_file_fails_under_windows s !!!~~eU++  YYtS ! ! T T  ' ' dgndjjll S S S T T T T T T T T T T T T T T T  ++D1122222s>B  B$'B$cl||dd}||||d|j|||jj |dSr) ryrArr|rr9rr"rrrs r'rzLFakeOsModuleTestCaseInsensitiveFS.test_remove_open_file_possible_under_posix s ~~eU++  $ tzz||$$$ ,,T2233333r)c^||j}|d}|jj|d}d}|jj||}|jjd|}||||jj || |||jj ||j ||j || |jj ||j || |jj |dSr)r_rrXrArrVrrrrr,rBr9r"rs r'rz@FakeOsModuleTestCaseInsensitiveFS.test_remove_file_relative_path$ s w~~'' NN5)) w|((E::  GL%%i;; !W\..tY?? **+++  ++I66777  %%%  ++L99:::  l((**+++ )//11222 ,,-?@@AAA  l((**+++ ,,Y7788888r)c|d}|||||jj|dSr)rAr,rIrr9rrs r'rz?FakeOsModuleTestCaseInsensitiveFS.check_remove_dir_raises_error6 sQNN5))   """ ##Itw~y?P?PQQQQQr)cl||tjdSr5rrs r'rzEFakeOsModuleTestCaseInsensitiveFS.test_remove_dir_raises_error_mac_os; rr)cl||tjdSr5rrs r'rzFFakeOsModuleTestCaseInsensitiveFS.test_remove_dir_raises_error_windows? rr)c||d}|d}|||j||||jj|||jj||j| ||jj|| |jj|dSr) rrAr,rrrrrr9rr"rs r'rz>%((gl''-@@  !!!  ))++Y__->->??? ##EM47>8YWWWWWr)c|||d}|d}|jj|d}|||j||| tj |jj ||dSr) rrrArrrVr,rrrIrJrrrs r'rzDFakeOsModuleTestCaseInsensitiveFS.test_rename_dir_to_symlink_windowsX s !!! **,,,NN6** >>%((gl''-@@  !!!  ))++Y__->->??? ##EL$'.(IVVVVVr)c||d}||d}|j||d}|j||j|||dg|j|jdS)NDestdestsrc) ryrAr_rrrrrpr)r% dest_dir_pathnew_dest_dir_pathsource_dir_paths r'test_rename_dir_to_existing_dirzAFakeOsModuleTestCaseInsensitiveFS.test_rename_dir_to_existing_dirb s v..   NN622  m$$$..//  o&&& (9::: &47??4>#B#BCCCCCr)c||d}|d}|j|||||j||||jj || |jj || |jj |dSr) ryrArrrrrr"rrrrfr!s r'r"z=FakeOsModuleTestCaseInsensitiveFS.test_rename_file_to_symlinko s NN;// NN6**   9--- ### y(()444 ,,Y77888  ++IOO,=,=>>???  ++IOO,=,=>>?????r)c||dd}|||jj|d}|jj|d}|j|||j|||j||| |jj || |jj |dSr$) ryrAr,rrrVrrrr"rrr's r'r*z@FakeOsModuleTestCaseInsensitiveFS.test_rename_symlink_to_symlinkz s NN5%00   """W\&&y':: W\&&y'::   )):666  :... z'')):+;+;+=+=>>> ,,Z88999  ++J7788888r)c||d}|d}|jj|d}|||j|||||tj |jj ||dSr,) ryrArrrVr,rrrIrJrrr/s r'r1zRFakeOsModuleTestCaseInsensitiveFS.test_rename_symlink_to_symlink_for_parent_raises s >>*-->>%((',++HkBB !!! (((333 ((( ## L$'.(O4I4I4K4K     r)c||d}|j|j||jj|d}|d}|j||j||| ddgt|j |jdS)NrrDir) rrArrrrrVrrrrrrp)r%r link_subdirr~s r'#test_rename_directory_to_linked_dirzEFakeOsModuleTestCaseInsensitiveFS.test_rename_directory_to_linked_dir s **,,,NN6**   222gl'' 599 >>%((  h x--- %&1P1P*Q*QRRRRRr)c@||dd}|||jj|d}|tj|jj | |dSrA) ryrAr,rrrVrIrJrrrrCs r'rEz>FakeOsModuleTestCaseInsensitiveFS.test_recursive_rename_raises s NN5%00   """7<$$Y :: ## L$'.)//*;*;X     r)c||dd}|||tj|jj||dzdSrK) ryrArrIrJrQrrrrs r'rLzRFakeOsModuleTestCaseInsensitiveFS.test_rename_with_target_parent_file_raises_posix s~ NN5%00  ### ## M GN  OO   &      r)c <||dd}|||tj|jj||jj | ddSrN) rrArrIrJrArrrrVrrs r'rPzTFakeOsModuleTestCaseInsensitiveFS.test_rename_with_target_parent_file_raises_windows s !!!NN5%00  ### ## L GN  GL  ioo// 7 7      r)cV||d}|d}|j|||j|||dg|j|jdS)NroBAZ)rrArrrrrpr)r% path_lower path_uppers r'test_rename_looping_symlinkz=FakeOsModuleTestCaseInsensitiveFS.test_rename_looping_symlink s **,,,^^E** ^^E**   J/// z:... %$'//$."A"ABBBBBr)c||d}|jj|d}|jj|d}|||j|||j||| |jj |dSrR) ryrArrrVrrrrr"rrTs r'rUz?FakeOsModuleTestCaseInsensitiveFS.test_rename_symlink_to_source s NN5)) GL%%i99 GL%%i88  ###  9--- y(()//*;*;<<< ,,Y7788888r)c||dd}|jj|d}|jj|d}|||j|||tj |jj ||dSrW) ryrArrrVr,rrrIrJrTrrXs r'rYzCFakeOsModuleTestCaseInsensitiveFS.test_rename_symlink_to_dir_raises s NN5%00 GL%%i<< 7<$$Y66 !!! )//"3"3444 ## L$'.)X^^5E5E     r)c||d}|||jj|d}|jj|d}|j|||j||| |jj || |jj || |jj |dSrR) ryrAr,rrrVrrrr"rrr]rTs r'r[z>++X^^-=-= > > >   TW\00:: ; ; ; OODGL//99 : : :    1 1(G D Df M M M##%% S  DO$>$>x$H$H$QRRR S Sr)c|d}|d}|||||||jj||dSri)rAr,rrIrrrrjs r'rkzPFakeOsModuleTestCaseInsensitiveFS.check_rename_directory_to_existing_file_raises s>>%((NN6**  !!! ### ## dgnh 0A0A     r)cl||tjdSr5rmrs r'rnzUFakeOsModuleTestCaseInsensitiveFS.test_rename_directory_to_existing_file_raises_posix ror)cl||tjdSr5rqrs r'rrzWFakeOsModuleTestCaseInsensitiveFS.test_rename_directory_to_existing_file_raises_windows rsr)cz||dd}|dd}|||||tj|jj||dSru) rrAr,rIrJrrrrres r'rvz^FakeOsModuleTestCaseInsensitiveFS.test_rename_to_existing_directory_should_raise_under_windows s !!!>>%//>>%// !!! !!! ## L$'.(..*:*:HNN>),, """>>% :: (+++  ++H55666 ,,X6677777r)c&|d}|dddd}|jj|d}|||||dd}|j||||jj|||jj|||jj||jj|d}||jj|dS)NoldrYrZrgzfoo.pngrOrh) rArrrVrrirrr")r% old_base_pathrf other_filerD removed_paths r'test_renames_removes_empty_dirszAFakeOsModuleTestCaseInsensitiveFS.test_renames_removes_empty_dirsV sGu-- >>%CCW\&&}i@@  """ $$$>>%33 (+++  ++H55666 ,,X66777  ++M::;;;w|((??  ,,\::;;;;;r)c||d}|jj|d}|||jj|d}|j|||jj|d}|j|dSr_)rrArrrVr,rr)r%rrs r'test_stat_with_mixed_casez;FakeOsModuleTestCaseInsensitiveFS.test_stat_with_mixed_cased s **,,,NN5)) w|  E22 w|  u--  4(((w|  u--  Tr)cd||d}|||jj|d}|j|||jj|dd}|||jj|dd}|j ||| |jj |dS)Nr@rSr3Slinkr}) rrAr,rrrVrrrrrrr~s r'rzBFakeOsModuleTestCaseInsensitiveFS.test_hardlink_works_with_symlinkp s **,,,NN5))   """w|((G<<   ))<888GL%%i&AA  ###GL%%i'BB   Y ***  ++I6677777r)cV||dd}|dd}|||||tj|jj||dSru) rrAr,rIrJrArrrres r'rz\FakeOsModuleTestCaseInsensitiveFS.test_replace_existing_directory_should_raise_under_windows| s !!!>>%//>>%// !!! !!! ## L$'/8X^^5E5E     r)c||dd}|d}||jj|d|||j||||jj |jj|d| |jj |dSr) ryrAr,rrrVrrrrr"res r'rzOFakeOsModuleTestCaseInsensitiveFS.test_rename_to_existing_directory_under_posix s >>%//>>'**  ))(E::;;; !!! x~~'')9)9:::  ++DGL,=,=h,N,NOOPPP ,,X6677777r)cz||ddd}|d}|||||t j|jj| | dSr) ryrArr,rIrJrTrrrrs r'rz[FakeOsModuleTestCaseInsensitiveFS.test_rename_file_to_existing_directory_raises_under_posix s NN5%77 >>'** ### !!! ## L$'.)//*;*;X^^=M=M     r)cn||d}|jj|d}|jj|d}||d||d||jj|||jj||j| | | |jj|||jj|| |ddSr) ryrArrrVrrrrrr"rrs r'rzDFakeOsModuleTestCaseInsensitiveFS.test_rename_to_existent_file_posix sh NN7++  )))[AA  )))[AA  1BCCC 1BCCC  ++M::;;;  ++M::;;; }**,,m.A.A.C.CDDD ,,];;<<<  ++M::;;; M+<=====r)c||d}|jj|d}|jj|d}||d||d||jj|||jj||tj |jj | | dSr) rrArrrVrrrrIrJrrrrs r'rzFFakeOsModuleTestCaseInsensitiveFS.test_rename_to_existent_file_windows s !!!NN7++  )))[AA  )))[AA  1BCCC 1BCCC  ++M::;;;  ++M::;;; ## L GN    ! !    ! !      r)cF|d}|jj|d}|jj|d}||d||d||jj|||jj||j||| |jj|||jj|| |ddSr) rArrrVrrrrrr"rrs r'rz?FakeOsModuleTestCaseInsensitiveFS.test_replace_to_existent_file sXNN7++  )))[AA  )))[AA  1BCCC 1BCCC  ++M::;;;  ++M::;;;  ++--}/B/B/D/DEEE ,,];;<<<  ++M::;;; M+<=====r)c<|d}|jj|d}|jj|dd}||d||jj|||jj||tj |jj | | ||jj|||jj|| |ddSr)rArrrVrrrr"rIrJrKrrrrs r'rz@FakeOsModuleTestCaseInsensitiveFS.test_rename_to_nonexistent_dir sTNN7++  )))[AA  )))^[QQ  AAA  ++M::;;; ,,];;<<< ## L GN    ! !    ! !     ++M::;;; ,,];;<<< M?;;;;;r)c|j|j|d|dd}|j||d}|j|||ddgt|j|jdS)NrAlphar ) rrrrArrrrrrp)r% dir_upper dir_lowers r'*check_rename_case_only_with_symlink_parentzLFakeOsModuleTestCaseInsensitiveFS.check_rename_case_only_with_symlink_parent s v(>(>???NN6733   i   NN7++  y),,, '6*F47??4>3R3R,S,STTTTTr)c~|||dSr5)rrrrs r'1test_rename_case_only_with_symlink_parent_windowszSFakeOsModuleTestCaseInsensitiveFS.test_rename_case_only_with_symlink_parent_windows s> !!! **,,, 7799999r)cV||dSr5)r!rrs r'/test_rename_case_only_with_symlink_parent_macoszQFakeOsModuleTestCaseInsensitiveFS.test_rename_case_only_with_symlink_parent_macos s,  7799999r)cR|d}|jj|d}|jj|dd}|jj|d}|jj|dd}||||d||jj|||jj|| |jj|| |jj||j ||| |jj|| |jj|||jj|||jj|| |ddSr) rArrrVr,rrrrr"rrrs r'rz1FakeOsModuleTestCaseInsensitiveFS.test_rename_dir shNN7++ W\&&y(;; gl'' 8VDD GL%%i99 W\&&y'6BB   ### y999  ++J,<,<,>,>??@@@  ++K,=,=,?,?@@AAA ,,Y__->->??@@@ ,,Z-=-=-?-?@@AAA z''))9555 ,,Z-=-=-?-?@@AAA ,,[->->-@-@AABBB  ++IOO,=,=>>???  ++J,<,<,>,>??@@@ J 22222r)c(|d}d}|jj|d}||||j|||||dSr)rArrrVrrrrrs r'rz>%((>>*-- !!! (+++W\&&x88   ### :++--... ,,Z88999  ++H5566666r)c||dd}|jj|d}|jj|d}|||j|||tj |jj |dSr.) ryrArrrVr,rrrIrJrQrrXs r'r/zGFakeOsModuleTestCaseInsensitiveFS.test_mkdir_raises_on_symlink_in_posix7s NN5%00 GL%%i?? 7<$$Y66 !!! (()//*;*;<<< ##EM47=)LLLLLr)c|||dd}|jj|d}|jj|d}|||j|||j || |jj || |jj |dSr.) rrrArrrVr,rrrr"rrrXs r'r1zGFakeOsModuleTestCaseInsensitiveFS.test_mkdir_removes_symlink_in_windows@s  !!! **,,,NN5%00 GL%%i?? 7<$$Y66 !!! (()//*;*;<<<  i    ,,Y77888  ++H5566666r)c8|d}||||jj||tj|jj | dSr3) rAr,rrrrrIrJrrrrCs r'r4zGFakeOsModuleTestCaseInsensitiveFS.test_mkdir_raises_if_directory_existsLswNN7++   """  ++I66777 ##EL$'-ARARSSSSSr)cx|d}|jj|d}||||jj||tj |jj | dSr6) rArrrVrrrrIrJrrrrs r'r8zBFakeOsModuleTestCaseInsensitiveFS.test_mkdir_raises_if_file_existsSsNN7++ GL%%i99  ###  ++I66777 ##EL$'-ARARSSSSSr)c||d}|j|||d}|t j|jj|dS)NroBaz)rrArrrIrJrr)r%r9path2s r'#test_mkdir_raises_if_symlink_existszEFakeOsModuleTestCaseInsensitiveFS.test_mkdir_raises_if_symlink_exists[sp **,,,u%% u%%%u%% ##EL$'-GGGGGr)c<|d}|jj|d}|||||jj|jj|ddSr:)rArrrVrrIrrr<s r'r>zFFakeOsModuleTestCaseInsensitiveFS.check_mkdir_raises_if_parent_is_filecsNN7++ GL%%i99  ### ##  GM GL  ioo// 6 6     r)cl||tjdSr5r@rs r'rAzKFakeOsModuleTestCaseInsensitiveFS.test_mkdir_raises_if_parent_is_file_posixnryr)cl||tjdSr5rCrs r'rDzMFakeOsModuleTestCaseInsensitiveFS.test_mkdir_raises_if_parent_is_file_windowsrr|r)c|d}|jj|d}||jj||j|||jj|dSrV) rArrrVr"rrWrrr*s r'rXz/FakeOsModuleTestCaseInsensitiveFS.test_makedirsvs((GL%%fe44  ,,V44555 **+++  ++I6677777r)cd|d}|jj|d}||||jj||||jj| dSrZ) rArrrVrrrrIrWrr[s r'r\zIFakeOsModuleTestCaseInsensitiveFS.check_makedirs_raises_if_parent_is_file~sNN7++ GL%%i99  ###  ++I66777 ##J0@)//BSBSTTTTTr)cl||tjdSr5r^rs r'r_zNFakeOsModuleTestCaseInsensitiveFS.test_makedirs_raises_if_parent_is_file_posixr`r)cl||tjdSr5rbrs r'rczPFakeOsModuleTestCaseInsensitiveFS.test_makedirs_raises_if_parent_is_file_windowsrdr)cj||d}|j|d||t j|jj|jj | ddSrf) ryrArrrIrJrKrWrrVrrs r'rjzOFakeOsModuleTestCaseInsensitiveFS.test_makedirs_raises_if_parent_is_broken_links NN=11  w//;;; ## L G  GL  ioo// : :     r)c|dd}||||jj||tj|jj | |j | d||jj|dSrx) rAr,rrrrrIrJrrWrrCs r'r{z8FakeOsModuleTestCaseInsensitiveFS.test_makedirs_exist_oksNN7E22   """  ++I66777 ##EL$'2BIOODUDUVVV **T:::  ++I6677777r)c|d}||d||d}|}|j||tj |jj|dz| dS)Nrrrrr) rArr|rrrrrIrJr{rrs r'test_fsync_passz1FakeOsModuleTestCaseInsensitiveFS.test_fsync_passs 44 2GHHHIIn2244d;; ""$$  g ##EK" MMMr)c |||d}|||j|d|j|}|d|j | |j tj z| |j tj zdSr)ryr_rAr(rrrrrr rr!r"r#r$s r'rz,FakeOsModuleTestCaseInsensitiveFS.test_chmods  ~~k** D!!!  djjllF+++ W\\$   vrz222  T\1222 dl233333r)c||ddd}||dd|jd|||jj|| |jj || |ddd||jj|||jj |dS)Nr@rOrorhrrBogus) rrAr,rrrrrr]r"rrrs r'r z.FakeOsModuleTestCaseInsensitiveFS.test_symlinks% **,,,NN5%77  ue44555 !2!2333  ,,Y77888 ,,Y77888 ug>>???  ,,Y77888  ++I6677777r)cv||d}|d}d}||||j|||j|||jj || |5}| | |ddddS#1swxYwYdSry) rrArrrrr rrrr|rrr}s r'rz2FakeOsModuleTestCaseInsensitiveFS.test_link_deletesK **,,,^^L11 ^^L11   i888  Z%%''444 z"""  ++J77888 YYz'')) * * 2a   QVVXXy 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2s8)D..D25D2c$||dd}|||tj|jj||dSrg) rrArrIrJrrrrrs r'rzrArDrXr\r_rcrjr{rrr rrrrrrs@r'rrJ s..... MMMDDDTTT)))" D D D   *YYY MMMWWW 888 888XXXBBB CCC       " L L L+++,,,999999333444999$RRR 888999 4 4 4XXXWWW D D D @ @ @ 9 9 9     S S S           CCC999     9 9 9 H H H333 S S S   KKKJJJ     8 8 8444CCCCCC888 < < <    8 8 8     8 8 8    > > >   " > > ><<<$UUU::: :::333(666777$ 8 8 8 7 7 7MMM 7 7 7TTTTTTHHH    AAA@@@888UUUDDDCCC   888    4 4 4 8 8 8222"    W W W2222222r)rceZdZdZdS)!RealOsModuleTestCaseInsensitiveFScdSrr1rs r'rbz-RealOsModuleTestCaseInsensitiveFS.use_real_fsrr)Nrr1r)r'rrrr)rcPeZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d S) FakeOsModuleTimeTestc |d5d}|j|||jj||j|}|d|j |j |d|j|}|d|j ddddS#1swxYwYdS)Nrstartri) mock_timerarrrrrrrst_ctimerrs r'test_chmod_st_ctimez(FakeOsModuleTimeTest.test_chmod_st_ctimes% ^^#^ & & / /#I O ' ' 2 2 2 OODGL// :: ; ; ;i((B   S"+ . . . GMM)U + + +i((B   S"+ . . . / / / / / / / / / / / / / / / / / /sCC88C<?C<c|d}|||d5|j|d|j|}|d|j|d|jddddS#1swxYwYdS)Nrrrtimes) rAr(rrutimerrst_atimerr$s r',test_utime_sets_current_time_if_args_is_nonezAFakeOsModuleTimeTest.test_utime_sets_current_time_if_args_is_nones~~k** D!!! ^^#^ & & / / GMM$dM + + +d##B   S"+ . . .   S"+ . . .  / / / / / / / / / / / / / / / / / /sA-B;;B?B?cf|d}|||j||j|d|j|}|d|j|d|jdS)NrrrrrrrAr(rrrrrrr$s r'test_utime_sets_specified_timez3FakeOsModuleTimeTest.test_utime_sets_specified_times~~k** D!!!  T  d& ))) W\\$   BK((( BK(((((r)c d}|||j|d|j|}|d|j|d|jdS)N /some_dir)?@rrr)r-rrrrrrr$s r'test_utime_dirz#FakeOsModuleTimeTest.test_utime_dirs|   &&&  d* --- W\\$   bk*** bk*****r)cl|d}||d}|j|||j|d|j|}|d|j|d|j dS)Nr/link_to_some_filerrrr) rAr(rarrrrrrrrs r'test_utime_follow_symlinksz/FakeOsModuleTimeTest.test_utime_follow_symlinks's~~k** D!!!(  &&y$777  iv ... W\\) $ $ BK((( BK(((((r)c|d}||d}|j|||j|dd|j|}|d|j|d|j |j|d}| d|j| d|j dS) NrrrF)rrrrr) rAr(rarrrrrrrrrs r'test_utime_no_follow_symlinksz2FakeOsModuleTimeTest.test_utime_no_follow_symlinks2s~~k** D!!!(  &&y$777  ivu EEE W\\) $ $ Ar{+++ Ar{+++ W\\)U\ ; ; BK((( BK(((((r)cd}||jj||t j|jj|ddS)Nz/non/existent/filer)r"rrrrIrJrKrrs r'test_utime_non_existentz,FakeOsModuleTimeTest.test_utime_non_existent@sS# ,,T22333 ##EL$'-vNNNNNr)cd}|||t|jj|d|t|jj|ddS)Nr)rrra)rr)r-rrrrrs r'#test_utime_invalid_times_arg_raisesz8FakeOsModuleTimeTest.test_utime_invalid_times_arg_raisesEs_   &&& )TW]D)DDD )TW]D*EEEEEr)cf|d}|||j||j|d|j|}|d|j|d|jdS)Nr) insg?g?rr$s r'$test_utime_sets_specified_time_in_nsz9FakeOsModuleTimeTest.test_utime_sets_specified_time_in_nsNs~~k** D!!!  T  d5 666 W\\$   bk*** bk*****r)c0d}|j||t|jj|d|t|jj|d|t |jj|dddS)Nrrr)rr4r)rr)rr)rarrrrr ValueErrorrs r''test_utime_incorrect_ns_argument_raisesz ) )       ##EK6JJJ~~k** D!!! *\$/ * *4 0 0 -A GMM!)6M 2 2 2d##B   Q , , ,   Q , , ,  - - - - - - - - - - - - - - - - - -s A2DD#&D#N)r.r/r0rrrrrrrrrrrr1r)r'rrs / / //// ) ) )+++ ) ) ) ) ) )OOO FFF + + +    - - - - -r)rceZdZdZfdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZdZdZejej ddZdZdZdZdZdZdZdZdZdZ dZ!dZ"dZ#dZ$d Z%d!Z&d"Z'd#Z(d$Z)d%Z*d&Z+d'Z,d(Z-d)Z.d*Z/d+Z0d,Z1d-Z2d.Z3d/Z4d0Z5d1Z6d2Z7d3Z8ejej9 d4d5Z:xZ;S)6FakeOsModuleLowLevelFileOpTestzCTest low level functions `os.open()`, `os.read()` and `os.write()`.c~tjdtt|dSr)rrr6rr7r=s r'r7z$FakeOsModuleLowLevelFileOpTest.setUpus3  ,d3399;;;;;r)c|d}||d|j|tj}|d|j|d|tj |jj |d|j |dS)NrrDrrr) rArrr|r}rrrIrJr{rrr%rfile_dess r'test_open_read_onlyz2FakeOsModuleLowLevelFileOpTest.test_open_read_onlyysNN7++  [9997<< 2;77 dgll8Q&?&?@@@ ##EK'RRR  hr)c\||d}||d|j|tj}|tj|jj |d|j |dS)NrrDrr) ryrArrr|r}rIrJr{rrrs r'*test_open_read_only_write_zero_bytes_posixzIFakeOsModuleLowLevelFileOpTest.test_open_read_only_write_zero_bytes_posixs NN7++  [9997<< 2;77 ##EK'RRR  hr)cb||d}||d|j|tj}|d|j|d|j|dS)NrrDrrr)) rrArrr|r}rrrrs r',test_open_read_only_write_zero_bytes_windowszKFakeOsModuleLowLevelFileOpTest.test_open_read_only_write_zero_bytes_windowss !!!NN7++  [9997<< 2;77 DGMM(C88999  hr)cf|d}||d|j|tj}|d|j|d||d|j|dSNrrDrrrstestents) rArrr|rPrrrrrs r'test_open_write_onlyz3FakeOsModuleLowLevelFileOpTest.test_open_write_onlysNN7++  [9997<< 2;77 DGMM(G<<=== I{333  hr)cH|d}||d|j|tj}|t j|jj|d|j ||j|tjtj z}|t j|jj|d|j ||d}|j|tj tjz}|t j|jj|d|j ||j|tj tjztj z}|t j|jj|d|j |dS)NrrDrrr) rArrr|rPrIrJr{rrrQrO)r%rrrs r'#test_open_write_only_raises_on_readzBFakeOsModuleLowLevelFileOpTest.test_open_write_only_raises_on_readsNN7++  [9997<< 2;77 ##EKxKKK  h7<< 2;+CDD ##EKxKKK  h^^G,, 7<< BJ,DEE ##EKxKKK  h7<< BJ,Drz,QRR ##EKxKKK  hr)cH||d}|j|tjtjz}|tj|jj |d|j |dS)Nrr) ryrArr|rOrPrIrJr{rrrs r'*test_open_write_only_read_zero_bytes_posixzIFakeOsModuleLowLevelFileOpTest.test_open_write_only_read_zero_bytes_posixs} NN7++ 7<< 2: +CDD ##EKxKKK  hr)cN||d}|j|tjtjz}|d|j|d|j|dS)Nrr)r) rrArr|rOrPrrrrs r',test_open_write_only_read_zero_bytes_windowszKFakeOsModuleLowLevelFileOpTest.test_open_write_only_read_zero_bytes_windowss !!!NN7++ 7<< 2: +CDD dgll8Q77888  hr)cf|d}||d|j|tj}|d|j|d||d|j|dSr) rArrr|rrrrrrs r'test_open_read_writez3FakeOsModuleLowLevelFileOpTest.test_open_read_writesNN7++  [9997<< 2955 DGMM(G<<=== I{333  hr)cd|d}|j|tj}|d|j|d|tj|jj |d|j |dSNrr)rsfoo) rArr|rOrrrIrJr{rrrs r'test_open_create_is_read_onlyz> dgll8Q77888 ##EK#NNN  hr)cr||d}|j|tjtjzd}||jj|| tj |jj |d| d|j|d|d|j|j|j|dS)Nrrrrr)ryrArr|rPrOrrrrIrJr{rrrrrr rrs r'test_open_create_mode_posixz:FakeOsModuleLowLevelFileOpTest.test_open_create_mode_posix$s NN7++ 7<< 2;+CUKK  ++I66777 ##EKxKKK DGMM(G<<=== udgll9&=&=&EFFF  hr)cr||d}|j|tjtjzd}||jj|| tj |jj |d| d|j|d|d|j|j|j|dS)Nrrrrrr)rrArr|rPrOrrrrIrJr{rrrrrr rrs r'test_open_create_mode_windowsz>%(( !!! ##EL$',"+VVV ##EL$',"+VVV ##EL$',")TTTTTr)cZ||d}|||tj|jj|t j|tj|jj|t j dSr) ryrAr,rIrJrTrr|rPrrs r'2test_open_directory_for_writing_raises_under_posixzQFakeOsModuleLowLevelFileOpTest.test_open_directory_for_writing_raises_under_posixzs >>%(( !!! ##EL$',"+VVV ##EL$',")TTTTTr)cT|||d}|||j|tj}|d||j|dS)Nrra) ryr_rAr,rr|r}rr)r%r~rs r')test_open_directory_read_only_under_posixzHFakeOsModuleLowLevelFileOpTest.test_open_directory_read_only_under_posixs  >>%(( !!!7<<"+66 H%%%  hr)c||d}|j||t j|jj|tjdSr ) rrArrrIrJrTr|rOrs r'0test_opening_existing_directory_in_creation_modezOFakeOsModuleLowLevelFileOpTest.test_opening_existing_directory_in_creation_modesa >>'**  h ##EL$',"*UUUUUr)c.||d}|j||j|tj}|tj|jj |ddS)Nr r)) r!rArrr|rOrIrJr{r)r%r~rs r'"test_writing_to_existing_directoryzAFakeOsModuleLowLevelFileOpTest.test_writing_to_existing_directorysv >>'**  h W\\(BJ / / ##EKCHHHHHr)c||d}|j||t j|jj|tjdSr ) ryrArrrIrJrTr|rPrs r'-test_opening_existing_directory_in_write_modezLFakeOsModuleLowLevelFileOpTest.test_opening_existing_directory_in_write_modesa >>'**  h ##EL$',"+VVVVVr)c|||d}|j|tjtjztjz}|j|}| d|j z|j |j |dS)Nroi) ryr_rArr|rOrPrQrr_umaskr rr%rrstat0s r'test_open_mode_posixz3FakeOsModuleLowLevelFileOpTest.test_open_mode_posixs  NN5)) 7<< 2: +Cbj+PQQ h'' TW^^%5%5$55u}EEE  hr)ct||d}|j|tjtjztjz}|j|}|d|j |j |dS)Nro鶁) rrArr|rOrPrQrrr rr$s r'test_open_mode_windowsz5FakeOsModuleLowLevelFileOpTest.test_open_mode_windowss !!!NN5)) 7<< 2: +Cbj+PQQ h'' 5=111  hr)c|d}||dd}||d5}|}|t ||j|||||dddn #1swxYwY||d5}|}|d|j |d||dd |j |d ||d d |j |d ||d d|j |d |d|j |d dddn #1swxYwY| tj |jj||| tj |jj |d dS) Nrs orig contentsrs1234567890abcdefrrr)rrrrr) rArr|rrrrrrrrIrJr{)r%r new_contentsfhrs r'test_write_readz.FakeOsModuleLowLevelFileOpTest.test_write_readsNN7++  -=>>>* YYy$ ' ' 92YY[[F   S.. fl0S0S T T T    < 8 8 8 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 YYy$ ' ' <2YY[[F   S$',,vq"9"9 : : :   \!A#. VQ0G0G H H H   \!B$/fa1H1H I I I   \"##. VS0I0I J J J   S$',,vr":": ; ; ;  < < < < < < < < < < < < < < < ##EK UUU ##EKvrJJJJJs&A'B88B<?B<DG==HHc|d}|j|tjtjztjz}|j|tjtjztjz}|j|d|j|d|d|jj || |d|j ||j |dS)Nrosaaaasbbrsbbaa) rArr|rOrPrQrrrr0rrr%rfd0fd1s r'test_write_from_different_f_dsz=FakeOsModuleLowLevelFileOpTest.test_write_from_different_f_dssNN5)) gll9bj2;&>&KLLgll9bj2;&>&KLL  c7###  c5!!! DGL00;;<<< Iw///  c  cr)cx|d}|j|tjtjztjz}|j|tjtjz}|j|d|j|d|d|jj || |d|j ||j |dS)Nrosaaasbbbsaaabbb) rArr|rOrPrQrrrrr0rrr/s r')test_write_from_different_fds_with_appendzHFakeOsModuleLowLevelFileOpTest.test_write_from_different_fds_with_appendsNN5)) gll9bj2;&>&KLLgll9bkBK&?@@  c6"""  c6""" DGL00;;<<< Iy111  c  cr)c||ddd}||d|j|tj}|j|tjtjztjz}|d|j |d|j ||j |dS)Nr@rOrorrr)r) ryrArrr|rOrPrQrrrr/s r'test_read_only_read_after_writez>FakeOsModuleLowLevelFileOpTest.test_read_only_read_after_writes NN5%77  W555gll9bj11gll9bj2;&>&KLL dgll322333  c  cr)c|d}|j|tjtjztjz}|j|tjtjztjz}|j|tj}|j|d|j||d|j |d|j||j|dS)Nrosabcra) rArr|rOrPrQrrrr)r%rr0r1fd2s r'(test_read_after_closing_write_descriptorzGFakeOsModuleLowLevelFileOpTest.test_read_after_closing_write_descriptorsNN5)) gll9bj2;&>&KLLgll9bj2;&>&KLLgll9bj11  c6"""  c c1!5!5666  c  cr)c|d}|j|tj}|j|tj}|j|d|j|tjtjztjz}|d|j |d|j|d|d|j |d|j ||j ||j |dS)Nromr)rsmr) rArr|rOrrrPrQrrr)r%rr1r9fd3s r'test_writing_behind_end_of_filez>FakeOsModuleLowLevelFileOpTest.test_writing_behind_end_of_files NN5)) gll9bj11gll9bi00  c4   gll9bj2;&>&KLL dgll322333  c4    47<<Q#7#7888  c  c  cr)c||||jj|jjdSr5)ry setup_fake_fsrrrrdevnullrs r'test_devnull_posixz1FakeOsModuleLowLevelFileOpTest.test_devnull_posixsT    ++DGO<<=====r)cj||tjdkr>||jj|jjdS| |jj|jjdS)N)rar) rr@r version_infor"rrrrArrs r'test_devnull_windowsz3FakeOsModuleLowLevelFileOpTest.test_devnull_windowss !!!   f $ $   TW\00AA B B B B B OODGL//@@ A A A A Ar)cD|j|jjtj}|d|j|d|d|j|d|j||j|jjtj}|d|j|d|j|dS)Nrrr)) rr|rArrrrrr}r%rs r'test_write_devnullz1FakeOsModuleLowLevelFileOpTest.test_write_devnulls W\\$'/29 5 5 DGMM"g66777 dgll2q11222  b W\\$'/2; 7 7 dgll2q11222  br)c$||tj|jjdddd|d}|d}||d|||j|tj }|j|tj }|tj|jj||dddS)Nrrrr@rO testcontentr) rrIrJr{rsendfilerArr|r}r% src_file_path dst_file_pathr1r9s r'test_sendfile_with_invalid_fdzrBrErHrOrTrXr[r_is_macosrarrs@r'rrrs~MM<<<<<               $               VVV    (      X_,,.STT99UT9               (((            UUUUUU   VVV IIIWWW       KKK*               >>> BBB S S S . . . / / / 3 3 3 2 2 2X_**,IJJ  KJ     r)rceZdZdZdS)RealOsModuleLowLevelFileOpTestcdSrr1rs r'rbz*RealOsModuleLowLevelFileOpTest.use_real_fsnrr)Nrr1r)r'rfrfmrr)rfcjeZdZddZdZdZdZdZdZd Z d Z d Z d Z d Z dZdZdZdZdS)FakeOsModuleWalkTestTFcBtd|j|||D}t|d}t|d}|t |t |t ||D]\}}||d|d||dt|d||dt|ddS) Nc3K|]}|VdSr5r1).0steps r' z9FakeOsModuleWalkTest.assertWalkResults..vs3  D      r))topdown followlinksc|dSNrr1lsts r'z8FakeOsModuleWalkTest.assertWalkResults..ys Ar)keyc|dSrrr1rss r'ruz8FakeOsModuleWalkTest.assertWalkResults..zs CFr)rrr)listrrrrrrzip)r%expectedtoprorpr7entryexpected_entrys r'assertWalkResultsz&FakeOsModuleWalkTest.assertWalkResultsss/  !W\\#wK\XX     $6$6777((:(:;;; XF 444%(%:%: B B !E>   ^A.a 9 9 9   ^A.uQx0@0@ A A A   ^A.uQx0@0@ A A A A B Br)cd|_dS)zReset the last seen errno.FN last_errnors r' ResetErrnozFakeOsModuleWalkTest.ResetErrnos r)c|j|_dS)zStore the last errno we saw.N)rJr)r%rLs r' StoreErrnozFakeOsModuleWalkTest.StoreErrnos".r)c|jS)zReturn the last errno we saw.rrs r'GetErrnozFakeOsModuleWalkTest.GetErrnos r)c|d}||jj|d||jj|dd||jj|ddd||jj|dd|ddgdgf|jj|ddgdgf|jj|ddgdgf|jj|dgdgfg}|||d S) zWalk down ordering is correct.r@1.txtr2.txtro3.txtr4.txtNrArrrrVrr%rrr{s r'test_walk_top_downz'FakeOsModuleWalkTest.test_walk_top_downsU>>%(( **8W==>>> **8VWEEFFF **8VUGLLMMM **8VWEEFFF '' 3 W\  x 0 05'G9 E W\  x 7 7gY G W\  x 0 0"wi @   x22222r)c|d}||jj|ddd||jj|dd||jj|dd||jj|d|jj|ddgdgf|jj|ddgdgf|jj|dgdgf|ddgdgfg}|||dd d S) zWalk up ordering is correct.r@rrorrrrrF)roNrrs r'test_walk_bottom_upz(FakeOsModuleWalkTest.test_walk_bottom_upsh>>%(( **8VUGLLMMM **8VWEEFFF **8VWEEFFF **8W==>>>W\  x 7 7gY G W\  x 0 05'G9 E W\  x 0 0"wi @ '' 3   x)>)>NNNNNr)c|dd}|d|jj||j|}|tt|dS)zKRaises an exception when attempting to walk non-existent directory.r@rOFN) rArrrrrr StopIterationr)r%rDrs r' test_walk_raises_if_non_existentz5FakeOsModuleWalkTest.test_walk_raises_if_non_existentspNN5%00   3 3I > >???GLL++  -y99999r)c|dd}|||j|}|t t |dS)z>%// """GLL**  -y99999r)c||dd}|d|jj||j||jD]}|| tj tj fvdS)zMCalls onerror with correct errno when walking non-existent directory.r@rOFonerrorN) rrArrrrrrrrrJrQrK)r%rD_s r'(test_walk_calls_on_error_if_non_existentz=FakeOsModuleWalkTest.test_walk_calls_on_error_if_non_existents NN5%00   3 3I > >???iAA  A   EM5<+HHIIIIIr)c||d}|||d|jj||j||jD]}| | tj tj fvdS)zFakeOsModuleWalkTest.test_walk_calls_on_error_if_not_directorys >>+.. """ tw|228<<===h@@  A   EM5<+HHIIIIIr)c|d}d}d}||jj|d||jj||d||jj||d||jj||d||jj||d|j|d}t |}|d |d }t|D]j\}}}| d | |jjj |z| |jjj |zrd }k| d |d S) z=Caller can modify list of directories to visit while walking.r@visitno_visitrOrrrrrFTN) rArrrrVrrr9iterrendswithr ) r%rrrr root_contentsvisited_visit_directory_dirs_filess r'#test_walk_skips_removed_directoriesz8FakeOsModuleWalkTest.test_walk_skips_removed_directoriess~~e$$ **477888 **4@@AAA **4@@AAA **47CCDDD **47CCDDDGLL!6!677 Y a)))"'#' ?? / / D%   UDMM$',2BX2M$N$N O O O}}TW\-566 /*.' 677777r)c||d}|d}||jj|d||jj|dd||jj|ddd||jj|d||ddggf|jj|ddgdgf|jj|ddgdgfg}|||d |jj|dgdgfg}|||jj|dd dS) Nr@rosubfilerOrorlrm created_linkFrpryrArrrrVrrr%rrrsr{s r' test_walk_followsymlink_disabledz5FakeOsModuleWalkTest.test_walk_followsymlink_disableds >>%((>>(++ **8Y??@@@ **8UEBBCCC **8UGWMMNNN DGL--hGGRRR~. 3 W\  x / /'UG D W\  x 8 8"wi H  xuEEEW\&&x@@"ykRS   GL  h 7 7      r)c(||d}|d}||jj|d||jj|dd||jj|ddd||jj|d|jj||ddggf|jj|ddgdgf|jj|ddgdgf|jj|dgdgfg}|||d |jj|dgdgfg}|||jj|dd dS) Nr@rorrOrorlrmrTrrrs r'test_walk_followsymlink_enabledz4FakeOsModuleWalkTest.test_walk_followsymlink_enableds >>%((>>(++ **8Y??@@@ **8UEBBCCC **8UGWMMNNN  GL  h 7 7 GL  h ' '   ~. 3 W\  x / /'UG D W\  x 8 8"wi H W\  x 8 8"yk J   xtDDDW\&&x@@"ykRS   GL  h 7 7      r)c||d}|||d|ddggfdgdgfg}||ddS)Nz /foo/bar/bazrOr)rro)ryr_rrr)r%rr{s r'test_walk_linked_file_in_subdirz4FakeOsModuleWalkTest.test_walk_linked_file_in_subdirs  "  ### E9---eWb)JUG+DE x00000r)c|ddd}|||dd|dddd|dddd|jjjdzz|d|jjjdzzdzg}|D]9}|j|D]\}}}|||:|dddd}|||D]K}|j|D].\}}}|||/LdS)Nr@rOror^rar) rArrrr rrr startswith)r%rvariantsrrdirpath _dirnames _filenamess r'test_base_dirpathz&FakeOsModuleWalkTest.test_base_dirpath*sNN5%77  ### NN5% ( ( NN5$u 5 5 NN5$u 5 5 8H18L L NN5 ! !DGL$4q$8 85 @   ! 4 4H26',,x2H2H 4 4.J  (3333 4NN5%>>  ###  > >H26',,x2H2H > >.J 2 28 < <==== > > >r)N)TF)r.r/r0rrrrrrrrrrrrrrrr1r)r'ririrs B B B B   ))) 3 3 3OOO :::::: J J J J J J8880   .   6 1 1 1>>>>>r)riceZdZdZdS)RealOsModuleWalkTestcdSrr1rs r'rbz RealOsModuleWalkTest.use_real_fs@rr)Nrr1r)r'rr?rr)rceZdZfdZdZdZejee d ddZ dZ dZ d Z d Zd Zd Zd ZdZejee d ddZdZdZdZdZdZdZdZdZxZS)FakeOsModuleDirFdTestcftt||jjd|j_|jd|j dtj |_ |j ddS)NFrr)/foo/baz) r6rr7rrclearra is_windows_fsr,r|r}dir_fdrr=s r'r7zFakeOsModuleDirFdTest.setUpEs #T**00222 %%'''(-% "":...gll62;77  ##J/////r)cF|t|jjd|jj|j|jj|jj||jd|jj|jdS)Nror) rrrrrrraddrrs r' test_accessz!FakeOsModuleDirFdTest.test_accessMs   GN  GL;     ##DGN333 udgl4;OOPPPPPr)cb|t|jjdd|j|jj|jj|jdd|j|jd}|d|j dS)Nrorrr) rrrrrrrrrr r%r&s r'rz FakeOsModuleDirFdTest.test_chmodXs   GM  ;     ##DGM222  eVDK 888 W\\* % % vrz22222r)rz$chown not on all platforms availablec|t|jjddd|j|jj|jj|jddd|j|jd}||tj d||tj ddS)Nrorrrr) rrrrrrrrrrrrs r' test_chownz FakeOsModuleDirFdTest.test_chownes   GM   ;     ##DGM222  eS#dk ::: W\\* % % DK#... DK#.....r)c\|t|jjdd|j|jj|jj|jdd|j||jj ddS)Nro/bat src_dir_fd rrrrrrrrrrrs r'test_link_src_fdz&FakeOsModuleDirFdTest.test_link_src_fdus   GL  {     ##DGL111  UFt{ ;;;  ++F3344444r)c\|t|jjdd|j|jj|jj|jdd|j||jj ddS)Nror dst_dir_fdrbatz/foo/batrrs r'test_link_dst_fdz&FakeOsModuleDirFdTest.test_link_dst_fds   GL  {     ##DGL111  Z4; ???  ++J7788888r)c\|t|jjdd|j|jj|jj|jdd|j||jj ddS)Nrorr) rrrrrrrrrrrs r'r z"FakeOsModuleDirFdTest.test_symlinks   GO  ;     ##DGO444 vdk:::  ++F3344444r)c||jdd|jdd|t|jjd|j|jj |jj| d|jd|jdS)Nz/meyer/lemon/pierz /geo/metroz/meyerz/geo/metro/lemon/pier) rrarrrrrrrrrrs r'rz#FakeOsModuleDirFdTest.test_readlinks **,,, &&'9:FFF &&|X>>>   G  ";    ##DG$4555   G  3DK  H H     r)c*|t|jjd|j|jj|jj|jd|j}||jddSNrorr() rrrrrrrrr rs r'rzFakeOsModuleDirFdTest.test_statsz -tw|U4;WWW ##DGL111 W\\% \ 4 4 X.....r)c*|t|jjd|j|jj|jj|jd|j}||jddSr) rrrrrrrrr rs r' test_lstatz FakeOsModuleDirFdTest.test_lstatsz -tw}eDKXXX ##DGM222 W]]5] 5 5 X.....r)cX|t|jjd|j|jj|jj|jd|j||jj ddSNrirz /foo/newdir) rrrrrrrrrrrs r'r#z FakeOsModuleDirFdTest.test_mkdirs       ##DGM222  ht{ 333  ++M::;;;;;r)cX|t|jjd|j|jj|jj|jd|j||jj ddS)NrOrr) rrrrrrrr"rrrs r'rz FakeOsModuleDirFdTest.test_rmdirs -tw}eDKXXX ##DGM222  eDK 000 ,,Z8899999r)rz$mknod not on all platforms availablecX|t|jjd|j|jj|jj|jd|j||jj ddSr) rrrrrrrrrrrs r' test_mknodz FakeOsModuleDirFdTest.test_mknods       ##DGM222  ht{ 333  ++M::;;;;;r)c\|t|jjdd|j|jj|jj|jdd|j||jj ddSNro /foo/batzrrO rrrrrrrrrrrs r'test_rename_src_fdz(FakeOsModuleDirFdTest.test_rename_src_fds   GN  {     ##DGN333 ukdkBBB  ++K8899999r)c\|t|jjdd|j|jj|jj|jdd|j||jj ddSNrorrrbatzrrs r'test_rename_dst_fdz(FakeOsModuleDirFdTest.test_rename_dst_fds   GN  {     ##DGN333 z6dkBBB  ++K8899999r)c\|t|jjdd|j|jj|jj|jdd|j||jj ddSr rrrrrrrrrrrrs r'test_replace_src_fdz)FakeOsModuleDirFdTest.test_replace_src_fds   GN  {     ##DGN333 {t{CCC  ++K8899999r)c\|t|jjdd|j|jj|jj|jdd|j||jj ddSrrrs r'test_replace_dst_fdz)FakeOsModuleDirFdTest.test_replace_dst_fds   GN  {     ##DGN333  Ft{CCC  ++K8899999r)cX|t|jjd|j|jj|jj|jd|j||jj ddSNrorr) rrrr9rrrr"rrrs r' test_removez!FakeOsModuleDirFdTest.test_remove  t{     ##DGN333 uT[111 ,,Z8899999r)cX|t|jjd|j|jj|jj|jd|j||jj ddSr) rrrr rrrr"rrrs r' test_unlinkz!FakeOsModuleDirFdTest.test_unlinkrr)c|t|jjdd|j|jj|jj|jdd|j|jd}|d|j |d|j dS)Nrorr)rrrrr) rrrrrrrrrrrrs r' test_utimez FakeOsModuleDirFdTest.test_utime s   GM  ;     ##DGM222  e6$+ >>> W\\* % % BK((( BK(((((r)cL|t|jjdtj|j|jj|jj|jdtj|j}|d|dS)Nrorr) rrrr|r}rrr assertLessrGs r' test_openzFakeOsModuleDirFdTest.test_opens   GL  K;     ##DGL111 W\\%T[\ A A 2r))r.r/r0r7rrrrhasattrrrrrr rrrr#rrrrrrrrrrrrs@r'rrDs00000 Q Q Q 3 3 3X_W---/UVV / /WV / 5 5 5 9 9 9 5 5 5   /// /// <<<::: X_W---/UVV<<WV< : : : : : : : : : : : ::::::: ) ) )       r)rc8eZdZdZdZdZdZdZdZdZ dS) StatPropagationTestctjd|_tj|j|_t j|j|_dS)Nr")r) rFakeFilesystemrar FakeOsModulerr r r|rs r'r7zStatPropagationTest.setUp(sC)8LLL&t77*4?;; r)cd}d}d}|j|||d}|d|j|tj|d|j|j| ||d|j|tj|d|j|j| |t||j|tj|||j|jdS)z-test that file size gets updated via close().rl xyzzy/closezThis is a test.rrrN) rrr|rrrrarcrrrrr%file_dirrcontentr,s r' test_file_size_updated_via_closez4StatPropagationTest.test_file_size_updated_via_close-s_! #  h YYy# & & DGLL33DLABBB T_77 BBKLLL  DGLL33DLABBB T_77 BBKLLL   Wtw||I'>'>t|'LMMM $/"<"._sBHH]++r))rrarr|rr FakeLargeFileIoException)r%rrrrr,s @@r' test_large_file_size_after_writez4StatPropagationTest.test_large_file_size_after_writeVs #,--  ##I}#EEE! YYy# & &   . + + + + +     r)cd}d}|jj||}d}|j|||d}|d|j|t j|d|j |j | ||d|j|t j|d|j |j | |t||j|t j|||j |j ||t||j|t j|||j |j dS)z-test that file size gets updated via flush().rlflushzThis might be a test.rrrN)rrrVrr|rrrrarcrrrrr)r%rrrrr,s r' test_file_size_updated_via_flushz4StatPropagationTest.test_file_size_updated_via_flushbs GL%%h :: )  h YYy# & & DGLL33DLABBB T_77 BBKLLL  DGLL33DLABBB T_77 BBKLLL   Wtw||I'>'>t|'LMMM $/"<"'>t|'LMMM $/"<"'>t|'LMMM $/"<".fake_scan_dirs#088!LLLr)rlrmrorIrr^ link_filers rel_link_file rel_link_dirbrac|jSr5rp)r}s r'ruz'FakeScandirTest.setUp..s r)rv)%r6rr7rcrbsupports_symlinksrrpyfakefs.fake_scandirrrArDrrVlinked_file_pathlinked_dir_pathrel_linked_dir_pathrel_linked_file_pathr~rfile_link_path dir_link_pathfile_rel_link_pathdir_rel_link_pathr,r FILE_SIZELINKED_FILE_SIZErrX pretest_cwdrBrry do_scandir dir_entriesrq)r%rr$rsr#r>s` @r'r7zFakeScandirTest.setUps ot$$**,,,%)_!4!ND>(G44 $ 1 1(F C C#w|005AA#'7<#4#4 $'5$ $  %)GL$5$5 $'6% % ! ))$.%@@ **4>6BB"gl// LL!W\..t~zJJ"&',"3"3DNO"T"T!%!2!24>>!R!R  &&& $2GHHH  ! T OOD0 1 1 1   %t7L0L         2D4H I I I    3T5J K K K    68P Q Q Q    79R S S S 7>>++  dn%%% 1 122 ":":;;;;;r)c|j|jtdSr5)rrBr7r6tearDownr=s r'r;zFakeScandirTest.tearDowns6  d&''' r)c6||jS)z'Hook to override how scandir is called.)rrDrs r'r8zFakeScandirTest.do_scandirs||DN+++r)c|jS)z>Hook to override the expected scandir() path in DirEntry.path.)rDrs r' scandir_pathzFakeScandirTest.scandir_paths ~r)cfddg}jr|gdt|tj|djDfd|D}|djDdS)NrrI)rsr%r'r&cg|] }|j Sr1rprlr}s r' z.FakeScandirTest.test_paths..'Q'Q'Qu 'Q'Q'Qr)ctg|]4}jj|5Sr1)rrrVr>)rlrqr%s r'rBz.FakeScandirTest.test_paths..sF   =ADGL  d//114 8 8   r)cg|] }|j Sr1rrAs r'rBz.FakeScandirTest.test_paths..rCr))r+extendrrr9)r% sorted_names sorted_pathss` r' test_pathszFakeScandirTest.test_pathssv  !    JJJ    \**C0@,A,ABBB 'Q'Q@P'Q'Q'QRRR    EQ    'Q'Q@P'Q'Q'QRRRRRr)c||jd||jd|jr||jd||jdd||jd||jdd||jd||jdd||jd||jdddSdS NrrrFrrarr)r"r9is_filerr+rs r' test_isfilezFakeScandirTest.test_isfiles )!,4466777 (+3355666  ! Q   T-a088:: ; ; ;   T-a0888OO P P P OOD,Q/7799 : : :   T-a0888OO P P P   T-a088:: ; ; ;   T-a0888OO P P P OOD,Q/7799 : : :   T-a0888OO P P P P P Q Qr)c||jd||jd|jr||jd||jdd||jd||jdd||jd||jdd||jd||jdddSdSrL)rr9is_dirr"r+rs r' test_isdirzFakeScandirTest.test_isdirs (+2244555 )!,3355666  ! P OOD,Q/6688 9 9 9   T-a0777NN O O O   T-a07799 : : :   T-a0777NN O O O OOD,Q/6688 9 9 9   T-a0777NN O O O   T-a07799 : : :   T-a0777NN O O O O O P Pr)cr|jr.||jd||jd||jd||jd||jd||jddSdS)Nrrrrarr)r+r"r9 is_symlinkrrs r' test_is_linkzFakeScandirTest.test_is_links  ! >   T-a0;;== > > >   T-a0;;== > > > OOD,Q/::<< = = = OOD,Q/::<< = = = OOD,Q/::<< = = = OOD,Q/::<< = = = = =  > >r)c||ddd}|j|jj|d|dd}|j||||jj|dgd||DdS)NABCDcg|] }|j Sr1rF)rlrus r'rBz@FakeScandirTest.test_path_links_not_resolved..s 5 5 5QV 5 5 5r)) rrArrWrrVrrrr s r'test_path_links_not_resolvedz,FakeScandirTest.test_path_links_not_resolved s **,,,>>#sC00 **8S99:::NN3,,  ),,,  W\  y# . . / 5 5T\\)44 5 5 5     r)ctrL|r8|jr|dtr|d||j|jj |j d ||j|j j |j d |j rV||j|jj |j d ||j|jj |j d ||j|jj |j d ||j|jj |j d dSdS) Nz7inode seems not to work in scandir module under Windowsz-inode seems not to work in a Docker containerrrrrarr)rrbrcskipTestrrrrr~st_inor9inoderr+rr2r1r4r3rs r' test_inodezFakeScandirTest.test_inodes"  O4++-- O Y WXXX O MNNN  GLL ' ' .0@0C0I0I0K0K     GLL ( ( /1A!1D1J1J1L1L     !     d0118 #))++       d1229 #))++       d455< #))++       d566= #))++       r)c|j|jj}|d|||j}|D]}|j|jkr|j}|jr|d|n|d||d|j|jjdS)Nrr) rrrrdrrrDrr)r% stat_nlinkdir_iteritemscandir_stat_nlinks r'test_scandir_stat_nlinkz'FakeScandirTest.test_scandir_stat_nlink3sW\\$.11:  J'''<<// K KDyDN**%)YY[[%9"%<$$Q(:;;;;$$Q(:;;;  DGLL$@$@$IJJJ K Kr) O_DIRECTORYzopening directory not supported)rarzfd not supported for scandirc|dd}||||jj|d||jj|d||jj|d|j||j|tjtj z}d|j |D}t|gdksJdS) Nrrrrr})flagscg|] }|j Sr1rp)rl dir_entrys r'rBz8FakeScandirTest.test_scandir_with_fd..LsHHHyINHHHr))rrr}) rAr,rrrrVrBr|r}rgrrr)r%temp_dirrchildrens r'test_scandir_with_fdz$FakeScandirTest.test_scandir_with_fdAs>>%// !!! **8W==>>> **8W==>>>  ))(H==>>>  h W\\("+*F\ G GHHDGOOB4G4GHHHh#?#?#???????r)cV||j|jdj|jrt jdkrt|t|j |j j t|jdj |j r||j |jdj|||jddj|t|j |jjt|jdj||j |jdj|||jddj|t|j |jjt|jd jdSdS) Nrra rraFrrrr)rr5r9rrrrrDintrr~rr+r6r.r)r%absolute_symlink_expected_sizerelative_symlink_expected_sizes r' check_statzFakeScandirTest.check_statOsP )9!)<)A)A)C)C)KLLL! S%5%?%?   DGLL//899D$Q',,..788     !    T2D4DQ4G4L4L4N4N4V W W W   . #(((??G      DGLL!566?@@D$Q',,..788      T2D4DQ4G4L4L4N4N4V W W W   . #(((??G      DGLL!566?@@D$Q',,..788       r)zPOSIX specific behaviorcz|t|jt|jdSr5)rurr-r0rs r'test_stat_posixzFakeScandirTest.test_stat_posixns2 D122C8Q4R4RSSSSSr)zWindows specific behaviorc2|dddSrr)rurs r'test_stat_windowsz!FakeScandirTest.test_stat_windowsrs 1r)c|jrtjdkrr||j|jt jt|j dj |j r||j|j t j t|j dj||j|j t j t|j djdSdS)Nrprrr)rrrDrrrr~ST_CTIMErrr9rr+r.ST_MTIMErrs r'+test_index_access_to_stat_times_returns_intz;FakeScandirTest.test_index_access_to_stat_times_returns_intvs;! S%5%?%?    T]++DM:D$Q',,..788     !     T1224=AD$Q',,..788       T1224=AD$Q',,..788        r)c@|jr|j|j}||j|jdj||j|jdj||j|jdj||j|jdjdSdS)Nrar)r+rrr-rr^r9st_dev)r% file_stats r'test_stat_ino_devz!FakeScandirTest.test_stat_ino_devs  ! R T%:;;I   Y-t/?/B/G/G/I/I/P Q Q Q   Y-t/?/B/G/G/I/I/P Q Q Q   Y-t/?/B/G/G/I/I/P Q Q Q   Y-t/?/B/G/G/I/I/P Q Q Q Q Q  R Rr))rar4z4Path-like objects have been introduced in Python 3.6c|t|jdtj||jj|dtj |jd||jj|dtj |jddS)NrrrIr) r isinstancer9rPathLikerrrVr>fspathrs r'test_path_likezFakeScandirTest.test_path_likes  4#3A#6 DDEEE  GL  d//115 9 9 Id&q) * *     GL  d//116 : : Id&q) * *     r)cz||tj|jddS)Nrk)r_rIrJrKrrs r'test_non_existing_dirz%FakeScandirTest.test_non_existing_dirs7  ##EL$,@WXXXXXr))"r.r/r0r5r6r7r;r8r>rJrNrQrTr[r`rfrrrrrrDrnrurrcrwryr}rrrrrrs@r'rrs>I:<:<:<:<:>>    < K K KX_]3335VWWX_S%.0NOO @ @POXW @>X_X(*CDDTTEDTX_,,.IJJKJ"RRRX_ 6!<)<%<>     YYYYYYYr)rceZdZdZdS)RealScandirTestcdSrr1rs r'rbzRealScandirTest.use_real_fsrr)Nrr1r)r'rrrr)rceZdZdZdZdS)FakeScandirRelTestcJ|jj|jSr5)rrrelpathrDrs r'r>zFakeScandirRelTest.scandir_pathsw|##DN333r)cp||jj|jSr5)rrrrrDrs r'r8zFakeScandirRelTest.do_scandirs(||DGL00@@AAAr)N)r.r/r0r>r8r1r)r'rrs7444 BBBBBr)rceZdZdZdS)RealScandirRelTestcdSrr1rs r'rbzRealScandirRelTest.use_real_fsrr)Nrr1r)r'rrrr)rz.dir_fd not supported for os.scandir in Windowsz%no dir_fd support for scandir packagec*eZdZfdZdZdZxZS)FakeScandirFdTestc|j|jtt|dSr5)rrrr6rr;r=s r'r;zFakeScandirFdTest.tearDowns<  dk""" &&//11111r)cdSrr1rs r'r>zFakeScandirFdTest.scandir_paths rr)c|j|jtj|_||jSr5)rr|rDr}rrrs r'r8zFakeScandirFdTest.do_scandirs1gll4>2;?? ||DK(((r))r.r/r0r;r>r8rrs@r'rrsV22222 )))))))r)rceZdZdZdS)RealScandirFdTestcdSrr1rs r'rbzRealScandirFdTest.use_real_fsrr)Nrr1r)r'rrrr)rceZdZdZdS)FakeScandirFdRelTestc|j|jj|jtj|_||jSr5)rr|rrrDr}rrrs r'r8zFakeScandirFdRelTest.do_scandirsCgll47<#7#7#G#GUU ||DK(((r)N)r.r/r0r8r1r)r'rrs#)))))r)rceZdZdZdS)RealScandirFdRelTestcdSrr1rs r'rbz RealScandirFdRelTest.use_real_fsrr)Nrr1r)r'rrrr)rc6eZdZfdZdZdZdZdZxZS)FakeExtendedAttributeTestc:tt|||d|_|jj|jd|_ | |j dSrg) r6rr7rrAr~rrrVrrr=s r'r7zFakeExtendedAttributeTest.setUps~ '..44666 u-- **4=%@@ (((((r)c|g|j|j|g|j|jdSr5)rr listxattrr~rrs r'test_empty_xattrz*FakeExtendedAttributeTest.test_empty_xattrsX TW..t}==>>> TW..t~>>?????r)c|t|jj|jdd|t j|jj|jdd|jj|j|jdd| d|j |jd|t j |jj|jdd|jj dS)Nrvaluevalue) rrrsetxattrrrIrJr XATTR_REPLACErgetxattrENODATA XATTR_CREATErs r' test_setxattrz'FakeExtendedAttributeTest.test_setxattrs )TW%5t~vwWWW ## L G  N   G !     ::: 47#3#3DNF#K#KLLL ## M G  N   G      r)c|j|jd|g|j|j|j|jdd|dg|j|j|d|j|jd|j|jd|g|j|j||j|jddS)Nrrr)r removexattrrrrrr assertIsNoners r'test_removeattrz)FakeExtendedAttributeTest.test_removeattrs$ DNF333 TW..t~>>??? (;;; &47#4#4T^#D#DEEE 47#3#3DNF#K#KLLL DNF333 TW..t~>>??? $'**4>6BBCCCCCr)cJ|j|j|j|jdd|dg|j|d|j|jddS)Nrrr)rrBr~rrrrrs r'test_default_pathz+FakeExtendedAttributeTest.test_default_paths  dm$$$ ::: &47#4#4#6#6777 47#3#3DM6#J#JKKKKKr)) r.r/r0r7rrrrrrs@r'rrs)))))@@@   *DDDLLLLLLLr)rcreZdZfdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZdZxZS)FakeOsUnreadableDirTestc|r|tt||d|_|jj |jd|_ | |j | |jddS)Nrrr) rbryr6rr7rAr~rrrVrrrr=s r'r7zFakeOsUnreadableDirTest.setUp s      $  ! ! # # # %t,,22444z22 **4=+FF ((( 4=%(((((r)c|jr|j||ddS|j||dS)NT)force_unix_mode)rrarr)r%rrs r'rzFakeOsUnreadableDirTest.chmodsL   & O ! !$d ! C C C C C GMM$ % % % % %r)c|||j}t |dz||dz|j||dzt t ||||jdSNr)r_ryrgetuidr rr)r%uids r' test_getuidz#FakeOsUnreadableDirTest.test_getuid  gnnb r47>>#3#3444 r799---  dgnn../////r)c|||j}t |dz||dz|j||dzt t ||||jdSr)r_ryrgetgidrrr)r%gids r' test_getgidz#FakeOsUnreadableDirTest.test_getgid(rr)cts2|tj|jj|jdS|dg|j|jdS)Nr)r rIrJrArrpr~rrs r'test_listdir_unreadable_dirz3FakeOsUnreadableDirTest.test_listdir_unreadable_dir2scyy L  ' ' dgot} U U U U U   k]DGOODM,J,J K K K K Kr)c||jd|dg|j|j||jddS)Nrrr)rr~rrrprs r'test_listdir_user_readable_dirz6FakeOsUnreadableDirTest.test_listdir_user_readable_dir8s\ 4=%((( + (F(FGGG 4=%(((((r)c||t}t|dz|d}||d||jj |t|tsO| t5|j |ddddS#1swxYwYdS|dg|j |jdS)NrrYrrkr)r_ryrr rAr,rrrrr rPermissionErrorrprr~r%user_idr~s r'.test_listdir_user_readable_dir_from_other_userzFFakeOsUnreadableDirTest.test_listdir_user_readable_dir_from_other_user=sc  ))! >>&)) u---  ++H55666yy L""?33 * *))) * * * * * * * * * * * * * * * * * *   k]DGOODM,J,J K K K K KsDD  D c|t}t|dz|d}||d||jj|t|| g|j |dS)NrrYirk) r_rr rAr,rrrrrrprs r'/test_listdir_group_readable_dir_from_other_userzGFakeOsUnreadableDirTest.test_listdir_group_readable_dir_from_other_userLs ))! >>&)) u---  ++H55666 TW__X6677777r)c|||j}t |dz|d}||d||jj |t |tsO| t5|j |ddddS#1swxYwYdS|g|j |dS)NrrY0rk)r_ryrrrrAr,rrrr rrrprr%group_idr~s r'0test_listdir_group_readable_dir_from_other_groupzHFakeOsUnreadableDirTest.test_listdir_group_readable_dir_from_other_groupVsf  7>>##1 >>&)) u---  ++H55666yy <""?33 * *))) * * * * * * * * * * * * * * * * * *   R!:!: ; ; ; ; ;s)DDDc|t}t|dz|d}||d||jj|t|| g|j |dS)NrrYrrk) r_rrrAr,rrrrrrprs r'0test_listdir_other_readable_dir_from_other_groupzHFakeOsUnreadableDirTest.test_listdir_other_readable_dir_from_other_groupes 991 >>&)) u---  ++H55666 TW__X6677777r)c||d|j|jjdzdS)Nrr)rrrr~r rs r'test_stat_unreadable_dirz0FakeOsUnreadableDirTest.test_stat_unreadable_diros6 DGLL77?%GHHHHHr)c^||jd|d|j|jjdz||jd|d|j|jjdzdS)Nrr)rr~rrrr rs r'test_chmod_unreadable_dirz1FakeOsUnreadableDirTest.test_chmod_unreadable_dirrs 4=%(((  T] ; ; Ce KLLL 4=%((( DGLL77?%GHHHHHr)cts2|tj|jj|jdS|d|j|jjdSrr) r rIrJrArrrrrrs r' test_stat_file_in_unreadable_dirz8FakeOsUnreadableDirTest.test_stat_file_in_unreadable_dirxsdyy F  ' ' dglDN S S S S S   Q T^ < < D E E E E Er)c||d}||d||jj||j|||jj|dS)NrYrrk) ryrAr,rrrrrr"rs r'test_remove_unreadable_dirz2FakeOsUnreadableDirTest.test_remove_unreadable_dir~s >>&)) u---  ++H55666  h ,,X6677777r)c|t}t|dz|d}||d||jj|t|ts| t5|j |dddn #1swxYwY||jj|dS|j || |jj|dS)NrrYrrk)r_rr rAr,rrrrr rrrr"rs r'*test_remove_unreadable_dir_from_other_userzBFakeOsUnreadableDirTest.test_remove_unreadable_dir_from_other_users{ ))! >>&)) u---  ++H55666yy <""?33 ( ( h''' ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( OODGL//99 : : : : : GMM( # # #   TW\00:: ; ; ; ; ;s C11C58C5)r.r/r0r7rrrrrrrrrrrrrrrrs@r'rr s ) ) ) ) )&&& 000000LLL ))) L L L888 < < <888IIIIII FFF 888<<<<<<rs +* AAAAAAAAAAAACCCCCCCCCCCC  ?>>>>>>>33333>333$F, F, F, F, F, +F, F, F, RX' h2h2h2h2h2(<h2h2h2V(I u-u-u-u-u-/u-u-u-pxxxxx%9xxxv%C J>J>J>J>J>/J>J>J>Z/ `````0```Faaaaa(aaaH["DEEUYUYUYUYUY*UYUYFEUYpo BBBBBBBB+ $&VWW$&MNN ) ) ) ) ) ) )ONXW )) ))))),))) / /L/L/L/L/L 4/L/L/LdI<I<I<I<I<2I<I<IW>WXXX diinn555  IIdii&& %(8(8 9 9499Y;O;O     IIf   (8 3 II* + +     rc||d|d||d|d||d|d||ddd|dd S) lTests for collapsing path during initialization. Taken from pathlib.PurePath documentation. zfoo//barrCz foo/./barz foo/../barrD/usrlib64z /usr/lib64N)rGr$assertNotEqualr&s rtest_init_collapsez0FakePathlibInitializationTest.test_init_collapsees :.. )0D0DEEE ;//91E1EFFF DIIl33TYYy5I5IJJJ 667;;TYY|=T=TUUUUUrc 6|jjj}|||jjdddz}||j|dddf||jd||j|||j|||j d||j d||j d||j |||jjddz||j d|||jjddz||j d||dz||j d ||dS) Nr>r?setup.pysetup.pyr)rr$sepjoinrGpartsdriverootanchornamestemsuffixparentparents)rrVr$s rtest_path_partsz-FakePathlibInitializationTest.test_path_partsnsglyytw|00zJJJKK c5%%DEEE R((( C((( c*** J/// G,,, e,,, diidgl6G6Gu6U6U0U&V&VWWW  LOTYYsTW\->->ue-L-L'LMM    a$))C%K*@*@AAA a$))C..99999rPOSIX specific behaviorcb||d||d||ddSN/a/bza/bzd:/br2r$ is_absolute assertFalser&s rtest_is_absolute_posixz4FakePathlibInitializationTest.test_is_absolute_posixs  &))5577888 5))5577888 6**668899999rWindows specific behaviorcb||d||d||ddSrd)rhr$rgr2r&s rtest_is_absolute_windowsz6FakePathlibInitializationTest.test_is_absolute_windowss 6**6688999 5))5577888  &))557788888rN) r)r*r+r;rHrNraunittestskipIfr.rirlr(rrr0r0?s<<<.    VVV:::"X_Z!:;;::<;: X_^%@AA99BA999rr0ceZdZdZdS)RealPathlibInitializationTestcdSNTr(r&s rrz)RealPathlibInitializationTest.use_real_fstrNr)r*r+rr(rrrprp#rrprjcVeZdZdZdZdZeje ddZ dS)&FakePathlibInitializationWithDriveTestcD||dddd|d|||d|||d|d|d||dd z d z |d d S) zJBasic initialization tests - taken from pathlib.Path documentationc:/r>r?r@zc:/foo/bar/bazrBrCzc:/Usersjohndatazc:/Users/john/dataNrFr&s rrHz>FakePathlibInitializationWithDriveTest.test_init_with_segmentss  IIeUE5 1 1499=M3N3N    diinn555  IIdii&& %(8(8 9 9499Y;O;O     IIj ! !F *V 3 II* + +     rc||dd|d||dd|ddS)rJz c:/Windowszd:bar/Program Filesc:/Program FilesNrFr&s rrNz9FakePathlibInitializationWithDriveTest.test_init_collapsesx <99499W;M;MNNN  IIl$4 5 5 II( ) )     rc ||jjddd}||jd||jd||jd||jd||jd||j d||j d||j ||jjdd||j d||jjdd||j d |ddS) Nd:python scriptsrP)rrrPrQrRrSrrT) r$rrWrGrXrYrZr[r\r]r^r_r`r:s rraz6FakePathlibInitializationWithDriveTest.test_path_partssyy**41A:NNOO %IJJJ T*** B''' d+++ J/// G,,, e,,,  K47<#4#4T;K#L#LMM     LO IIdgl''.>?? @ @    a$))D//:::::rzWindows-specifc behaviorc||d||d||d||ddS)Nzc:/a/brec:z //some/sharerfr&s rtest_is_absolutez7FakePathlibInitializationWithDriveTest.test_is_absolutes  (++7799::: 6**6688999 44466777  .11==??@@@@@rN) r)r*r+rHrNrarmrnr.rr(rrrwrwst       ;;;$X_^%?@@AAA@AAArrwceZdZdZdS)&RealPathlibInitializationWithDriveTestcdSrrr(r&s rrz2RealPathlibInitializationWithDriveTest.use_real_fsrsrNrtr(rrrrrurrceZdZdZdZeje ddZdZ dZ dZ dZ eje jd kd d Zd Zd ZdS)FakePathlibPurePathTestz.Tests functionality present in PurePath class.c|||d||d||d||ddSNz/devr=COM1znul.txt)check_posix_onlyrhr$ is_reservedr&s rtest_is_reserved_posixz.FakePathlibPurePathTest.test_is_reserved_posixs  6**6688999 33355666 6**6688999 9--99;;<<<<>??? ;//55h??@@@  '**0099::: 8,,227;;<<<< >z J J II- . .     z * * 3 3 IIe   & &z 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3s>)B44B8;B8cB||dd|d||dd|ddS)Nrz.bz2zc:/Downloads/pathlib.tar.bz2READMEz.txtz README.txt)rGr$ with_suffixr&s rtest_with_suffixz(FakePathlibPurePathTest.test_with_suffixs  II3 4 4 @ @ H H II4 5 5     IIh   + +F 3 3TYY|5L5L     rN)r)r*r+__doc__rrmrnr.rrrrrr, version_inforrrr(rrrrs88===X_^%@AA<<BA<      ===444X_S%.0RSS66TS6 333     rrceZdZdZdS)RealPathlibPurePathTestcdSrrr(r&s rrz#RealPathlibPurePathTest.use_real_fsrsrNrtr(rrrrrurrcVeZdZfdZdZdZdZdZdZdZ e j e dd Z e j e d d Ze j e d d ZdZe j ejdkddZdZdZdZdZdZdZdZxZS)!FakePathlibFileObjectPropertyTestcTtt||ddd|_||jd||dd |n#tj $rYdSwxYw| |d|dd|d|_ | |j |j| |d|dd| |d |ddddS) Nhomejanetest.pysdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacontentsrzbroken_dir_linknonebroken_file_link) superrr make_path file_path create_file create_dirskip_if_symlink_not_supportedrmSkipTestcreate_symlinkfile_link_path)r __class__s rrz'FakePathlibFileObjectPropertyTest.setUps /66<<>>> BB *=== vv66777   . . 0 0 0 0     FF  DNN622DNN664R4RSSS"nnY77 D/@@@  NN, - -t~~ff/M/M     NN- . . NN669 5 5     s B B32B3c 2||||j|||dd|||ddd|||d|||j|||d|||ddS)Nrrtestrzrr)rr2r$rexistsrrhrr&s r test_existsz-FakePathlibFileObjectPropertyTest.test_exists2s **,,,  $.1188::;;;  $.."@"@AAHHJJKKK 4>>&&&#I#IJJQQSSTTT  $.."8"899@@BBCCC  $"566==??@@@ 4>>2C#D#DEELLNNOOO 4>>2D#E#EFFMMOOPPPPPrc||||j|||d|||d|||j|||d|||ddS)N home/janerzrr)rrhr$ris_dirr2rrr&s r test_is_dirz-FakePathlibFileObjectPropertyTest.test_is_dir<sU **,,, 4>2299;;<<<  $.."="=>>EEGGHHH  $.."8"899@@BBCCC 4#677>>@@AAA 4>>2C#D#DEELLNNOOO 4>>2D#E#EFFMMOOPPPPPrc||||d|||d|||d|||j|||d|||ddSNzhome/jane/test.pyrrzrr)rr2r$ris_filerhrr&s r test_is_filez.FakePathlibFileObjectPropertyTest.test_is_fileEs` **,,,  $..1D"E"EFFNNPPQQQ 4>>+#>#>??GGIIJJJ 4>> #9::BBDDEEE  $"566>>@@AAA 4>>2C#D#DEEMMOOPPP 4>>2D#E#EFFNNPPQQQQQrc||||d|||d|||d|||j|||d|||ddSr)rrhr$r is_symlinkr2rr&s rtest_is_symlinkz1FakePathlibFileObjectPropertyTest.test_is_symlinkNs\ **,,, 4>>2E#F#FGGRRTTUUU 4>>+#>#>??JJLLMMM  $.."8"899DDFFGGG  $"566AACCDDD  $..1B"C"CDDOOQQRRR  $..1C"D"DEEPPRRSSSSSrc||j|j}||j}||jtjz| |jtj z| |j |j | |j d| |j|j| |tjt!|jdS)Nd)rrstatrr$rrhst_modeS_IFDIRr2S_IFREGrGst_inost_sizest_mtimeST_MTIMEint)r file_stat stat_results r test_statz+FakePathlibFileObjectPropertyTest.test_statWs **,,,GLL00 ii 34499;;  ,t|;<<<  +dl:;;; +Y-=>>> ,c222 -y/ABBB T]3S9K5L5LMMMMMrc||j|j}||j}||jtjz||jtj z| |j |j | |j || |j |j dSr)rrlstatrr$r2rrrS_IFLNKrGrrr)r expected_size link_statrs r check_lstatz-FakePathlibFileObjectPropertyTest.check_lstatcs **,,,GMM$"566 ii 344::<<   +dl:;;;  +dl:;;; +Y-=>>> ,m<<< -y/ABBBBBrrbcT|t|jdSr)rlenrr&s rtest_lstat_posixz2FakePathlibFileObjectPropertyTest.test_lstat_posixns& T^,,-----rrjcX||ddS)Nr)rrr&s rtest_lstat_windowsz4FakePathlibFileObjectPropertyTest.test_lstat_windowsrs. **,,, rzLinux specific behaviorcJ||j|j}||jtjdz|j|j}||jtj dzdS)Ni) check_linux_onlyrrrrGrrrrrrrrs r test_chmodz,FakePathlibFileObjectPropertyTest.test_chmodws GLL00  *DL5,@AAAGMM$"566  *DL5,@AAAAArc||j|j}|j|j}t |jdsb|t5| |j dddddS#1swxYwYdS| |j d| |j tjdz| |j dztjdzdS)Nlchmod$r)rrrrrrhasattrrr7r8r$rrGrrrrs r test_lchmodz-FakePathlibFileObjectPropertyTest.test_lchmods` **,,,GLL00 GMM$"566 t|X.. Q""#677 = = $-..55e<<< = = = = = = = = = = = = = = = = = = IId) * * 1 1% 8 8 8   Y. u0D E E E   Y.94<%;O P P P P Ps.B==CCr z+follow_symlinks argument new in Python 3.10c||j|j}|j|j}|jj|jjvstrd| t5| |jddddddS#1swxYwYdS| |jdd| |j tjdz| |j dztjdzdS)NrFfollow_symlinksrrr)rrrrrrchmodsupports_follow_symlinksr r7r8r$rGrrrrs rtest_chmod_no_followsymlinksz>FakePathlibFileObjectPropertyTest.test_chmod_no_followsymlinkss **,,,GLL00 GMM$"566 7= @ @ @G @""#677 S S $-..44UE4RRR S S S S S S S S S S S S S S S S S S IId) * * 0 0 0 N N N   Y. u0D E E E   Y.94<%;O P P P P Ps 0C  C C c :||dd||dd|j|d||||jj|d|||jj ddd||jj|dddS)NantoinedocsrP..) rrrrchdirassert_equal_pathsr$resolverealpathrWr&s r test_resolvez.FakePathlibFileObjectPropertyTest.test_resolvesD y&99:::  :>>???  dnnY//000  IIKK   ! ! IIdgl++DNN9,E,EFF G G     IIdgl''jAA B B J J L L IIdgl++DNN9j,Q,QRR S S     rc||d}|jj|d}|||j|dts:|tj ||j dS| d|| j dSNsome_dir some_filer)rrrr$rWrrr assert_raises_os_errorerrnoEACCESrrGr)rdir_pathrs r test_stat_file_in_unreadable_dirzBFakePathlibFileObjectPropertyTest.test_stat_file_in_unreadable_dirs >>*--GL%%h <<  ###  h&&&yy E  ' ' dii 6J6J6O P P P P P   Q ) 4 4 9 9 ; ; C D D D D DrcF||d}|jj|d}|||j|d||}ts(| tj t|dStt|d}||ddSr)rrrr$rWrriterdirr rrrliststrr2endswith)rrritr$s rtest_iterdir_in_unreadable_dirz@FakePathlibFileObjectPropertyTest.test_iterdir_in_unreadable_dirs >>*--GL%%h <<  ###  h&&& YYx ( ( * *yy 8  ' ' dB ? ? ? ? ?tBxx{##D OODMM+66 7 7 7 7 7rc||dddd}|||dS)Nz/pathtofilezthis can not exist)r$rrGr r:s rtest_resolve_nonexisting_filez?FakePathlibFileObjectPropertyTest.test_resolve_nonexisting_filesJyyv?STTUU t||~~.....rcH|d}|||j|||j||jj|dS)Nr)rrrr r r$cwdr)rrs rtest_cwdz*FakePathlibFileObjectPropertyTest.test_cwds>>&)) !!!  h  IMMOOTYYtw|'<'> #9::AACCDDD 4>>&&&#I#IJJQQSSTTTTTrcX||d|t5||dddddn #1swxYwY||ddd||jj |dddS)Nr>bar.txtw) rrr7OSErrorr$r%closer2rrr&s r test_openz*FakePathlibPathFileOperationTest.test_opens' u--...   w ' ' ? ? IIdnnUI66 7 7 < < > > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? $.. 223388==CCEEE  ++DNN5),L,LMMNNNNNsrrrr$rG read_textrrs rtest_read_textz/FakePathlibPathFileOperationTest.test_read_textsl  44uEEEIIdnn[99::  ,,..66666r)r z%is_junction method new in Python 3.12c||dd||d}||dSr@)rrr$rh is_junctionrDs rtest_is_junctionz1FakePathlibPathFileOperationTest.test_is_junctionsl  44uEEEIIdnn[99::  ..0011111rc||ddd||d}||dddS)NrAu ерундаcyrillic)rencodingrLrBrDs rtest_read_text_with_encodingz=FakePathlibPathFileOperationTest.test_read_text_with_encoding s~  NN; ' '.:    IIdnn[99::  ,,j,AA>RRRRRrc.|d}||}|td||jj|||ddS)NrAr>)rr$ write_textrr2rrcheck_contentsr path_namers rtest_write_textz0FakePathlibPathFileOperationTest.test_write_texts~NN;// IIi(( SZZ(((  ++I66777 Iu-----rc>|d}||}|dd||jj|||dddS)NrAuανοησίεςgreekrM)rr$rPr2rrrQencoderRs rtest_write_text_with_encodingz>FakePathlibPathFileOperationTest.test_write_text_with_encodingsNN;// IIi(( /'BBB  ++I66777 I'9'@'@'I'IJJJJJrrz#newline argument new in Python 3.10c||d}|dd||d|dd||d|dd||d|dd ||d dS) Nrz1 2 3 4rQ)newlines1 2 3 4 z s 1 2 3 4 s1 2 3 4)r$rrPrQr:s rtest_write_with_newline_argz?????rcl|dd}||d|dd}|||||jj|||ddS)Nr>r:rrbaz.txt)rrr$renamerhrrrQ)r file_name new_file_names r test_renamez,FakePathlibPathFileOperationTest.test_rename;sNN5)44  V444ui88  )##M222 ,,Y77888 M622222rc2||ddd||ddd||dd|dd||jj|dd||ddddS)Nr>r:rrr?zold.txtreplaced)rrr$r.rhrrrQr&s r test_replacez-FakePathlibPathFileOperationTest.test_replaceCs y99FKKK y99JOOO $.. 2233;; NN5) , ,    ,,T^^E9-M-MNNOOO DNN5)<r:rr)rrr2rr$runlinkrhrDs r test_unlinkz,FakePathlibPathFileOperationTest.test_unlinkLsNN5)44  V444  ++I66777 )##%%% ,,Y7788888rc||d|dd}||d||d||j|jtj dz|j |ddS)Nr>r:r)moderQr) rrr$touchrQr2rrrrr)rris rtest_touch_non_existingz8FakePathlibPathFileOperationTest.test_touch_non_existingSs u--...NN5)44  )"""... Ir***  Y//79MNNN  ie ,,,,,rc,|dd}||d||}|tj|jd|||ddS)Nr>r:rrFexist_ok)rrr$rrEEXISTrtrQ)rrirs rtest_touch_existingz4FakePathlibPathFileOperationTest.test_touch_existing[sNN5)44  V444IIi((  ##EL)/E#RRR Iv.....rc 2|dd}|||dd}|||t5||dd|dddddn #1swxYwY||}|dd}|t5||dddn #1swxYwY|t5|||dddn #1swxYwY||||||||||dddd||||dddddS)Nr>r:rgotherz other.txtr )rrr7r<r$samefilerhr2)rri file_name2r$ other_names r test_samefilez.FakePathlibPathFileOperationTest.test_samefilecsNN5)44  ###^^E955  $$$   w ' '   IIdnnUG44 5 5 > >uk22                  yy##^^E;77   w ' ' & & MM* % % % & & & & & & & & & & & & & & &   w ' ' 1 1 MM$))J// 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 z22333 tyy'<'<==>>>  dnnUD%&S&STTUUU  MM$))DNN5$y$Q$QRR S S     s71ACCCEEE%)FF!Fc||dd}|||d}||}||||jj|||dS)Nr>r: link_to_bar) rrrr$ symlink_tor2rrrrri link_namer$s rtest_symlink_toz0FakePathlibPathFileOperationTest.test_symlink_toys **,,,NN5)44  ###NN=11 yy##  """  ++I66777 ))*****rrzlink_to new in Python 3.8zlink_to removed in Python 3.12c||dd}|||d|j|j|d}||}||| |jj || | |d|j|jdSNr>r:rTrrU) rrrrGrrst_nlinkr$link_tor2rrhrrs r test_link_toz-FakePathlibPathFileOperationTest.test_link_tos **,,,NN5)44  ### DGLL33<===NN=11 yy## Y  ++I66777 **+++ DGLL33<=====rzhardlink_to new in Python 3.10c||dd}|||d|j|j||d}||}||| |jj || | |d|j|jdSr) rrrrGrrrr$ hardlink_tor2rrhr)rri link_pathr$s rtest_hardlink_toz1FakePathlibPathFileOperationTest.test_hardlink_tos **,,,NN5)44  ### DGLL33<===IIdnn];;<< yy##d###  ++I66777 **+++ DGLL33<=====rrzreadlink new in Python 3.9cR||ddd}|d}|||||}||||dSNr>r?r@tarJAY)rrrr$r readlink)rrtargetr$s r test_readlinkz.FakePathlibPathFileOperationTest.test_readlinks **,,,NN5%77 )) Iv...yy##  61B1BCCCCCrc|dd}|tj||j||d||jj||tj ||jdS)Nr>r?T)r`) rrrENOENTr$mkdirr2rrryrdir_names r test_mkdirz+FakePathlibPathFileOperationTest.test_mkdirs>>%// ##EL$))H2E2E2KLLL (!!$!///  ++H55666 ##EL$))H2E2E2KLLLLLrc|dd}||||d|jj|d}|||tj ||jddS)Nr>r?Trwr@) rrr$rrrWrrrry)rrris rtest_mkdir_exist_okz4FakePathlibPathFileOperationTest.test_mkdir_exist_oks>>%// !!! (!!4!000GL%%h66  ### ## L$))I..4t $     rcL|dd}||||||jj|||jj|d||dd| t5||ddddn #1swxYwY||jj|ddSNr>r?r@) rrr$rmdirrhrrr2rr7r<rs r test_rmdirz+FakePathlibPathFileOperationTest.test_rmdirs>>%// !!! (!!### ,,X66777  ++DNN5,A,ABBCCC u55666   w ' ' 5 5 IIdnnU++ , , 2 2 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5  ++DNN5,A,ABBCCCCCs ;EEEc R||ddd||ddd||ddd||dd}d|D}|dt ||||ddd|dS)Nr>r?file1file2file3cg|]}|Sr(r(.0entrys r zAFakePathlibPathFileOperationTest.test_iterdir..s666eE666rr)rrr$rrGrassertIn)rr$rs r test_iterdirz-FakePathlibPathFileOperationTest.test_iterdirs ug>>??? ug>>??? ug>>???yyu556666t||~~666 CMM*** diiueW E EFFQQQQQrc ||dd||dd||dd||dd||d}|t |d||dd||ddgdS)Nr>rPz all_tests.py README.mdz setup.pycrrrr$rGsortedglobr:s r test_globz*FakePathlibPathFileOperationTest.test_globs z::;;; ~>>??? {;;<<< {;;<<<yy..//  499V$$ % % $..??@@ $.. ;;<<      rWindows specific testc ||dd||dd||dd||dd||d}|t |d||dd||dd||ddgdSNr>rPz all_tests.PYrz example.Pyrrr:s rtest_glob_case_windowsz7FakePathlibPathFileOperationTest.test_glob_case_windowss< z::;;; ~>>??? {;;<<< |<<===yy..//  499V$$ % % $..??@@ $.. ==>> $.. ;;<<      rzPosix specific testc |||dd||dd||dd||dd||d}|t |d||ddgdSr)rrrr$rGrrr:s rtest_glob_case_posixz5FakePathlibPathFileOperationTest.test_glob_case_posixs  z::;;; ~>>??? {;;<<< |<<===yy..//  499V$$ % % YYt~~eZ88 9 9 :     rN)$r)r*r+rrr>rErmrnr,rrIrNrTrXr]rbrerkrnrqrurzrrrrrrrrrrr.rrr(rrr7r7s?? U U UOOO777 X_ 7"/22 2 SSS...KKKX_S%/1VWW 3 3XW 3JJJ @@@333JJJ999---///   ,+++X_S%.0KLLX_S%02RSS > >TSML >X_S%/1QRR > >SR >X_S%.0LMMDDNMDMMM    D D DRRR    X_^%<==   >=  X_Z!677   87    rr7ceZdZdZdS) RealPathlibPathFileOperationTestcdSrrr(r&s rrz,RealPathlibPathFileOperationTest.use_real_fsrsrNrtr(rrrrrurrc\eZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZe j!e"o e#j$dkdd Z%e j!e"o e#j$dkdd!Z&d"Z'd#Z(d$Z)d%Z*d&Z+d'Z,d(Z-e j!e#j$d)kd*d+Z.d,Z/d-Z0e j!e#j1d.kd/d0Z2e j!e#j1d.kd/d1Z3d2Z4d3S)4!FakePathlibUsageInOsFunctionsTestzTest that many os / os.path functions accept a path-like object since Python 3.6. The functionality of these functions is tested elsewhere, we just check that they accept a fake path object as an argument. c d}d}|jj||}|||jj||||||jj||||||jj||||dSNr>r?)rr$rWrG)rdir1dir2dirs r test_joinz+FakePathlibUsageInOsFunctionsTest.test_joinsgld++ dgl// $FFGGG dgl//diiooFFGGG dgl// $4QQRRRRRrc|ddd}||jj||jj||dSNFooBarBaz)rrGrr$normcaserrs r test_normcasez/FakePathlibUsageInOsFunctionsTest.test_normcase sl~~eUE22  GL ! !$ ' ')>)>tyy)O)O     rc|dddd}||jj||jj||dSNr>r?r r@)rrGrr$normpathrs r test_normpathz/FakePathlibUsageInOsFunctionsTest.test_normpathn~~eUD%88  GL ! !$ ' ')>)>tyy)O)O     rc|dddd}||jj||jj||dSr)rrGrr$rrs r test_realpathz/FakePathlibUsageInOsFunctionsTest.test_realpathrrc r|ddd}|ddd}|jj||}|||jj||||||jj||||||jj||||dS)Nr$r!r>r?)rrr$relpathrG)rpath_foopath_barrel_paths r test_relpathz.FakePathlibUsageInOsFunctionsTest.test_relpaths>>&$66>>&$667<''(;; 47<#7#7 (8K8KX#V#VWWW 47<#7#7$))HBUBU#V#VWWW   GL 8!4!4dii6I6I J J     rc|ddd}||jj||jj||dSr)rrGrr$splitrs r test_splitz,FakePathlibUsageInOsFunctionsTest.test_split)sb~~eUE22 ++D1147<3E3EdiiPToo3V3VWWWWWrc|dddd}||jj||jj||dS)NzC:rrr)rrGrr$ splitdrivers rtest_splitdrivez1FakePathlibUsageInOsFunctionsTest.test_splitdrive-so~~dE5%88  GL # #D ) ) GL # #DIIdOO 4 4     rc|dddd}||jj||jj||dSr)rrGrr$abspathrs r test_abspathz.FakePathlibUsageInOsFunctionsTest.test_abspath4n~~eUD%88  GL  & & (<()rr$rWrGr,rs rr/z1FakePathlibUsageInOsFunctionsTest.test_expanduserFsqw|  e,,  GL # #D ) ) GL # #DIIdOO 4 4     rcb||dd}|j|}d|_||jj||jj||dS)Nr>bar1.txt) skip_real_fsrrr _st_mtimerGrr$getmtimerrpath_objs r test_getmtimez/FakePathlibUsageInOsFunctionsTest.test_getmtimeMs ~~eZ00?..t44  GL ! !$ ' ')>)>tyy)O)O     rcb||dd}|j|}d|_||jj||jj||dS)Nr>r*) rrrrst_ctimerGrr$getctimers r test_getctimez/FakePathlibUsageInOsFunctionsTest.test_getctimeV ~~eZ00?..t44  GL ! !$ ' ')>)>tyy)O)O     rcb||dd}|j|}d|_||jj||jj||dS)Nr>r ) rrrrst_atimerGrr$getatimers r test_getatimez/FakePathlibUsageInOsFunctionsTest.test_getatime_rrc(|ddd}||d||jj||jj||dSNr>r?r@1234567r)rrrGrr$getsizer:s r test_getsizez.FakePathlibUsageInOsFunctionsTest.test_getsizehs~~eUE22  222  GL  & & (<(r?r@r)permrr:s rtest_isfile_not_readablez:FakePathlibUsageInOsFunctionsTest.test_isfile_not_readablezs~~eUE22 A&&&  GL   % %tw|':':499T??'K'K     rc$|ddd}||||jj||jj||dSr)rrrGrr$islinkr:s r test_islinkz-FakePathlibUsageInOsFunctionsTest.test_islinkr rc$|ddd}||||jj||jj||dSr)rrrGrr$isdirr:s r test_isdirz,FakePathlibUsageInOsFunctionsTest.test_isdirsv~~eUE22  ++D1147<3E3EdiiPToo3V3VWWWWWrc|jjj}||jj||jj||dSr)rr$rVrGismountr:s r test_ismountz.FakePathlibUsageInOsFunctionsTest.test_ismountscw|  GL  & & (<(|dd}||||dz||j||j||dS)Nr>r?rg)rrrrGrlistdirr$r:s r test_listdirz.FakePathlibUsageInOsFunctionsTest.test_listdirs~~eU++   )*** .. $0P0PQQQQQrc|d}|j||||jj|dS)Nr>)rrrr$r2rr:s rrz,FakePathlibUsageInOsFunctionsTest.test_mkdirs[~~e$$  diioo&&&  ++D1122222rc|dd}|j||||jj|dSr)rrmakedirsr$r2rr:s r test_makedirsz/FakePathlibUsageInOsFunctionsTest.test_makedirss_~~eU++ 4)))  ++D1122222rrzQos.readlink does not to support path-like objects under Windows before Python 3.8c4||ddd}|d}|||||j|||dSrrrrr rrr$rrrs rrz/FakePathlibUsageInOsFunctionsTest.test_readlinks **,,,NN5%77 )) Iv...  0 091E1E F FOOOOOrc4||ddd}|d}|||||j|||dS)NsfoosbarsbazstarJAYr/r0s rtest_readlink_bytesz5FakePathlibUsageInOsFunctionsTest.test_readlink_bytess **,,,NN666::  ** Iv...  0 091E1E F FOOOOOrc|d}|||j||||jj|dS)Ntest.txt)rrrremover$rhrr:s r test_removez-FakePathlibUsageInOsFunctionsTest.test_removesq~~j))  tyy''' ,,T2233333rc*|d}|d}|||j|||||jj||j||||||jj|dSNz test1.txtz test2.txt)rrrrhr$r2rrpath1path2s rrkz-FakePathlibUsageInOsFunctionsTest.test_renames{++{++  tyy''///  ++E22333 tyy''5)9)9:::  ++E2233333rc*|d}|d}|||j|||||jj||j||||||jj|dSr8)rrrr.r$r2rr9s rrnz.FakePathlibUsageInOsFunctionsTest.test_replaces{++{++   %((%000  ++E22333  %(($))E*:*:;;;  ++E2233333rc|dd}|||j||||jj|dSr)rrrrr$rhrr:s rrz,FakePathlibUsageInOsFunctionsTest.test_rmdirsq~~eU++   diioo&&& ,,T2233333rcv|dd}||||jj|dd|j||D}|dt|dS)Nxyzzyplughr4cg|]}|Sr(r(rs rrzBFakePathlibUsageInOsFunctionsTest.test_scandir..sPPPuPPPrrT) rrrrr$rWscandirrGr)r directory dir_entriess r test_scandirz.FakePathlibUsageInOsFunctionsTest.test_scandirsNN7G44   """ **9jAABBBPP$'//$))I:N:N*O*OPPP  C ,,-----rc||d}|d}|||j|||||jj||j||j||||||jj|dS)Nr!r#) rrrrsymlinkr$r2rr5)rrrs r test_symlinkz.FakePathlibUsageInOsFunctionsTest.test_symlinks **,,,NN<00 NN6**  ###  ),,i888  ++I66777 y!!!  ),,dii .B.BCCC  ++I6677777rc|ddd}||d||j|||dSr)rrrGrrr$r:s rrz+FakePathlibUsageInOsFunctionsTest.test_statsp~~eUE22  222 d++TYYt__-A-A-C-CDDDDDrrzNew in Python 3.10c||d}d}||jj||}||jj|d}d}|||||||t|| dtj |t|| dtj dS) Nr>r?r#rrTrF) rrr$rrWrrrGrrST_SIZE)rrC base_namerrrs rtest_stat_follow_symlinksz;FakePathlibUsageInOsFunctionsTest.test_stat_follow_symlinkss$ NN5))  IIdgl// 9EEFF IIdgl// 6BBCC  X666 Iy111  MM9>>$>?? M      NNINN5NAA$,O     rc\|d}||d|j||d|j|}|d|j|d|jdS)Nrrr)rTrU)timesrTrU) rrrutimer$rrGrrrr$sts r test_utimez,FakePathlibUsageInOsFunctionsTest.test_utime%s~~k** ///  diiooV 444 W\\$   BK((( BK(((((rc&|d}||d|j||d|j|}|d|jdS)Nr test_testr)length)rrrtruncater$rrGrrQs r test_truncatez/FakePathlibUsageInOsFunctionsTest.test_truncate-s~~k**  444 4333 W\\$   BJ'''''rr z!no pwd and grp modules in WindowscB|d}||||||||dSNr)rrr2r$ownergroupr:s rtest_owner_and_group_posixz.fake_getpwuid=s.byy(1BCC &/ #""NrcN|dkrtdd}d|_|St)Nr]zgr_name, gr_gidNewGroup)rgr_namerd)re group_structs r fake_getgrgidzUFakePathlibUsageInOsFunctionsTest.test_changed_owner_and_group..fake_getgrgidDs.axx)'3DEE '1 $##Nrrrriz pwd.getpwuidz grp.getgrgidrbrj) rrrrchownrpatchrGr$r\r])rrgrmr$s rtest_changed_owner_and_groupz>FakePathlibUsageInOsFunctionsTest.test_changed_owner_and_group;s       ~~k**   dB""" Z 6 6 F FNM:: F F  DIIdOO,A,A,C,CDDD  TYYt__-B-B-D-DEEE F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F F Fs76D' A7D D'D D'D D''D+.D+c||d}|||t5||dddn #1swxYwY|t5||ddddS#1swxYwYdSr[)rrrr7r8r$r\r]r:s rtest_owner_and_group_windowsz>FakePathlibUsageInOsFunctionsTest.test_owner_and_group_windowsTsT !!!~~k**    2 3 3 $ $ IIdOO ! ! # # # $ $ $ $ $ $ $ $ $ $ $ $ $ $ $   2 3 3 $ $ IIdOO ! ! # # # $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $s$(B  BB2(C''C+.C+N)5r)r*r+rrrrrrrrrrrr/rrrrrr r rrrrrrr&r)rr-rmrnr.r,rrr2r6rkrnrrErHrrMrSrYr-r^rprrr(rrrrs SSS            XXX                           XXX         XXX       OOO... 9 9 9RRR 333 333 X_0s'&0 * PP  PX_0s'&0 * PP  P444 444444444 ... 8 8 8EEE X_S%/1EFF  GF )))(((X_S\W,.QRR11SR1 X_S\W,.QRRFFSRF0$$$$$rrceZdZdZdS)!RealPathlibUsageInOsFunctionsTestcdSrrr(r&s rrz-RealPathlibUsageInOsFunctionsTest.use_real_fs_rsrNrtr(rrrtrt^rurrtc2eZdZdZdZdZdZdZdZdS) FakeFilesystemPathLikeObjectTestctjd|_tj|j|_t j|j|_dS)Nr=)path_separator) rFakeFilesystemrrFakePathlibModuler"r FakeOsModulerr&s rrz&FakeFilesystemPathLikeObjectTest.setUpdsC)8LLL#5doFF &t77rcjd}|j|}|j|||jj||tj |j |j tj zdSN foo/bar/baz) r"r#rrr2rr$rrGrrr)rdir_path_stringrs r!test_create_dir_with_pathlib_pathzBFakeFilesystemPathLikeObjectTest.test_create_dir_with_pathlib_pathis'<$$_55 ""8,,,  ++O<<===  L$',,77?$,N     rcjd}|j|}|j|||jj||tj |j |j tj zdSr~) r"r#rrr2rr$rrGrrr)rfile_path_stringrs r"test_create_file_with_pathlib_pathzCFakeFilesystemPathLikeObjectTest.test_create_file_with_pathlib_pathrs(L%%&677  ##I...  ++,<==>>>  L$',,'788@4<O     rc|jd}d}|j|}|j||||jj||tj |j |j tj zdS)Nrzfoo/link) r"r#rrr2rr$rrGrrrr)rrlink_path_stringrs r%test_create_symlink_with_pathlib_pathzFFakeFilesystemPathLikeObjectTest.test_create_symlink_with_pathlib_path{sL%%m44 %L%%&677  &&y)<<<  ,,-=>>???  L GMM* + + 3dl B     rctjt}|j|}|j||tj |jj }| |jj || tj|j |jtjzdSr)rr$r__file__r"r#r add_real_filer.rVr2rrGrrr)rreal_file_path_stringreal_file_pathfake_filepath_strings r-test_add_existing_real_file_with_pathlib_pathzNFakeFilesystemPathLikeObjectTest.test_add_existing_real_file_with_pathlib_paths " 9 9**+@AA %%n5554<>  **=999199"&$'+NN  ++,?@@AAA  L GLL, - - 5 D     rN) r)r*r+rrrrrrr(rrrwrwcsn888                     rrwc\eZdZddZejejdkddZdS)FakeFilesystemChmodTestreturnNc.|dSr)rr&s rrzFakeFilesystemChmodTest.setUps rr rctj|j_t jd}|j||jdd|| |jddd| t5| ddddS#1swxYwYdS)Nz/foo/barrrT)force_unix_mode) r WINDOWSr rr"r#rrr2rr7PermissionErrorr:s r'test_is_file_for_unreadable_dir_windowsz?FakeFilesystemChmodTest.test_is_file_for_unreadable_dir_windowss^ |J'' D!!!  fe$$$  '''  feT :::    / /   LLNNN                  s>C  C$'C$)rN) r)r*r+rrmrnr,r-rr(rrrrs[X_S\W,.EFF  GF   rr__main__rU) verbosity)+rrrr"rr,rm collectionsrrpyfakefsrrrrpyfakefs.fake_filesystemr pyfakefs.helpersr r pyfakefs.tests.test_utilsr r-r.rrr0rprnrwrrrrr4r7rrrtrwrr)mainr(rrrs  """"""UUUUUUUUUUUU++++++--------555555 \W $ 2;_0J9J9J9J9J9$7J9J9J9Z$A Z!<==1A1A1A1A1A-@1A1A>=1Ah-S J J J J J 1J J J Z5 CNCNCNCNCN(;CNCNCNL(I M M M M M ':M M M `'G ^$^$^$^$^$(;^$^$^$B (I 7 7 7 7 7 x'87 7 7 t6?$ zHMArtests/__pycache__/fake_stat_time_test.cpython-311.pyc000064400000125555150043321530016647 0ustar00 bgWdZddlZddlZddlmZddlmZeddZGddeZGd d eZ Gd d e Z Gd deZ Gdde Z GddeZ Gdde ZGddeZGddeZGddeZGddeZGddeZGdd eZed!krejdSdS)"z&Unit tests for file timestamp updates.N) namedtuple)RealFsTestCaseFileTimezst_ctime, st_atime, st_mtimeceZdZfdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZdZdZdZdZdZdZdZdZdZdZdZxZS)FakeStatTestBasect||d|_|jrdnd|_d|_dS)N some_fileg?g{Gz?)supersetUpcheck_linux_and_windows make_path file_pathis_macos sleep_timemodeself __class__s s/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/tests/fake_stat_time_test.pyr zFakeStatTestBase.setUpsX   $$&&& 44!%8##D c|j|}|rtj|jntjt |j|j|j S)N)st_ctimest_atimest_mtime) osstat use_real_fstimesleeprrrrr)rpathrs r stat_timezFakeStatTestBase.stat_time#sqw||D!!       Jt ' ' ' ' IKKK]]]    rcp|jr|||dS|||dSN) is_windows_fsassertLessEqual assertLessrtime1time2s rassertLessExceptWindowsz(FakeStatTestBase.assertLessExceptWindows1sC   *   . . . . . OOE5 ) ) ) ) )rcp|jr|||dS|||dSr$)r%r' assertEqualr(s rassertLessExceptPosixz&FakeStatTestBase.assertLessExceptPosix7sC   + OOE5 ) ) ) ) )   UE * * * * *rc>|5||j|j5||j}dddn #1swxYwY||j}||fcdddS#1swxYwYdSr$) mock_timeopenrrr"rcreatedcloseds ropen_close_new_filez$FakeStatTestBase.open_close_new_file=s ^^   # #4>4955 9 9..88 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9^^DN33FF?  # # # # # # # # # # # # # # # # # #s4!BA BA! !B$A! % BBBc|5||j|j5}||j}|d||j}dddn #1swxYwY||j}dddn #1swxYwY|||fSNfoo)r0r1rrr"write)rfr3writtenr4s ropen_write_close_new_filez*FakeStatTestBase.open_write_close_new_fileDs* ^^   4 44>4955 9..88..88 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9^^DN33F  4 4 4 4 4 4 4 4 4 4 4 4 4 4 4''s5!B=A B  B= B B=B B==CCc|5||j||j}||j|j5||j}dddn #1swxYwY||j}|||fcdddS#1swxYwYdSr$)r0 create_filerr"r1rrbeforeopenedr4s r open_closezFakeStatTestBase.open_closeNs< ^^   * *   T^ , , ,^^DN33F4>4955 8 877 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8^^DN33F66) * * * * * * * * * * * * * * * * * *s6AC*B CB CB !CC C c|5||j||j}||j|j5}||j}|d||j}dddn #1swxYwY||j}||||fcdddS#1swxYwYdSr7)r0r>rr"r1rr9)rr@r:rAr;r4s ropen_write_closez!FakeStatTestBase.open_write_closeYs_ ^^   3 3   T^ , , ,^^DN33F4>4955 977..88 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9^^DN33F67F2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3s7AC7*A C4 C7C C7C "C77C;>C;c|5||j||j}||j|j5}||j}|||j}dddn #1swxYwY||j}||||fcdddS#1swxYwYdSr$)r0r>rr"r1rflush)rr@r:rAflushedr4s ropen_flush_closez!FakeStatTestBase.open_flush_closefs] ^^   3 3   T^ , , ,^^DN33F4>4955 977 ..88 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9^^DN33F67F2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 37AC6*A B?3 C6?C C6C "C66C:=C:cf|5||j||j}||j|j5}||j}|d||j}|||j}dddn #1swxYwY||j}|||||fcdddS#1swxYwYdSr7)r0r>rr"r1rr9rF)rr@r:rAr;rGr4s ropen_write_flushz!FakeStatTestBase.open_write_flushss ^^   < <   T^ , , ,^^DN33F4>4955 977..88 ..88  9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 ^^DN33F67GV; < < < < < < < < < < < < < < < < < rr"r1readrF)rr@r:rArOrGr4s ropen_read_flushz FakeStatTestBase.open_read_flushs} ^^   9 9   T^ , , ,^^DN33F4>3// 9177~~dn55 ..88  9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 ^^DN33F64&8 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9s7AD %A7C( D (C, ,D /C, 0#D  D$'D$c|5||j|j5}||j}|||j}dddn #1swxYwY||j}|||fcdddS#1swxYwYdSr$)r0r1rrr"rO)rr:r3rOr4s ropen_read_close_new_filez)FakeStatTestBase.open_read_close_new_files2 ^^   ) )4>4955 6..88~~dn55 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6^^DN33FD&( ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) )s5!CA B ? C B CB !CCCc|5||j||j}||j|j5}||j}|||j}dddn #1swxYwY||j}||||fcdddS#1swxYwYdSr$)r0r>rr"r1rrO)rr@r:rArOr4s ropen_read_closez FakeStatTestBase.open_read_closes] ^^   0 0   T^ , , ,^^DN33F4>4955 677~~dn55 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6^^DN33F64/ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0rIc|\}}||j|j||j|j||j|jdS)zq When a file is created on opening and closed again, no timestamps are updated on close. N)r5r-rrrr2s rcheck_open_close_new_filez*FakeStatTestBase.check_open_close_new_filesp 2244 )6?;;; )6?;;; )6?;;;;;rc|\}}}||j|j||j|j||j|j||j|j||j|j||j|jdS)z When a file is created on opening, st_ctime is updated under Posix, and st_mtime is updated on close. N)r<r-rr+rr&rr')rr3r;r4s rcheck_open_write_close_new_filez0FakeStatTestBase.check_open_write_close_new_files $(#A#A#C#C & )7+;<<< $$W%5vGGG )7+;<<< W-v??? )7+;<<< (&/:::::rc|\}}}||j|j||j|j||j|j||j|j||j|j||j|jdS)z When an existing file is opened with 'w' or 'w+' mode, st_ctime (Posix only) and st_mtime are updated on open (truncating), but not on close. N)rBr+rr-r&rr'rr?s rcheck_open_close_w_modez(FakeStatTestBase.check_open_close_w_modes "&!2!2 $$V_foFFF &/::: V_fo>>> &/::: 999 &/:::::rc|\}}}||j|j||j|j||j|j||j|j||j|j||j|jdS)zz When an existing file is opened with any mode other than 'w' or 'w+', no timestamps are updated. N)rBr-rrrr?s rcheck_open_close_non_w_modez,FakeStatTestBase.check_open_close_non_w_modes "&!2!2 &/::: &/::: &/::: &/::: &/::: &/:::::rcx|\}}}}||j|j||j|j||j|j||j|j||j|j||j|j||j|j||j|j||j|jdS)z When an existing file is opened with 'w' or 'w+' mode and is then written to, st_ctime (Posix only) and st_mtime are updated on open (truncating) and again on close (flush), but not when written to. N)rDr+rr-r&rr'rrr@rAr;r4s rcheck_open_write_close_w_modez.FakeStatTestBase.check_open_write_close_w_modes +/*?*?*A*A' $$V_foFFF '*:;;; $$W%5vGGG V_fo>>> '*:;;; W-v??? 999 '*:;;; (&/:::::rcx|\}}}}||j|j||j|j||j|j||j|j||j|j||j|j||j|j||j|j||j|jdS)z When an existing file is opened with 'w' or 'w+' mode (truncating), st_ctime (Posix only) and st_mtime are updated. No updates are done on flush or close. N)rHr+rr-r&rr'rrr@rArGr4s rcheck_open_flush_close_w_modez.FakeStatTestBase.check_open_flush_close_w_modes +/*?*?*A*A' $$V_foFFF '*:;;; )6?;;; V_fo>>> '*:;;; )6?;;; 999 '*:;;; )6?;;;;;rcx|\}}}}||j|j||j|j||j|j||j|j||j|j||j|j||j|j||j|j||j|jdS)z When an existing file is opened with any mode other than 'w' or 'w+', flushed and closed, no timestamps are updated. N)rHr-rrrras r!check_open_flush_close_non_w_modez2FakeStatTestBase.check_open_flush_close_non_w_mode s +/*?*?*A*A' &/::: '*:;;; )6?;;; &/::: '*:;;; )6?;;; &/::: '*:;;; )6?;;;;;rcx|\}}}}||j|j||j|j||j|j||j|j||j|j||j|j||j|j||j|j||j|jdS)zo Reading from a file opened with 'r', 'r+', or 'a+' mode updates st_atime under Posix. N)rTr-rrr&rrr@rArOr4s r check_open_read_close_non_w_modez1FakeStatTestBase.check_open_read_close_non_w_modes (,';';'='=$f &/::: $-888 888 &/::: V_dm<<< 888 &/::: $-888 88888rc|\}}}||j|j||j|j||j|j||j|j||j|j||j|jdS)z| When a file is created with 'w+' or 'a+' mode and then read from, st_atime is updated under Posix. N)rRr-rr&rr)rr3rOr4s rcheck_open_read_close_new_filez/FakeStatTestBase.check_open_read_close_new_file1s !% = = ? ?v )4=999 888 W-t}=== 888 )4=999 88888rcx|\}}}}||j|j||j|j||j|j||j|j||j|j||j|j||j|j||j|j||j|jdS)z When an existing file is opened with 'a', 'a+' or 'r+' mode and is then written to, st_ctime (Posix only) and st_mtime are updated close (flush), but not on opening or when written to. N)rDr-rr+rr&rr'r^s r!check_open_write_close_non_w_modez2FakeStatTestBase.check_open_write_close_non_w_modeAs +/*?*?*A*A' &/::: '*:;;; $$W%5vGGG &/::: '*:;;; W-v??? &/::: '*:;;; (&/:::::rc:|\}}}}}||j|j||j|j||j|j||j|j||j|j||j|j||j|j||j|j||j|j||j|j||j|j||j|jdS)a When an existing file is opened with 'w' or 'w+' mode and is then written to, st_ctime (Posix only) and st_mtime are updated on open (truncating). Under Posix, st_mtime is updated on flush, under Windows, on close instead. N)rKr&rr-rr'rr+rr@rAr;rGr4s r#check_open_write_flush_close_w_modez4FakeStatTestBase.check_open_write_flush_close_w_modeUsh483H3H3J3J0& V_fo>>> W-w/?@@@ '*:;;; )6?;;; V_fo>>> '*:;;; W-w/?@@@ W-v??? 999 '*:;;; $$W%5w7GHHH W-v?????rc:|\}}}}}||j|j||j|j||j|j||j|j||j|j||j|j||j|j||j|j||j|j||j|j||j|j||j|jdS)z When an existing file is opened with 'a', 'a+' or 'r+' mode and is then written to, st_ctime and st_mtime are updated on flush under Posix. Under Windows, only st_mtime is updated on close instead. N)rKr-rr+rr&rrms r'check_open_write_flush_close_non_w_modez8FakeStatTestBase.check_open_write_flush_close_non_w_modemsj 483H3H3J3J0& &/::: '*:;;; $$W%5w7GHHH )6?;;; &/::: '*:;;; W-w/?@@@ W-v??? &/::: '*:;;; $$W%5w7GHHH W-v?????r)__name__ __module__ __qualname__r r"r+r.r5r<rBrDrHrKrPrRrTrVrXrZr\r_rbrdrgrirkrnrp __classcell__rs@rrrs         *** +++ ###((( * * * 3 3 3 3 3 3 < < < 9 9 9))) 0 0 0 < < <;;; ;;; ;;; ;;;(<<<(<<<&999&999 ;;;(@@@0@@@@@@@rrcHeZdZfdZdZdZdZdZdZdZ dZ xZ S) TestFakeModeWcdtt|d|_dSNw)r rwr rrs rr zTestFakeModeW.setUp* mT""((*** rc.|dSr$rVrs rtest_open_close_new_filez&TestFakeModeW.test_open_close_new_file &&(((((rc.|dSr$rXr~s rtest_open_write_close_new_filez,TestFakeModeW.test_open_write_close_new_file ,,.....rc.|dSr$rZr~s rtest_open_closezTestFakeModeW.test_open_close $$&&&&&rc.|dSr$r_r~s rtest_open_write_closez#TestFakeModeW.test_open_write_close **,,,,,rc.|dSr$rbr~s rtest_open_flush_closez#TestFakeModeW.test_open_flush_closerrc.|dSr$rnr~s rtest_open_write_flush_closez)TestFakeModeW.test_open_write_flush_close 0022222rc||jd5}|t5|dddn #1swxYwYddddS#1swxYwYdSryr1r assertRaisesOSErrorrOrr:s rtest_read_raiseszTestFakeModeW.test_read_raises YYt~s + + q""7++                                   4A0A A0A A0A A00A47A4 rqrrrsr rrrrrrrrtrus@rrwrws)))///'''------333rrwceZdZdZdS) TestRealModeWcdSNTr~s rrzTestRealModeW.use_real_fstrNrqrrrsrrrrrr#rrcNeZdZfdZdZdZdZdZdZdZ dZ d Z xZ S) TestFakeModeWPluscdtt|d|_dS)Nzw+)r rr rrs rr zTestFakeModeWPlus.setUp+ &&,,... rc.|dSr$r}r~s rrz*TestFakeModeWPlus.test_open_close_new_filerrc.|dSr$rr~s rrz0TestFakeModeWPlus.test_open_write_close_new_filerrc.|dSr$rir~s rtest_open_read_close_new_filez/TestFakeModeWPlus.test_open_read_close_new_file ++-----rc.|dSr$rr~s rrz!TestFakeModeWPlus.test_open_closerrc.|dSr$rr~s rrz'TestFakeModeWPlus.test_open_write_closerrcx|\}}}}||j|j||j|j||j|j||j|j||j|j||j|j||j|j||j|j||j|jdS)z When an existing file is opened with 'w+' mode and is then written to, st_ctime (Posix only) and st_mtime are updated on open (truncating) and again on close (flush). Under Posix, st_atime is updated on read. N)rTr+rr-r&rr'rrfs rtest_open_read_closez&TestFakeModeWPlus.test_open_read_closes (,';';'='=$f $$V_foFFF $-888 888 V_fo>>> V_dm<<< 888 999 $-888 88888rc.|dSr$rr~s rrz'TestFakeModeWPlus.test_open_flush_closerrc.|dSr$rr~s rrz-TestFakeModeWPlus.test_open_write_flush_closerr rqrrrsr rrrrrrrrrtrus@rrrs)))///...'''---999*---3333333rrceZdZdZdS)TestRealModeWPluscdSrrr~s rrzTestRealModeWPlus.use_real_fsrrNrrrrrrrrrcHeZdZfdZdZdZdZdZdZdZ dZ xZ S) TestFakeModeAcdtt|d|_dSNa)r rr rrs rr zTestFakeModeA.setUpr{rc.|dSr$r}r~s rrz&TestFakeModeA.test_open_close_new_filerrc.|dSr$rr~s rrz,TestFakeModeA.test_open_write_close_new_filerrc.|dSr$r\r~s rrzTestFakeModeA.test_open_close ((*****rc.|dSr$rkr~s rrz#TestFakeModeA.test_open_write_close ..00000rc.|dSr$rdr~s rrz#TestFakeModeA.test_open_flush_closerrc.|dSr$rpr~s rrz)TestFakeModeA.test_open_write_flush_close 4466666rc||jd5}|t5|dddn #1swxYwYddddS#1swxYwYdSrrrs rrzTestFakeModeA.test_read_raisesrrrrus@rrrs)))///+++111111777rrceZdZdZdS) TestRealModeAcdSrrr~s rrzTestRealModeA.use_real_fsrrNrrrrrrrrrcNeZdZfdZdZdZdZdZdZdZ dZ d Z xZ S) TestFakeModeAPluscdtt|d|_dS)Nza+)r rr rrs rr zTestFakeModeAPlus.setUprrc.|dSr$r}r~s rrz*TestFakeModeAPlus.test_open_close_new_filerrc.|dSr$rr~s rrz0TestFakeModeAPlus.test_open_write_close_new_filerrc.|dSr$rr~s rrz/TestFakeModeAPlus.test_open_read_close_new_file rrc.|dSr$rr~s rrz!TestFakeModeAPlus.test_open_close rrc.|dSr$rr~s rrz'TestFakeModeAPlus.test_open_write_closerrc.|dSr$rgr~s rrz&TestFakeModeAPlus.test_open_read_close --/////rc.|dSr$rr~s rrz'TestFakeModeAPlus.test_open_flush_closerrc.|dSr$rr~s rrz-TestFakeModeAPlus.test_open_write_flush_closerrrrus@rrrs)))///...+++1110001117777777rrceZdZdZdS)TestRealModeAPluscdSrrr~s rrzTestRealModeAPlus.use_real_fsrrNrrrrrrrrrc<eZdZfdZdZdZdZdZdZxZ S) TestFakeModeRcdtt|d|_dSrM)r rr rrs rr zTestFakeModeR.setUp"r{rc.|dSr$rr~s rrzTestFakeModeR.test_open_close&rrc.|dSr$rr~s rrz"TestFakeModeR.test_open_read_close)rrc.|dSr$rr~s rrz#TestFakeModeR.test_open_flush_close,rrc:|\}}}}}||j|j||j|j||j|j||j|j||j|j||j|j||j|j||j|j||j|j||j|j||j|j||j|jdS)z When an existing file is opened with 'r' mode, read, flushed and closed, st_atime is updated after reading under Posix. N)rPr-rrr&r)rr@rArOrGr4s rtest_open_read_flush_closez(TestFakeModeR.test_open_read_flush_close/sd 150D0D0F0F-gv &/::: $-888 (8999 )6?;;; &/::: V_dm<<< (8999 )6?;;; &/::: $-888 (8999 )6?;;;;;rc|t5||jd5 dddn #1swxYwYddddS#1swxYwYdSrMrrr1rr~s rtest_open_not_existing_raisesz+TestFakeModeR.test_open_not_existing_raisesEs   w ' '  4>3//                                   3AA AA A A AA!$A!) rqrrrsr rrrrrrtrus@rrr!s+++000111<<<,rrceZdZdZdS) TestRealModeRcdSrrr~s rrzTestRealModeR.use_real_fsLrrNrrrrrrKrrrcBeZdZfdZdZdZdZdZdZdZ xZ S)TestFakeModeRPluscdtt|d|_dSNzr+)r rr rrs rr zTestFakeModeRPlus.setUpQrrc.|dSr$rr~s rrz!TestFakeModeRPlus.test_open_closeUrrc.|dSr$rr~s rrz'TestFakeModeRPlus.test_open_write_closeXrrc.|dSr$rr~s rrz&TestFakeModeRPlus.test_open_read_close[rrc.|dSr$rr~s rrz'TestFakeModeRPlus.test_open_flush_close^rrc.|dSr$rr~s rrz-TestFakeModeRPlus.test_open_write_flush_closearrc|t5||jd5 dddn #1swxYwYddddS#1swxYwYdSrrr~s rrz/TestFakeModeRPlus.test_open_not_existing_raisesds   w ' '  4>400                                   r) rqrrrsr rrrrrrrtrus@rrrPs+++111000111777rrceZdZdZdS)TestRealModeRPluscdSrrr~s rrzTestRealModeRPlus.use_real_fskrrNrrrrrrjrrr__main__)__doc__runittest collectionsrpyfakefs.tests.test_utilsrrrrwrrrrrrrrrrrrqmainrrrrs-, """"""444444 :j"@ A Ak@k@k@k@k@~k@k@k@\ $:M -3-3-3-3-3(-3-3-3`) $:M 77777(777<) '''''$'''TM (4)  zHMOOOOOrtests/__pycache__/fake_tempfile_test.cpython-311.pyc000064400000022355150043321530016455 0ustar00 bgVdZddlZddlZddlZddlZddlmZGddejZe dkrej dSdS)zTests that ensure that the `tempfile` module works with `fake_filesystem` if using `Patcher` (via `fake_filesystem_unittest`). N)fake_filesystem_unittestcHeZdZdZdZdZdZdZdZdZ dZ d Z d Z d S) FakeTempfileModuleTestz5Test the 'tempfile' module with the fake file system.c.|dSN) setUpPyfakefs)selfs r/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/tests/fake_tempfile_test.pysetUpzFakeTempfileModuleTest.setUps c\tj}||j|j||t5|j|jddddS#1swxYwYdSr) tempfileNamedTemporaryFile assertTruefs get_objectnameclose assertRaisesOSError)r objs r test_named_temporary_filez0FakeTempfileModuleTest.test_named_temporary_file!s)++ **3844555   w ' ' ) ) G  sx ( ( ( ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) )s4 B!!B%(B%ctjd}|d||j|j}|j}|d|tjdd}|d||j|j}|d|jdS)NF)deletesfoofoow)moder) rrwriterrrrcontents assertEqual)r rfile_objrs r #test_named_temporary_file_no_deletez:FakeTempfileModuleTest.test_named_temporary_file_no_delete(s)777 & 7%%ch//$ ))))s5AAA % 7%%ch//  122222r c:t|jj}tj}|dt|||dtj tj d|||d||j |d|jj rdnd}||j|djt j|ztj|dd}||d|dS)Ntmprzw+b)lenr open_filesrmkstempr r startswithospathjoin gettempdirexists is_windows_fsrst_modestatS_IFREGfdopenfileno)r next_fd temporaryrfhs r test_mkstempz#FakeTempfileModuleTest.test_mkstemp5sGdg())$&&  C NN+++  aL # #BGLL1D1F1F$N$N O O    )A,/// y|44555-8uu5 ++IaL99A4r&r'r()rrrr+r create_dirr)r*r rr,r-r.r/ root_dir_namer1r2rr3r4r5)r r8r9rs r test_mkstemp_dirz'FakeTempfileModuleTest.test_mkstemp_dirCs  w ' ' ) )   ( ( ( ( ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) 6"""dg())$000  C NN+++ )A,///  aL # #BGLL1Fu$U$U V V    y|44555-8uu5 ++IaL99A4RSSSSSr cbtj5}||||j|||j|jtj dzddddS#1swxYwYdSrC) rTemporaryDirectoryrrr1r rr3r4rE)r tmpdirs r test_temporary_directoryz/FakeTempfileModuleTest.test_temporary_directory[s  ( * * Wf OOF # # # OODGNN622 3 3 3   TW//77?PUAU V V V W W W W W W W W W W W W W W W W W WsBB$$B(+B(ctj5}|d|d|d|ddddS#1swxYwYdS)Ntestr)r TemporaryFilerseekr readr fs r test_temporary_filez*FakeTempfileModuleTest.test_temporary_fileas  # % % 0 GGG    FF1III   Waffhh / / / 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0sAA44A8;A8c|t5tjddddn #1swxYwYt jdtj5}|d|d|d| ddddS#1swxYwYdS)Nz/parentr=rMr) rFileNotFoundErrorrrNr-mkdirrrOr rPrQs r test_temporay_file_with_dirz2FakeTempfileModuleTest.test_temporay_file_with_dirgs?   0 1 1 2 2  "y 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2   # % % 0 GGG    FF1III   Waffhh / / / 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0s"=AA/ACCCN) __name__ __module__ __qualname____doc__r rr"r;rArGrKrSrWr r rrs??))) 3 3 3 4 4 4XXX$TTT WWW 000 00000r r__main__) r[r-r4runittestpyfakefsrTestCaserrXmainr\r r rbs ------S0S0S0S0S05>S0S0S0l zHMOOOOOr tests/__pycache__/mox3_stubout_test.cpython-311.pyc000064400000024451150043321530016334 0ustar00 bgdZddlZddlZddlZddlZddlmZddlmZddlm Z GddZ Gdd Z Gd d ej Z Gd d ejZedkrejdSdS)zUnit tests for mox3_stubout.N)path) mox3_stubout)mox3_stubout_examplec.eZdZeZedZdZdS) NoPanicMathcdS)N*)_xs q/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/tests/mox3_stubout_test.pyfabszNoPanicMath.fabssrc,t|j|Sz2Forwards any unfaked calls to the standard module.)getattr real_mathselfnames r __getattr__zNoPanicMath.__getattr__ t~t,,,rN)__name__ __module__ __qualname__mathr staticmethodr rr rr rrsAI\-----rrc.eZdZeZedZdZdS) ExistingPathcdSNTr )_paths r existszExistingPath.exists(strc,t|j|Sr)r real_pathrs r rzExistingPath.__getattr__,rrN)rrrrr$rr"rr rr rr%sAI\-----rrc$eZdZedZdS) GroundhogDatec.tjdddS)N)datetimedate)clss r todayzGroundhogDate.today2s}T1a(((rN)rrr classmethodr-r rr r&r&1s-))[)))rr&cTeZdZfdZdZdZdZdZdZdZ dZ d Z d Z xZ S) StubOutForTestingTestctt|tj|_dS)N)superr0setUprStubOutForTestingstubber)r __class__s r r3zStubOutForTestingTest.setUp8s4 #T**00222#577 rctd}|tj||jt jdd|tj||j|tj|dS)Nnon_existing_pathr"cdSr r xs r zDStubOutForTestingTest.test_stubout_method_with_set..?sdr) assertFalsercheck_if_existsr5setosr assertTrue unset_allrr8s r test_stubout_method_with_setz2StubOutForTestingTest.test_stubout_method_with_set<s/ -=>OPPQQQ (NN;;; ,<=NOOPPP     -=>OPPQQQQQrc|tjjd|jt dt|tjt j ddd|j |tjjddS)Nr+r(r)) assertGreaterrtomorrowyearr5r?r*r& assertEqualr+rBrs r test_stubout_class_with_setz1StubOutForTestingTest.test_stubout_class_with_setDs /8::?FFF 6=999 -688(-aQR:S:STTT     /8::?FFFFFrct|dtjd|jtdt |dtjd|j|dtjddSN irr )rKrr r5r?rrBrLs r test_stubout_module_with_setz2StubOutForTestingTest.test_stubout_module_with_setMs 16s;;<<< -v{CCC 16s;;<<<     16s;;<<<<.\drrImath1) assertRaisesAttributeErrorr5r?r@rr*r&rrrLs r #test_set_raise_if_unknown_attributez9StubOutForTestingTest.test_set_raise_if_unknown_attributeVs   L  G  N       L           L         rc&d}|jtjdd|t j||j|t j|dS)Nr8r"cdSr r r:s r r<zJStubOutForTestingTest.test_stubout_method_with_smart_set..osDr) r5 smart_setr@rrArr>smart_unset_allr=rCs r "test_stubout_method_with_smart_setz8StubOutForTestingTest.test_stubout_method_with_smart_setms/ rw..AAA ,<=NOOPPP $$&&& -=>OPPQQQQQrcR|jtdt|t jtjddd|j| t jj ddS)Nr+r(r)rGrF) r5r\r*r&rKrrIr+r]rHrJrLs r !test_stubout_class_with_smart_setz7StubOutForTestingTest.test_stubout_class_with_smart_setts x??? -688(-aQR:S:STTT $$&&& /8::?FFFFFrct|dtjd|jtdt |dtjd|j|dtjddSrO)rKrr r5r\rr]rLs r "test_stubout_module_with_smart_setz8StubOutForTestingTest.test_stubout_module_with_smart_set{s 16s;;<<< 3V[III 16s;;<<< $$&&& 16s;;<<<<r5r\r@rrAr]rCs r %test_stubout_submodule_with_smart_setz;StubOutForTestingTest.test_stubout_submodule_with_smart_sets/ -=>OPPQQQ r6<888 ,<=NOOPPP $$&&& -=>OPPQQQQQrc4|t|jjtjdd|t|jjt dt|t|jjtdtdS)NrScdSr r r:s r r<zQStubOutForTestingTest.test_smart_set_raise_if_unknown_attribute..rUrrIrV) rWrXr5r\r@rr*r&rrrLs r )test_smart_set_raise_if_unknown_attributez?StubOutForTestingTest.test_smart_set_raise_if_unknown_attributes   L " G  N       L "          L "        r)rrrr3rDrMrQrYr^r`rbrdrg __classcell__)r6s@r r0r07s88888RRRGGG===   .RRRGGG===RRR       rr0__main__)__doc__r*rr@unittestrpyfakefsrpyfakefs.testsrrrr+r&TestCaser0rmainr rr rps?#" !!!!!!////// - - - - - - - - - - - - - - - -)))))HM))) k k k k k H-k k k \ zHMOOOOOrtests/__pycache__/patched_packages_test.cpython-311.pyc000064400000010511150043321530017117 0ustar00 bg dZddlZddlZddlZddlmZddlmZ ddlZ n #e $rdZ YnwxYw ddl Z n #e $rdZ YnwxYw ddl Z n #e $rdZ YnwxYwej eo ejdkdGddejZdS) zY Provides patches for some commonly used modules that enable them to work with pyfakefs. N)fake_filesystem_unittest)IS_PYPY)z&Has a problem with older PyPy versionscHeZdZdZedZdZeedZee dZ dSdSdS)TestPatchedPackagesc.|dS)N) setUpPyfakefs)selfs u/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/tests/patched_packages_test.pysetUpzTestPatchedPackages.setUp,s Ncd}|j|dtj|}|jgdksJdS)N /foo/bar.csvz1,2,3,4contents1234)fs create_filepdread_csvcolumnsallr pathdfs r test_read_csvz!TestPatchedPackages.test_read_csv1s]!D G  y  9 9 9T""BJ"6"6"66;;== = == = =rcd}|j|dtj|d}|jgdksJdS)Nrz1|2|3|4r|) delimiterr)rrr read_tablerrrs r test_read_tablez#TestPatchedPackages.test_read_table7sb!D G  y  9 9 9ts333BJ"6"6"66;;== = == = =rcpd}tjtjt}tj|dd}|j||tj |}|j gdk sJdS)N /foo/bar.xlsxfixtureszexcel_test.xlsx) target_path)r) osrdirnameabspath__file__joinr add_real_filer read_excelrr)r rsrc_pathr s r test_read_excelz#TestPatchedPackages.test_read_excel?s"Dwrwx'@'@AAHw||Hj:KLLH G ! !( ! = = =t$$BJ,,,.3355 5 55 5 5rcX|jdd}tjgdg}tj|5}||dddn #1swxYwYtj|}|jgdksJdS)Nz/foor()rr+r,r)z Unnamed: 0rr+r,r) r create_dirr DataFrame ExcelWriterto_excelr4rr)r rr writers r test_write_excelz$TestPatchedPackages.test_write_excelKs G  v & & &"D|||n--B%% $ F### $ $ $ $ $ $ $ $ $ $ $ $ $ $ $t$$BJ"<"<"<<AACC C CC C CsA**A.1A.) __name__ __module__ __qualname__r rr!r&xlrdr6openpyxlr=rr rr(s ~ > > >  > > >  ~$* 6 6 6 ~(. D D D D D~..rr)__doc__r.sysunittestpyfakefsrpyfakefs.helpersrpandasr ImportErrorrArBskipIf version_infoTestCaserrCrr rNsb ------$$$$$$ BBBKKKK DDDOOOOHHH ) 6)+S'D'D'D'D'D2;'D'D'D'D'Ds*!++4>>AAAtests/all_tests.py000064400000004706150043321530010255 0ustar00# Copyright 2009 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """A test suite that runs all tests for pyfakefs at once. Includes tests with external pathlib2 and scandir packages if installed.""" import sys import unittest from pyfakefs.tests import ( dynamic_patch_test, fake_stat_time_test, example_test, fake_filesystem_glob_test, fake_filesystem_shutil_test, fake_filesystem_test, fake_filesystem_unittest_test, fake_filesystem_vs_real_test, fake_open_test, fake_os_test, fake_pathlib_test, fake_tempfile_test, patched_packages_test, mox3_stubout_test, ) class AllTests(unittest.TestSuite): """A test suite that runs all tests for pyfakefs at once.""" def suite(self): # pylint: disable-msg=C6409 loader = unittest.defaultTestLoader self.addTests( [ loader.loadTestsFromModule(fake_filesystem_test), loader.loadTestsFromModule(fake_filesystem_glob_test), loader.loadTestsFromModule(fake_filesystem_shutil_test), loader.loadTestsFromModule(fake_os_test), loader.loadTestsFromModule(fake_stat_time_test), loader.loadTestsFromModule(fake_open_test), loader.loadTestsFromModule(fake_tempfile_test), loader.loadTestsFromModule(fake_filesystem_vs_real_test), loader.loadTestsFromModule(fake_filesystem_unittest_test), loader.loadTestsFromModule(example_test), loader.loadTestsFromModule(mox3_stubout_test), loader.loadTestsFromModule(dynamic_patch_test), loader.loadTestsFromModule(fake_pathlib_test), loader.loadTestsFromModule(patched_packages_test), ] ) return self if __name__ == "__main__": result = unittest.TextTestRunner(verbosity=2).run(AllTests().suite()) sys.exit(int(not result.wasSuccessful())) tests/all_tests_without_extra_packages.py000064400000002234150043321530015073 0ustar00# Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """A test suite that runs all tests for pyfakefs at once. Excludes tests using external scandir package.""" import sys import unittest from pyfakefs import extra_packages if extra_packages.use_scandir_package: extra_packages.use_scandir_package = False try: from os import scandir except ImportError: scandir = None extra_packages.scandir = scandir extra_packages.use_scandir = scandir from pyfakefs.tests.all_tests import AllTests # noqa: E402 if __name__ == "__main__": result = unittest.TextTestRunner(verbosity=2).run(AllTests().suite()) sys.exit(int(not result.wasSuccessful())) tests/dynamic_patch_test.py000064400000004055150043321530012122 0ustar00# Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """ Tests for patching modules loaded after `setUpPyfakefs()`. """ import pathlib import unittest from pyfakefs import fake_filesystem_unittest class TestPyfakefsUnittestBase(fake_filesystem_unittest.TestCase): def setUp(self): """Set up the fake file system""" self.setUpPyfakefs() class DynamicImportPatchTest(TestPyfakefsUnittestBase): def __init__(self, methodName="runTest"): super(DynamicImportPatchTest, self).__init__(methodName) def test_os_patch(self): import os os.mkdir("test") self.assertTrue(self.fs.exists("test")) self.assertTrue(os.path.exists("test")) def test_os_import_as_patch(self): import os as _os _os.mkdir("test") self.assertTrue(self.fs.exists("test")) self.assertTrue(_os.path.exists("test")) def test_os_path_patch(self): import os.path os.mkdir("test") self.assertTrue(self.fs.exists("test")) self.assertTrue(os.path.exists("test")) def test_shutil_patch(self): import shutil self.fs.set_disk_usage(100) self.assertEqual(100, shutil.disk_usage("/").total) def test_pathlib_path_patch(self): file_path = "test.txt" path = pathlib.Path(file_path) with path.open("w") as f: f.write("test") self.assertTrue(self.fs.exists(file_path)) file_object = self.fs.get_object(file_path) self.assertEqual("test", file_object.contents) if __name__ == "__main__": unittest.main() tests/example.py000064400000007612150043321530007715 0ustar00# Copyright 2014 Altera Corporation. All Rights Reserved. # Author: John McGehee # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """ Example module that is tested in :py:class`pyfakefs.example_test.TestExample`. This demonstrates the usage of the :py:class`pyfakefs.fake_filesystem_unittest.TestCase` base class. The modules related to file handling are bound to the respective fake modules: >>> os #doctest: +ELLIPSIS >>> os.path #doctest: +ELLIPSIS >>> shutil #doctest: +ELLIPSIS `open()` is an alias for `io.open()` and is bound to `FakeIoModule.open`. """ import glob import os import shutil try: import scandir has_scandir = True except ImportError: scandir = None has_scandir = False def create_file(path): """Create the specified file and add some content to it. Use the `open()` built in function. For example, the following file operations occur in the fake file system. In the real file system, we would not even have permission to write `/test`: >>> os.path.isdir('/test') False >>> os.mkdir('/test') >>> os.path.isdir('/test') True >>> os.path.exists('/test/file.txt') False >>> create_file('/test/file.txt') >>> os.path.exists('/test/file.txt') True >>> with open('/test/file.txt') as f: ... f.readlines() ["This is test file '/test/file.txt'.\\n", \ 'It was created using open().\\n'] """ with open(path, "w") as f: f.write("This is test file '{0}'.\n".format(path)) f.write("It was created using open().\n") def delete_file(path): """Delete the specified file. For example: >>> os.mkdir('/test') >>> os.path.exists('/test/file.txt') False >>> create_file('/test/file.txt') >>> os.path.exists('/test/file.txt') True >>> delete_file('/test/file.txt') >>> os.path.exists('/test/file.txt') False """ os.remove(path) def path_exists(path): """Return True if the specified file exists. For example: >>> path_exists('/test') False >>> os.mkdir('/test') >>> path_exists('/test') True >>> >>> path_exists('/test/file.txt') False >>> create_file('/test/file.txt') >>> path_exists('/test/file.txt') True """ return os.path.exists(path) def get_glob(glob_path): r"""Return the list of paths matching the specified glob expression. For example: >>> os.mkdir('/test') >>> create_file('/test/file1.txt') >>> create_file('/test/file2.txt') >>> file_names = sorted(get_glob('/test/file*.txt')) >>> >>> import sys >>> if sys.platform.startswith('win'): ... # Windows style path ... file_names == [r'/test\file1.txt', r'/test\file2.txt'] ... else: ... # UNIX style path ... file_names == ['/test/file1.txt', '/test/file2.txt'] True """ return glob.glob(glob_path) def rm_tree(path): """Delete the specified file hierarchy.""" shutil.rmtree(path) def scan_dir(path): """Return a list of directory entries for the given path.""" if has_scandir: return list(scandir.scandir(path)) return list(os.scandir(path)) def file_contents(path): """Return the contents of the given path as byte array.""" with open(path, "rb") as f: return f.read() tests/example_test.py000064400000015452150043321530010755 0ustar00# Copyright 2014 Altera Corporation. All Rights Reserved. # Author: John McGehee # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """ Test the :py:class`pyfakefs.example` module to demonstrate the usage of the :py:class`pyfakefs.fake_filesystem_unittest.TestCase` base class. Fake filesystem functions like `create_file()`, `create_dir()` or `create_symlink()` are often used to set up file structures at the beginning of a test. While you could also use the familiar `open()`, `os.mkdirs()` and similar functions, these functions can make the test code shorter and more readable. `create_file()` is particularly convenient because it creates all parent directories and allows you to specify the contents or the size of the file. """ import io import os import sys import unittest from pyfakefs import fake_filesystem_unittest from pyfakefs.extra_packages import use_scandir_package from pyfakefs.tests import example # The module under test def load_tests(loader, tests, ignore): """Load the pyfakefs/example.py doctest tests into unittest.""" return fake_filesystem_unittest.load_doctests(loader, tests, ignore, example) class TestExample(fake_filesystem_unittest.TestCase): # pylint: disable=R0904 """Test the example module. The os and shutil modules have been replaced with the fake modules, so that all of the calls to os and shutil in the tested example code occur in the fake filesystem. """ def setUp(self): """Invoke the :py:class:`pyfakefs.fake_filesystem_unittest.TestCase` `self.setUp()` method. This defines: * Attribute `self.fs`, an instance of :py:class:`pyfakefs.fake_filesystem.FakeFilesystem`. This is useful for creating test files. * Attribute `self.stubs`, an instance of :py:class:`pyfakefs.mox3_stubout.StubOutForTesting`. Use this if you need to define additional stubs. """ # This is before setUpPyfakefs(), so still using the real file system self.filepath = os.path.realpath(__file__) with io.open(self.filepath, "rb") as f: self.real_contents = f.read() self.setUpPyfakefs() def tearDown(self): # No longer need self.tearDownPyfakefs() pass def test_create_file(self): """Test example.create_file() which uses `open()` and `file.write()`. """ self.assertFalse(os.path.isdir("/test")) os.mkdir("/test") self.assertTrue(os.path.isdir("/test")) self.assertFalse(os.path.exists("/test/file.txt")) example.create_file("/test/file.txt") self.assertTrue(os.path.exists("/test/file.txt")) def test_delete_file(self): """Test example.delete_file() which uses `os.remove()`.""" self.fs.create_file("/test/full.txt", contents="First line\n" "Second Line\n") self.assertTrue(os.path.exists("/test/full.txt")) example.delete_file("/test/full.txt") self.assertFalse(os.path.exists("/test/full.txt")) def test_file_exists(self): """Test example.path_exists() which uses `os.path.exists()`.""" self.assertFalse(example.path_exists("/test/empty.txt")) self.fs.create_file("/test/empty.txt") self.assertTrue(example.path_exists("/test/empty.txt")) def test_get_globs(self): """Test example.get_glob().""" self.assertFalse(os.path.isdir("/test")) self.fs.create_dir("/test/dir1/dir2a") self.assertTrue(os.path.isdir("/test/dir1/dir2a")) # os.mkdirs() works, too. os.makedirs("/test/dir1/dir2b") self.assertTrue(os.path.isdir("/test/dir1/dir2b")) self.assertEqual(example.get_glob("/test/dir1/nonexistent*"), []) is_windows = sys.platform.startswith("win") matching_paths = sorted(example.get_glob("/test/dir1/dir*")) if is_windows: self.assertEqual(matching_paths, [r"/test/dir1\dir2a", r"/test/dir1\dir2b"]) else: self.assertEqual(matching_paths, ["/test/dir1/dir2a", "/test/dir1/dir2b"]) def test_rm_tree(self): """Test example.rm_tree() using `shutil.rmtree()`.""" self.fs.create_dir("/test/dir1/dir2a") # os.mkdirs() works, too. os.makedirs("/test/dir1/dir2b") self.assertTrue(os.path.isdir("/test/dir1/dir2b")) self.assertTrue(os.path.isdir("/test/dir1/dir2a")) example.rm_tree("/test/dir1") self.assertFalse(os.path.exists("/test/dir1")) def test_os_scandir(self): """Test example.scandir() which uses `os.scandir()`. The os module has been replaced with the fake os module so the fake filesystem path entries are returned instead of `os.DirEntry` objects. """ self.fs.create_file("/test/text.txt") self.fs.create_dir("/test/dir") self.fs.create_file("/linktest/linked") self.fs.create_symlink("/test/linked_file", "/linktest/linked") entries = sorted(example.scan_dir("/test"), key=lambda e: e.name) self.assertEqual(3, len(entries)) self.assertEqual("linked_file", entries[1].name) self.assertTrue(entries[0].is_dir()) self.assertTrue(entries[1].is_symlink()) self.assertTrue(entries[2].is_file()) @unittest.skipIf( not use_scandir_package, "Testing only if scandir module is installed" ) def test_scandir_scandir(self): """Test example.scandir() which uses `scandir.scandir()`. The scandir module has been replaced with the fake_scandir module so the fake filesystem path entries are returned instead of `scandir.DirEntry` objects. """ self.fs.create_file("/test/text.txt") self.fs.create_dir("/test/dir") entries = sorted(example.scan_dir("/test"), key=lambda e: e.name) self.assertEqual(2, len(entries)) self.assertEqual("text.txt", entries[1].name) self.assertTrue(entries[0].is_dir()) self.assertTrue(entries[1].is_file()) def test_real_file_access(self): """Test `example.file_contents()` for a real file after adding it using `add_real_file()`.""" with self.assertRaises(OSError): example.file_contents(self.filepath) self.fs.add_real_file(self.filepath) self.assertEqual(example.file_contents(self.filepath), self.real_contents) if __name__ == "__main__": unittest.main() tests/fake_filesystem_glob_test.py000064400000005033150043321530013471 0ustar00# Copyright 2009 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Test for glob using fake_filesystem.""" import glob import os import unittest from pyfakefs import fake_filesystem_unittest class FakeGlobUnitTest(fake_filesystem_unittest.TestCase): def setUp(self): self.setUpPyfakefs() directory = "./xyzzy" self.fs.create_dir(directory) self.fs.create_dir("%s/subdir" % directory) self.fs.create_dir("%s/subdir2" % directory) self.fs.create_file("%s/subfile" % directory) self.fs.create_file("[Temp]") def test_glob_empty(self): self.assertEqual(glob.glob(""), []) def test_glob_star(self): basedir = "/xyzzy" self.assertEqual( [ os.path.join(basedir, "subdir"), os.path.join(basedir, "subdir2"), os.path.join(basedir, "subfile"), ], sorted(glob.glob("/xyzzy/*")), ) def test_glob_exact(self): self.assertEqual(["/xyzzy"], glob.glob("/xyzzy")) self.assertEqual(["/xyzzy/subfile"], glob.glob("/xyzzy/subfile")) def test_glob_question(self): basedir = "/xyzzy" self.assertEqual( [ os.path.join(basedir, "subdir"), os.path.join(basedir, "subdir2"), os.path.join(basedir, "subfile"), ], sorted(glob.glob("/x?zz?/*")), ) def test_glob_no_magic(self): self.assertEqual(["/xyzzy"], glob.glob("/xyzzy")) self.assertEqual(["/xyzzy/subdir"], glob.glob("/xyzzy/subdir")) def test_non_existent_path(self): self.assertEqual([], glob.glob("nonexistent")) def test_magic_dir(self): self.assertEqual(["/[Temp]"], glob.glob("/*emp*")) def test_glob1(self): self.assertEqual(["[Temp]"], glob.glob1("/", "*Tem*")) def test_has_magic(self): self.assertTrue(glob.has_magic("[")) self.assertFalse(glob.has_magic("a")) if __name__ == "__main__": unittest.main() tests/fake_filesystem_shutil_test.py000064400000053322150043321530014062 0ustar00# Copyright 2009 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Tests for `fake_filesystem_shutil` if used in `fake_filesystem_unittest.TestCase`. Note that almost all of the functionality is delegated to the real `shutil` and works correctly with the fake filesystem because of the faked `os` module. """ import os import shutil import sys import tempfile import unittest from pathlib import Path from pyfakefs import fake_filesystem_unittest from pyfakefs.helpers import get_uid, set_uid, is_root, IS_PYPY from pyfakefs.tests.test_utils import RealFsTestMixin is_windows = sys.platform == "win32" class RealFsTestCase(fake_filesystem_unittest.TestCase, RealFsTestMixin): def __init__(self, methodName="runTest"): fake_filesystem_unittest.TestCase.__init__(self, methodName) RealFsTestMixin.__init__(self) def setUp(self): RealFsTestMixin.setUp(self) self.cwd = os.getcwd() self.uid = get_uid() set_uid(1000) if not self.use_real_fs(): self.setUpPyfakefs() self.filesystem = self.fs self.os = os self.open = open self.create_basepath() self.fs.set_disk_usage(1000, self.base_path) def tearDown(self): set_uid(self.uid) RealFsTestMixin.tearDown(self) @property def is_windows_fs(self): if self.use_real_fs(): return sys.platform == "win32" return self.filesystem.is_windows_fs class FakeShutilModuleTest(RealFsTestCase): @unittest.skipIf(is_windows, "Posix specific behavior") def test_catch_permission_error(self): root_path = self.make_path("rootpath") self.create_dir(root_path) dir1_path = self.os.path.join(root_path, "dir1") dir2_path = self.os.path.join(root_path, "dir2") self.create_dir(dir1_path) self.os.chmod(dir1_path, 0o555) # remove write permissions self.create_dir(dir2_path) old_file_path = self.os.path.join(dir2_path, "f1.txt") new_file_path = self.os.path.join(dir1_path, "f1.txt") self.create_file(old_file_path) with self.assertRaises(PermissionError): shutil.move(old_file_path, new_file_path) def test_rmtree(self): directory = self.make_path("xyzzy") dir_path = os.path.join(directory, "subdir") self.create_dir(dir_path) file_path = os.path.join(directory, "subfile") self.create_file(file_path) self.assertTrue(os.path.exists(directory)) shutil.rmtree(directory) self.assertFalse(os.path.exists(directory)) self.assertFalse(os.path.exists(dir_path)) self.assertFalse(os.path.exists(file_path)) def test_rmtree_with_trailing_slash(self): directory = self.make_path("xyzzy") dir_path = os.path.join(directory, "subdir") self.create_dir(dir_path) file_path = os.path.join(directory, "subfile") self.create_file(file_path) shutil.rmtree(directory + "/") self.assertFalse(os.path.exists(directory)) self.assertFalse(os.path.exists(dir_path)) self.assertFalse(os.path.exists(file_path)) @unittest.skipIf(not is_windows, "Windows specific behavior") def test_rmtree_without_permission_for_a_file_in_windows(self): self.check_windows_only() dir_path = self.make_path("foo") self.create_file(os.path.join(dir_path, "bar")) file_path = os.path.join(dir_path, "baz") self.create_file(file_path) self.os.chmod(file_path, 0o444) with self.assertRaises(OSError): shutil.rmtree(dir_path) self.assertTrue(os.path.exists(file_path)) self.os.chmod(file_path, 0o666) @unittest.skipIf(is_windows, "Posix specific behavior") def test_rmtree_without_permission_for_a_dir_in_posix(self): self.check_posix_only() dir_path = self.make_path("foo") self.create_file(os.path.join(dir_path, "bar")) file_path = os.path.join(dir_path, "baz") self.create_file(file_path) self.os.chmod(dir_path, 0o555) if not is_root(): with self.assertRaises(OSError): shutil.rmtree(dir_path) self.assertTrue(os.path.exists(file_path)) self.os.chmod(dir_path, 0o777) else: shutil.rmtree(dir_path) self.assertFalse(os.path.exists(file_path)) @unittest.skipIf(is_windows, "Posix specific behavior") def test_rmtree_with_open_file_posix(self): self.check_posix_only() dir_path = self.make_path("foo") self.create_file(os.path.join(dir_path, "bar")) file_path = os.path.join(dir_path, "baz") self.create_file(file_path) with open(file_path): shutil.rmtree(dir_path) self.assertFalse(os.path.exists(file_path)) @unittest.skipIf(not is_windows, "Windows specific behavior") def test_rmtree_with_open_file_fails_under_windows(self): self.check_windows_only() dir_path = self.make_path("foo") self.create_file(os.path.join(dir_path, "bar")) file_path = os.path.join(dir_path, "baz") self.create_file(file_path) with open(file_path): with self.assertRaises(OSError): shutil.rmtree(dir_path) self.assertTrue(os.path.exists(dir_path)) def test_rmtree_non_existing_dir(self): directory = "nonexisting" with self.assertRaises(OSError): shutil.rmtree(directory) try: shutil.rmtree(directory, ignore_errors=True) except OSError: self.fail("rmtree raised despite ignore_errors True") def test_rmtree_non_existing_dir_with_handler(self): class NonLocal: pass def error_handler(_, path, _error_info): NonLocal.errorHandled = True NonLocal.errorPath = path directory = self.make_path("nonexisting") NonLocal.errorHandled = False NonLocal.errorPath = "" try: shutil.rmtree(directory, onerror=error_handler) except OSError: self.fail("rmtree raised exception despite onerror defined") self.assertTrue(NonLocal.errorHandled) self.assertEqual(NonLocal.errorPath, directory) NonLocal.errorHandled = False NonLocal.errorPath = "" try: shutil.rmtree(directory, ignore_errors=True, onerror=error_handler) except OSError: self.fail("rmtree raised exception despite ignore_errors True") # ignore_errors is True, so the onerror() error handler was # not executed self.assertFalse(NonLocal.errorHandled) self.assertEqual(NonLocal.errorPath, "") def test_copy(self): src_file = self.make_path("xyzzy") dst_file = self.make_path("xyzzy_copy") self.create_file(src_file) os.chmod(src_file, 0o750) self.assertTrue(os.path.exists(src_file)) self.assertFalse(os.path.exists(dst_file)) shutil.copy(src_file, dst_file) self.assertTrue(os.path.exists(dst_file)) self.assertEqual(os.stat(src_file).st_mode, os.stat(dst_file).st_mode) def test_copy_directory(self): src_file = self.make_path("xyzzy") parent_directory = self.make_path("parent") dst_file = os.path.join(parent_directory, "xyzzy") self.create_file(src_file) self.create_dir(parent_directory) os.chmod(src_file, 0o750) self.assertTrue(os.path.exists(src_file)) self.assertTrue(os.path.exists(parent_directory)) self.assertFalse(os.path.exists(dst_file)) shutil.copy(src_file, parent_directory) self.assertTrue(os.path.exists(dst_file)) self.assertEqual(os.stat(src_file).st_mode, os.stat(dst_file).st_mode) def test_copystat(self): src_file = self.make_path("xyzzy") self.create_file(src_file) os.chmod(src_file, 0o750) dst_file = self.make_path("xyzzy_copy") self.create_file(dst_file) self.assertTrue(os.path.exists(src_file)) self.assertTrue(os.path.exists(dst_file)) shutil.copystat(src_file, dst_file) src_stat = os.stat(src_file) dst_stat = os.stat(dst_file) self.assertEqual(src_stat.st_mode, dst_stat.st_mode) self.assertAlmostEqual(src_stat.st_atime, dst_stat.st_atime, places=2) self.assertAlmostEqual(src_stat.st_mtime, dst_stat.st_mtime, places=2) @unittest.skipIf(IS_PYPY, "Functionality not supported in PyPy") def test_copystat_symlinks(self): """Regression test for #799""" self.skip_if_symlink_not_supported() f = self.make_path("xyzzy") self.create_file(f) sym1 = self.make_path("sym1") sym2 = self.make_path("sym2") self.create_symlink(sym1, f) self.create_symlink(sym2, f) shutil.copystat(sym1, sym2, follow_symlinks=False) def test_copy2(self): src_file = self.make_path("xyzzy") self.create_file(src_file) os.chmod(src_file, 0o750) dst_file = self.make_path("xyzzy_copy") self.assertTrue(os.path.exists(src_file)) self.assertFalse(os.path.exists(dst_file)) shutil.copy2(src_file, dst_file) self.assertTrue(os.path.exists(dst_file)) src_stat = os.stat(src_file) dst_stat = os.stat(dst_file) self.assertEqual(src_stat.st_mode, dst_stat.st_mode) self.assertAlmostEqual(src_stat.st_atime, dst_stat.st_atime, places=2) self.assertAlmostEqual(src_stat.st_mtime, dst_stat.st_mtime, places=2) def test_copy2_directory(self): src_file = self.make_path("xyzzy") parent_directory = self.make_path("parent") dst_file = os.path.join(parent_directory, "xyzzy") self.create_file(src_file) self.create_dir(parent_directory) os.chmod(src_file, 0o750) self.assertTrue(os.path.exists(src_file)) self.assertTrue(os.path.exists(parent_directory)) self.assertFalse(os.path.exists(dst_file)) shutil.copy2(src_file, parent_directory) self.assertTrue(os.path.exists(dst_file)) src_stat = os.stat(src_file) dst_stat = os.stat(dst_file) self.assertEqual(src_stat.st_mode, dst_stat.st_mode) self.assertAlmostEqual(src_stat.st_atime, dst_stat.st_atime, places=2) self.assertAlmostEqual(src_stat.st_mtime, dst_stat.st_mtime, places=2) def test_copytree(self): src_directory = self.make_path("xyzzy") dst_directory = self.make_path("xyzzy_copy") self.create_dir(src_directory) self.create_dir("%s/subdir" % src_directory) self.create_file(os.path.join(src_directory, "subfile")) self.assertTrue(os.path.exists(src_directory)) self.assertFalse(os.path.exists(dst_directory)) shutil.copytree(src_directory, dst_directory) self.assertTrue(os.path.exists(dst_directory)) self.assertTrue(os.path.exists(os.path.join(dst_directory, "subdir"))) self.assertTrue(os.path.exists(os.path.join(dst_directory, "subfile"))) def test_copytree_src_is_file(self): src_file = self.make_path("xyzzy") dst_directory = self.make_path("xyzzy_copy") self.create_file(src_file) self.assertTrue(os.path.exists(src_file)) self.assertFalse(os.path.exists(dst_directory)) with self.assertRaises(OSError): shutil.copytree(src_file, dst_directory) def test_move_file_in_same_filesystem(self): self.skip_real_fs() src_file = "/original_xyzzy" dst_file = "/moved_xyzzy" src_object = self.fs.create_file(src_file) src_ino = src_object.st_ino src_dev = src_object.st_dev self.assertTrue(os.path.exists(src_file)) self.assertFalse(os.path.exists(dst_file)) shutil.move(src_file, dst_file) self.assertTrue(os.path.exists(dst_file)) self.assertFalse(os.path.exists(src_file)) dst_object = self.fs.get_object(dst_file) self.assertEqual(src_ino, dst_object.st_ino) self.assertEqual(src_dev, dst_object.st_dev) def test_move_file_into_other_filesystem(self): self.skip_real_fs() mount_point = self.create_mount_point() src_file = self.make_path("original_xyzzy") dst_file = self.os.path.join(mount_point, "moved_xyzzy") src_object = self.fs.create_file(src_file) src_ino = src_object.st_ino src_dev = src_object.st_dev shutil.move(src_file, dst_file) self.assertTrue(os.path.exists(dst_file)) self.assertFalse(os.path.exists(src_file)) dst_object = self.fs.get_object(dst_file) self.assertNotEqual(src_ino, dst_object.st_ino) self.assertNotEqual(src_dev, dst_object.st_dev) def test_move_file_into_directory(self): src_file = self.make_path("xyzzy") dst_directory = self.make_path("directory") dst_file = os.path.join(dst_directory, "xyzzy") self.create_file(src_file) self.create_dir(dst_directory) self.assertTrue(os.path.exists(src_file)) self.assertFalse(os.path.exists(dst_file)) shutil.move(src_file, dst_directory) self.assertTrue(os.path.exists(dst_file)) self.assertFalse(os.path.exists(src_file)) def test_move_directory(self): src_directory = self.make_path("original_xyzzy") dst_directory = self.make_path("moved_xyzzy") self.create_dir(src_directory) self.create_file(os.path.join(src_directory, "subfile")) self.create_dir(os.path.join(src_directory, "subdir")) self.assertTrue(os.path.exists(src_directory)) self.assertFalse(os.path.exists(dst_directory)) shutil.move(src_directory, dst_directory) self.assertTrue(os.path.exists(dst_directory)) self.assertTrue(os.path.exists(os.path.join(dst_directory, "subfile"))) self.assertTrue(os.path.exists(os.path.join(dst_directory, "subdir"))) self.assertFalse(os.path.exists(src_directory)) def test_disk_usage(self): self.skip_real_fs() file_path = self.make_path("foo", "bar") self.fs.create_file(file_path, st_size=400) disk_usage = shutil.disk_usage(file_path) self.assertEqual(1000, disk_usage.total) self.assertEqual(400, disk_usage.used) self.assertEqual(600, disk_usage.free) self.assertEqual((1000, 400, 600), disk_usage) mount_point = self.create_mount_point() dir_path = self.os.path.join(mount_point, "foo") file_path = self.os.path.join(dir_path, "bar") self.fs.create_file(file_path, st_size=400) disk_usage = shutil.disk_usage(dir_path) self.assertEqual((500, 400, 100), disk_usage) def test_disk_usage_with_path(self): self.skip_real_fs() file_path = self.make_path("foo", "bar") self.fs.create_file(file_path, st_size=400) path = Path(file_path) disk_usage = shutil.disk_usage(path) self.assertEqual(1000, disk_usage.total) self.assertEqual(400, disk_usage.used) self.assertEqual(600, disk_usage.free) self.assertEqual((1000, 400, 600), disk_usage) def create_mount_point(self): mount_point = "M:" if self.is_windows_fs else "/mount" self.fs.add_mount_point(mount_point, total_size=500) return mount_point class RealShutilModuleTest(FakeShutilModuleTest): def use_real_fs(self): return True class FakeCopyFileTest(RealFsTestCase): def tearDown(self): super(FakeCopyFileTest, self).tearDown() def test_common_case(self): src_file = self.make_path("xyzzy") dst_file = self.make_path("xyzzy_copy") contents = "contents of file" self.create_file(src_file, contents=contents) self.assertTrue(os.path.exists(src_file)) self.assertFalse(os.path.exists(dst_file)) shutil.copyfile(src_file, dst_file) self.assertTrue(os.path.exists(dst_file)) self.check_contents(dst_file, contents) def test_raises_if_source_and_dest_are_the_same_file(self): src_file = self.make_path("xyzzy") dst_file = src_file contents = "contents of file" self.create_file(src_file, contents=contents) self.assertTrue(os.path.exists(src_file)) with self.assertRaises(shutil.Error): shutil.copyfile(src_file, dst_file) def test_raises_if_dest_is_a_symlink_to_src(self): self.skip_if_symlink_not_supported() src_file = self.make_path("foo") dst_file = self.make_path("bar") contents = "contents of file" self.create_file(src_file, contents=contents) self.create_symlink(dst_file, src_file) self.assertTrue(os.path.exists(src_file)) with self.assertRaises(shutil.Error): shutil.copyfile(src_file, dst_file) def test_succeeds_if_dest_exists_and_is_writable(self): src_file = self.make_path("xyzzy") dst_file = self.make_path("xyzzy_copy") src_contents = "contents of source file" dst_contents = "contents of dest file" self.create_file(src_file, contents=src_contents) self.create_file(dst_file, contents=dst_contents) self.assertTrue(os.path.exists(src_file)) self.assertTrue(os.path.exists(dst_file)) shutil.copyfile(src_file, dst_file) self.assertTrue(os.path.exists(dst_file)) self.check_contents(dst_file, src_contents) def test_raises_if_dest_exists_and_is_not_writable(self): src_file = self.make_path("xyzzy") dst_file = self.make_path("xyzzy_copy") src_contents = "contents of source file" dst_contents = "contents of dest file" self.create_file(src_file, contents=src_contents) self.create_file(dst_file, contents=dst_contents) os.chmod(dst_file, 0o400) self.assertTrue(os.path.exists(src_file)) self.assertTrue(os.path.exists(dst_file)) if is_root(): shutil.copyfile(src_file, dst_file) self.assertTrue(self.os.path.exists(dst_file)) with self.open(dst_file) as f: self.assertEqual("contents of source file", f.read()) else: with self.assertRaises(OSError): shutil.copyfile(src_file, dst_file) os.chmod(dst_file, 0o666) @unittest.skipIf(is_windows, "Posix specific behavior") def test_raises_if_dest_dir_is_not_writable_under_posix(self): self.check_posix_only() src_file = self.make_path("xyzzy") dst_dir = self.make_path("tmp", "foo") dst_file = os.path.join(dst_dir, "xyzzy") src_contents = "contents of source file" self.create_file(src_file, contents=src_contents) self.create_dir(dst_dir) os.chmod(dst_dir, 0o555) self.assertTrue(os.path.exists(src_file)) self.assertTrue(os.path.exists(dst_dir)) if not is_root(): with self.assertRaises(OSError): shutil.copyfile(src_file, dst_file) else: shutil.copyfile(src_file, dst_file) self.assertTrue(os.path.exists(dst_file)) self.check_contents(dst_file, src_contents) def test_raises_if_src_doesnt_exist(self): src_file = self.make_path("xyzzy") dst_file = self.make_path("xyzzy_copy") self.assertFalse(os.path.exists(src_file)) with self.assertRaises(OSError): shutil.copyfile(src_file, dst_file) @unittest.skipIf(is_windows, "Posix specific behavior") def test_raises_if_src_not_readable(self): self.check_posix_only() src_file = self.make_path("xyzzy") dst_file = self.make_path("xyzzy_copy") src_contents = "contents of source file" self.create_file(src_file, contents=src_contents) os.chmod(src_file, 0o000) self.assertTrue(os.path.exists(src_file)) if not is_root(): with self.assertRaises(OSError): shutil.copyfile(src_file, dst_file) else: shutil.copyfile(src_file, dst_file) self.assertTrue(os.path.exists(dst_file)) self.check_contents(dst_file, src_contents) def test_raises_if_src_is_a_directory(self): src_file = self.make_path("xyzzy") dst_file = self.make_path("xyzzy_copy") self.create_dir(src_file) self.assertTrue(os.path.exists(src_file)) with self.assertRaises(OSError): shutil.copyfile(src_file, dst_file) def test_raises_if_dest_is_a_directory(self): src_file = self.make_path("xyzzy") dst_dir = self.make_path("tmp", "foo") src_contents = "contents of source file" self.create_file(src_file, contents=src_contents) self.create_dir(dst_dir) self.assertTrue(os.path.exists(src_file)) self.assertTrue(os.path.exists(dst_dir)) with self.assertRaises(OSError): shutil.copyfile(src_file, dst_dir) def test_moving_dir_into_dir(self): # regression test for #515 source_dir = tempfile.mkdtemp() target_dir = tempfile.mkdtemp() filename = "foo.pdf" with open(os.path.join(source_dir, filename), "wb") as fp: fp.write(b"stub") shutil.move(source_dir, target_dir) shutil.rmtree(target_dir) class RealCopyFileTest(FakeCopyFileTest): def use_real_fs(self): return True if __name__ == "__main__": unittest.main() tests/fake_filesystem_test.py000064400000316253150043321530012477 0ustar00# Copyright 2009 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Unittest for fake_filesystem module.""" import contextlib import errno import os import stat import sys import unittest from pyfakefs import fake_filesystem, fake_os, fake_open from pyfakefs.fake_filesystem import ( set_uid, set_gid, is_root, reset_ids, OSType, ) from pyfakefs.helpers import IS_WIN from pyfakefs.tests.test_utils import TestCase, RealFsTestCase, time_mock class FakeDirectoryUnitTest(TestCase): def setUp(self): self.filesystem = fake_filesystem.FakeFilesystem(path_separator="/") self.os = fake_os.FakeOsModule(self.filesystem) self.time = time_mock(10, 1) self.time.start() self.fake_file = fake_filesystem.FakeFile( "foobar", contents="dummy_file", filesystem=self.filesystem ) self.fake_dir = fake_filesystem.FakeDirectory( "somedir", filesystem=self.filesystem ) def tearDown(self): self.time.stop() def test_new_file_and_directory(self): self.assertTrue(stat.S_IFREG & self.fake_file.st_mode) self.assertTrue(stat.S_IFDIR & self.fake_dir.st_mode) self.assertEqual({}, self.fake_dir.entries) def test_add_entry(self): self.fake_dir.add_entry(self.fake_file) self.assertEqual({"foobar": self.fake_file}, self.fake_dir.entries) def test_get_entry(self): self.fake_dir.add_entry(self.fake_file) self.assertEqual(self.fake_file, self.fake_dir.get_entry("foobar")) def test_path(self): root_dir = self.filesystem.root_dir_name self.filesystem.root.add_entry(self.fake_dir) self.fake_dir.add_entry(self.fake_file) self.assertEqual(f"{root_dir}somedir/foobar", self.fake_file.path) self.assertEqual(f"{root_dir}somedir", self.fake_dir.path) def test_path_with_drive(self): self.filesystem.is_windows_fs = True dir_path = "C:/foo/bar/baz" self.filesystem.create_dir(dir_path) dir_object = self.filesystem.get_object(dir_path) self.assertEqual(dir_path, dir_object.path) def test_path_after_chdir(self): root_dir = self.filesystem.root_dir_name dir_path = "/foo/bar/baz" self.filesystem.create_dir(dir_path) self.os.chdir(dir_path) dir_object = self.filesystem.get_object(dir_path) self.assertEqual(f"{root_dir}foo/bar/baz", dir_object.path) def test_path_after_chdir_with_drive(self): self.filesystem.is_windows_fs = True dir_path = "C:/foo/bar/baz" self.filesystem.create_dir(dir_path) self.os.chdir(dir_path) dir_object = self.filesystem.get_object(dir_path) self.assertEqual(dir_path, dir_object.path) def test_remove_entry(self): self.fake_dir.add_entry(self.fake_file) self.assertEqual(self.fake_file, self.fake_dir.get_entry("foobar")) self.fake_dir.remove_entry("foobar") with self.assertRaises(KeyError): self.fake_dir.get_entry("foobar") def test_should_throw_if_set_size_is_not_integer(self): with self.raises_os_error(errno.ENOSPC): self.fake_file.size = 0.1 def test_should_throw_if_set_size_is_negative(self): with self.raises_os_error(errno.ENOSPC): self.fake_file.size = -1 def test_produce_empty_file_if_set_size_is_zero(self): self.fake_file.size = 0 self.assertEqual("", self.fake_file.contents) def test_sets_content_empty_if_set_size_is_zero(self): self.fake_file.size = 0 self.assertEqual("", self.fake_file.contents) def test_truncate_file_if_size_is_smaller_than_current_size(self): self.fake_file.size = 6 self.assertEqual("dummy_", self.fake_file.contents) def test_leave_file_unchanged_if_size_is_equal_to_current_size(self): self.fake_file.size = 10 self.assertEqual("dummy_file", self.fake_file.contents) def test_set_contents_to_dir_raises(self): # Regression test for #276 self.filesystem.is_windows_fs = True with self.raises_os_error(errno.EISDIR): self.fake_dir.set_contents("a") self.filesystem.is_windows_fs = False with self.raises_os_error(errno.EISDIR): self.fake_dir.set_contents("a") def test_pads_with_nullbytes_if_size_is_greater_than_current_size(self): self.fake_file.size = 13 self.assertEqual("dummy_file\0\0\0", self.fake_file.contents) def test_set_m_time(self): self.assertEqual(10, self.fake_file.st_mtime) self.fake_file.st_mtime = 14 self.assertEqual(14, self.fake_file.st_mtime) self.fake_file.st_mtime = 131 self.assertEqual(131, self.fake_file.st_mtime) def test_file_inode(self): filesystem = fake_filesystem.FakeFilesystem(path_separator="/") fake_os_module = fake_os.FakeOsModule(filesystem) file_path = "some_file1" filesystem.create_file(file_path, contents="contents here1") self.assertLess(0, fake_os_module.stat(file_path)[stat.ST_INO]) file_obj = filesystem.get_object(file_path) file_obj.st_ino = 43 self.assertEqual(43, fake_os_module.stat(file_path)[stat.ST_INO]) def test_directory_inode(self): filesystem = fake_filesystem.FakeFilesystem(path_separator="/") fake_os_module = fake_os.FakeOsModule(filesystem) dirpath = "testdir" filesystem.create_dir(dirpath) self.assertLess(0, fake_os_module.stat(dirpath)[stat.ST_INO]) dir_obj = filesystem.get_object(dirpath) dir_obj.st_ino = 43 self.assertEqual(43, fake_os_module.stat(dirpath)[stat.ST_INO]) def test_directory_size(self): fs = fake_filesystem.FakeFilesystem(path_separator="/") foo_dir = fs.create_dir("/foo") fs.create_file("/foo/bar.txt", st_size=20) bar_dir = fs.create_dir("/foo/bar/") fs.create_file("/foo/bar/baz1.txt", st_size=30) fs.create_file("/foo/bar/baz2.txt", st_size=40) foo1_dir = fs.create_dir("/foo1") fs.create_file("/foo1/bar.txt", st_size=50) fs.create_file("/foo1/bar/baz/file", st_size=60) self.assertEqual(90, foo_dir.size) self.assertEqual(70, bar_dir.size) self.assertEqual(110, foo1_dir.size) self.assertEqual(200, fs.root_dir.size) with self.raises_os_error(errno.EISDIR): foo1_dir.size = 100 def test_ordered_dirs(self): filesystem = fake_filesystem.FakeFilesystem(path_separator="/") filesystem.create_dir("/foo") filesystem.create_file("/foo/2") filesystem.create_file("/foo/4") filesystem.create_file("/foo/1") filesystem.create_file("/foo/3") fake_dir = filesystem.get_object("/foo") self.assertEqual(["2", "4", "1", "3"], fake_dir.ordered_dirs) class SetLargeFileSizeTest(TestCase): def setUp(self): filesystem = fake_filesystem.FakeFilesystem() self.fake_file = fake_filesystem.FakeFile("foobar", filesystem=filesystem) def test_should_throw_if_size_is_not_integer(self): with self.raises_os_error(errno.ENOSPC): self.fake_file.set_large_file_size(0.1) def test_should_throw_if_size_is_negative(self): with self.raises_os_error(errno.ENOSPC): self.fake_file.set_large_file_size(-1) def test_sets_content_none_if_size_is_non_negative_integer(self): self.fake_file.set_large_file_size(1000000000) self.assertEqual(None, self.fake_file.contents) self.assertEqual(1000000000, self.fake_file.st_size) class NormalizePathTest(TestCase): def setUp(self): self.filesystem = fake_filesystem.FakeFilesystem(path_separator="/") self.root_name = self.filesystem.root_dir_name def test_empty_path_should_get_normalized_to_root_path(self): self.assertEqual(self.root_name, self.filesystem.absnormpath("")) def test_root_path_remains_unchanged(self): self.assertEqual(self.root_name, self.filesystem.absnormpath(self.root_name)) def test_relative_path_forced_to_cwd(self): path = "bar" self.filesystem.cwd = "/foo" self.assertEqual("/foo/bar", self.filesystem.absnormpath(path)) def test_absolute_path_remains_unchanged(self): path = "foo/bar" self.assertEqual(self.root_name + path, self.filesystem.absnormpath(path)) def test_dotted_path_is_normalized(self): path = "/foo/.." self.assertEqual( self.filesystem.root_dir_name, self.filesystem.absnormpath(path) ) path = "foo/../bar" self.assertEqual( f"{self.filesystem.root_dir_name}bar", self.filesystem.absnormpath(path), ) def test_dot_path_is_normalized(self): path = "." self.assertEqual(self.root_name, self.filesystem.absnormpath(path)) class GetPathComponentsTest(TestCase): def setUp(self): self.filesystem = fake_filesystem.FakeFilesystem(path_separator="/") self.root_name = "/" def test_root_path_should_return_empty_list(self): self.assertEqual([], self.filesystem._path_components(self.root_name)) def test_empty_path_should_return_empty_list(self): self.assertEqual([], self.filesystem._path_components("")) def test_relative_path_with_one_component_should_return_component(self): self.assertEqual(["foo"], self.filesystem._path_components("foo")) def test_absolute_path_with_one_component_should_return_component(self): self.assertEqual(["foo"], self.filesystem._path_components("/foo")) def test_two_level_relative_path_should_return_components(self): self.assertEqual(["foo", "bar"], self.filesystem._path_components("foo/bar")) def test_two_level_absolute_path_should_return_components(self): self.assertEqual(["foo", "bar"], self.filesystem._path_components("/foo/bar")) class FakeFilesystemUnitTest(TestCase): def setUp(self): self.filesystem = fake_filesystem.FakeFilesystem(path_separator="/") self.root_name = self.filesystem.root_dir_name self.fake_file = fake_filesystem.FakeFile("foobar", filesystem=self.filesystem) self.fake_child = fake_filesystem.FakeDirectory( "foobaz", filesystem=self.filesystem ) self.fake_grandchild = fake_filesystem.FakeDirectory( "quux", filesystem=self.filesystem ) def test_new_filesystem(self): self.assertEqual("/", self.filesystem.path_separator) self.assertTrue(stat.S_IFDIR & self.filesystem.root.st_mode) self.assertEqual({}, self.filesystem.root_dir.entries) def test_none_raises_type_error(self): with self.assertRaises(TypeError): self.filesystem.exists(None) def test_empty_string_does_not_exist(self): self.assertFalse(self.filesystem.exists("")) def test_exists_root(self): self.assertTrue(self.filesystem.exists(self.root_name)) def test_exists_unadded_file(self): self.assertFalse(self.filesystem.exists(self.fake_file.name)) def test_not_exists_subpath_named_like_file_contents(self): # Regression test for #219 file_path = "/foo/bar" self.filesystem.create_file(file_path, contents="baz") self.assertFalse(self.filesystem.exists(file_path + "/baz")) def test_get_root_object(self): self.assertEqual( self.filesystem.root_dir, self.filesystem.get_object(self.root_name), ) def test_add_object_to_root(self): self.filesystem.add_object(self.root_name, self.fake_file) self.assertEqual({"foobar": self.fake_file}, self.filesystem.root_dir.entries) def test_windows_root_dir_name(self): self.filesystem.is_windows_fs = True self.assertEqual("C:/", self.filesystem.root_dir_name) self.filesystem.cwd = "E:/foo" self.assertEqual("E:/", self.filesystem.root_dir_name) self.filesystem.cwd = "//foo/bar" self.assertEqual("//foo/bar/", self.filesystem.root_dir_name) def test_exists_added_file(self): self.filesystem.add_object(self.root_name, self.fake_file) self.assertTrue(self.filesystem.exists(self.fake_file.name)) def test_exists_relative_path_posix(self): self.filesystem.is_windows_fs = False self.filesystem.create_file("/a/b/file_one") self.filesystem.create_file("/a/c/file_two") self.assertTrue(self.filesystem.exists("a/b/../c/file_two")) self.assertTrue(self.filesystem.exists("/a/c/../b/file_one")) self.assertTrue(self.filesystem.exists("/a/c/../../a/b/file_one")) self.assertFalse(self.filesystem.exists("a/b/../z/d")) self.assertFalse(self.filesystem.exists("a/b/../z/../c/file_two")) self.filesystem.cwd = "/a/c" self.assertTrue(self.filesystem.exists("../b/file_one")) self.assertTrue(self.filesystem.exists("../../a/b/file_one")) self.assertTrue(self.filesystem.exists("../../a/b/../../a/c/file_two")) self.assertFalse(self.filesystem.exists("../z/file_one")) self.assertFalse(self.filesystem.exists("../z/../c/file_two")) def test_exists_relative_path_windows(self): self.filesystem.is_windows_fs = True self.filesystem.is_macos = False self.filesystem.create_file("/a/b/file_one") self.filesystem.create_file("/a/c/file_two") self.assertTrue(self.filesystem.exists("a/b/../c/file_two")) self.assertTrue(self.filesystem.exists("/a/c/../b/file_one")) self.assertTrue(self.filesystem.exists("/a/c/../../a/b/file_one")) self.assertFalse(self.filesystem.exists("a/b/../z/d")) self.assertTrue(self.filesystem.exists("a/b/../z/../c/file_two")) self.filesystem.cwd = "C:/a/c" self.assertTrue(self.filesystem.exists("../b/file_one")) self.assertTrue(self.filesystem.exists("../../a/b/file_one")) self.assertTrue(self.filesystem.exists("../../a/b/../../a/c/file_two")) self.assertFalse(self.filesystem.exists("../z/file_one")) self.assertTrue(self.filesystem.exists("../z/../c/file_two")) def test_get_object_from_root(self): self.filesystem.add_object(self.root_name, self.fake_file) self.assertEqual(self.fake_file, self.filesystem.get_object("foobar")) def test_get_nonexistent_object_from_root_error(self): self.filesystem.add_object(self.root_name, self.fake_file) self.assertEqual(self.fake_file, self.filesystem.get_object("foobar")) with self.raises_os_error(errno.ENOENT): self.filesystem.get_object("some_bogus_filename") def test_remove_object_from_root(self): self.filesystem.add_object(self.root_name, self.fake_file) self.filesystem.remove_object(self.fake_file.name) with self.raises_os_error(errno.ENOENT): self.filesystem.get_object(self.fake_file.name) def test_remove_nonexisten_object_from_root_error(self): with self.raises_os_error(errno.ENOENT): self.filesystem.remove_object("some_bogus_filename") def test_exists_removed_file(self): self.filesystem.add_object(self.root_name, self.fake_file) self.filesystem.remove_object(self.fake_file.name) self.assertFalse(self.filesystem.exists(self.fake_file.name)) def test_add_object_to_child(self): self.filesystem.add_object(self.root_name, self.fake_child) self.filesystem.add_object(self.fake_child.name, self.fake_file) self.assertEqual( {self.fake_file.name: self.fake_file}, self.filesystem.root_dir.get_entry(self.fake_child.name).entries, ) def test_add_object_to_regular_file_error_posix(self): self.filesystem.is_windows_fs = False self.filesystem.add_object(self.filesystem.root_dir_name, self.fake_file) with self.raises_os_error(errno.ENOTDIR): self.filesystem.add_object(self.fake_file.name, self.fake_file) def test_add_object_to_regular_file_error_windows(self): self.filesystem.is_windows_fs = True self.filesystem.add_object(self.root_name, self.fake_file) with self.raises_os_error(errno.ENOENT): self.filesystem.add_object(self.fake_file.name, self.fake_file) def test_exists_file_added_to_child(self): self.filesystem.add_object(self.root_name, self.fake_child) self.filesystem.add_object(self.fake_child.name, self.fake_file) path = self.filesystem.joinpaths(self.fake_child.name, self.fake_file.name) self.assertTrue(self.filesystem.exists(path)) def test_get_object_from_child(self): self.filesystem.add_object(self.root_name, self.fake_child) self.filesystem.add_object(self.fake_child.name, self.fake_file) self.assertEqual( self.fake_file, self.filesystem.get_object( self.filesystem.joinpaths(self.fake_child.name, self.fake_file.name) ), ) def test_get_nonexistent_object_from_child_error(self): self.filesystem.add_object(self.root_name, self.fake_child) self.filesystem.add_object(self.fake_child.name, self.fake_file) with self.raises_os_error(errno.ENOENT): self.filesystem.get_object( self.filesystem.joinpaths(self.fake_child.name, "some_bogus_filename") ) def test_remove_object_from_child(self): self.filesystem.add_object(self.root_name, self.fake_child) self.filesystem.add_object(self.fake_child.name, self.fake_file) target_path = self.filesystem.joinpaths( self.fake_child.name, self.fake_file.name ) self.filesystem.remove_object(target_path) with self.raises_os_error(errno.ENOENT): self.filesystem.get_object(target_path) def test_remove_object_from_child_error(self): self.filesystem.add_object(self.root_name, self.fake_child) with self.raises_os_error(errno.ENOENT): self.filesystem.remove_object( self.filesystem.joinpaths(self.fake_child.name, "some_bogus_filename") ) def test_remove_object_from_non_directory_error(self): self.filesystem.add_object(self.root_name, self.fake_file) with self.raises_os_error(errno.ENOTDIR): self.filesystem.remove_object( self.filesystem.joinpaths( "%s" % self.fake_file.name, "file_does_not_matter_since_parent_not_a_directory", ) ) def test_exists_file_removed_from_child(self): self.filesystem.add_object(self.root_name, self.fake_child) self.filesystem.add_object(self.fake_child.name, self.fake_file) path = self.filesystem.joinpaths(self.fake_child.name, self.fake_file.name) self.filesystem.remove_object(path) self.assertFalse(self.filesystem.exists(path)) def test_operate_on_grandchild_directory(self): self.filesystem.add_object(self.root_name, self.fake_child) self.filesystem.add_object(self.fake_child.name, self.fake_grandchild) grandchild_directory = self.filesystem.joinpaths( self.fake_child.name, self.fake_grandchild.name ) grandchild_file = self.filesystem.joinpaths( grandchild_directory, self.fake_file.name ) with self.assertRaises(OSError): self.filesystem.get_object(grandchild_file) self.filesystem.add_object(grandchild_directory, self.fake_file) self.assertEqual(self.fake_file, self.filesystem.get_object(grandchild_file)) self.assertTrue(self.filesystem.exists(grandchild_file)) self.filesystem.remove_object(grandchild_file) with self.assertRaises(OSError): self.filesystem.get_object(grandchild_file) self.assertFalse(self.filesystem.exists(grandchild_file)) def test_create_directory_in_root_directory(self): path = "foo" self.filesystem.create_dir(path) new_dir = self.filesystem.get_object(path) self.assertEqual(os.path.basename(path), new_dir.name) self.assertTrue(stat.S_IFDIR & new_dir.st_mode) def test_create_directory_in_root_directory_already_exists_error(self): path = "foo" self.filesystem.create_dir(path) with self.raises_os_error(errno.EEXIST): self.filesystem.create_dir(path) def test_create_directory(self): path = "foo/bar/baz" self.filesystem.create_dir(path) new_dir = self.filesystem.get_object(path) self.assertEqual(os.path.basename(path), new_dir.name) self.assertTrue(stat.S_IFDIR & new_dir.st_mode) # Create second directory to make sure first is OK. path = "%s/quux" % path self.filesystem.create_dir(path) new_dir = self.filesystem.get_object(path) self.assertEqual(os.path.basename(path), new_dir.name) self.assertTrue(stat.S_IFDIR & new_dir.st_mode) def test_create_directory_already_exists_error(self): path = "foo/bar/baz" self.filesystem.create_dir(path) with self.raises_os_error(errno.EEXIST): self.filesystem.create_dir(path) def test_create_file_in_read_only_directory_raises_in_posix(self): self.filesystem.is_windows_fs = False dir_path = "/foo/bar" self.filesystem.create_dir(dir_path, perm_bits=0o555) file_path = dir_path + "/baz" if not is_root(): with self.raises_os_error(errno.EACCES): self.filesystem.create_file(file_path) else: self.filesystem.create_file(file_path) self.assertTrue(self.filesystem.exists(file_path)) def test_create_file_in_read_only_directory_possible_in_windows(self): self.filesystem.is_windows_fs = True dir_path = "C:/foo/bar" self.filesystem.create_dir(dir_path, perm_bits=0o555) file_path = dir_path + "/baz" self.filesystem.create_file(file_path) self.assertTrue(self.filesystem.exists(file_path)) def test_create_file_in_current_directory(self): path = "foo" contents = "dummy data" self.filesystem.create_file(path, contents=contents) self.assertTrue(self.filesystem.exists(path)) self.assertFalse(self.filesystem.exists(os.path.dirname(path))) path = "./%s" % path self.assertTrue(self.filesystem.exists(os.path.dirname(path))) def test_create_file_in_root_directory(self): path = "/foo" contents = "dummy data" self.filesystem.create_file(path, contents=contents) new_file = self.filesystem.get_object(path) self.assertTrue(self.filesystem.exists(path)) self.assertTrue(self.filesystem.exists(os.path.dirname(path))) self.assertEqual(os.path.basename(path), new_file.name) self.assertTrue(stat.S_IFREG & new_file.st_mode) self.assertEqual(contents, new_file.contents) def test_create_file_with_size_but_no_content_creates_large_file(self): path = "large_foo_bar" self.filesystem.create_file(path, st_size=100000000) new_file = self.filesystem.get_object(path) self.assertEqual(None, new_file.contents) self.assertEqual(100000000, new_file.st_size) def test_create_file_in_root_directory_already_exists_error(self): path = "foo" self.filesystem.create_file(path) with self.raises_os_error(errno.EEXIST): self.filesystem.create_file(path) def test_create_file(self): path = "foo/bar/baz" retval = self.filesystem.create_file(path, contents="dummy_data") self.assertTrue(self.filesystem.exists(path)) self.assertTrue(self.filesystem.exists(os.path.dirname(path))) new_file = self.filesystem.get_object(path) self.assertEqual(os.path.basename(path), new_file.name) if IS_WIN: self.assertEqual(1, new_file.st_uid) self.assertEqual(1, new_file.st_gid) else: self.assertEqual(os.getuid(), new_file.st_uid) self.assertEqual(os.getgid(), new_file.st_gid) self.assertEqual(new_file, retval) def test_create_file_with_changed_ids(self): path = "foo/bar/baz" set_uid(42) set_gid(2) self.filesystem.create_file(path) self.assertTrue(self.filesystem.exists(path)) new_file = self.filesystem.get_object(path) self.assertEqual(42, new_file.st_uid) self.assertEqual(2, new_file.st_gid) reset_ids() def test_empty_file_created_for_none_contents(self): fake_open = fake_filesystem.FakeFileOpen(self.filesystem) path = "foo/bar/baz" self.filesystem.create_file(path, contents=None) with fake_open(path) as f: self.assertEqual("", f.read()) def test_create_file_with_incorrect_mode_type(self): with self.assertRaises(TypeError): self.filesystem.create_file("foo", "bar") def test_create_file_already_exists_error(self): path = "foo/bar/baz" self.filesystem.create_file(path, contents="dummy_data") with self.raises_os_error(errno.EEXIST): self.filesystem.create_file(path) def test_create_link(self): path = "foo/bar/baz" target_path = "foo/bar/quux" new_file = self.filesystem.create_symlink(path, "quux") # Neither the path nor the final target exists before we actually # write to one of them, even though the link appears in the file # system. self.assertFalse(self.filesystem.exists(path)) self.assertFalse(self.filesystem.exists(target_path)) self.assertTrue(stat.S_IFLNK & new_file.st_mode) # but once we write the linked to file, they both will exist. self.filesystem.create_file(target_path) self.assertTrue(self.filesystem.exists(path)) self.assertTrue(self.filesystem.exists(target_path)) def test_resolve_object(self): target_path = "dir/target" target_contents = "0123456789ABCDEF" link_name = "x" self.filesystem.create_dir("dir") self.filesystem.create_file("dir/target", contents=target_contents) self.filesystem.create_symlink(link_name, target_path) obj = self.filesystem.resolve(link_name) self.assertEqual("target", obj.name) self.assertEqual(target_contents, obj.contents) def check_lresolve_object(self): target_path = "dir/target" target_contents = "0123456789ABCDEF" link_name = "x" self.filesystem.create_dir("dir") self.filesystem.create_file("dir/target", contents=target_contents) self.filesystem.create_symlink(link_name, target_path) obj = self.filesystem.lresolve(link_name) self.assertEqual(link_name, obj.name) self.assertEqual(target_path, obj.contents) def test_lresolve_object_windows(self): self.filesystem.is_windows_fs = True self.check_lresolve_object() def test_lresolve_object_posix(self): self.filesystem.is_windows_fs = False self.check_lresolve_object() def check_directory_access_on_file(self, error_subtype): self.filesystem.create_file("not_a_dir") with self.raises_os_error(error_subtype): self.filesystem.resolve("not_a_dir/foo") with self.raises_os_error(error_subtype): self.filesystem.lresolve("not_a_dir/foo/bar") def test_directory_access_on_file_windows(self): self.filesystem.is_windows_fs = True self.check_directory_access_on_file(errno.ENOENT) def test_directory_access_on_file_posix(self): self.filesystem.is_windows_fs = False self.check_directory_access_on_file(errno.ENOTDIR) def test_pickle_fs(self): """Regression test for #445""" import pickle self.filesystem.open_files = [] p = pickle.dumps(self.filesystem) fs = pickle.loads(p) self.assertEqual(str(fs.root), str(self.filesystem.root)) self.assertEqual(fs.mount_points, self.filesystem.mount_points) class CaseInsensitiveFakeFilesystemTest(TestCase): def setUp(self): self.filesystem = fake_filesystem.FakeFilesystem(path_separator="/") self.filesystem.is_case_sensitive = False self.os = fake_os.FakeOsModule(self.filesystem) self.path = self.os.path def test_get_object(self): self.filesystem.create_dir("/foo/bar") self.filesystem.create_file("/foo/bar/baz") self.assertTrue(self.filesystem.get_object("/Foo/Bar/Baz")) def test_remove_object(self): self.filesystem.create_dir("/foo/bar") self.filesystem.create_file("/foo/bar/baz") self.filesystem.remove_object("/Foo/Bar/Baz") self.assertFalse(self.filesystem.exists("/foo/bar/baz")) def test_exists(self): self.filesystem.create_dir("/Foo/Bar") self.assertTrue(self.filesystem.exists("/Foo/Bar")) self.assertTrue(self.filesystem.exists("/foo/bar")) self.filesystem.create_file("/foo/Bar/baz") self.assertTrue(self.filesystem.exists("/Foo/bar/BAZ")) self.assertTrue(self.filesystem.exists("/foo/bar/baz")) def test_create_directory_with_different_case_root(self): self.filesystem.create_dir("/Foo/Bar") self.filesystem.create_dir("/foo/bar/baz") dir1 = self.filesystem.get_object("/Foo/Bar") dir2 = self.filesystem.get_object("/foo/bar") self.assertEqual(dir1, dir2) def test_create_file_with_different_case_dir(self): self.filesystem.create_dir("/Foo/Bar") self.filesystem.create_file("/foo/bar/baz") dir1 = self.filesystem.get_object("/Foo/Bar") dir2 = self.filesystem.get_object("/foo/bar") self.assertEqual(dir1, dir2) def test_resolve_path(self): self.filesystem.create_dir("/foo/baz") self.filesystem.create_symlink("/Foo/Bar", "./baz/bip") self.assertEqual( f"{self.filesystem.root_dir_name}foo/baz/bip", self.filesystem.resolve_path("/foo/bar"), ) def test_isdir_isfile(self): self.filesystem.create_file("foo/bar") self.assertTrue(self.path.isdir("Foo")) self.assertFalse(self.path.isfile("Foo")) self.assertTrue(self.path.isfile("Foo/Bar")) self.assertFalse(self.path.isdir("Foo/Bar")) def test_getsize(self): file_path = "foo/bar/baz" self.filesystem.create_file(file_path, contents="1234567") self.assertEqual(7, self.path.getsize("FOO/BAR/BAZ")) def test_getsize_with_looping_symlink(self): self.filesystem.is_windows_fs = False dir_path = "/foo/bar" self.filesystem.create_dir(dir_path) link_path = dir_path + "/link" link_target = link_path + "/link" self.os.symlink(link_target, link_path) with self.raises_os_error(errno.ELOOP): self.os.path.getsize(link_path) def test_get_mtime(self): test_file = self.filesystem.create_file("foo/bar1.txt") test_file.st_mtime = 24 self.assertEqual(24, self.path.getmtime("Foo/Bar1.TXT")) def test_get_object_with_file_size(self): self.filesystem.create_file("/Foo/Bar", st_size=10) self.assertTrue(self.filesystem.get_object("/foo/bar")) class CaseSensitiveFakeFilesystemTest(TestCase): def setUp(self): self.filesystem = fake_filesystem.FakeFilesystem(path_separator="/") self.filesystem.is_case_sensitive = True self.os = fake_os.FakeOsModule(self.filesystem) self.path = self.os.path def test_get_object(self): self.filesystem.create_dir("/foo/bar") self.filesystem.create_file("/foo/bar/baz") with self.assertRaises(OSError): self.filesystem.get_object("/Foo/Bar/Baz") def test_remove_object(self): self.filesystem.create_dir("/foo/bar") self.filesystem.create_file("/foo/bar/baz") with self.assertRaises(OSError): self.filesystem.remove_object("/Foo/Bar/Baz") self.assertTrue(self.filesystem.exists("/foo/bar/baz")) def test_exists(self): self.filesystem.create_dir("/Foo/Bar") self.assertTrue(self.filesystem.exists("/Foo/Bar")) self.assertFalse(self.filesystem.exists("/foo/bar")) self.filesystem.create_file("/foo/Bar/baz") self.assertFalse(self.filesystem.exists("/Foo/bar/BAZ")) self.assertFalse(self.filesystem.exists("/foo/bar/baz")) def test_create_directory_with_different_case_root(self): self.filesystem.create_dir("/Foo/Bar") self.filesystem.create_dir("/foo/bar/baz") dir1 = self.filesystem.get_object("/Foo/Bar") dir2 = self.filesystem.get_object("/foo/bar") self.assertNotEqual(dir1, dir2) def test_create_file_with_different_case_dir(self): self.filesystem.create_dir("/Foo/Bar") self.filesystem.create_file("/foo/bar/baz") dir1 = self.filesystem.get_object("/Foo/Bar") dir2 = self.filesystem.get_object("/foo/bar") self.assertNotEqual(dir1, dir2) def test_isdir_isfile(self): self.filesystem.create_file("foo/bar") self.assertFalse(self.path.isdir("Foo")) self.assertFalse(self.path.isfile("Foo")) self.assertFalse(self.path.isfile("Foo/Bar")) self.assertFalse(self.path.isdir("Foo/Bar")) def test_getsize(self): file_path = "foo/bar/baz" self.filesystem.create_file(file_path, contents="1234567") with self.assertRaises(os.error): self.path.getsize("FOO/BAR/BAZ") def test_get_mtime(self): test_file = self.filesystem.create_file("foo/bar1.txt") test_file.st_mtime = 24 with self.raises_os_error(errno.ENOENT): self.path.getmtime("Foo/Bar1.TXT") class OsPathInjectionRegressionTest(TestCase): """Test faking os.path before calling os.walk. Found when investigating a problem with gws/tools/labrat/rat_utils_unittest, which was faking out os.path before calling os.walk. """ def setUp(self): self.filesystem = fake_filesystem.FakeFilesystem(path_separator="/") self.os_path = os.path # The bug was that when os.path gets faked, the FakePathModule doesn't # get called in self.os.walk(). FakePathModule now insists that it is # created as part of FakeOsModule. self.os = fake_os.FakeOsModule(self.filesystem) def tearDown(self): os.path = self.os_path def test_create_top_level_directory(self): top_level_dir = "/x" self.assertFalse(self.filesystem.exists(top_level_dir)) self.filesystem.create_dir(top_level_dir) self.assertTrue(self.filesystem.exists("/")) self.assertTrue(self.filesystem.exists(top_level_dir)) self.filesystem.create_dir("%s/po" % top_level_dir) self.filesystem.create_file("%s/po/control" % top_level_dir) self.filesystem.create_file("%s/po/experiment" % top_level_dir) self.filesystem.create_dir("%s/gv" % top_level_dir) self.filesystem.create_file("%s/gv/control" % top_level_dir) expected = [ ("/", ["x"], []), ("/x", ["gv", "po"], []), ("/x/gv", [], ["control"]), ("/x/po", [], ["control", "experiment"]), ] # as the result is unsorted, we have to check against sorted results result = sorted([step for step in self.os.walk("/")], key=lambda v: v[0]) self.assertEqual(len(expected), len(result)) for entry, expected_entry in zip(result, expected): self.assertEqual(expected_entry[0], entry[0]) self.assertEqual(expected_entry[1], sorted(entry[1])) self.assertEqual(expected_entry[2], sorted(entry[2])) class FakePathModuleTest(TestCase): def setUp(self): self.filesystem = fake_filesystem.FakeFilesystem(path_separator="!") self.os = fake_os.FakeOsModule(self.filesystem) self.path = self.os.path def check_abspath(self, is_windows): # the implementation differs in Windows and Posix, so test both self.filesystem.is_windows_fs = is_windows filename = "foo" abspath = self.filesystem.root_dir_name + filename self.filesystem.create_file(abspath) self.assertEqual(abspath, self.path.abspath(abspath)) self.assertEqual(abspath, self.path.abspath(filename)) self.assertEqual(abspath, self.path.abspath("..!%s" % filename)) def test_abspath_windows(self): self.check_abspath(is_windows=True) def test_abspath_posix(self): """abspath should return a consistent representation of a file.""" self.check_abspath(is_windows=False) def check_abspath_bytes(self, is_windows): """abspath should return a consistent representation of a file.""" self.filesystem.is_windows_fs = is_windows filename = b"foo" abspath = self.filesystem.root_dir_name.encode() + filename self.filesystem.create_file(abspath) self.assertEqual(abspath, self.path.abspath(abspath)) self.assertEqual(abspath, self.path.abspath(filename)) self.assertEqual(abspath, self.path.abspath(b"..!" + filename)) def test_abspath_bytes_windows(self): self.check_abspath_bytes(is_windows=True) def test_abspath_bytes_posix(self): self.check_abspath_bytes(is_windows=False) def test_abspath_deals_with_relative_non_root_path(self): """abspath should correctly handle relative paths from a non-! directory. This test is distinct from the basic functionality test because fake_filesystem has historically been based in !. """ filename = "!foo!bar!baz" file_components = filename.split(self.path.sep) root_name = self.filesystem.root_dir_name basedir = f"{root_name}{file_components[0]}" self.filesystem.create_file(filename) self.os.chdir(basedir) self.assertEqual(basedir, self.path.abspath(self.path.curdir)) self.assertEqual(root_name, self.path.abspath("..")) self.assertEqual( self.path.join(basedir, file_components[1]), self.path.abspath(file_components[1]), ) def test_abs_path_with_drive_component(self): self.filesystem.is_windows_fs = True self.filesystem.cwd = "C:!foo" self.assertEqual("C:!foo!bar", self.path.abspath("bar")) self.assertEqual("C:!foo!bar", self.path.abspath("C:bar")) self.assertEqual("C:!foo!bar", self.path.abspath("!foo!bar")) def test_isabs_with_drive_component(self): self.filesystem.is_windows_fs = False self.assertFalse(self.path.isabs("C:!foo")) self.assertFalse(self.path.isabs(b"C:!foo")) self.assertTrue(self.path.isabs("!")) self.assertTrue(self.path.isabs(b"!")) self.filesystem.is_windows_fs = True self.assertTrue(self.path.isabs("C:!foo")) self.assertTrue(self.path.isabs(b"C:!foo")) self.assertTrue(self.path.isabs("!")) self.assertTrue(self.path.isabs(b"!")) def test_relpath(self): path_foo = "!path!to!foo" path_bar = "!path!to!bar" path_other = "!some!where!else" with self.assertRaises(ValueError): self.path.relpath(None) with self.assertRaises(ValueError): self.path.relpath("") self.assertEqual("path!to!foo", self.path.relpath(path_foo)) self.assertEqual("..!foo", self.path.relpath(path_foo, path_bar)) self.assertEqual( "..!..!..%s" % path_other, self.path.relpath(path_other, path_bar) ) self.assertEqual(".", self.path.relpath(path_bar, path_bar)) def test_realpath_vs_abspath(self): self.filesystem.is_windows_fs = False self.filesystem.create_file("!george!washington!bridge") self.filesystem.create_symlink("!first!president", "!george!washington") self.assertEqual( "!first!president!bridge", self.os.path.abspath("!first!president!bridge"), ) self.assertEqual( "!george!washington!bridge", self.os.path.realpath("!first!president!bridge"), ) self.os.chdir("!first!president") self.assertEqual("!george!washington!bridge", self.os.path.realpath("bridge")) @unittest.skipIf(sys.version_info < (3, 10), "'strict' new in Python 3.10") def test_realpath_strict(self): self.filesystem.create_file("!foo!bar") root_dir = self.filesystem.root_dir_name self.filesystem.cwd = f"{root_dir}foo" self.assertEqual( f"{root_dir}foo!baz", self.os.path.realpath("baz", strict=False) ) with self.raises_os_error(errno.ENOENT): self.os.path.realpath("baz", strict=True) self.assertEqual( f"{root_dir}foo!bar", self.os.path.realpath("bar", strict=True) ) def test_samefile(self): file_path1 = "!foo!bar!baz" file_path2 = "!foo!bar!boo" self.filesystem.create_file(file_path1) self.filesystem.create_file(file_path2) self.assertTrue(self.path.samefile(file_path1, file_path1)) self.assertFalse(self.path.samefile(file_path1, file_path2)) self.assertTrue(self.path.samefile(file_path1, "!foo!..!foo!bar!..!bar!baz")) self.assertTrue(self.path.samefile(file_path1, b"!foo!..!foo!bar!..!bar!baz")) def test_exists(self): file_path = "foo!bar!baz" file_path_bytes = b"foo!bar!baz" self.filesystem.create_file(file_path) self.assertTrue(self.path.exists(file_path)) self.assertTrue(self.path.exists(file_path_bytes)) self.assertFalse(self.path.exists("!some!other!bogus!path")) def test_exists_with_drive(self): self.filesystem.os = OSType.WINDOWS self.filesystem.add_mount_point("F:") self.assertTrue(self.path.exists("C:")) self.assertTrue(self.path.exists("c:\\")) self.assertTrue(self.path.exists("f:")) self.assertTrue(self.path.exists("F:\\")) self.assertFalse(self.path.exists("Z:")) self.assertFalse(self.path.exists("z:\\")) def test_lexists(self): file_path = "foo!bar!baz" file_path_bytes = b"foo!bar!baz" self.filesystem.create_dir("foo!bar") self.filesystem.create_symlink(file_path, "bogus") self.assertTrue(self.path.lexists(file_path)) self.assertTrue(self.path.lexists(file_path_bytes)) self.assertFalse(self.path.exists(file_path)) self.assertFalse(self.path.exists(file_path_bytes)) self.filesystem.create_file("foo!bar!bogus") self.assertTrue(self.path.exists(file_path)) def test_dirname_with_drive(self): self.filesystem.is_windows_fs = True self.assertEqual("c:!foo", self.path.dirname("c:!foo!bar")) self.assertEqual(b"c:!", self.path.dirname(b"c:!foo")) self.assertEqual("!foo", self.path.dirname("!foo!bar")) self.assertEqual(b"!", self.path.dirname(b"!foo")) self.assertEqual("c:foo", self.path.dirname("c:foo!bar")) self.assertEqual(b"c:", self.path.dirname(b"c:foo")) self.assertEqual("foo", self.path.dirname("foo!bar")) def test_dirname(self): dirname = "foo!bar" self.assertEqual(dirname, self.path.dirname("%s!baz" % dirname)) def test_join_strings(self): components = ["foo", "bar", "baz"] self.assertEqual("foo!bar!baz", self.path.join(*components)) def test_join_bytes(self): components = [b"foo", b"bar", b"baz"] self.assertEqual(b"foo!bar!baz", self.path.join(*components)) def test_expand_user(self): if self.is_windows: self.assertEqual( self.path.expanduser("~"), self.os.environ["USERPROFILE"].replace("\\", "!"), ) else: self.assertEqual( self.path.expanduser("~"), self.os.environ["HOME"].replace("/", "!"), ) @unittest.skipIf( TestCase.is_windows or TestCase.is_cygwin, "only tested on unix systems", ) def test_expand_root(self): if sys.platform == "darwin": roothome = "!var!root" else: roothome = "!root" self.assertEqual(self.path.expanduser("~root"), roothome) def test_getsize_path_nonexistent(self): file_path = "foo!bar!baz" with self.assertRaises(os.error): self.path.getsize(file_path) def test_getsize_file_empty(self): file_path = "foo!bar!baz" self.filesystem.create_file(file_path) self.assertEqual(0, self.path.getsize(file_path)) def test_getsize_file_non_zero_size(self): file_path = "foo!bar!baz" file_path_bytes = b"foo!bar!baz" self.filesystem.create_file(file_path, contents="1234567") self.assertEqual(7, self.path.getsize(file_path)) self.assertEqual(7, self.path.getsize(file_path_bytes)) def test_getsize_dir_empty(self): # For directories, only require that the size is non-negative. dir_path = "foo!bar" self.filesystem.create_dir(dir_path) size = self.path.getsize(dir_path) self.assertFalse(int(size) < 0, "expected non-negative size; actual: %s" % size) def test_getsize_dir_non_zero_size(self): # For directories, only require that the size is non-negative. dir_path = "foo!bar" self.filesystem.create_file(self.filesystem.joinpaths(dir_path, "baz")) size = self.path.getsize(dir_path) self.assertFalse(int(size) < 0, "expected non-negative size; actual: %s" % size) def test_isdir(self): self.filesystem.create_file("foo!bar") self.assertTrue(self.path.isdir("foo")) self.assertTrue(self.path.isdir(b"foo")) self.assertFalse(self.path.isdir("foo!bar")) self.assertFalse(self.path.isdir("it_dont_exist")) def test_isdir_with_cwd_change(self): self.filesystem.create_file("!foo!bar!baz") self.assertTrue(self.path.isdir("!foo")) self.assertTrue(self.path.isdir("!foo!bar")) self.assertTrue(self.path.isdir("foo")) self.assertTrue(self.path.isdir("foo!bar")) self.filesystem.cwd = f"{self.filesystem.root_dir_name}foo" self.assertTrue(self.path.isdir("!foo")) self.assertTrue(self.path.isdir("!foo!bar")) self.assertTrue(self.path.isdir("bar")) def test_isfile(self): self.filesystem.create_file("foo!bar") self.assertFalse(self.path.isfile("foo")) self.assertTrue(self.path.isfile("foo!bar")) self.assertTrue(self.path.isfile(b"foo!bar")) self.assertFalse(self.path.isfile("it_dont_exist")) def test_get_mtime(self): test_file = self.filesystem.create_file("foo!bar1.txt") self.assertNotEqual(24, self.path.getmtime("foo!bar1.txt")) test_file.st_mtime = 24 self.assertEqual(24, self.path.getmtime("foo!bar1.txt")) self.assertEqual(24, self.path.getmtime(b"foo!bar1.txt")) def test_get_mtime_raises_os_error(self): self.assertFalse(self.path.exists("does_not_exist")) with self.raises_os_error(errno.ENOENT): self.path.getmtime("does_not_exist") def test_islink(self): self.filesystem.create_dir("foo") self.filesystem.create_file("foo!regular_file") self.filesystem.create_symlink("foo!link_to_file", "regular_file") self.assertFalse(self.path.islink("foo")) # An object can be both a link and a file or file, according to the # comments in Python/Lib/posixpath.py. self.assertTrue(self.path.islink("foo!link_to_file")) self.assertTrue(self.path.isfile("foo!link_to_file")) self.assertTrue(self.path.islink(b"foo!link_to_file")) self.assertTrue(self.path.isfile(b"foo!link_to_file")) self.assertTrue(self.path.isfile("foo!regular_file")) self.assertFalse(self.path.islink("foo!regular_file")) self.assertFalse(self.path.islink("it_dont_exist")) def test_is_link_case_sensitive(self): # Regression test for #306 self.filesystem.is_case_sensitive = False self.filesystem.create_dir("foo") self.filesystem.create_symlink("foo!bar", "foo") self.assertTrue(self.path.islink("foo!Bar")) def test_ismount(self): self.assertFalse(self.path.ismount("")) self.assertTrue(self.path.ismount("!")) self.assertTrue(self.path.ismount(b"!")) self.assertFalse(self.path.ismount("!mount!")) self.filesystem.add_mount_point("!mount") self.assertTrue(self.path.ismount("!mount")) self.assertTrue(self.path.ismount(b"!mount")) self.assertTrue(self.path.ismount("!mount!")) def test_ismount_with_drive_letters(self): self.filesystem.is_windows_fs = True self.assertTrue(self.path.ismount("!")) self.assertTrue(self.path.ismount("c:!")) self.assertFalse(self.path.ismount("c:")) self.assertTrue(self.path.ismount("z:!")) self.filesystem.add_mount_point("!mount") self.assertTrue(self.path.ismount("!mount")) self.assertTrue(self.path.ismount("!mount!")) def test_ismount_with_unc_paths(self): self.filesystem.is_windows_fs = True self.assertTrue(self.path.ismount("!!a!")) self.assertTrue(self.path.ismount("!!a!b")) self.assertTrue(self.path.ismount("!!a!b!")) self.assertFalse(self.path.ismount("!a!b!")) self.assertFalse(self.path.ismount("!!a!b!c")) def test_ismount_with_alternate_path_separator(self): self.filesystem.alternative_path_separator = "!" self.filesystem.add_mount_point("!mount") self.assertTrue(self.path.ismount("!mount")) self.assertTrue(self.path.ismount("!mount!")) self.assertTrue(self.path.ismount("!mount!!")) self.filesystem.is_windows_fs = True self.assertTrue(self.path.ismount("Z:!")) def test_getattr_forward_to_real_os_path(self): """Forwards any non-faked calls to os.path.""" self.assertTrue(hasattr(self.path, "sep"), "Get a faked os.path function") private_path_function = None if sys.version_info < (3, 6): if self.is_windows: private_path_function = "_get_bothseps" else: private_path_function = "_join_real_path" if private_path_function: self.assertTrue( hasattr(self.path, private_path_function), "Get a real os.path function " "not implemented in fake os.path", ) self.assertFalse(hasattr(self.path, "nonexistent")) def test_splitroot_posix(self): self.filesystem.is_windows_fs = False self.assertEqual(("", "", "foo!bar"), self.filesystem.splitroot("foo!bar")) self.assertEqual(("", "!", "foo!bar"), self.filesystem.splitroot("!foo!bar")) self.assertEqual( ("", "!!", "foo!!bar"), self.filesystem.splitroot("!!foo!!bar") ) class PathManipulationTestBase(TestCase): def setUp(self): self.filesystem = fake_filesystem.FakeFilesystem(path_separator="|") class CollapsePathPipeSeparatorTest(PathManipulationTestBase): """Tests CollapsePath (mimics os.path.normpath) using | as path separator.""" def test_empty_path_becomes_dot_path(self): self.assertEqual(".", self.filesystem.normpath("")) def test_dot_path_unchanged(self): self.assertEqual(".", self.filesystem.normpath(".")) def test_slashes_are_not_collapsed(self): """Tests that '/' is not treated specially if the path separator is '|'. In particular, multiple slashes should not be collapsed. """ self.assertEqual("/", self.filesystem.normpath("/")) self.assertEqual("/////", self.filesystem.normpath("/////")) def test_root_path(self): self.assertEqual("|", self.filesystem.normpath("|")) def test_multiple_separators_collapsed_into_root_path(self): self.assertEqual("|", self.filesystem.normpath("|||||")) def test_all_dot_paths_removed_but_one(self): self.assertEqual(".", self.filesystem.normpath(".|.|.|.")) def test_all_dot_paths_removed_if_another_path_component_exists(self): self.assertEqual("|", self.filesystem.normpath("|.|.|.|")) self.assertEqual("foo|bar", self.filesystem.normpath("foo|.|.|.|bar")) def test_ignores_up_level_references_starting_from_root(self): self.assertEqual("|", self.filesystem.normpath("|..|..|..|")) self.assertEqual("|", self.filesystem.normpath("|..|..|foo|bar|..|..|")) self.filesystem.is_windows_fs = False # not an UNC path self.assertEqual("|", self.filesystem.normpath("||..|.|..||")) def test_conserves_up_level_references_starting_from_current_dir(self): self.assertEqual("..|..", self.filesystem.normpath("..|foo|bar|..|..|..")) def test_combine_dot_and_up_level_references_in_absolute_path(self): self.assertEqual("|yes", self.filesystem.normpath("|||||.|..|||yes|no|..|.|||")) def test_dots_in_path_collapses_to_last_path(self): self.assertEqual("bar", self.filesystem.normpath("foo|..|bar")) self.assertEqual("bar", self.filesystem.normpath("foo|..|yes|..|no|..|bar")) class SplitPathTest(PathManipulationTestBase): """Tests SplitPath (which mimics os.path.split) using | as path separator.""" def test_empty_path(self): self.assertEqual(("", ""), self.filesystem.splitpath("")) def test_no_separators(self): self.assertEqual(("", "ab"), self.filesystem.splitpath("ab")) def test_slashes_do_not_split(self): """Tests that '/' is not treated specially if the path separator is '|'.""" self.assertEqual(("", "a/b"), self.filesystem.splitpath("a/b")) def test_eliminate_trailing_separators_from_head(self): self.assertEqual(("a", "b"), self.filesystem.splitpath("a|b")) self.assertEqual(("a", "b"), self.filesystem.splitpath("a|||b")) self.assertEqual(("|a", "b"), self.filesystem.splitpath("|a||b")) self.assertEqual(("a|b", "c"), self.filesystem.splitpath("a|b|c")) self.assertEqual(("|a|b", "c"), self.filesystem.splitpath("|a|b|c")) def test_root_separator_is_not_stripped(self): self.assertEqual(("|||", ""), self.filesystem.splitpath("|||")) self.assertEqual(("|", "a"), self.filesystem.splitpath("|a")) self.assertEqual(("|||", "a"), self.filesystem.splitpath("|||a")) def test_empty_tail_if_path_ends_in_separator(self): self.assertEqual(("a|b", ""), self.filesystem.splitpath("a|b|")) def test_empty_path_components_are_preserved_in_head(self): self.assertEqual(("|a||b", "c"), self.filesystem.splitpath("|a||b||c")) class JoinPathTest(PathManipulationTestBase): """Tests JoinPath (which mimics os.path.join) using | as path separator.""" def test_one_empty_component(self): self.assertEqual("", self.filesystem.joinpaths("")) def test_multiple_empty_components(self): self.assertEqual("", self.filesystem.joinpaths("", "", "")) def test_separators_not_stripped_from_single_component(self): self.assertEqual("||a||", self.filesystem.joinpaths("||a||")) def test_one_separator_added_between_components(self): self.assertEqual("a|b|c|d", self.filesystem.joinpaths("a", "b", "c", "d")) def test_no_separator_added_for_components_ending_in_separator(self): self.assertEqual("a|b|c", self.filesystem.joinpaths("a|", "b|", "c")) self.assertEqual("a|||b|||c", self.filesystem.joinpaths("a|||", "b|||", "c")) def test_components_preceding_absolute_component_are_ignored(self): self.assertEqual("|c|d", self.filesystem.joinpaths("a", "|b", "|c", "d")) def test_one_separator_added_for_trailing_empty_components(self): self.assertEqual("a|", self.filesystem.joinpaths("a", "")) self.assertEqual("a|", self.filesystem.joinpaths("a", "", "")) def test_no_separator_added_for_leading_empty_components(self): self.assertEqual("a", self.filesystem.joinpaths("", "a")) def test_internal_empty_components_ignored(self): self.assertEqual("a|b", self.filesystem.joinpaths("a", "", "b")) self.assertEqual("a|b|", self.filesystem.joinpaths("a|", "", "b|")) class PathSeparatorTest(TestCase): def test_os_path_sep_matches_fake_filesystem_separator(self): filesystem = fake_filesystem.FakeFilesystem(path_separator="!") fake_os_module = fake_os.FakeOsModule(filesystem) self.assertEqual("!", fake_os_module.sep) self.assertEqual("!", fake_os_module.path.sep) class NormalizeCaseTest(TestCase): def setUp(self): self.filesystem = fake_filesystem.FakeFilesystem(path_separator="/") self.filesystem.is_case_sensitive = False def test_normalize_case(self): self.filesystem.create_file("/Foo/Bar") self.assertEqual( f"{self.filesystem.root_dir_name}Foo/Bar", self.filesystem._original_path("/foo/bar"), ) self.assertEqual( f"{self.filesystem.root_dir_name}Foo/Bar", self.filesystem._original_path("/FOO/BAR"), ) def test_normalize_case_for_drive(self): self.filesystem.is_windows_fs = True self.filesystem.create_file("C:/Foo/Bar") self.assertEqual("C:/Foo/Bar", self.filesystem._original_path("c:/foo/bar")) self.assertEqual("C:/Foo/Bar", self.filesystem._original_path("C:/FOO/BAR")) def test_normalize_case_for_non_existing_file(self): self.filesystem.create_dir("/Foo/Bar") self.assertEqual( f"{self.filesystem.root_dir_name}Foo/Bar/baz", self.filesystem._original_path("/foo/bar/baz"), ) self.assertEqual( f"{self.filesystem.root_dir_name}Foo/Bar/BAZ", self.filesystem._original_path("/FOO/BAR/BAZ"), ) @unittest.skipIf( not TestCase.is_windows, "Regression test for Windows problem only" ) def test_normalize_case_for_lazily_added_empty_file(self): # regression test for specific issue with added empty real files filesystem = fake_filesystem.FakeFilesystem() real_dir_path = os.path.split(os.path.dirname(os.path.abspath(__file__)))[0] filesystem.add_real_directory(real_dir_path) initPyPath = os.path.join(real_dir_path, "__init__.py") self.assertEqual(initPyPath, filesystem._original_path(initPyPath.upper())) class AlternativePathSeparatorTest(TestCase): def setUp(self): self.filesystem = fake_filesystem.FakeFilesystem(path_separator="!") self.filesystem.alternative_path_separator = "?" def test_initial_value(self): filesystem = fake_filesystem.FakeFilesystem() if self.is_windows: self.assertEqual("/", filesystem.alternative_path_separator) else: self.assertIsNone(filesystem.alternative_path_separator) filesystem = fake_filesystem.FakeFilesystem(path_separator="/") self.assertIsNone(filesystem.alternative_path_separator) def test_alt_sep(self): fake_os_module = fake_os.FakeOsModule(self.filesystem) self.assertEqual("?", fake_os_module.altsep) self.assertEqual("?", fake_os_module.path.altsep) def test_collapse_path_with_mixed_separators(self): self.assertEqual("!foo!bar", self.filesystem.normpath("!foo??bar")) def test_normalize_path_with_mixed_separators(self): path = "foo?..?bar" self.assertEqual( f"{self.filesystem.root_dir_name}bar", self.filesystem.absnormpath(path), ) def test_exists_with_mixed_separators(self): self.filesystem.create_file("?foo?bar?baz") self.filesystem.create_file("!foo!bar!xyzzy!plugh") self.assertTrue(self.filesystem.exists("!foo!bar!baz")) self.assertTrue(self.filesystem.exists("?foo?bar?xyzzy?plugh")) class DriveLetterSupportTest(TestCase): def setUp(self): self.filesystem = fake_filesystem.FakeFilesystem(path_separator="!") self.filesystem.alternative_path_separator = "^" self.filesystem.is_windows_fs = True def test_initial_value(self): filesystem = fake_filesystem.FakeFilesystem() if self.is_windows: self.assertTrue(filesystem.is_windows_fs) else: self.assertFalse(filesystem.is_windows_fs) def test_collapse_path(self): self.assertEqual("c:!foo!bar", self.filesystem.normpath("c:!!foo!!bar")) def test_collapse_unc_path(self): self.assertEqual("!!foo!bar!baz", self.filesystem.normpath("!!foo!bar!!baz!!")) def test_normalize_path_str(self): self.filesystem.cwd = "" self.assertEqual("c:!foo!bar", self.filesystem.absnormpath("c:!foo!!bar")) self.filesystem.cwd = "c:!foo" self.assertEqual("c:!foo!bar", self.filesystem.absnormpath("bar")) def test_normalize_path_bytes(self): self.filesystem.cwd = b"" self.assertEqual(b"c:!foo!bar", self.filesystem.absnormpath(b"c:!foo!!bar")) self.filesystem.cwd = b"c:!foo" self.assertEqual(b"c:!foo!bar", self.filesystem.absnormpath(b"bar")) def test_split_path_str(self): self.assertEqual(("c:!foo", "bar"), self.filesystem.splitpath("c:!foo!bar")) self.assertEqual(("c:!", "foo"), self.filesystem.splitpath("c:!foo")) self.assertEqual(("!foo", "bar"), self.filesystem.splitpath("!foo!bar")) self.assertEqual(("!", "foo"), self.filesystem.splitpath("!foo")) self.assertEqual(("c:foo", "bar"), self.filesystem.splitpath("c:foo!bar")) self.assertEqual(("c:", "foo"), self.filesystem.splitpath("c:foo")) self.assertEqual(("foo", "bar"), self.filesystem.splitpath("foo!bar")) def test_split_with_alt_separator(self): self.assertEqual(("a^b", "c"), self.filesystem.splitpath("a^b^c")) self.assertEqual(("a^b!c", "d"), self.filesystem.splitpath("a^b!c^d")) self.assertEqual(("a^b!c", "d"), self.filesystem.splitpath("a^b!c!d")) self.assertEqual((b"a^b", b"c"), self.filesystem.splitpath(b"a^b^c")) self.assertEqual((b"a^b!c", b"d"), self.filesystem.splitpath(b"a^b!c^d")) self.assertEqual((b"a^b!c", b"d"), self.filesystem.splitpath(b"a^b!c!d")) def test_split_path_bytes(self): self.assertEqual((b"c:!foo", b"bar"), self.filesystem.splitpath(b"c:!foo!bar")) self.assertEqual((b"c:!", b"foo"), self.filesystem.splitpath(b"c:!foo")) self.assertEqual((b"!foo", b"bar"), self.filesystem.splitpath(b"!foo!bar")) self.assertEqual((b"!", b"foo"), self.filesystem.splitpath(b"!foo")) self.assertEqual((b"c:foo", b"bar"), self.filesystem.splitpath(b"c:foo!bar")) self.assertEqual((b"c:", b"foo"), self.filesystem.splitpath(b"c:foo")) self.assertEqual((b"foo", b"bar"), self.filesystem.splitpath(b"foo!bar")) def test_characters_before_root_ignored_in_join_paths(self): self.assertEqual("c:d", self.filesystem.joinpaths("b", "c:", "d")) def test_resolve_path(self): self.assertEqual("C:!foo!bar", self.filesystem.resolve_path("C:!foo!bar")) def test_get_path_components(self): self.assertEqual( ["c:", "foo", "bar"], self.filesystem._path_components("c:!foo!bar"), ) self.assertEqual(["c:"], self.filesystem._path_components("c:")) def test_split_drive_str(self): self.assertEqual(("c:", "!foo!bar"), self.filesystem.splitdrive("c:!foo!bar")) self.assertEqual(("", "!foo!bar"), self.filesystem.splitdrive("!foo!bar")) self.assertEqual(("c:", "foo!bar"), self.filesystem.splitdrive("c:foo!bar")) self.assertEqual(("", "foo!bar"), self.filesystem.splitdrive("foo!bar")) def test_split_drive_bytes(self): self.assertEqual( (b"c:", b"!foo!bar"), self.filesystem.splitdrive(b"c:!foo!bar") ) self.assertEqual((b"", b"!foo!bar"), self.filesystem.splitdrive(b"!foo!bar")) def test_split_drive_alt_sep(self): self.assertEqual(("c:", "^foo^bar"), self.filesystem.splitdrive("c:^foo^bar")) self.assertEqual(("", "foo^bar"), self.filesystem.splitdrive("foo^bar")) self.assertEqual(("", "foo^bar!baz"), self.filesystem.splitdrive("foo^bar!baz")) self.assertEqual( (b"c:", b"^foo^bar"), self.filesystem.splitdrive(b"c:^foo^bar") ) self.assertEqual((b"", b"^foo^bar"), self.filesystem.splitdrive(b"^foo^bar")) self.assertEqual( (b"", b"^foo^bar!baz"), self.filesystem.splitdrive(b"^foo^bar!baz") ) def test_split_drive_with_unc_path(self): self.assertEqual( ("!!foo!bar", "!baz"), self.filesystem.splitdrive("!!foo!bar!baz") ) self.assertEqual(("", "!!foo"), self.filesystem.splitdrive("!!foo")) self.assertEqual(("", "!!foo!!bar"), self.filesystem.splitdrive("!!foo!!bar")) self.assertEqual(("!!foo!bar", "!!"), self.filesystem.splitdrive("!!foo!bar!!")) def test_split_drive_with_unc_path_alt_sep(self): self.assertEqual( ("^^foo^bar", "!baz"), self.filesystem.splitdrive("^^foo^bar!baz") ) self.assertEqual(("", "^^foo"), self.filesystem.splitdrive("^^foo")) self.assertEqual(("", "^^foo^^bar"), self.filesystem.splitdrive("^^foo^^bar")) self.assertEqual(("^^foo^bar", "^^"), self.filesystem.splitdrive("^^foo^bar^^")) def test_split_path_with_drive(self): self.assertEqual(("d:!foo", "baz"), self.filesystem.splitpath("d:!foo!baz")) self.assertEqual(("d:!foo!baz", ""), self.filesystem.splitpath("d:!foo!baz!")) self.assertEqual(("c:", ""), self.filesystem.splitpath("c:")) self.assertEqual(("c:!", ""), self.filesystem.splitpath("c:!")) self.assertEqual(("c:!!", ""), self.filesystem.splitpath("c:!!")) def test_split_path_with_drive_alt_sep(self): self.assertEqual(("d:^foo", "baz"), self.filesystem.splitpath("d:^foo^baz")) self.assertEqual(("d:^foo^baz", ""), self.filesystem.splitpath("d:^foo^baz^")) self.assertEqual(("c:", ""), self.filesystem.splitpath("c:")) self.assertEqual(("c:^", ""), self.filesystem.splitpath("c:^")) self.assertEqual(("c:^^", ""), self.filesystem.splitpath("c:^^")) def test_split_path_with_unc_path(self): self.assertEqual( ("!!foo!bar!", "baz"), self.filesystem.splitpath("!!foo!bar!baz") ) self.assertEqual(("!!foo!bar", ""), self.filesystem.splitpath("!!foo!bar")) self.assertEqual(("!!foo!bar!!", ""), self.filesystem.splitpath("!!foo!bar!!")) def test_split_path_with_unc_path_alt_sep(self): self.assertEqual( ("^^foo^bar^", "baz"), self.filesystem.splitpath("^^foo^bar^baz") ) self.assertEqual(("^^foo^bar", ""), self.filesystem.splitpath("^^foo^bar")) self.assertEqual(("^^foo^bar^^", ""), self.filesystem.splitpath("^^foo^bar^^")) def test_splitroot_with_drive(self): self.assertEqual( ("E:", "!", "foo!bar"), self.filesystem.splitroot("E:!foo!bar") ) self.assertEqual( ("E:", "!", "!foo!!!bar"), self.filesystem.splitroot("E:!!foo!!!bar") ) self.assertEqual( (b"E:", b"!", b"!foo!!!bar"), self.filesystem.splitroot(b"E:!!foo!!!bar") ) self.assertEqual( ("C:", "^", "foo^bar"), self.filesystem.splitroot("C:^foo^bar") ) def test_splitroot_with_unc_path(self): self.assertEqual( ("!!foo!bar", "!", "baz"), self.filesystem.splitroot("!!foo!bar!baz") ) self.assertEqual( ("!!?!UNC", "!", "foo!bar"), self.filesystem.splitroot("!!?!UNC!foo!bar") ) self.assertEqual( ("^^foo^bar", "^", "baz"), self.filesystem.splitroot("^^foo^bar^baz") ) self.assertEqual( (b"!!foo!bar", b"!", b"baz"), self.filesystem.splitroot(b"!!foo!bar!baz") ) def test_splitroot_with_empty_parts(self): self.assertEqual(("", "", ""), self.filesystem.splitroot("")) self.assertEqual(("", "!", "foo"), self.filesystem.splitroot("!foo")) self.assertEqual(("!!foo!bar", "", ""), self.filesystem.splitroot("!!foo!bar")) self.assertEqual(("!!foo", "", ""), self.filesystem.splitroot("!!foo")) self.assertEqual( ("!!foo!bar", "!", ""), self.filesystem.splitroot("!!foo!bar!") ) self.assertEqual(("C:", "", "foo!bar"), self.filesystem.splitroot("C:foo!bar")) class DiskSpaceTest(TestCase): def setUp(self): self.fs = fake_filesystem.FakeFilesystem(path_separator="!", total_size=100) self.os = fake_os.FakeOsModule(self.fs) self.open = fake_open.FakeFileOpen(self.fs) def test_disk_usage_on_file_creation(self): total_size = 100 self.fs.add_mount_point("!mount", total_size) def create_too_large_file(): with self.open("!mount!file", "w") as dest: dest.write("a" * (total_size + 1)) with self.assertRaises(OSError): create_too_large_file() self.assertEqual(0, self.fs.get_disk_usage("!mount").used) with self.open("!mount!file", "w") as dest: dest.write("a" * total_size) self.assertEqual(total_size, self.fs.get_disk_usage("!mount").used) def test_disk_usage_on_automounted_drive(self): self.fs.is_windows_fs = True self.fs.reset(total_size=100) self.fs.create_file("!foo!bar", st_size=50) self.assertEqual(0, self.fs.get_disk_usage("D:!").used) self.fs.cwd = "E:!foo" self.assertEqual(0, self.fs.get_disk_usage("!foo").used) def test_disk_usage_on_mounted_paths(self): self.fs.add_mount_point("!foo", total_size=200) self.fs.add_mount_point("!foo!bar", total_size=400) self.fs.create_file("!baz", st_size=50) self.fs.create_file("!foo!baz", st_size=60) self.fs.create_file("!foo!bar!baz", st_size=100) self.assertEqual(50, self.fs.get_disk_usage("!").used) self.assertEqual(60, self.fs.get_disk_usage("!foo").used) self.assertEqual(100, self.fs.get_disk_usage("!foo!bar").used) self.assertEqual(400, self.fs.get_disk_usage("!foo!bar").total) def test_file_system_size_after_large_file_creation(self): filesystem = fake_filesystem.FakeFilesystem( path_separator="!", total_size=1024 * 1024 * 1024 * 100 ) filesystem.create_file("!foo!baz", st_size=1024 * 1024 * 1024 * 10) self.assertEqual( ( 1024 * 1024 * 1024 * 100, 1024 * 1024 * 1024 * 10, 1024 * 1024 * 1024 * 90, ), filesystem.get_disk_usage(), ) def test_file_system_size_after_binary_file_creation(self): self.fs.create_file("!foo!bar", contents=b"xyzzy") self.assertEqual((100, 5, 95), self.fs.get_disk_usage()) def test_file_system_size_after_ascii_string_file_creation(self): self.fs.create_file("!foo!bar", contents="complicated") self.assertEqual((100, 11, 89), self.fs.get_disk_usage()) def test_filesystem_size_after_2byte_unicode_file_creation(self): self.fs.create_file("!foo!bar", contents="сложно", encoding="utf-8") self.assertEqual((100, 12, 88), self.fs.get_disk_usage()) def test_filesystem_size_after_3byte_unicode_file_creation(self): self.fs.create_file("!foo!bar", contents="複雑", encoding="utf-8") self.assertEqual((100, 6, 94), self.fs.get_disk_usage()) def test_file_system_size_after_file_deletion(self): self.fs.create_file("!foo!bar", contents=b"xyzzy") self.fs.create_file("!foo!baz", st_size=20) self.fs.remove_object("!foo!bar") self.assertEqual((100, 20, 80), self.fs.get_disk_usage()) def test_file_system_size_after_directory_removal(self): self.fs.create_file("!foo!bar", st_size=10) self.fs.create_file("!foo!baz", st_size=20) self.fs.create_file("!foo1!bar", st_size=40) self.fs.remove_object("!foo") self.assertEqual((100, 40, 60), self.fs.get_disk_usage()) def test_creating_file_with_fitting_content(self): initial_usage = self.fs.get_disk_usage() try: self.fs.create_file("!foo!bar", contents=b"a" * 100) except OSError: self.fail( "File with contents fitting into disk space " "could not be written." ) self.assertEqual(initial_usage.used + 100, self.fs.get_disk_usage().used) def test_creating_file_with_content_too_large(self): def create_large_file(): self.fs.create_file("!foo!bar", contents=b"a" * 101) initial_usage = self.fs.get_disk_usage() with self.assertRaises(OSError): create_large_file() self.assertEqual(initial_usage, self.fs.get_disk_usage()) def test_creating_file_with_fitting_size(self): initial_usage = self.fs.get_disk_usage() try: self.fs.create_file("!foo!bar", st_size=100) except OSError: self.fail("File with size fitting into disk space could not be written.") self.assertEqual(initial_usage.used + 100, self.fs.get_disk_usage().used) def test_creating_file_with_size_too_large(self): initial_usage = self.fs.get_disk_usage() def create_large_file(): self.fs.create_file("!foo!bar", st_size=101) with self.assertRaises(OSError): create_large_file() self.assertEqual(initial_usage, self.fs.get_disk_usage()) def test_resize_file_with_fitting_size(self): file_object = self.fs.create_file("!foo!bar", st_size=50) try: file_object.set_large_file_size(100) file_object.set_contents(b"a" * 100) except OSError: self.fail("Resizing file failed although disk space was sufficient.") def test_resize_file_with_size_too_large(self): file_object = self.fs.create_file("!foo!bar", st_size=50) with self.raises_os_error(errno.ENOSPC): file_object.set_large_file_size(200) with self.raises_os_error(errno.ENOSPC): file_object.set_contents("a" * 150) def test_file_system_size_after_directory_rename(self): self.fs.create_file("!foo!bar", st_size=20) self.os.rename("!foo", "!baz") self.assertEqual(20, self.fs.get_disk_usage().used) def test_file_system_size_after_file_rename(self): self.fs.create_file("!foo!bar", st_size=20) self.os.rename("!foo!bar", "!foo!baz") self.assertEqual(20, self.fs.get_disk_usage().used) def test_that_hard_link_does_not_change_used_size(self): file1_path = "test_file1" file2_path = "test_file2" self.fs.create_file(file1_path, st_size=20) self.assertEqual(20, self.fs.get_disk_usage().used) # creating a hard link shall not increase used space self.os.link(file1_path, file2_path) self.assertEqual(20, self.fs.get_disk_usage().used) # removing a file shall not decrease used space # if a hard link still exists self.os.unlink(file1_path) self.assertEqual(20, self.fs.get_disk_usage().used) self.os.unlink(file2_path) self.assertEqual(0, self.fs.get_disk_usage().used) def test_that_the_size_of_correct_mount_point_is_used(self): self.fs.add_mount_point("!mount_limited", total_size=50) self.fs.add_mount_point("!mount_unlimited") with self.raises_os_error(errno.ENOSPC): self.fs.create_file("!mount_limited!foo", st_size=60) with self.raises_os_error(errno.ENOSPC): self.fs.create_file("!bar", st_size=110) try: self.fs.create_file("!foo", st_size=60) self.fs.create_file("!mount_limited!foo", st_size=40) self.fs.create_file("!mount_unlimited!foo", st_size=1000000) except OSError: self.fail( "File with contents fitting into " "disk space could not be written." ) def test_that_disk_usage_of_correct_mount_point_is_used(self): self.fs.add_mount_point("!mount1", total_size=20) self.fs.add_mount_point("!mount1!bar!mount2", total_size=50) self.fs.create_file("!foo!bar", st_size=10) self.fs.create_file("!mount1!foo!bar", st_size=10) self.fs.create_file("!mount1!bar!mount2!foo!bar", st_size=10) self.assertEqual(90, self.fs.get_disk_usage("!foo").free) self.assertEqual(10, self.fs.get_disk_usage("!mount1!foo").free) self.assertEqual(40, self.fs.get_disk_usage("!mount1!bar!mount2").free) def test_set_larger_disk_size(self): self.fs.add_mount_point("!mount1", total_size=20) with self.raises_os_error(errno.ENOSPC): self.fs.create_file("!mount1!foo", st_size=100) self.fs.set_disk_usage(total_size=200, path="!mount1") self.fs.create_file("!mount1!foo", st_size=100) self.assertEqual(100, self.fs.get_disk_usage("!mount1!foo").free) def test_set_smaller_disk_size(self): self.fs.add_mount_point("!mount1", total_size=200) self.fs.create_file("!mount1!foo", st_size=100) with self.raises_os_error(errno.ENOSPC): self.fs.set_disk_usage(total_size=50, path="!mount1") self.fs.set_disk_usage(total_size=150, path="!mount1") self.assertEqual(50, self.fs.get_disk_usage("!mount1!foo").free) def test_disk_size_on_unlimited_disk(self): self.fs.add_mount_point("!mount1") self.fs.create_file("!mount1!foo", st_size=100) self.fs.set_disk_usage(total_size=1000, path="!mount1") self.assertEqual(900, self.fs.get_disk_usage("!mount1!foo").free) def test_disk_size_on_auto_mounted_drive_on_file_creation(self): self.fs.is_windows_fs = True # drive d: shall be auto-mounted and the used size adapted self.fs.create_file("d:!foo!bar", st_size=100) self.fs.set_disk_usage(total_size=1000, path="d:") self.assertEqual(self.fs.get_disk_usage("d:!foo").free, 900) def test_disk_size_on_auto_mounted_drive_on_directory_creation(self): self.fs.is_windows_fs = True self.fs.create_dir("d:!foo!bar") self.fs.create_file("d:!foo!bar!baz", st_size=100) self.fs.create_file("d:!foo!baz", st_size=100) self.fs.set_disk_usage(total_size=1000, path="d:") self.assertEqual(800, self.fs.get_disk_usage("d:!foo").free) def test_copying_preserves_byte_contents(self): source_file = self.fs.create_file("foo", contents=b"somebytes") dest_file = self.fs.create_file("bar") dest_file.set_contents(source_file.contents) self.assertEqual(dest_file.contents, source_file.contents) def test_diskusage_after_open_write(self): with self.open("bar.txt", "w") as f: f.write("a" * 60) f.flush() self.assertEqual(60, self.fs.get_disk_usage()[1]) def test_disk_full_after_reopened(self): with self.open("bar.txt", "w") as f: f.write("a" * 60) with self.open("bar.txt") as f: self.assertEqual("a" * 60, f.read()) with self.raises_os_error(errno.ENOSPC): with self.open("bar.txt", "w") as f: f.write("b" * 110) with self.raises_os_error(errno.ENOSPC): f.flush() with self.open("bar.txt") as f: self.assertEqual("", f.read()) def test_disk_full_append(self): file_path = "bar.txt" with self.open(file_path, "w") as f: f.write("a" * 60) with self.open(file_path) as f: self.assertEqual("a" * 60, f.read()) with self.raises_os_error(errno.ENOSPC): with self.open(file_path, "a") as f: f.write("b" * 41) with self.raises_os_error(errno.ENOSPC): f.flush() with self.open("bar.txt") as f: self.assertEqual(f.read(), "a" * 60) def test_disk_full_after_reopened_rplus_seek(self): with self.open("bar.txt", "w") as f: f.write("a" * 60) with self.open("bar.txt") as f: self.assertEqual(f.read(), "a" * 60) with self.raises_os_error(errno.ENOSPC): with self.open("bar.txt", "r+") as f: f.seek(50) f.write("b" * 60) with self.raises_os_error(errno.ENOSPC): f.flush() with self.open("bar.txt") as f: self.assertEqual(f.read(), "a" * 60) class MountPointTest(TestCase): def setUp(self): self.filesystem = fake_filesystem.FakeFilesystem( path_separator="!", total_size=100 ) def add_mount_points(self): self.filesystem.add_mount_point("!foo") self.filesystem.add_mount_point("!bar") self.filesystem.add_mount_point("!foo!baz") def test_that_new_mount_points_get_new_device_number(self): self.add_mount_points() self.assertEqual(1, self.filesystem.get_object("!").st_dev) self.assertEqual(2, self.filesystem.get_object("!foo").st_dev) self.assertEqual(3, self.filesystem.get_object("!bar").st_dev) self.assertEqual(4, self.filesystem.get_object("!foo!baz").st_dev) def test_that_new_directories_get_correct_device_number(self): self.add_mount_points() self.assertEqual(1, self.filesystem.create_dir("!foo1!bar").st_dev) self.assertEqual(2, self.filesystem.create_dir("!foo!bar").st_dev) self.assertEqual(4, self.filesystem.create_dir("!foo!baz!foo!bar").st_dev) def test_that_new_files_get_correct_device_number(self): self.add_mount_points() self.assertEqual(1, self.filesystem.create_file("!foo1!bar").st_dev) self.assertEqual(2, self.filesystem.create_file("!foo!bar").st_dev) self.assertEqual(4, self.filesystem.create_file("!foo!baz!foo!bar").st_dev) def test_that_mount_point_cannot_be_added_twice(self): self.add_mount_points() with self.raises_os_error(errno.EEXIST): self.filesystem.add_mount_point("!foo") with self.raises_os_error(errno.EEXIST): self.filesystem.add_mount_point("!foo!") def test_that_drives_are_auto_mounted(self): self.filesystem.is_windows_fs = True self.add_mount_points() self.filesystem.create_dir("d:!foo!bar") self.filesystem.create_file("d:!foo!baz") self.filesystem.create_file("z:!foo!baz") self.assertEqual(5, self.filesystem.get_object("d:").st_dev) self.assertEqual(5, self.filesystem.get_object("d:!foo!bar").st_dev) self.assertEqual(5, self.filesystem.get_object("d:!foo!baz").st_dev) self.assertEqual(6, self.filesystem.get_object("z:!foo!baz").st_dev) def test_that_drives_are_auto_mounted_case_insensitive(self): self.filesystem.is_windows_fs = True self.add_mount_points() self.filesystem.is_case_sensitive = False self.filesystem.create_dir("D:!foo!bar") self.filesystem.create_file("e:!foo!baz") self.assertEqual(5, self.filesystem.get_object("D:").st_dev) self.assertEqual(5, self.filesystem.get_object("d:!foo!bar").st_dev) self.assertEqual(6, self.filesystem.get_object("e:!foo").st_dev) self.assertEqual(6, self.filesystem.get_object("E:!Foo!Baz").st_dev) def test_that_unc_paths_are_auto_mounted(self): self.filesystem.is_windows_fs = True self.add_mount_points() self.filesystem.create_dir("!!foo!bar!baz") self.filesystem.create_file("!!foo!bar!bip!bop") self.assertEqual(5, self.filesystem.get_object("!!foo!bar").st_dev) self.assertEqual(5, self.filesystem.get_object("!!foo!bar!bip!bop").st_dev) class ConvenienceMethodTest(RealFsTestCase): def test_create_link_with_non_existent_parent(self): self.skip_if_symlink_not_supported() file1_path = self.make_path("test_file1") link_path = self.make_path("nonexistent", "test_file2") self.filesystem.create_file(file1_path, contents="link test") self.assertEqual(self.os.stat(file1_path).st_nlink, 1) self.filesystem.create_link(file1_path, link_path) self.assertEqual(self.os.stat(file1_path).st_nlink, 2) self.assertTrue(self.filesystem.exists(link_path)) def test_create_symlink_with_non_existent_parent(self): self.skip_if_symlink_not_supported() file1_path = self.make_path("test_file1") link_path = self.make_path("nonexistent", "test_file2") self.filesystem.create_file(file1_path, contents="symlink test") self.filesystem.create_symlink(link_path, file1_path) self.assertTrue(self.filesystem.exists(link_path)) self.assertTrue(self.filesystem.islink(link_path)) class RealFileSystemAccessTest(RealFsTestCase): def setUp(self): # use the real path separator to work with the real file system self.filesystem = fake_filesystem.FakeFilesystem() self.fake_open = fake_filesystem.FakeFileOpen(self.filesystem) self.pyfakefs_path = os.path.split(os.path.dirname(os.path.abspath(__file__)))[ 0 ] self.root_path = os.path.split(self.pyfakefs_path)[0] def test_add_non_existing_real_file_raises(self): nonexisting_path = os.path.join("nonexisting", "test.txt") with self.assertRaises(OSError): self.filesystem.add_real_file(nonexisting_path) self.assertFalse(self.filesystem.exists(nonexisting_path)) def test_add_non_existing_real_directory_raises(self): nonexisting_path = "/nonexisting" with self.raises_os_error(errno.ENOENT): self.filesystem.add_real_directory(nonexisting_path) self.assertFalse(self.filesystem.exists(nonexisting_path)) def test_existing_fake_file_raises(self): real_file_path = __file__ self.filesystem.create_file(real_file_path) with self.raises_os_error(errno.EEXIST): self.filesystem.add_real_file(real_file_path) def test_existing_fake_directory_raises(self): self.filesystem.create_dir(self.root_path) with self.raises_os_error(errno.EEXIST): self.filesystem.add_real_directory(self.root_path) def check_fake_file_stat(self, fake_file, real_file_path, target_path=None): if target_path is None or target_path == real_file_path: self.assertTrue(self.filesystem.exists(real_file_path)) else: self.assertFalse(self.filesystem.exists(real_file_path)) self.assertTrue(self.filesystem.exists(target_path)) real_stat = os.stat(real_file_path) self.assertIsNone(fake_file._byte_contents) self.assertEqual(fake_file.st_size, real_stat.st_size) self.assertAlmostEqual(fake_file.st_ctime, real_stat.st_ctime, places=5) self.assertAlmostEqual(fake_file.st_atime, real_stat.st_atime, places=5) self.assertAlmostEqual(fake_file.st_mtime, real_stat.st_mtime, places=5) self.assertEqual(fake_file.st_uid, real_stat.st_uid) self.assertEqual(fake_file.st_gid, real_stat.st_gid) def check_read_only_file(self, fake_file, real_file_path): with open(real_file_path, "rb") as f: real_contents = f.read() self.assertEqual(fake_file.byte_contents, real_contents) if not is_root(): with self.raises_os_error(errno.EACCES): self.fake_open(real_file_path, "w") else: with self.fake_open(real_file_path, "w"): pass def check_writable_file(self, fake_file, real_file_path): with open(real_file_path, "rb") as f: real_contents = f.read() self.assertEqual(fake_file.byte_contents, real_contents) with self.fake_open(real_file_path, "wb") as f: f.write(b"test") with open(real_file_path, "rb") as f: real_contents1 = f.read() self.assertEqual(real_contents1, real_contents) with self.fake_open(real_file_path, "rb") as f: fake_contents = f.read() self.assertEqual(fake_contents, b"test") def test_add_existing_real_file_read_only(self): real_file_path = os.path.abspath(__file__) fake_file = self.filesystem.add_real_file(real_file_path) self.check_fake_file_stat(fake_file, real_file_path) self.assertEqual(fake_file.st_mode & 0o333, 0) self.check_read_only_file(fake_file, real_file_path) def test_add_existing_real_file_read_write(self): real_file_path = os.path.realpath(__file__) fake_file = self.filesystem.add_real_file(real_file_path, read_only=False) self.check_fake_file_stat(fake_file, real_file_path) self.assertEqual(fake_file.st_mode, os.stat(real_file_path).st_mode) self.check_writable_file(fake_file, real_file_path) def test_add_real_file_to_existing_path(self): real_file_path = os.path.abspath(__file__) self.filesystem.create_file("/foo/bar") with self.raises_os_error(errno.EEXIST): self.filesystem.add_real_file(real_file_path, target_path="/foo/bar") def test_add_real_file_to_non_existing_path(self): real_file_path = os.path.abspath(__file__) fake_file = self.filesystem.add_real_file( real_file_path, target_path="/foo/bar" ) self.check_fake_file_stat(fake_file, real_file_path, target_path="/foo/bar") def test_write_to_real_file(self): # regression test for #470 real_file_path = os.path.abspath(__file__) self.filesystem.add_real_file(real_file_path, read_only=False) with self.fake_open(real_file_path, "w") as f: f.write("foo") with self.fake_open(real_file_path, "rb") as f: self.assertEqual(b"foo", f.read()) def test_add_existing_real_directory_read_only(self): self.filesystem.add_real_directory(self.pyfakefs_path) self.assertTrue(self.filesystem.exists(self.pyfakefs_path)) self.assertTrue( self.filesystem.exists( os.path.join(self.pyfakefs_path, "fake_filesystem.py") ) ) self.assertTrue( self.filesystem.exists(os.path.join(self.pyfakefs_path, "fake_pathlib.py")) ) file_path = os.path.join(self.pyfakefs_path, "fake_filesystem_shutil.py") fake_file = self.filesystem.resolve(file_path) self.check_fake_file_stat(fake_file, file_path) self.check_read_only_file(fake_file, file_path) def test_add_existing_real_directory_tree(self): self.filesystem.add_real_directory(self.root_path) self.assertTrue( self.filesystem.exists( os.path.join( self.root_path, "pyfakefs", "tests", "fake_filesystem_test.py", ) ) ) self.assertTrue( self.filesystem.exists( os.path.join(self.root_path, "pyfakefs", "fake_filesystem.py") ) ) self.assertTrue( self.filesystem.exists( os.path.join(self.root_path, "pyfakefs", "__init__.py") ) ) @contextlib.contextmanager def create_symlinks(self, symlinks): for link in symlinks: os.symlink(link[0], link[1]) yield for link in symlinks: os.unlink(link[1]) def test_add_existing_real_directory_symlink(self): fake_open = fake_filesystem.FakeFileOpen(self.filesystem) real_directory = os.path.join(self.root_path, "pyfakefs", "tests") symlinks = [ ( "..", os.path.join(real_directory, "fixtures", "symlink_dir_relative"), ), ( "../all_tests.py", os.path.join(real_directory, "fixtures", "symlink_file_relative"), ), ( real_directory, os.path.join(real_directory, "fixtures", "symlink_dir_absolute"), ), ( os.path.join(real_directory, "all_tests.py"), os.path.join(real_directory, "fixtures", "symlink_file_absolute"), ), ( "/etc/something", os.path.join( real_directory, "fixtures", "symlink_file_absolute_outside" ), ), ] self.filesystem.create_file("/etc/something") with fake_open("/etc/something", "w") as f: f.write("good morning") try: with self.create_symlinks(symlinks): self.filesystem.add_real_directory(real_directory, lazy_read=False) except OSError: if self.is_windows: raise unittest.SkipTest("Symlinks under Windows need admin privileges") raise for link in symlinks: self.assertTrue(self.filesystem.islink(link[1])) # relative self.assertTrue( self.filesystem.exists( os.path.join( self.root_path, "pyfakefs", "tests", "fixtures/symlink_dir_relative", ) ) ) self.assertTrue( self.filesystem.exists( os.path.join( self.root_path, "pyfakefs", "tests", "fixtures/symlink_dir_relative/all_tests.py", ) ) ) self.assertTrue( self.filesystem.exists( os.path.join( self.root_path, "pyfakefs", "tests", "fixtures/symlink_file_relative", ) ) ) # absolute self.assertTrue( self.filesystem.exists( os.path.join( self.root_path, "pyfakefs", "tests", "fixtures/symlink_dir_absolute", ) ) ) self.assertTrue( self.filesystem.exists( os.path.join( self.root_path, "pyfakefs", "tests", "fixtures/symlink_dir_absolute/all_tests.py", ) ) ) self.assertTrue( self.filesystem.exists( os.path.join( self.root_path, "pyfakefs", "tests", "fixtures/symlink_file_absolute", ) ) ) # outside self.assertTrue( self.filesystem.exists( os.path.join( self.root_path, "pyfakefs", "tests", "fixtures/symlink_file_absolute_outside", ) ) ) self.assertEqual( fake_open( os.path.join( self.root_path, "pyfakefs", "tests", "fixtures/symlink_file_absolute_outside", ) ).read(), "good morning", ) def test_add_existing_real_directory_symlink_target_path(self): self.skip_if_symlink_not_supported(force_real_fs=True) real_directory = os.path.join(self.root_path, "pyfakefs", "tests") symlinks = [ ( "..", os.path.join(real_directory, "fixtures", "symlink_dir_relative"), ), ( "../all_tests.py", os.path.join(real_directory, "fixtures", "symlink_file_relative"), ), ] with self.create_symlinks(symlinks): self.filesystem.add_real_directory( real_directory, target_path="/path", lazy_read=False ) self.assertTrue(self.filesystem.exists("/path/fixtures/symlink_dir_relative")) self.assertTrue( self.filesystem.exists("/path/fixtures/symlink_dir_relative/all_tests.py") ) self.assertTrue(self.filesystem.exists("/path/fixtures/symlink_file_relative")) def test_add_existing_real_directory_symlink_lazy_read(self): self.skip_if_symlink_not_supported(force_real_fs=True) real_directory = os.path.join(self.root_path, "pyfakefs", "tests") symlinks = [ ( "..", os.path.join(real_directory, "fixtures", "symlink_dir_relative"), ), ( "../all_tests.py", os.path.join(real_directory, "fixtures", "symlink_file_relative"), ), ] with self.create_symlinks(symlinks): self.filesystem.add_real_directory( real_directory, target_path="/path", lazy_read=True ) self.assertTrue( self.filesystem.exists("/path/fixtures/symlink_dir_relative") ) self.assertTrue( self.filesystem.exists( "/path/fixtures/symlink_dir_relative/all_tests.py" ) ) self.assertTrue( self.filesystem.exists("/path/fixtures/symlink_file_relative") ) def test_add_existing_real_directory_tree_to_existing_path(self): self.filesystem.create_dir("/foo/bar") with self.raises_os_error(errno.EEXIST): self.filesystem.add_real_directory(self.root_path, target_path="/foo/bar") def test_add_existing_real_directory_tree_to_other_path(self): self.filesystem.add_real_directory(self.root_path, target_path="/foo/bar") self.assertFalse( self.filesystem.exists( os.path.join(self.pyfakefs_path, "tests", "fake_filesystem_test.py") ) ) self.assertTrue( self.filesystem.exists( os.path.join( "foo", "bar", "pyfakefs", "tests", "fake_filesystem_test.py", ) ) ) self.assertFalse( self.filesystem.exists( os.path.join(self.root_path, "pyfakefs", "fake_filesystem.py") ) ) self.assertTrue( self.filesystem.exists( os.path.join("foo", "bar", "pyfakefs", "__init__.py") ) ) def test_get_object_from_lazily_added_real_directory(self): self.filesystem.is_case_sensitive = True self.filesystem.add_real_directory(self.root_path) self.assertTrue( self.filesystem.get_object( os.path.join(self.root_path, "pyfakefs", "fake_filesystem.py") ) ) self.assertTrue( self.filesystem.get_object( os.path.join(self.root_path, "pyfakefs", "__init__.py") ) ) def test_add_existing_real_directory_lazily(self): disk_size = 1024 * 1024 * 1024 real_dir_path = os.path.join(self.root_path, "pyfakefs") self.filesystem.set_disk_usage(disk_size, real_dir_path) self.filesystem.add_real_directory(real_dir_path) # the directory contents have not been read, the the disk usage # has not changed self.assertEqual(disk_size, self.filesystem.get_disk_usage(real_dir_path).free) # checking for existence shall read the directory contents self.assertTrue( self.filesystem.get_object( os.path.join(real_dir_path, "fake_filesystem.py") ) ) # so now the free disk space shall have decreased self.assertGreater( disk_size, self.filesystem.get_disk_usage(real_dir_path).free ) def test_add_existing_real_directory_not_lazily(self): disk_size = 1024 * 1024 * 1024 self.filesystem.set_disk_usage(disk_size, self.pyfakefs_path) self.filesystem.add_real_directory(self.pyfakefs_path, lazy_read=False) # the directory has been read, so the file sizes have # been subtracted from the free space self.assertGreater( disk_size, self.filesystem.get_disk_usage(self.pyfakefs_path).free ) def test_add_existing_real_directory_read_write(self): self.filesystem.add_real_directory(self.pyfakefs_path, read_only=False) self.assertTrue(self.filesystem.exists(self.pyfakefs_path)) self.assertTrue( self.filesystem.exists( os.path.join(self.pyfakefs_path, "fake_filesystem.py") ) ) self.assertTrue( self.filesystem.exists(os.path.join(self.pyfakefs_path, "fake_pathlib.py")) ) file_path = os.path.join(self.pyfakefs_path, "pytest_plugin.py") fake_file = self.filesystem.resolve(file_path) self.check_fake_file_stat(fake_file, file_path) self.check_writable_file(fake_file, file_path) def test_add_existing_real_paths_read_only(self): real_file_path = os.path.realpath(__file__) fixture_path = os.path.join(self.pyfakefs_path, "tests", "fixtures") self.filesystem.add_real_paths([real_file_path, fixture_path]) fake_file = self.filesystem.resolve(real_file_path) self.check_fake_file_stat(fake_file, real_file_path) self.check_read_only_file(fake_file, real_file_path) real_file_path = os.path.join(fixture_path, "module_with_attributes.py") fake_file = self.filesystem.resolve(real_file_path) self.check_fake_file_stat(fake_file, real_file_path) self.check_read_only_file(fake_file, real_file_path) def test_add_existing_real_paths_read_write(self): real_file_path = os.path.realpath(__file__) fixture_path = os.path.join(self.pyfakefs_path, "tests", "fixtures") self.filesystem.add_real_paths([real_file_path, fixture_path], read_only=False) fake_file = self.filesystem.resolve(real_file_path) self.check_fake_file_stat(fake_file, real_file_path) self.check_writable_file(fake_file, real_file_path) real_file_path = os.path.join(fixture_path, "module_with_attributes.py") fake_file = self.filesystem.resolve(real_file_path) self.check_fake_file_stat(fake_file, real_file_path) self.check_writable_file(fake_file, real_file_path) class FileSideEffectTests(TestCase): def side_effect(self): test_case = self test_case.side_effect_called = False def __side_effect(file_object): test_case.side_effect_called = True test_case.side_effect_file_object_content = file_object.contents return __side_effect def setUp(self): # use the real path separator to work with the real file system self.filesystem = fake_filesystem.FakeFilesystem() self.filesystem.create_file("/a/b/file_one", side_effect=self.side_effect()) def test_side_effect_called(self): fake_open = fake_filesystem.FakeFileOpen(self.filesystem) self.side_effect_called = False with fake_open("/a/b/file_one", "w") as handle: handle.write("foo") self.assertTrue(self.side_effect_called) def test_side_effect_file_object(self): fake_open = fake_filesystem.FakeFileOpen(self.filesystem) self.side_effect_called = False with fake_open("/a/b/file_one", "w") as handle: handle.write("foo") self.assertEqual(self.side_effect_file_object_content, "foo") if __name__ == "__main__": unittest.main() tests/fake_filesystem_unittest_test.py000064400000102427150043321530014432 0ustar00# Copyright 2014 Altera Corporation. All Rights Reserved. # Copyright 2015-2017 John McGehee # Author: John McGehee # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """ Test the :py:class`pyfakefs.fake_filesystem_unittest.TestCase` base class. """ import glob import io import multiprocessing import os import pathlib import runpy import shutil import sys import tempfile import unittest import warnings from pathlib import Path from unittest import TestCase, mock import pyfakefs.tests.import_as_example import pyfakefs.tests.logsio from pyfakefs import fake_filesystem_unittest, fake_filesystem from pyfakefs.fake_filesystem import OSType from pyfakefs.fake_filesystem_unittest import ( Patcher, Pause, patchfs, PatchMode, ) from pyfakefs.tests.fixtures import module_with_attributes if sys.version_info < (3, 12): # distutils removed in Python 3.12 from distutils.dir_util import copy_tree, remove_tree class TestPatcher(TestCase): def test_context_manager(self): with Patcher() as patcher: patcher.fs.create_file("/foo/bar", contents="test") with open("/foo/bar") as f: contents = f.read() self.assertEqual("test", contents) @patchfs def test_context_decorator(self, fake_fs): fake_fs.create_file("/foo/bar", contents="test") with open("/foo/bar") as f: contents = f.read() self.assertEqual("test", contents) class TestPatchfsArgumentOrder(TestCase): @patchfs @mock.patch("os.system") def test_argument_order1(self, fake_fs, patched_system): fake_fs.create_file("/foo/bar", contents="test") with open("/foo/bar") as f: contents = f.read() self.assertEqual("test", contents) os.system("foo") patched_system.assert_called_with("foo") @mock.patch("os.system") @patchfs def test_argument_order2(self, patched_system, fake_fs): fake_fs.create_file("/foo/bar", contents="test") with open("/foo/bar") as f: contents = f.read() self.assertEqual("test", contents) os.system("foo") patched_system.assert_called_with("foo") class TestPyfakefsUnittestBase(fake_filesystem_unittest.TestCase): def setUp(self): """Set up the fake file system""" self.setUpPyfakefs() class TestPyfakefsUnittest(TestPyfakefsUnittestBase): # pylint: disable=R0904 """Test the `pyfakefs.fake_filesystem_unittest.TestCase` base class.""" def test_open(self): """Fake `open()` function is bound""" self.assertFalse(os.path.exists("/fake_file.txt")) with open("/fake_file.txt", "w") as f: f.write("This test file was created using the open() function.\n") self.assertTrue(self.fs.exists("/fake_file.txt")) with open("/fake_file.txt") as f: content = f.read() self.assertEqual( "This test file was created using the " "open() function.\n", content, ) def test_io_open(self): """Fake io module is bound""" self.assertFalse(os.path.exists("/fake_file.txt")) with io.open("/fake_file.txt", "w") as f: f.write("This test file was created using the" " io.open() function.\n") self.assertTrue(self.fs.exists("/fake_file.txt")) with open("/fake_file.txt") as f: content = f.read() self.assertEqual( "This test file was created using the " "io.open() function.\n", content, ) def test_os(self): """Fake os module is bound""" self.assertFalse(self.fs.exists("/test/dir1/dir2")) os.makedirs("/test/dir1/dir2") self.assertTrue(self.fs.exists("/test/dir1/dir2")) def test_glob(self): """Fake glob module is bound""" is_windows = sys.platform.startswith("win") self.assertEqual([], glob.glob("/test/dir1/dir*")) self.fs.create_dir("/test/dir1/dir2a") matching_paths = glob.glob("/test/dir1/dir*") if is_windows: self.assertEqual([r"/test/dir1\dir2a"], matching_paths) else: self.assertEqual(["/test/dir1/dir2a"], matching_paths) self.fs.create_dir("/test/dir1/dir2b") matching_paths = sorted(glob.glob("/test/dir1/dir*")) if is_windows: self.assertEqual([r"/test/dir1\dir2a", r"/test/dir1\dir2b"], matching_paths) else: self.assertEqual(["/test/dir1/dir2a", "/test/dir1/dir2b"], matching_paths) def test_shutil(self): """Fake shutil module is bound""" self.fs.create_dir("/test/dir1/dir2a") self.fs.create_dir("/test/dir1/dir2b") self.assertTrue(self.fs.exists("/test/dir1/dir2b")) self.assertTrue(self.fs.exists("/test/dir1/dir2a")) shutil.rmtree("/test/dir1") self.assertFalse(self.fs.exists("/test/dir1")) def test_fakepathlib(self): p = pathlib.Path("/fake_file.txt") with p.open("w") as f: f.write("text") is_windows = sys.platform.startswith("win") if is_windows: self.assertTrue(self.fs.exists(r"\fake_file.txt")) else: self.assertTrue(self.fs.exists("/fake_file.txt")) class TestPatchingImports(TestPyfakefsUnittestBase): def test_import_as_other_name(self): file_path = "/foo/bar/baz" self.fs.create_file(file_path) self.assertTrue(self.fs.exists(file_path)) self.assertTrue(pyfakefs.tests.import_as_example.check_if_exists1(file_path)) def test_import_path_from_os(self): """Make sure `from os import path` patches `path`.""" file_path = "/foo/bar/baz" self.fs.create_file(file_path) self.assertTrue(self.fs.exists(file_path)) self.assertTrue(pyfakefs.tests.import_as_example.check_if_exists2(file_path)) def test_import_path_from_pathlib(self): file_path = "/foo/bar" self.fs.create_dir(file_path) self.assertTrue(pyfakefs.tests.import_as_example.check_if_exists3(file_path)) def test_import_exists_from_os_path(self): file_path = "/foo/bar" self.fs.create_dir(file_path) self.assertTrue(pyfakefs.tests.import_as_example.check_if_exists5(file_path)) def test_import_isfile_from_os_path(self): file_path = "/foo/bar" self.fs.create_file(file_path) self.assertTrue(pyfakefs.tests.import_as_example.check_if_isfile(file_path)) def test_import_isdir_from_os_path(self): file_path = "/foo/bar" self.fs.create_dir(file_path) self.assertTrue(pyfakefs.tests.import_as_example.check_if_isdir(file_path)) def test_import_islink_from_os_path(self): file_path = "/foo/bar" link_path = "/foo/link" self.fs.create_file(file_path) self.fs.create_symlink(link_path, file_path) self.assertTrue(pyfakefs.tests.import_as_example.check_if_islink(link_path)) def test_import_function_from_os_path_as_other_name(self): file_path = "/foo/bar" self.fs.create_dir(file_path) self.assertTrue(pyfakefs.tests.import_as_example.check_if_exists6(file_path)) def test_import_pathlib_path(self): file_path = "/foo/bar" self.fs.create_dir(file_path) self.assertTrue(pyfakefs.tests.import_as_example.check_if_exists7(file_path)) def test_import_function_from_os(self): file_path = "/foo/bar" self.fs.create_file(file_path, contents=b"abc") stat_result = pyfakefs.tests.import_as_example.file_stat1(file_path) self.assertEqual(3, stat_result.st_size) def test_import_function_from_os_as_other_name(self): file_path = "/foo/bar" self.fs.create_file(file_path, contents=b"abc") stat_result = pyfakefs.tests.import_as_example.file_stat2(file_path) self.assertEqual(3, stat_result.st_size) @unittest.skipIf(sys.version_info >= (3, 12), "Currently not working in 3.12") def test_import_open_as_other_name(self): file_path = "/foo/bar" self.fs.create_file(file_path, contents=b"abc") contents = pyfakefs.tests.import_as_example.file_contents1(file_path) self.assertEqual("abc", contents) @unittest.skipIf(sys.version_info >= (3, 12), "Currently not working in 3.12") def test_import_io_open_as_other_name(self): file_path = "/foo/bar" self.fs.create_file(file_path, contents=b"abc") contents = pyfakefs.tests.import_as_example.file_contents2(file_path) self.assertEqual("abc", contents) class TestPatchingDefaultArgs(fake_filesystem_unittest.TestCase): def setUp(self): self.setUpPyfakefs(patch_default_args=True) def test_path_exists_as_default_arg_in_function(self): file_path = "/foo/bar" self.fs.create_dir(file_path) self.assertTrue(pyfakefs.tests.import_as_example.check_if_exists4(file_path)) def test_path_exists_as_default_arg_in_method(self): file_path = "/foo/bar" self.fs.create_dir(file_path) sut = pyfakefs.tests.import_as_example.TestDefaultArg() self.assertTrue(sut.check_if_exists(file_path)) def test_fake_path_exists4(self): self.fs.create_file("foo") self.assertTrue(pyfakefs.tests.import_as_example.check_if_exists4("foo")) class TestAttributesWithFakeModuleNames(TestPyfakefsUnittestBase): """Test that module attributes with names like `path` or `io` are not stubbed out. """ def test_attributes(self): """Attributes of module under test are not patched""" self.assertEqual(module_with_attributes.os, "os attribute value") self.assertEqual(module_with_attributes.path, "path attribute value") self.assertEqual(module_with_attributes.pathlib, "pathlib attribute value") self.assertEqual(module_with_attributes.shutil, "shutil attribute value") self.assertEqual(module_with_attributes.io, "io attribute value") import math as path # noqa: E402 wanted import not at top class TestPathNotPatchedIfNotOsPath(TestPyfakefsUnittestBase): """Tests that `path` is not patched if it is not `os.path`. An own path module (in this case an alias to math) can be imported and used. """ def test_own_path_module(self): self.assertEqual(2, path.floor(2.5)) class FailedPatchingTest(TestPyfakefsUnittestBase): """Negative tests: make sure the tests for `modules_to_reload` and `modules_to_patch` fail if not providing the arguments. """ @unittest.expectedFailure def test_system_stat(self): file_path = "/foo/bar" self.fs.create_file(file_path, contents=b"test") self.assertEqual( 4, pyfakefs.tests.import_as_example.system_stat(file_path).st_size ) class ReloadModuleTest(fake_filesystem_unittest.TestCase): """Make sure that reloading a module allows patching of classes not patched automatically. """ def setUp(self): """Set up the fake file system""" self.setUpPyfakefs(modules_to_reload=[pyfakefs.tests.import_as_example]) class NoSkipNamesTest(fake_filesystem_unittest.TestCase): """Reference test for additional_skip_names tests: make sure that the module is patched by default.""" def setUp(self): self.setUpPyfakefs() def test_path_exists(self): self.assertFalse(pyfakefs.tests.import_as_example.exists_this_file()) def test_fake_path_exists1(self): self.fs.create_file("foo") self.assertTrue(pyfakefs.tests.import_as_example.check_if_exists1("foo")) def test_fake_path_exists2(self): self.fs.create_file("foo") self.assertTrue(pyfakefs.tests.import_as_example.check_if_exists2("foo")) def test_fake_path_exists3(self): self.fs.create_file("foo") self.assertTrue(pyfakefs.tests.import_as_example.check_if_exists3("foo")) def test_fake_path_exists5(self): self.fs.create_file("foo") self.assertTrue(pyfakefs.tests.import_as_example.check_if_exists5("foo")) def test_fake_path_exists6(self): self.fs.create_file("foo") self.assertTrue(pyfakefs.tests.import_as_example.check_if_exists6("foo")) def test_fake_path_exists7(self): self.fs.create_file("foo") self.assertTrue(pyfakefs.tests.import_as_example.check_if_exists7("foo")) def test_open_fails(self): with self.assertRaises(OSError): pyfakefs.tests.import_as_example.open_this_file() def test_open_patched_in_module_ending_with_io(self): # regression test for #569 file_path = "/foo/bar" self.fs.create_file(file_path, contents=b"abc") contents = pyfakefs.tests.logsio.file_contents(file_path) self.assertEqual(b"abc", contents) class AdditionalSkipNamesTest(fake_filesystem_unittest.TestCase): """Make sure that modules in additional_skip_names are not patched. Passes module name to `additional_skip_names`.""" def setUp(self): self.setUpPyfakefs(additional_skip_names=["pyfakefs.tests.import_as_example"]) def test_path_exists(self): self.assertTrue(pyfakefs.tests.import_as_example.exists_this_file()) def test_fake_path_does_not_exist1(self): self.fs.create_file("foo") self.assertFalse(pyfakefs.tests.import_as_example.check_if_exists1("foo")) def test_fake_path_does_not_exist2(self): self.fs.create_file("foo") self.assertFalse(pyfakefs.tests.import_as_example.check_if_exists2("foo")) def test_fake_path_does_not_exist3(self): self.fs.create_file("foo") self.assertFalse(pyfakefs.tests.import_as_example.check_if_exists3("foo")) def test_fake_path_does_not_exist4(self): self.fs.create_file("foo") self.assertFalse(pyfakefs.tests.import_as_example.check_if_exists4("foo")) def test_fake_path_does_not_exist5(self): self.fs.create_file("foo") self.assertFalse(pyfakefs.tests.import_as_example.check_if_exists5("foo")) def test_fake_path_does_not_exist6(self): self.fs.create_file("foo") self.assertFalse(pyfakefs.tests.import_as_example.check_if_exists6("foo")) def test_fake_path_does_not_exist7(self): self.fs.create_file("foo") self.assertFalse(pyfakefs.tests.import_as_example.check_if_exists7("foo")) @unittest.skipIf( sys.version_info >= (3, 12), "Skip modules currently not working for open in 3.12", ) def test_open_succeeds(self): pyfakefs.tests.import_as_example.open_this_file() def test_path_succeeds(self): pyfakefs.tests.import_as_example.return_this_file_path() class AdditionalSkipNamesModuleTest(fake_filesystem_unittest.TestCase): """Make sure that modules in additional_skip_names are not patched. Passes module to `additional_skip_names`.""" def setUp(self): self.setUpPyfakefs(additional_skip_names=[pyfakefs.tests.import_as_example]) def test_path_exists(self): self.assertTrue(pyfakefs.tests.import_as_example.exists_this_file()) def test_fake_path_does_not_exist1(self): self.fs.create_file("foo") self.assertFalse(pyfakefs.tests.import_as_example.check_if_exists1("foo")) def test_fake_path_does_not_exist2(self): self.fs.create_file("foo") self.assertFalse(pyfakefs.tests.import_as_example.check_if_exists2("foo")) def test_fake_path_does_not_exist3(self): self.fs.create_file("foo") self.assertFalse(pyfakefs.tests.import_as_example.check_if_exists3("foo")) def test_fake_path_does_not_exist4(self): self.fs.create_file("foo") self.assertFalse(pyfakefs.tests.import_as_example.check_if_exists4("foo")) def test_fake_path_does_not_exist5(self): self.fs.create_file("foo") self.assertFalse(pyfakefs.tests.import_as_example.check_if_exists5("foo")) def test_fake_path_does_not_exist6(self): self.fs.create_file("foo") self.assertFalse(pyfakefs.tests.import_as_example.check_if_exists6("foo")) def test_fake_path_does_not_exist7(self): self.fs.create_file("foo") self.assertFalse(pyfakefs.tests.import_as_example.check_if_exists7("foo")) @unittest.skipIf( sys.version_info >= (3, 12), "Skip modules currently not working for open in 3.12", ) def test_open_succeeds(self): pyfakefs.tests.import_as_example.open_this_file() def test_path_succeeds(self): pyfakefs.tests.import_as_example.return_this_file_path() class FakeExampleModule: """Used to patch a function that uses system-specific functions that cannot be patched automatically.""" _orig_module = pyfakefs.tests.import_as_example def __init__(self, fs): pass def system_stat(self, filepath): return os.stat(filepath) def __getattr__(self, name): """Forwards any non-faked calls to the standard module.""" return getattr(self._orig_module, name) class PatchModuleTest(fake_filesystem_unittest.TestCase): """Make sure that reloading a module allows patching of classes not patched automatically. """ def setUp(self): """Set up the fake file system""" self.setUpPyfakefs( modules_to_patch={"pyfakefs.tests.import_as_example": FakeExampleModule} ) def test_system_stat(self): file_path = "/foo/bar" self.fs.create_file(file_path, contents=b"test") self.assertEqual( 4, pyfakefs.tests.import_as_example.system_stat(file_path).st_size ) class PatchModuleTestUsingDecorator(unittest.TestCase): """Make sure that reloading a module allows patching of classes not patched automatically - use patchfs decorator with parameter. """ @patchfs @unittest.expectedFailure def test_system_stat_failing(self, fake_fs): file_path = "/foo/bar" fake_fs.create_file(file_path, contents=b"test") self.assertEqual( 4, pyfakefs.tests.import_as_example.system_stat(file_path).st_size ) @patchfs(modules_to_patch={"pyfakefs.tests.import_as_example": FakeExampleModule}) def test_system_stat(self, fake_fs): file_path = "/foo/bar" fake_fs.create_file(file_path, contents=b"test") self.assertEqual( 4, pyfakefs.tests.import_as_example.system_stat(file_path).st_size ) class NoRootUserTest(fake_filesystem_unittest.TestCase): """Test allow_root_user argument to setUpPyfakefs.""" def setUp(self): self.setUpPyfakefs(allow_root_user=False) def test_non_root_behavior(self): """Check that fs behaves as non-root user regardless of actual user rights. """ self.fs.is_windows_fs = False dir_path = "/foo/bar" self.fs.create_dir(dir_path, perm_bits=0o555) file_path = dir_path + "baz" with self.assertRaises(OSError): self.fs.create_file(file_path) file_path = "/baz" self.fs.create_file(file_path) os.chmod(file_path, 0o400) with self.assertRaises(OSError): open(file_path, "w") class PauseResumeTest(fake_filesystem_unittest.TestCase): def setUp(self): self.real_temp_file = None self.setUpPyfakefs() def tearDown(self): if self.real_temp_file is not None: self.real_temp_file.close() def test_pause_resume(self): fake_temp_file = tempfile.NamedTemporaryFile() self.assertTrue(self.fs.exists(fake_temp_file.name)) self.assertTrue(os.path.exists(fake_temp_file.name)) self.pause() self.assertTrue(self.fs.exists(fake_temp_file.name)) self.assertFalse(os.path.exists(fake_temp_file.name)) self.real_temp_file = tempfile.NamedTemporaryFile() self.assertFalse(self.fs.exists(self.real_temp_file.name)) self.assertTrue(os.path.exists(self.real_temp_file.name)) self.resume() self.assertFalse(os.path.exists(self.real_temp_file.name)) self.assertTrue(os.path.exists(fake_temp_file.name)) def test_pause_resume_fs(self): fake_temp_file = tempfile.NamedTemporaryFile() self.assertTrue(self.fs.exists(fake_temp_file.name)) self.assertTrue(os.path.exists(fake_temp_file.name)) # resume does nothing if not paused self.fs.resume() self.assertTrue(os.path.exists(fake_temp_file.name)) self.fs.pause() self.assertTrue(self.fs.exists(fake_temp_file.name)) self.assertFalse(os.path.exists(fake_temp_file.name)) self.real_temp_file = tempfile.NamedTemporaryFile() self.assertFalse(self.fs.exists(self.real_temp_file.name)) self.assertTrue(os.path.exists(self.real_temp_file.name)) # pause does nothing if already paused self.fs.pause() self.assertFalse(self.fs.exists(self.real_temp_file.name)) self.assertTrue(os.path.exists(self.real_temp_file.name)) self.fs.resume() self.assertFalse(os.path.exists(self.real_temp_file.name)) self.assertTrue(os.path.exists(fake_temp_file.name)) def test_pause_resume_contextmanager(self): fake_temp_file = tempfile.NamedTemporaryFile() self.assertTrue(self.fs.exists(fake_temp_file.name)) self.assertTrue(os.path.exists(fake_temp_file.name)) with Pause(self): self.assertTrue(self.fs.exists(fake_temp_file.name)) self.assertFalse(os.path.exists(fake_temp_file.name)) self.real_temp_file = tempfile.NamedTemporaryFile() self.assertFalse(self.fs.exists(self.real_temp_file.name)) self.assertTrue(os.path.exists(self.real_temp_file.name)) self.assertFalse(os.path.exists(self.real_temp_file.name)) self.assertTrue(os.path.exists(fake_temp_file.name)) def test_pause_resume_fs_contextmanager(self): fake_temp_file = tempfile.NamedTemporaryFile() self.assertTrue(self.fs.exists(fake_temp_file.name)) self.assertTrue(os.path.exists(fake_temp_file.name)) with Pause(self.fs): self.assertTrue(self.fs.exists(fake_temp_file.name)) self.assertFalse(os.path.exists(fake_temp_file.name)) self.real_temp_file = tempfile.NamedTemporaryFile() self.assertFalse(self.fs.exists(self.real_temp_file.name)) self.assertTrue(os.path.exists(self.real_temp_file.name)) self.assertFalse(os.path.exists(self.real_temp_file.name)) self.assertTrue(os.path.exists(fake_temp_file.name)) def test_pause_resume_without_patcher(self): fs = fake_filesystem.FakeFilesystem() with self.assertRaises(RuntimeError): fs.resume() class PauseResumePatcherTest(fake_filesystem_unittest.TestCase): def test_pause_resume(self): with Patcher() as p: fake_temp_file = tempfile.NamedTemporaryFile() self.assertTrue(p.fs.exists(fake_temp_file.name)) self.assertTrue(os.path.exists(fake_temp_file.name)) p.pause() self.assertTrue(p.fs.exists(fake_temp_file.name)) self.assertFalse(os.path.exists(fake_temp_file.name)) real_temp_file = tempfile.NamedTemporaryFile() self.assertFalse(p.fs.exists(real_temp_file.name)) self.assertTrue(os.path.exists(real_temp_file.name)) p.resume() self.assertFalse(os.path.exists(real_temp_file.name)) self.assertTrue(os.path.exists(fake_temp_file.name)) real_temp_file.close() def test_pause_resume_contextmanager(self): with Patcher() as p: fake_temp_file = tempfile.NamedTemporaryFile() self.assertTrue(p.fs.exists(fake_temp_file.name)) self.assertTrue(os.path.exists(fake_temp_file.name)) with Pause(p): self.assertTrue(p.fs.exists(fake_temp_file.name)) self.assertFalse(os.path.exists(fake_temp_file.name)) real_temp_file = tempfile.NamedTemporaryFile() self.assertFalse(p.fs.exists(real_temp_file.name)) self.assertTrue(os.path.exists(real_temp_file.name)) self.assertFalse(os.path.exists(real_temp_file.name)) self.assertTrue(os.path.exists(fake_temp_file.name)) real_temp_file.close() class TestPyfakefsTestCase(unittest.TestCase): def setUp(self): class TestTestCase(fake_filesystem_unittest.TestCase): def runTest(self): pass self.test_case = TestTestCase("runTest") def test_test_case_type(self): self.assertIsInstance(self.test_case, unittest.TestCase) self.assertIsInstance(self.test_case, fake_filesystem_unittest.TestCaseMixin) class TestTempDirCreation(fake_filesystem_unittest.TestCase): """Test that the temp directory exists at test start.""" def setUp(self): self.setUpPyfakefs() def test_tempdir_exists(self): self.assertTrue(os.path.exists(tempfile.gettempdir())) @unittest.skipIf(sys.platform == "win32", "POSIX only test") def test_tmp_exists(self): # directory or link under Linux, link under macOS self.assertTrue(os.path.exists("/tmp")) class TestTempFileReload(unittest.TestCase): """Regression test for #356 to make sure that reloading the tempfile does not affect other tests.""" def test_fakefs(self): with Patcher() as patcher: patcher.fs.create_file("/mytempfile", contents="abcd") def test_value(self): v = multiprocessing.Value("I", 0) self.assertEqual(v.value, 0) class TestPyfakefsTestCaseMixin( unittest.TestCase, fake_filesystem_unittest.TestCaseMixin ): def test_set_up_pyfakefs(self): self.setUpPyfakefs() self.assertTrue(hasattr(self, "fs")) self.assertIsInstance(self.fs, fake_filesystem.FakeFilesystem) class TestShutilWithZipfile(fake_filesystem_unittest.TestCase): """Regression test for #427.""" def setUp(self): self.setUpPyfakefs() self.fs.create_file("foo/bar") def test_a(self): shutil.make_archive("archive", "zip", root_dir="foo") def test_b(self): # used to fail because 'bar' could not be found shutil.make_archive("archive", "zip", root_dir="foo") if sys.version_info < (3, 12): class TestDistutilsCopyTree(fake_filesystem_unittest.TestCase): """Regression test for #501.""" def setUp(self): self.setUpPyfakefs() self.fs.create_dir("./test/subdir/") self.fs.create_dir("./test/subdir2/") self.fs.create_file("./test2/subdir/1.txt") def test_file_copied(self): copy_tree("./test2/", "./test/") remove_tree("./test2/") self.assertTrue(os.path.isfile("./test/subdir/1.txt")) self.assertFalse(os.path.isdir("./test2/")) def test_file_copied_again(self): # used to fail because 'test2' could not be found self.assertTrue(os.path.isfile("./test2/subdir/1.txt")) copy_tree("./test2/", "./test/") remove_tree("./test2/") self.assertTrue(os.path.isfile("./test/subdir/1.txt")) self.assertFalse(os.path.isdir("./test2/")) class PathlibTest(TestCase): """Regression test for #527""" @patchfs def test_cwd(self, fs): """Make sure fake file system is used for os in pathlib""" is_windows = sys.platform.startswith("win") root_dir = "C:" + os.path.sep if is_windows else os.path.sep self.assertEqual(root_dir, str(pathlib.Path.cwd())) dot_abs = pathlib.Path(".").absolute() self.assertEqual(root_dir, str(dot_abs)) self.assertTrue(dot_abs.exists()) class TestDeprecationSuppression(fake_filesystem_unittest.TestCase): @unittest.skipIf( sys.version_info[1] == 6, "Test fails for Python 3.6 for unknown reason", ) def test_no_deprecation_warning(self): """Ensures that deprecation warnings are suppressed during module lookup, see #542. """ from pyfakefs.tests.fixtures.deprecated_property import ( # noqa: F401 DeprecationTest, ) with warnings.catch_warnings(record=True) as w: warnings.simplefilter("error", DeprecationWarning) self.setUpPyfakefs() self.assertEqual(0, len(w)) def load_configs(configs): """Helper code for patching open_code in auto mode, see issue #554.""" retval = [] for config in configs: if len(config) > 3 and config[-3:] == ".py": retval += runpy.run_path(config) else: retval += runpy.run_module(config) return retval class AutoPatchOpenCodeTestCase(fake_filesystem_unittest.TestCase): """Test patching open_code in auto mode, see issue #554.""" def setUp(self): self.setUpPyfakefs(patch_open_code=PatchMode.AUTO) self.configpy = "configpy.py" self.fs.create_file(self.configpy, contents="configurable_value='yup'") self.config_module = "pyfakefs.tests.fixtures.config_module" def test_both(self): load_configs([self.configpy, self.config_module]) def test_run_path(self): load_configs([self.configpy]) def test_run_module(self): load_configs([self.config_module]) class TestOtherFS(fake_filesystem_unittest.TestCase): def setUp(self): self.setUpPyfakefs() def test_real_file_with_home(self): """Regression test for #558""" self.fs.is_windows_fs = os.name != "nt" if self.fs.is_windows_fs: self.fs.is_macos = False self.fs.add_real_file(__file__) with open(__file__) as f: self.assertTrue(f.read()) home = Path.home() os.chdir(home) with open(__file__) as f: self.assertTrue(f.read()) def test_windows(self): self.fs.os = OSType.WINDOWS path = r"C:\foo\bar" self.assertEqual(path, os.path.join("C:\\", "foo", "bar")) self.assertEqual(("C:", r"\foo\bar"), os.path.splitdrive(path)) self.fs.create_file(path) self.assertTrue(os.path.exists(path)) self.assertTrue(os.path.exists(path.upper())) self.assertTrue(os.path.ismount(r"\\share\foo")) self.assertTrue(os.path.ismount(r"C:")) self.assertEqual("\\", os.sep) self.assertEqual("\\", os.path.sep) self.assertEqual("/", os.altsep) self.assertEqual(";", os.pathsep) self.assertEqual("\r\n", os.linesep) self.assertEqual("nul", os.devnull) def test_linux(self): self.fs.os = OSType.LINUX path = "/foo/bar" self.assertEqual(path, os.path.join("/", "foo", "bar")) self.assertEqual(("", "C:/foo/bar"), os.path.splitdrive("C:/foo/bar")) self.fs.create_file(path) self.assertTrue(os.path.exists(path)) self.assertFalse(os.path.exists(path.upper())) self.assertTrue(os.path.ismount("/")) self.assertFalse(os.path.ismount("//share/foo")) self.assertEqual("/", os.sep) self.assertEqual("/", os.path.sep) self.assertEqual(None, os.altsep) self.assertEqual(":", os.pathsep) self.assertEqual("\n", os.linesep) self.assertEqual("/dev/null", os.devnull) def test_macos(self): self.fs.os = OSType.MACOS path = "/foo/bar" self.assertEqual(path, os.path.join("/", "foo", "bar")) self.assertEqual(("", "C:/foo/bar"), os.path.splitdrive("C:/foo/bar")) self.fs.create_file(path) self.assertTrue(os.path.exists(path)) self.assertTrue(os.path.exists(path.upper())) self.assertTrue(os.path.ismount("/")) self.assertFalse(os.path.ismount("//share/foo")) self.assertEqual("/", os.sep) self.assertEqual("/", os.path.sep) self.assertEqual(None, os.altsep) self.assertEqual(":", os.pathsep) self.assertEqual("\n", os.linesep) self.assertEqual("/dev/null", os.devnull) def test_drivelike_path(self): self.fs.os = OSType.LINUX folder = Path("/test") file_path = folder / "C:/testfile" file_path.parent.mkdir(parents=True) file_path.touch() os.chdir(folder) self.assertTrue(os.path.exists(str(file_path.relative_to(folder)))) @unittest.skipIf(sys.platform != "win32", "Windows-specific behavior") class TestAbsolutePathOnWindows(fake_filesystem_unittest.TestCase): @patchfs def test_is_absolute(self, fs): # regression test for #673 self.assertTrue(pathlib.Path(".").absolute().is_absolute()) @unittest.skipIf(sys.version_info < (3, 8), "Not available before Python 3.8") class TestClassSetup(fake_filesystem_unittest.TestCase): @classmethod def setUpClass(cls): cls.setUpClassPyfakefs() cls.fake_fs().create_file("foo/bar", contents="test") def test_using_fs_functions(self): self.assertTrue(os.path.exists("foo/bar")) with open("foo/bar") as f: contents = f.read() self.assertEqual("test", contents) def test_using_fakefs(self): self.assertTrue(self.fs.exists("foo/bar")) f = self.fs.get_object("foo/bar") self.assertEqual("test", f.contents) if __name__ == "__main__": unittest.main() tests/fake_filesystem_vs_real_test.py000064400000071671150043321530014214 0ustar00# Copyright 2009 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Test that FakeFilesystem calls work identically to a real filesystem.""" # pylint: disable-all import os import shutil import sys import tempfile import time import unittest from pyfakefs import fake_filesystem, fake_os, fake_open from pyfakefs.helpers import IS_PYPY def sep(path): """Converts slashes in the path to the architecture's path seperator.""" if isinstance(path, str): return path.replace("/", os.sep) return path def _get_errno(raised_error): if raised_error is not None: try: return raised_error.errno except AttributeError: pass class TestCase(unittest.TestCase): is_windows = sys.platform.startswith("win") _FAKE_FS_BASE = "C:\\fakefs" if is_windows else "/fakefs" class FakeFilesystemVsRealTest(TestCase): def _paths(self, path): """For a given path, return paths in the real and fake filesystems.""" if not path: return None, None return ( os.path.join(self.real_base, path), os.path.join(self.fake_base, path), ) def _create_test_file(self, file_type, path, contents=None): """Create a dir, file, or link in both the real fs and the fake.""" path = sep(path) self._created_files.append([file_type, path, contents]) real_path, fake_path = self._paths(path) if file_type == "d": os.mkdir(real_path) self.fake_os.mkdir(fake_path) if file_type == "f": fh = open(real_path, "w") fh.write(contents or "") fh.close() fh = self.fake_open(fake_path, "w") fh.write(contents or "") fh.close() # b for binary file if file_type == "b": fh = open(real_path, "wb") fh.write(contents or "") fh.close() fh = self.fake_open(fake_path, "wb") fh.write(contents or "") fh.close() # l for symlink, h for hard link if file_type in ("l", "h"): real_target, fake_target = (contents, contents) # If it begins with '/', make it relative to the base. You can't go # creating files in / for the real file system. if contents.startswith(os.sep): real_target, fake_target = self._paths(contents[1:]) if file_type == "l": os.symlink(real_target, real_path) self.fake_os.symlink(fake_target, fake_path) elif file_type == "h": os.link(real_target, real_path) self.fake_os.link(fake_target, fake_path) def setUp(self): # Base paths in the real and test file systems. We keep them different # so that missing features in the fake don't fall through to the base # operations and magically succeed. tsname = "fakefs.%s" % time.time() self.cwd = os.getcwd() # Fully expand the base_path - required on OS X. self.real_base = os.path.realpath(os.path.join(tempfile.gettempdir(), tsname)) os.chdir(tempfile.gettempdir()) if os.path.isdir(self.real_base): shutil.rmtree(self.real_base) os.mkdir(self.real_base) self.fake_base = self._FAKE_FS_BASE # Make sure we can write to the physical testing temp directory. self.assertTrue(os.access(self.real_base, os.W_OK)) self.fake_filesystem = fake_filesystem.FakeFilesystem() self.fake_filesystem.create_dir(self.fake_base) self.fake_os = fake_os.FakeOsModule(self.fake_filesystem) self.fake_open = fake_open.FakeFileOpen(self.fake_filesystem) self._created_files = [] os.chdir(self.real_base) self.fake_os.chdir(self.fake_base) def tearDown(self): # We have to remove all the files from the real FS. Doing the same for # the fake FS is optional, but doing it is an extra sanity check. os.chdir(tempfile.gettempdir()) try: rev_files = self._created_files[:] rev_files.reverse() for info in rev_files: real_path, fake_path = self._paths(info[1]) if info[0] == "d": try: os.rmdir(real_path) except OSError as e: if "Directory not empty" in e: self.fail( "Real path %s not empty: %s : %s" % (real_path, e, os.listdir(real_path)) ) else: raise self.fake_os.rmdir(fake_path) if info[0] == "f" or info[0] == "l": os.remove(real_path) self.fake_os.remove(fake_path) finally: shutil.rmtree(self.real_base) os.chdir(self.cwd) def _compare_behaviors( self, method_name, path, real, fake, method_returns_path=False ): """Invoke an os method in both real and fake contexts and compare results. Invoke a real filesystem method with a path to a real file and invoke a fake filesystem method with a path to a fake file and compare the results. We expect some calls to throw Exceptions, so we catch those and compare them. Args: method_name: Name of method being tested, for use in error messages. path: potential path to a file in the real and fake file systems, passing an empty tuple indicates that no arguments to pass to method. real: built-in system library or method from the built-in system library which takes a path as an arg and returns some value. fake: fake_filsystem object or method from a fake_filesystem class which takes a path as an arg and returns some value. method_returns_path: True if the method returns a path, and thus we must compensate for expected difference between real and fake. Returns: A description of the difference in behavior, or None. """ # pylint: disable=C6403 def _error_class(exc): if exc: if hasattr(exc, "errno"): return "{}({})".format(exc.__class__.__name__, exc.errno) return exc.__class__.__name__ return "None" real_err, real_value = self._get_real_value(method_name, path, real) fake_err, fake_value = self._get_fake_value(method_name, path, fake) method_call = f"{method_name}" method_call += "()" if path == () else "({path})" # We only compare on the error class because the acutal error contents # is almost always different because of the file paths. if _error_class(real_err) != _error_class(fake_err): if real_err is None: return "%s: real version returned %s, fake raised %s" % ( method_call, real_value, _error_class(fake_err), ) if fake_err is None: return "%s: real version raised %s, fake returned %s" % ( method_call, _error_class(real_err), fake_value, ) return "%s: real version raised %s, fake raised %s" % ( method_call, _error_class(real_err), _error_class(fake_err), ) real_errno = _get_errno(real_err) fake_errno = _get_errno(fake_err) if real_errno != fake_errno: return "%s(%s): both raised %s, real errno %s, fake errno %s" % ( method_name, path, _error_class(real_err), real_errno, fake_errno, ) # If the method is supposed to return a full path AND both values # begin with the expected full path, then trim it off. if method_returns_path: if ( real_value and fake_value and real_value.startswith(self.real_base) and fake_value.startswith(self.fake_base) ): real_value = real_value[len(self.real_base) :] fake_value = fake_value[len(self.fake_base) :] if real_value != fake_value: return "%s: real return %s, fake returned %s" % ( method_call, real_value, fake_value, ) return None @staticmethod def _get_fake_value(method_name, path, fake): fake_value = None fake_err = None try: fake_method = fake if not callable(fake): fake_method = getattr(fake, method_name) args = [] if path == () else [path] result = fake_method(*args) if isinstance(result, bytes): fake_value = result.decode() else: fake_value = str(result) except Exception as e: # pylint: disable-msg=W0703 fake_err = e return fake_err, fake_value @staticmethod def _get_real_value(method_name, path, real): real_value = None real_err = None # Catching Exception below gives a lint warning, but it's what we need. try: args = [] if path == () else [path] real_method = real if not callable(real): real_method = getattr(real, method_name) result = real_method(*args) if isinstance(result, bytes): real_value = result.decode() else: real_value = str(result) except Exception as e: # pylint: disable-msg=W0703 real_err = e return real_err, real_value def assertOsMethodBehaviorMatches( self, method_name, path, method_returns_path=False ): """Invoke an os method in both real and fake contexts and compare. For a given method name (from the os module) and a path, compare the behavior of the system provided module against the fake_filesystem module. We expect results and/or Exceptions raised to be identical. Args: method_name: Name of method being tested. path: potential path to a file in the real and fake file systems. method_returns_path: True if the method returns a path, and thus we must compensate for expected difference between real and fake. Returns: A description of the difference in behavior, or None. """ path = sep(path) return self._compare_behaviors( method_name, path, os, self.fake_os, method_returns_path ) def diff_open_method_behavior( self, method_name, path, mode, data, method_returns_data=True ): """Invoke an open method in both real and fkae contexts and compare. Args: method_name: Name of method being tested. path: potential path to a file in the real and fake file systems. mode: how to open the file. data: any data to pass to the method. method_returns_data: True if a method returns some sort of data. For a given method name (from builtin open) and a path, compare the behavior of the system provided module against the fake_filesystem module. We expect results and/or Exceptions raised to be identical. Returns: A description of the difference in behavior, or None. """ with open(path, mode) as real_fh: with self.fake_open(path, mode) as fake_fh: return self._compare_behaviors( method_name, data, real_fh, fake_fh, method_returns_data ) def diff_os_path_method_behavior( self, method_name, path, method_returns_path=False ): """Invoke an os.path method in both real and fake contexts and compare. For a given method name (from the os.path module) and a path, compare the behavior of the system provided module against the fake_filesytem module. We expect results and/or Exceptions raised to be identical. Args: method_name: Name of method being tested. path: potential path to a file in the real and fake file systems. method_returns_path: True if the method returns a path, and thus we must compensate for expected difference between real and fake. Returns: A description of the difference in behavior, or None. """ return self._compare_behaviors( method_name, path, os.path, self.fake_os.path, method_returns_path ) def assertOsPathMethodBehaviorMatches( self, method_name, path, method_returns_path=False ): """Assert that an os.path behaves the same in both real and fake contexts. Wraps DiffOsPathMethodBehavior, raising AssertionError if any differences are reported. Args: method_name: Name of method being tested. path: potential path to a file in the real and fake file systems. method_returns_path: True if the method returns a path, and thus we must compensate for expected difference between real and fake. Raises: AssertionError if there is any difference in behavior. """ path = sep(path) diff = self.diff_os_path_method_behavior(method_name, path, method_returns_path) if diff: self.fail(diff) def assertAllOsBehaviorsMatch(self, path): path = sep(path) os_method_names = [] if self.is_windows else ["readlink"] os_method_names_no_args = ["getcwd"] os_path_method_names = ["isabs", "isdir"] if not self.is_windows: os_path_method_names += ["islink", "lexists"] if not self.is_windows or not IS_PYPY: os_path_method_names += ["isfile", "exists"] wrapped_methods = [ ["access", self._access_real, self._access_fake], ["stat.size", self._stat_size_real, self._stat_size_fake], ["lstat.size", self._lstat_size_real, self._lstat_size_fake], ] differences = [] for method_name in os_method_names: diff = self.assertOsMethodBehaviorMatches(method_name, path) if diff: differences.append(diff) for method_name in os_method_names_no_args: diff = self.assertOsMethodBehaviorMatches( method_name, (), method_returns_path=True ) if diff: differences.append(diff) for method_name in os_path_method_names: diff = self.diff_os_path_method_behavior(method_name, path) if diff: differences.append(diff) for m in wrapped_methods: diff = self._compare_behaviors(m[0], path, m[1], m[2]) if diff: differences.append(diff) if differences: self.fail( "Behaviors do not match for %s:\n %s" % (path, "\n ".join(differences)) ) def assertFileHandleBehaviorsMatch(self, path, mode, data): path = sep(path) write_method_names = ["write", "writelines"] read_method_names = ["read", "readlines"] other_method_names = ["truncate", "flush", "close"] differences = [] for method_name in write_method_names: diff = self.diff_open_method_behavior(method_name, path, mode, data) if diff: differences.append(diff) for method_name in read_method_names + other_method_names: diff = self.diff_open_method_behavior(method_name, path, mode, ()) if diff: differences.append(diff) if differences: self.fail( "Behaviors do not match for %s:\n %s" % (path, "\n ".join(differences)) ) def assertFileHandleOpenBehaviorsMatch(self, *args, **kwargs): """Compare open() function invocation between real and fake. Runs open(*args, **kwargs) on both real and fake. Args: *args: args to pass through to open() **kwargs: kwargs to pass through to open(). Returns: None. Raises: AssertionError if underlying open() behavior differs from fake. """ real_err = None fake_err = None try: with open(*args, **kwargs): pass except Exception as e: # pylint: disable-msg=W0703 real_err = e try: with self.fake_open(*args, **kwargs): pass except Exception as e: # pylint: disable-msg=W0703 fake_err = e # default equal in case one is None and other is not. is_exception_equal = real_err == fake_err if real_err and fake_err: # exception __eq__ doesn't evaluate equal ever, thus manual check. is_exception_equal = ( type(real_err) is type(fake_err) and real_err.args == fake_err.args ) if not is_exception_equal: msg = "Behaviors don't match on open with args %s & kwargs %s.\n" % ( args, kwargs, ) real_err_msg = "Real open results in: %s\n" % repr(real_err) fake_err_msg = "Fake open results in: %s\n" % repr(fake_err) self.fail(msg + real_err_msg + fake_err_msg) # Helpers for checks which are not straight method calls. @staticmethod def _access_real(path): return os.access(path, os.R_OK) def _access_fake(self, path): return self.fake_os.access(path, os.R_OK) def _stat_size_real(self, path): real_path, unused_fake_path = self._paths(path) # fake_filesystem.py does not implement stat().st_size for directories if os.path.isdir(real_path): return None return os.stat(real_path).st_size def _stat_size_fake(self, path): unused_real_path, fake_path = self._paths(path) # fake_filesystem.py does not implement stat().st_size for directories if self.fake_os.path.isdir(fake_path): return None return self.fake_os.stat(fake_path).st_size def _lstat_size_real(self, path): real_path, unused_fake_path = self._paths(path) if os.path.isdir(real_path): return None size = os.lstat(real_path).st_size # Account for the difference in the lengths of the absolute paths. if os.path.islink(real_path): if os.readlink(real_path).startswith(os.sep): size -= len(self.real_base) return size def _lstat_size_fake(self, path): unused_real_path, fake_path = self._paths(path) # size = 0 if self.fake_os.path.isdir(fake_path): return None size = self.fake_os.lstat(fake_path).st_size # Account for the difference in the lengths of the absolute paths. if self.fake_os.path.islink(fake_path): if self.fake_os.readlink(fake_path).startswith(os.sep): size -= len(self.fake_base) return size def test_isabs(self): # We do not have to create any files for isabs. self.assertOsPathMethodBehaviorMatches("isabs", None) self.assertOsPathMethodBehaviorMatches("isabs", "") self.assertOsPathMethodBehaviorMatches("isabs", "/") self.assertOsPathMethodBehaviorMatches("isabs", "/a") self.assertOsPathMethodBehaviorMatches("isabs", "a") def test_none_path(self): self.assertAllOsBehaviorsMatch(None) def test_empty_path(self): self.assertAllOsBehaviorsMatch("") def test_root_path(self): self.assertAllOsBehaviorsMatch("/") def test_non_existant_file(self): self.assertAllOsBehaviorsMatch("foo") def test_empty_file(self): self._create_test_file("f", "aFile") self.assertAllOsBehaviorsMatch("aFile") def test_file_with_contents(self): self._create_test_file("f", "aFile", "some contents") self.assertAllOsBehaviorsMatch("aFile") def test_file_with_binary_contents(self): self._create_test_file("b", "aFile", b"some contents") self.assertAllOsBehaviorsMatch("aFile") @unittest.skipIf(TestCase.is_windows, "no symlink in Windows") def test_sym_link_to_empty_file(self): self._create_test_file("f", "aFile") self._create_test_file("l", "link_to_empty", "aFile") self.assertAllOsBehaviorsMatch("link_to_empty") @unittest.skipIf(TestCase.is_windows, "no symlink in Windows") def test_hard_link_to_empty_file(self): self._create_test_file("f", "aFile") self._create_test_file("h", "link_to_empty", "aFile") self.assertAllOsBehaviorsMatch("link_to_empty") @unittest.skipIf(TestCase.is_windows, "no symlink in Windows") def test_sym_link_to_real_file(self): self._create_test_file("f", "aFile", "some contents") self._create_test_file("l", "link_to_file", "aFile") self.assertAllOsBehaviorsMatch("link_to_file") @unittest.skipIf(TestCase.is_windows, "no symlink in Windows") def test_hard_link_to_real_file(self): self._create_test_file("f", "aFile", "some contents") self._create_test_file("h", "link_to_file", "aFile") self.assertAllOsBehaviorsMatch("link_to_file") @unittest.skipIf(TestCase.is_windows, "no symlink in Windows") def test_broken_sym_link(self): self._create_test_file("l", "broken_link", "broken") self._create_test_file("l", "loop", "/a/loop") self.assertAllOsBehaviorsMatch("broken_link") def test_file_in_a_folder(self): self._create_test_file("d", "a") self._create_test_file("d", "a/b") self._create_test_file("f", "a/b/file", "contents") self.assertAllOsBehaviorsMatch("a/b/file") @unittest.skipIf(TestCase.is_windows, "no symlink in Windows") def test_absolute_sym_link_to_folder(self): self._create_test_file("d", "a") self._create_test_file("d", "a/b") self._create_test_file("f", "a/b/file", "contents") self._create_test_file("l", "a/link", "/a/b") self.assertAllOsBehaviorsMatch("a/link/file") @unittest.skipIf(TestCase.is_windows, "no symlink in Windows") def test_link_to_folder_after_chdir(self): self._create_test_file("d", "a") self._create_test_file("d", "a/b") self._create_test_file("f", "a/b/file", "contents") self._create_test_file("l", "a/link", "/a/b") real_dir, fake_dir = self._paths("a/b") os.chdir(real_dir) self.fake_os.chdir(fake_dir) self.assertAllOsBehaviorsMatch("file") @unittest.skipIf(TestCase.is_windows, "no symlink in Windows") def test_relative_sym_link_to_folder(self): self._create_test_file("d", "a") self._create_test_file("d", "a/b") self._create_test_file("f", "a/b/file", "contents") self._create_test_file("l", "a/link", "b") self.assertAllOsBehaviorsMatch("a/link/file") @unittest.skipIf(TestCase.is_windows, "no symlink in Windows") def test_sym_link_to_parent(self): # Soft links on HFS+ / OS X behave differently. if os.uname()[0] != "Darwin": self._create_test_file("d", "a") self._create_test_file("d", "a/b") self._create_test_file("l", "a/b/c", "..") self.assertAllOsBehaviorsMatch("a/b/c") @unittest.skipIf(TestCase.is_windows, "no symlink in Windows") def test_path_through_sym_link_to_parent(self): self._create_test_file("d", "a") self._create_test_file("f", "a/target", "contents") self._create_test_file("d", "a/b") self._create_test_file("l", "a/b/c", "..") self.assertAllOsBehaviorsMatch("a/b/c/target") @unittest.skipIf(TestCase.is_windows, "no symlink in Windows") def test_sym_link_to_sibling_directory(self): self._create_test_file("d", "a") self._create_test_file("d", "a/b") self._create_test_file("d", "a/sibling_of_b") self._create_test_file("f", "a/sibling_of_b/target", "contents") self._create_test_file("l", "a/b/c", "../sibling_of_b") self.assertAllOsBehaviorsMatch("a/b/c/target") @unittest.skipIf(TestCase.is_windows, "no symlink in Windows") def test_sym_link_to_sibling_directory_non_existant_file(self): self._create_test_file("d", "a") self._create_test_file("d", "a/b") self._create_test_file("d", "a/sibling_of_b") self._create_test_file("f", "a/sibling_of_b/target", "contents") self._create_test_file("l", "a/b/c", "../sibling_of_b") self.assertAllOsBehaviorsMatch("a/b/c/file_does_not_exist") @unittest.skipIf(TestCase.is_windows, "no symlink in Windows") def test_broken_sym_link_to_sibling_directory(self): self._create_test_file("d", "a") self._create_test_file("d", "a/b") self._create_test_file("d", "a/sibling_of_b") self._create_test_file("f", "a/sibling_of_b/target", "contents") self._create_test_file("l", "a/b/c", "../broken_sibling_of_b") self.assertAllOsBehaviorsMatch("a/b/c/target") def test_relative_path(self): self._create_test_file("d", "a") self._create_test_file("d", "a/b") self._create_test_file("d", "a/sibling_of_b") self._create_test_file("f", "a/sibling_of_b/target", "contents") self.assertAllOsBehaviorsMatch("a/b/../sibling_of_b/target") def test_broken_relative_path(self): self._create_test_file("d", "a") self._create_test_file("d", "a/b") self._create_test_file("d", "a/sibling_of_b") self._create_test_file("f", "a/sibling_of_b/target", "contents") self.assertAllOsBehaviorsMatch("a/b/../broken/target") def test_bad_relative_path(self): self._create_test_file("d", "a") self._create_test_file("f", "a/target", "contents") self._create_test_file("d", "a/b") self._create_test_file("d", "a/sibling_of_b") self._create_test_file("f", "a/sibling_of_b/target", "contents") self.assertAllOsBehaviorsMatch("a/b/../broken/../target") def test_getmtime_nonexistant_path(self): self.assertOsPathMethodBehaviorMatches("getmtime", "no/such/path") def test_builtin_open_modes(self): self._create_test_file("f", "read", "some contents") self._create_test_file("f", "write", "some contents") self._create_test_file("f", "append", "some contents") self.assertFileHandleBehaviorsMatch("read", "r", "other contents") self.assertFileHandleBehaviorsMatch("write", "w", "other contents") self.assertFileHandleBehaviorsMatch("append", "a", "other contents") self._create_test_file("f", "readplus", "some contents") self._create_test_file("f", "writeplus", "some contents") self.assertFileHandleBehaviorsMatch("readplus", "r+", "other contents") self.assertFileHandleBehaviorsMatch("writeplus", "w+", "other contents") self._create_test_file("b", "binaryread", b"some contents") self._create_test_file("b", "binarywrite", b"some contents") self._create_test_file("b", "binaryappend", b"some contents") self.assertFileHandleBehaviorsMatch("binaryread", "rb", b"other contents") self.assertFileHandleBehaviorsMatch("binarywrite", "wb", b"other contents") self.assertFileHandleBehaviorsMatch("binaryappend", "ab", b"other contents") self.assertFileHandleBehaviorsMatch("read", "rb", "other contents") self.assertFileHandleBehaviorsMatch("write", "wb", "other contents") self.assertFileHandleBehaviorsMatch("append", "ab", "other contents") # binary cannot have encoding self.assertFileHandleOpenBehaviorsMatch("read", "rb", encoding="enc") self.assertFileHandleOpenBehaviorsMatch("write", mode="wb", encoding="enc") self.assertFileHandleOpenBehaviorsMatch("append", "ab", encoding="enc") # text can have encoding self.assertFileHandleOpenBehaviorsMatch("read", "r", encoding="utf-8") self.assertFileHandleOpenBehaviorsMatch("write", "w", encoding="utf-8") self.assertFileHandleOpenBehaviorsMatch("append", "a", encoding="utf-8") def main(_): unittest.main() if __name__ == "__main__": unittest.main() tests/fake_open_test.py000064400000244545150043321530011260 0ustar00# # Copyright 2009 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Unit tests for fake_open.FakeOsModule.""" import errno import io import locale import os import stat import sys import time import unittest from pyfakefs import fake_filesystem, helpers from pyfakefs.helpers import is_root, IS_PYPY from pyfakefs.fake_io import FakeIoModule from pyfakefs.fake_filesystem_unittest import PatchMode from pyfakefs.tests.test_utils import RealFsTestCase class FakeFileOpenTestBase(RealFsTestCase): def setUp(self): super(FakeFileOpenTestBase, self).setUp() if self.use_real_fs(): self.open = io.open else: self.fake_io_module = FakeIoModule(self.filesystem) self.open = self.fake_io_module.open def path_separator(self): return "!" class FakeFileOpenTest(FakeFileOpenTestBase): def setUp(self): super(FakeFileOpenTest, self).setUp() self.orig_time = time.time def tearDown(self): super(FakeFileOpenTest, self).tearDown() time.time = self.orig_time def test_open_no_parent_dir(self): """Expect raise when opening a file in a missing directory.""" file_path = self.make_path("foo", "bar.txt") self.assert_raises_os_error(errno.ENOENT, self.open, file_path, "w") def test_delete_on_close(self): self.skip_real_fs() file_dir = "boo" file_path = "boo!far" self.os.mkdir(file_dir) self.open = fake_filesystem.FakeFileOpen(self.filesystem, delete_on_close=True) with self.open(file_path, "w"): self.assertTrue(self.filesystem.exists(file_path)) self.assertFalse(self.filesystem.exists(file_path)) def test_no_delete_on_close_by_default(self): file_path = self.make_path("czar") with self.open(file_path, "w"): self.assertTrue(self.os.path.exists(file_path)) self.assertTrue(self.os.path.exists(file_path)) def test_compatibility_of_with_statement(self): self.skip_real_fs() self.open = fake_filesystem.FakeFileOpen(self.filesystem, delete_on_close=True) file_path = "foo" self.assertFalse(self.os.path.exists(file_path)) with self.open(file_path, "w"): self.assertTrue(self.os.path.exists(file_path)) # After the 'with' statement, the close() method should have been # called. self.assertFalse(self.os.path.exists(file_path)) def test_unicode_contents(self): file_path = self.make_path("foo") # note that this will work only if the string can be represented # by the locale preferred encoding - which under Windows is # usually not UTF-8, but something like Latin1, depending on the locale text_fractions = "Ümläüts" try: with self.open(file_path, "w") as f: f.write(text_fractions) except UnicodeEncodeError: # see https://github.com/pytest-dev/pyfakefs/issues/623 self.skipTest("This test does not work with an ASCII locale") with self.open(file_path) as f: contents = f.read() self.assertEqual(contents, text_fractions) def test_byte_contents(self): file_path = self.make_path("foo") byte_fractions = b"\xe2\x85\x93 \xe2\x85\x94 \xe2\x85\x95 \xe2\x85\x96" with self.open(file_path, "wb") as f: f.write(byte_fractions) # the encoding has to be specified, otherwise the locale default # is used which can be different on different systems with self.open(file_path, encoding="utf-8") as f: contents = f.read() self.assertEqual(contents, byte_fractions.decode("utf-8")) def test_write_str_read_bytes(self): file_path = self.make_path("foo") str_contents = "Äsgül" try: with self.open(file_path, "w") as f: f.write(str_contents) except UnicodeEncodeError: # see https://github.com/pytest-dev/pyfakefs/issues/623 self.skipTest("This test does not work with an ASCII locale") with self.open(file_path, "rb") as f: contents = f.read() self.assertEqual( str_contents, contents.decode(locale.getpreferredencoding(False)) ) def test_open_valid_file(self): contents = [ "I am he as\n", "you are he as\n", "you are me and\n", "we are all together\n", ] file_path = self.make_path("bar.txt") self.create_file(file_path, contents="".join(contents)) with self.open(file_path) as fake_file: self.assertEqual(contents, fake_file.readlines()) def test_open_valid_args(self): contents = [ "Bang bang Maxwell's silver hammer\n", "Came down on her head", ] file_path = self.make_path("abbey_road", "maxwell") self.create_file(file_path, contents="".join(contents)) with self.open(file_path, buffering=1) as f: self.assertEqual(contents, f.readlines()) with self.open( file_path, buffering=1, errors="strict", newline="\n", opener=None ) as f: expected_contents = [ contents[0][:-1] + self.os.linesep, contents[1], ] self.assertEqual(expected_contents, f.readlines()) def test_open_valid_file_with_cwd(self): contents = [ "I am he as\n", "you are he as\n", "you are me and\n", "we are all together\n", ] file_path = self.make_path("bar.txt") self.create_file(file_path, contents="".join(contents)) self.os.chdir(self.base_path) with self.open(file_path) as f: self.assertEqual(contents, f.readlines()) def test_iterate_over_file(self): contents = [ "Bang bang Maxwell's silver hammer", "Came down on her head", ] file_path = self.make_path("abbey_road", "maxwell") self.create_file(file_path, contents="\n".join(contents)) with self.open(file_path) as fake_file: result = [line.rstrip() for line in fake_file] self.assertEqual(contents, result) def test_next_over_file(self): contents = ["Live long\n", "and prosper\n"] result = [] file_path = self.make_path("foo.txt") self.create_file(file_path, contents="".join(contents)) with self.open(file_path) as fake_file: result.append(next(fake_file)) result.append(next(fake_file)) self.assertEqual(contents, result) def test_open_directory_error(self): directory_path = self.make_path("foo") self.os.mkdir(directory_path) if self.is_windows: self.assert_raises_os_error( errno.EACCES, self.open.__call__, directory_path ) else: self.assert_raises_os_error( errno.EISDIR, self.open.__call__, directory_path ) def test_create_file_with_write(self): contents = [ "Here comes the sun, little darlin'", "Here comes the sun, and I say,", "It's alright", ] file_dir = self.make_path("abbey_road") file_path = self.os.path.join(file_dir, "here_comes_the_sun") self.os.mkdir(file_dir) with self.open(file_path, "w") as fake_file: for line in contents: fake_file.write(line + "\n") with self.open(file_path) as fake_file: result = [line.rstrip() for line in fake_file] self.assertEqual(contents, result) def test_create_file_with_append(self): contents = [ "Here comes the sun, little darlin'", "Here comes the sun, and I say,", "It's alright", ] file_dir = self.make_path("abbey_road") file_path = self.os.path.join(file_dir, "here_comes_the_sun") self.os.mkdir(file_dir) with self.open(file_path, "a") as fake_file: for line in contents: fake_file.write(line + "\n") with self.open(file_path) as fake_file: result = [line.rstrip() for line in fake_file] self.assertEqual(contents, result) def test_exclusive_create_file_failure(self): self.skip_if_symlink_not_supported() file_path = self.make_path("bar") self.create_file(file_path) self.assert_raises_os_error(errno.EEXIST, self.open, file_path, "x") self.assert_raises_os_error(errno.EEXIST, self.open, file_path, "xb") def test_exclusive_create_file(self): file_dir = self.make_path("foo") file_path = self.os.path.join(file_dir, "bar") self.os.mkdir(file_dir) contents = "String contents" with self.open(file_path, "x") as fake_file: fake_file.write(contents) with self.open(file_path) as fake_file: self.assertEqual(contents, fake_file.read()) def test_exclusive_create_binary_file(self): file_dir = self.make_path("foo") file_path = self.os.path.join(file_dir, "bar") self.os.mkdir(file_dir) contents = b"Binary contents" with self.open(file_path, "xb") as fake_file: fake_file.write(contents) with self.open(file_path, "rb") as fake_file: self.assertEqual(contents, fake_file.read()) def test_overwrite_existing_file(self): file_path = self.make_path("overwite") self.create_file(file_path, contents="To disappear") new_contents = [ "Only these lines", "should be in the file.", ] with self.open(file_path, "w") as fake_file: for line in new_contents: fake_file.write(line + "\n") with self.open(file_path) as fake_file: result = [line.rstrip() for line in fake_file] self.assertEqual(new_contents, result) def test_append_existing_file(self): file_path = self.make_path("appendfile") contents = [ "Contents of original file" "Appended contents", ] self.create_file(file_path, contents=contents[0]) with self.open(file_path, "a") as fake_file: for line in contents[1:]: fake_file.write(line + "\n") with self.open(file_path) as fake_file: result = [line.rstrip() for line in fake_file] self.assertEqual(contents, result) def test_open_with_wplus(self): # set up file_path = self.make_path("wplus_file") self.create_file(file_path, contents="old contents") self.assertTrue(self.os.path.exists(file_path)) with self.open(file_path, "r") as fake_file: self.assertEqual("old contents", fake_file.read()) # actual tests with self.open(file_path, "w+") as fake_file: fake_file.write("new contents") fake_file.seek(0) self.assertTrue("new contents", fake_file.read()) def test_open_with_wplus_truncation(self): # set up file_path = self.make_path("wplus_file") self.create_file(file_path, contents="old contents") self.assertTrue(self.os.path.exists(file_path)) with self.open(file_path, "r") as fake_file: self.assertEqual("old contents", fake_file.read()) # actual tests with self.open(file_path, "w+") as fake_file: fake_file.seek(0) self.assertEqual("", fake_file.read()) def test_open_with_append_flag(self): contents = [ "I am he as\n", "you are he as\n", "you are me and\n", "we are all together\n", ] additional_contents = ["These new lines\n", "like you a lot.\n"] file_path = self.make_path("appendfile") self.create_file(file_path, contents="".join(contents)) with self.open(file_path, "a") as fake_file: with self.assertRaises(io.UnsupportedOperation): fake_file.read(0) with self.assertRaises(io.UnsupportedOperation): fake_file.readline() expected_len = len("".join(contents)) expected_len += len(contents) * (len(self.os.linesep) - 1) self.assertEqual(expected_len, fake_file.tell()) fake_file.seek(0) self.assertEqual(0, fake_file.tell()) fake_file.writelines(additional_contents) with self.open(file_path) as fake_file: self.assertEqual(contents + additional_contents, fake_file.readlines()) def check_append_with_aplus(self): file_path = self.make_path("aplus_file") self.create_file(file_path, contents="old contents") self.assertTrue(self.os.path.exists(file_path)) with self.open(file_path, "r") as fake_file: self.assertEqual("old contents", fake_file.read()) if self.filesystem: # need to recreate FakeFileOpen for OS specific initialization self.open = fake_filesystem.FakeFileOpen( self.filesystem, delete_on_close=True ) with self.open(file_path, "a+") as fake_file: self.assertEqual(12, fake_file.tell()) fake_file.write("new contents") self.assertEqual(24, fake_file.tell()) fake_file.seek(0) self.assertEqual("old contentsnew contents", fake_file.read()) def test_append_with_aplus_mac_os(self): self.check_macos_only() self.check_append_with_aplus() def test_append_with_aplus_linux_windows(self): self.check_linux_and_windows() self.check_append_with_aplus() def test_append_with_aplus_read_with_loop(self): # set up file_path = self.make_path("aplus_file") self.create_file(file_path, contents="old contents") self.assertTrue(self.os.path.exists(file_path)) with self.open(file_path, "r") as fake_file: self.assertEqual("old contents", fake_file.read()) # actual tests with self.open(file_path, "a+") as fake_file: fake_file.seek(0) fake_file.write("new contents") fake_file.seek(0) for line in fake_file: self.assertEqual("old contentsnew contents", line) def test_read_empty_file_with_aplus(self): file_path = self.make_path("aplus_file") with self.open(file_path, "a+") as fake_file: self.assertEqual("", fake_file.read()) def test_read_with_rplus(self): # set up file_path = self.make_path("rplus_file") self.create_file(file_path, contents="old contents here") self.assertTrue(self.os.path.exists(file_path)) with self.open(file_path, "r") as fake_file: self.assertEqual("old contents here", fake_file.read()) # actual tests with self.open(file_path, "r+") as fake_file: self.assertEqual("old contents here", fake_file.read()) fake_file.seek(0) fake_file.write("new contents") fake_file.seek(0) self.assertEqual("new contents here", fake_file.read()) def create_with_permission(self, file_path, perm_bits): self.create_file(file_path) self.os.chmod(file_path, perm_bits) if perm_bits & helpers.PERM_READ: st = self.os.stat(file_path) self.assert_mode_equal(perm_bits, st.st_mode) self.assertTrue(st.st_mode & stat.S_IFREG) self.assertFalse(st.st_mode & stat.S_IFDIR) def test_open_flags700(self): # set up self.check_posix_only() file_path = self.make_path("target_file") self.create_with_permission(file_path, 0o700) # actual tests self.open(file_path, "r").close() self.open(file_path, "w").close() self.open(file_path, "w+").close() with self.assertRaises(ValueError): self.open(file_path, "INV") def test_open_flags400(self): # set up self.check_posix_only() file_path = self.make_path("target_file") self.create_with_permission(file_path, 0o400) # actual tests self.open(file_path, "r").close() if not is_root(): self.assert_raises_os_error(errno.EACCES, self.open, file_path, "w") self.assert_raises_os_error(errno.EACCES, self.open, file_path, "w+") else: self.open(file_path, "w").close() self.open(file_path, "w+").close() def test_open_flags200(self): # set up self.check_posix_only() file_path = self.make_path("target_file") self.create_with_permission(file_path, 0o200) # actual tests self.open(file_path, "w").close() if not is_root(): with self.assertRaises(OSError): self.open(file_path, "r") with self.assertRaises(OSError): self.open(file_path, "w+") else: self.open(file_path, "r").close() self.open(file_path, "w+").close() def test_open_flags100(self): # set up self.check_posix_only() file_path = self.make_path("target_file") self.create_with_permission(file_path, 0o100) # actual tests if not is_root(): with self.assertRaises(OSError): self.open(file_path, "r") with self.assertRaises(OSError): self.open(file_path, "w") with self.assertRaises(OSError): self.open(file_path, "w+") else: self.open(file_path, "r").close() self.open(file_path, "w").close() self.open(file_path, "w+").close() def test_follow_link_read(self): self.skip_if_symlink_not_supported() link_path = self.make_path("foo", "bar", "baz") target = self.make_path("tarJAY") target_contents = "real baz contents" self.create_file(target, contents=target_contents) self.create_symlink(link_path, target) self.assert_equal_paths(target, self.os.readlink(link_path)) fh = self.open(link_path, "r") got_contents = fh.read() fh.close() self.assertEqual(target_contents, got_contents) def test_follow_link_write(self): self.skip_if_symlink_not_supported() link_path = self.make_path("foo", "bar", "TBD") target = self.make_path("tarJAY") target_contents = "real baz contents" self.create_symlink(link_path, target) self.assertFalse(self.os.path.exists(target)) with self.open(link_path, "w") as fh: fh.write(target_contents) with self.open(target, "r") as fh: got_contents = fh.read() self.assertEqual(target_contents, got_contents) def test_follow_intra_path_link_write(self): # Test a link in the middle of of a file path. self.skip_if_symlink_not_supported() link_path = self.os.path.join( self.base_path, "foo", "build", "local_machine", "output", "1" ) target = self.make_path("tmp", "output", "1") self.create_dir(self.make_path("tmp", "output")) self.create_symlink( self.os.path.join(self.base_path, "foo", "build", "local_machine"), self.make_path("tmp"), ) self.assertFalse(self.os.path.exists(link_path)) self.assertFalse(self.os.path.exists(target)) target_contents = "real baz contents" with self.open(link_path, "w") as fh: fh.write(target_contents) with self.open(target, "r") as fh: got_contents = fh.read() self.assertEqual(target_contents, got_contents) def test_open_raises_on_symlink_loop(self): # Regression test for #274 self.check_posix_only() file_dir = self.make_path("foo") self.os.mkdir(file_dir) file_path = self.os.path.join(file_dir, "baz") self.os.symlink(file_path, file_path) self.assert_raises_os_error(errno.ELOOP, self.open, file_path) def test_file_descriptors_for_different_files(self): first_path = self.make_path("some_file1") self.create_file(first_path, contents="contents here1") second_path = self.make_path("some_file2") self.create_file(second_path, contents="contents here2") third_path = self.make_path("some_file3") self.create_file(third_path, contents="contents here3") with self.open(first_path) as fake_file1: with self.open(second_path) as fake_file2: with self.open(third_path) as fake_file3: fileno2 = fake_file2.fileno() self.assertGreater(fileno2, fake_file1.fileno()) self.assertGreater(fake_file3.fileno(), fileno2) def test_file_descriptors_for_the_same_file_are_different(self): first_path = self.make_path("some_file1") self.create_file(first_path, contents="contents here1") second_path = self.make_path("some_file2") self.create_file(second_path, contents="contents here2") with self.open(first_path) as fake_file1: with self.open(second_path) as fake_file2: with self.open(first_path) as fake_file1a: fileno2 = fake_file2.fileno() self.assertGreater(fileno2, fake_file1.fileno()) self.assertGreater(fake_file1a.fileno(), fileno2) def test_reused_file_descriptors_do_not_affect_others(self): first_path = self.make_path("some_file1") self.create_file(first_path, contents="contents here1") second_path = self.make_path("some_file2") self.create_file(second_path, contents="contents here2") third_path = self.make_path("some_file3") self.create_file(third_path, contents="contents here3") with self.open(first_path, "r") as fake_file1: with self.open(second_path, "r") as fake_file2: fake_file3 = self.open(third_path, "r") fake_file1a = self.open(first_path, "r") fileno1 = fake_file1.fileno() fileno2 = fake_file2.fileno() fileno3 = fake_file3.fileno() fileno4 = fake_file1a.fileno() with self.open(second_path, "r") as fake_file2: with self.open(first_path, "r") as fake_file1b: self.assertEqual(fileno1, fake_file2.fileno()) self.assertEqual(fileno2, fake_file1b.fileno()) self.assertEqual(fileno3, fake_file3.fileno()) self.assertEqual(fileno4, fake_file1a.fileno()) fake_file3.close() fake_file1a.close() def test_intertwined_read_write(self): file_path = self.make_path("some_file") self.create_file(file_path) with self.open(file_path, "a") as writer: with self.open(file_path, "r") as reader: writes = [ "hello", "world\n", "somewhere\nover", "the\n", "rainbow", ] reads = [] # when writes are flushes, they are piped to the reader for write in writes: writer.write(write) writer.flush() reads.append(reader.read()) reader.flush() self.assertEqual(writes, reads) writes = ["nothing", "to\nsee", "here"] reads = [] # when writes are not flushed, the reader doesn't read # anything new for write in writes: writer.write(write) reads.append(reader.read()) self.assertEqual(["" for _ in writes], reads) def test_intertwined_read_write_python3_str(self): file_path = self.make_path("some_file") self.create_file(file_path) with self.open(file_path, "a", encoding="utf-8") as writer: with self.open(file_path, "r", encoding="utf-8") as reader: writes = ["привет", "мир\n", "где-то\nза", "радугой"] reads = [] # when writes are flushes, they are piped to the reader for write in writes: writer.write(write) writer.flush() reads.append(reader.read()) reader.flush() self.assertEqual(writes, reads) writes = ["ничего", "не\nвидно"] reads = [] # when writes are not flushed, the reader doesn't # read anything new for write in writes: writer.write(write) reads.append(reader.read()) self.assertEqual(["" for _ in writes], reads) def test_open_io_errors(self): file_path = self.make_path("some_file") self.create_file(file_path) with self.open(file_path, "a") as fh: with self.assertRaises(OSError): fh.read() with self.assertRaises(OSError): fh.readlines() with self.open(file_path, "w") as fh: with self.assertRaises(OSError): fh.read() with self.assertRaises(OSError): fh.readlines() with self.open(file_path, "r") as fh: with self.assertRaises(OSError): fh.truncate() with self.assertRaises(OSError): fh.write("contents") with self.assertRaises(OSError): fh.writelines(["con", "tents"]) def _iterator_open(mode): with self.open(file_path, mode) as f: for _ in f: pass with self.assertRaises(OSError): _iterator_open("w") with self.assertRaises(OSError): _iterator_open("a") def test_open_raises_io_error_if_parent_is_file_posix(self): self.check_posix_only() file_path = self.make_path("bar") self.create_file(file_path) file_path = self.os.path.join(file_path, "baz") self.assert_raises_os_error(errno.ENOTDIR, self.open, file_path, "w") def test_open_raises_io_error_if_parent_is_file_windows(self): self.check_windows_only() file_path = self.make_path("bar") self.create_file(file_path) file_path = self.os.path.join(file_path, "baz") self.assert_raises_os_error(errno.ENOENT, self.open, file_path, "w") def check_open_with_trailing_sep(self, error_nr): # regression test for #362 path = self.make_path("foo") + self.os.path.sep self.assert_raises_os_error(error_nr, self.open, path, "w") def test_open_with_trailing_sep_linux(self): self.check_linux_only() self.check_open_with_trailing_sep(errno.EISDIR) def test_open_with_trailing_sep_macos(self): self.check_macos_only() self.check_open_with_trailing_sep(errno.ENOENT) def test_open_with_trailing_sep_windows(self): self.check_windows_only() self.check_open_with_trailing_sep(errno.EINVAL) def test_can_read_from_block_device(self): self.skip_real_fs() device_path = "device" self.filesystem.create_file(device_path, stat.S_IFBLK | helpers.PERM_ALL) with self.open(device_path, "r") as fh: self.assertEqual("", fh.read()) def test_truncate_flushes_contents(self): # Regression test for #285 file_path = self.make_path("baz") self.create_file(file_path) with self.open(file_path, "w") as f0: f0.write("test") f0.truncate() self.assertEqual(4, self.os.path.getsize(file_path)) def test_update_other_instances_of_same_file_on_flush(self): # Regression test for #302 file_path = self.make_path("baz") with self.open(file_path, "w") as f0: with self.open(file_path, "w") as f1: f0.write("test") f0.truncate() f1.flush() self.assertEqual(4, self.os.path.getsize(file_path)) def test_getsize_after_truncate(self): # Regression test for #412 file_path = self.make_path("foo") with self.open(file_path, "a") as f: f.write("a") f.seek(0) f.truncate() f.write("b") f.truncate() self.assertEqual(1, self.os.path.getsize(file_path)) self.assertEqual(1, self.os.stat(file_path).st_size) def test_st_size_after_truncate(self): # Regression test for #412 file_path = self.make_path("foo") with self.open(file_path, "a") as f: f.write("a") f.truncate() f.write("b") f.truncate() self.assertEqual(2, self.os.stat(file_path).st_size) def test_that_read_over_end_does_not_reset_position(self): # Regression test for #286 file_path = self.make_path("baz") self.create_file(file_path) with self.open(file_path) as f0: f0.seek(2) f0.read() self.assertEqual(2, f0.tell()) def test_accessing_closed_file_raises(self): # Regression test for #275, #280 if self.is_pypy: raise unittest.SkipTest("Different exceptions with PyPy") file_path = self.make_path("foo") self.create_file(file_path, contents=b"test") fake_file = self.open(file_path, "r") fake_file.close() with self.assertRaises(ValueError): fake_file.read(1) with self.assertRaises(ValueError): fake_file.write("a") with self.assertRaises(ValueError): fake_file.readline() with self.assertRaises(ValueError): fake_file.truncate() with self.assertRaises(ValueError): fake_file.tell() with self.assertRaises(ValueError): fake_file.seek(1) with self.assertRaises(ValueError): fake_file.flush() def test_accessing_open_file_with_another_handle_raises(self): # Regression test for #282 if self.is_pypy: raise unittest.SkipTest("Different exceptions with PyPy") file_path = self.make_path("foo") f0 = self.os.open(file_path, os.O_CREAT | os.O_WRONLY | os.O_TRUNC) fake_file = self.open(file_path, "r") fake_file.close() with self.assertRaises(ValueError): fake_file.read(1) with self.assertRaises(ValueError): fake_file.write("a") self.os.close(f0) def test_tell_flushes_under_mac_os(self): # Regression test for #288 self.check_macos_only() file_path = self.make_path("foo") with self.open(file_path, "w") as f0: f0.write("test") self.assertEqual(4, f0.tell()) self.assertEqual(4, self.os.path.getsize(file_path)) def test_tell_flushes_in_python3(self): # Regression test for #288 self.check_linux_and_windows() file_path = self.make_path("foo") with self.open(file_path, "w") as f0: f0.write("test") self.assertEqual(4, f0.tell()) self.assertEqual(4, self.os.path.getsize(file_path)) def test_read_flushes_under_posix(self): # Regression test for #278 self.check_posix_only() file_path = self.make_path("foo") with self.open(file_path, "a+") as f0: f0.write("test") self.assertEqual("", f0.read()) self.assertEqual(4, self.os.path.getsize(file_path)) def test_read_flushes_under_windows_in_python3(self): # Regression test for #278 self.check_windows_only() file_path = self.make_path("foo") with self.open(file_path, "w+") as f0: f0.write("test") f0.read() self.assertEqual(4, self.os.path.getsize(file_path)) def test_seek_flushes(self): # Regression test for #290 file_path = self.make_path("foo") with self.open(file_path, "w") as f0: f0.write("test") self.assertEqual(0, self.os.path.getsize(file_path)) f0.seek(3) self.assertEqual(4, self.os.path.getsize(file_path)) def test_truncate_flushes(self): # Regression test for #291 file_path = self.make_path("foo") with self.open(file_path, "a") as f0: f0.write("test") self.assertEqual(0, self.os.path.getsize(file_path)) f0.truncate() self.assertEqual(4, self.os.path.getsize(file_path)) def check_seek_outside_and_truncate_sets_size(self, mode): # Regression test for #294 and #296 file_path = self.make_path("baz") with self.open(file_path, mode) as f0: f0.seek(1) f0.truncate() self.assertEqual(1, f0.tell()) self.assertEqual(1, self.os.path.getsize(file_path)) f0.seek(1) self.assertEqual(1, self.os.path.getsize(file_path)) self.assertEqual(1, self.os.path.getsize(file_path)) def test_seek_outside_and_truncate_sets_size_in_write_mode(self): # Regression test for #294 self.check_seek_outside_and_truncate_sets_size("w") def test_seek_outside_and_truncate_sets_size_in_append_mode(self): # Regression test for #295 self.check_seek_outside_and_truncate_sets_size("a") def test_closed(self): file_path = self.make_path("foo") f = self.open(file_path, "w") self.assertFalse(f.closed) f.close() self.assertTrue(f.closed) f = self.open(file_path) self.assertFalse(f.closed) f.close() self.assertTrue(f.closed) def test_closing_closed_file_does_nothing(self): # Regression test for #299 file_path = self.make_path("baz") f0 = self.open(file_path, "w") f0.close() with self.open(file_path) as f1: # would close f1 if not handled f0.close() self.assertEqual("", f1.read()) def test_closing_file_with_different_close_mode(self): self.skip_real_fs() filename = self.make_path("test.txt") fd = self.os.open(filename, os.O_CREAT | os.O_RDWR) file_obj = self.filesystem.get_object(filename) with self.open(fd, "wb", closefd=False) as fp: fp.write(b"test") self.assertTrue(self.filesystem.has_open_file(file_obj)) self.os.close(fd) self.assertFalse(self.filesystem.has_open_file(file_obj)) def test_truncate_flushes_zeros(self): # Regression test for #301 file_path = self.make_path("baz") with self.open(file_path, "w") as f0: with self.open(file_path) as f1: f0.seek(1) f0.truncate() self.assertEqual("\0", f1.read()) def test_byte_filename(self): file_path = self.make_path(b"test") with self.open(file_path, "wb") as f: f.write(b"test") with self.open(file_path, "rb") as f: self.assertEqual(b"test", f.read()) def test_unicode_filename(self): file_path = self.make_path("тест") with self.open(file_path, "wb") as f: f.write(b"test") with self.open(file_path, "rb") as f: self.assertEqual(b"test", f.read()) def test_write_devnull(self): for mode in ("r+", "w", "w+", "a", "a+"): with self.open(self.os.devnull, mode) as f: f.write("test") with self.open(self.os.devnull) as f: self.assertEqual("", f.read()) def test_utf16_text(self): # regression test for #574 file_path = self.make_path("foo") with self.open(file_path, "w", encoding="utf-16") as f: assert f.write("1") == 1 with self.open(file_path, "a", encoding="utf-16") as f: assert f.write("2") == 1 with self.open(file_path, "r", encoding="utf-16") as f: text = f.read() assert text == "12" class RealFileOpenTest(FakeFileOpenTest): def use_real_fs(self): return True class FakeFileOpenWithOpenerTest(FakeFileOpenTestBase): def opener(self, path, flags): return self.os.open(path, flags) def test_use_opener_with_read(self): file_path = self.make_path("foo") self.create_file(file_path, contents="test") with self.open(file_path, opener=self.opener) as f: assert f.read() == "test" with self.assertRaises(OSError): f.write("foo") def test_use_opener_with_read_plus(self): file_path = self.make_path("foo") self.create_file(file_path, contents="test") with self.open(file_path, "r+", opener=self.opener) as f: assert f.read() == "test" assert f.write("bar") == 3 with self.open(file_path) as f: assert f.read() == "testbar" def test_use_opener_with_write(self): file_path = self.make_path("foo") self.create_file(file_path, contents="foo") with self.open(file_path, "w", opener=self.opener) as f: with self.assertRaises(OSError): f.read() assert f.write("bar") == 3 with self.open(file_path) as f: assert f.read() == "bar" def test_use_opener_with_write_plus(self): file_path = self.make_path("foo") self.create_file(file_path, contents="test") with self.open(file_path, "w+", opener=self.opener) as f: assert f.read() == "" assert f.write("bar") == 3 with self.open(file_path) as f: assert f.read() == "bar" def test_use_opener_with_append(self): file_path = self.make_path("foo") self.create_file(file_path, contents="foo") with self.open(file_path, "a", opener=self.opener) as f: assert f.write("bar") == 3 with self.assertRaises(OSError): f.read() with self.open(file_path) as f: assert f.read() == "foobar" def test_use_opener_with_append_plus(self): file_path = self.make_path("foo") self.create_file(file_path, contents="foo") with self.open(file_path, "a+", opener=self.opener) as f: assert f.read() == "" assert f.write("bar") == 3 with self.open(file_path) as f: assert f.read() == "foobar" def test_use_opener_with_exclusive_write(self): file_path = self.make_path("foo") self.create_file(file_path, contents="test") with self.assertRaises(OSError): self.open(file_path, "x", opener=self.opener) file_path = self.make_path("bar") with self.open(file_path, "x", opener=self.opener) as f: assert f.write("bar") == 3 with self.assertRaises(OSError): f.read() with self.open(file_path) as f: assert f.read() == "bar" def test_use_opener_with_exclusive_plus(self): file_path = self.make_path("foo") self.create_file(file_path, contents="test") with self.assertRaises(OSError): self.open(file_path, "x+", opener=self.opener) file_path = self.make_path("bar") with self.open(file_path, "x+", opener=self.opener) as f: assert f.write("bar") == 3 assert f.read() == "" with self.open(file_path) as f: assert f.read() == "bar" class RealFileOpenWithOpenerTest(FakeFileOpenWithOpenerTest): def use_real_fs(self): return True @unittest.skipIf(sys.version_info < (3, 8), "open_code only present since Python 3.8") class FakeFilePatchedOpenCodeTest(FakeFileOpenTestBase): def setUp(self): super(FakeFilePatchedOpenCodeTest, self).setUp() if self.use_real_fs(): self.open_code = io.open_code else: self.filesystem.patch_open_code = PatchMode.ON self.open_code = self.fake_io_module.open_code def tearDown(self): if not self.use_real_fs(): self.filesystem.patch_open_code = False super(FakeFilePatchedOpenCodeTest, self).tearDown() @unittest.skipIf(IS_PYPY, "Different behavior in PyPy") def test_invalid_path(self): with self.assertRaises(TypeError): self.open_code(4) @unittest.skipIf(not IS_PYPY, "Different behavior in PyPy") def test_open_code_fd_pypy(self): file_path = self.make_path("foo") self.create_file(file_path, contents="test") fd = self.os.open(file_path, os.O_RDONLY) with self.open_code(fd) as f: assert f.read() == b"test" def test_byte_contents_open_code(self): byte_fractions = b"\xe2\x85\x93 \xe2\x85\x94 \xe2\x85\x95 \xe2\x85\x96" file_path = self.make_path("foo") self.create_file(file_path, contents=byte_fractions) with self.open_code(file_path) as f: contents = f.read() self.assertEqual(contents, byte_fractions) def test_open_code_in_real_fs(self): self.skip_real_fs() file_path = __file__ with self.assertRaises(OSError): self.open_code(file_path) class RealPatchedFileOpenCodeTest(FakeFilePatchedOpenCodeTest): def use_real_fs(self): return True @unittest.skipIf(sys.version_info < (3, 8), "open_code only present since Python 3.8") class FakeFileUnpatchedOpenCodeTest(FakeFileOpenTestBase): def setUp(self): super(FakeFileUnpatchedOpenCodeTest, self).setUp() if self.use_real_fs(): self.open_code = io.open_code else: self.open_code = self.fake_io_module.open_code @unittest.skipIf(IS_PYPY, "Different behavior in PyPy") def test_invalid_path(self): with self.assertRaises(TypeError): self.open_code(4) def test_open_code_in_real_fs(self): file_path = __file__ with self.open_code(file_path) as f: contents = f.read() self.assertTrue(len(contents) > 100) class RealUnpatchedFileOpenCodeTest(FakeFileUnpatchedOpenCodeTest): def use_real_fs(self): return True def test_byte_contents_open_code(self): byte_fractions = b"\xe2\x85\x93 \xe2\x85\x94 \xe2\x85\x95 \xe2\x85\x96" file_path = self.make_path("foo") self.create_file(file_path, contents=byte_fractions) with self.open_code(file_path) as f: contents = f.read() self.assertEqual(contents, byte_fractions) class BufferingModeTest(FakeFileOpenTestBase): def test_no_buffering(self): file_path = self.make_path("buffertest.bin") with self.open(file_path, "wb", buffering=0) as f: f.write(b"a" * 128) with self.open(file_path, "rb") as r: x = r.read() self.assertEqual(b"a" * 128, x) def test_no_buffering_not_allowed_in_textmode(self): file_path = self.make_path("buffertest.txt") with self.assertRaises(ValueError): self.open(file_path, "w", buffering=0) def test_default_buffering_no_flush(self): file_path = self.make_path("buffertest.bin") with self.open(file_path, "wb") as f: f.write(b"a" * 2048) with self.open(file_path, "rb") as r: x = r.read() self.assertEqual(b"", x) with self.open(file_path, "rb") as r: x = r.read() self.assertEqual(b"a" * 2048, x) def test_default_buffering_flush(self): file_path = self.make_path("buffertest.bin") with self.open(file_path, "wb") as f: f.write(b"a" * 2048) f.flush() with self.open(file_path, "rb") as r: x = r.read() self.assertEqual(b"a" * 2048, x) def test_writing_with_specific_buffer(self): file_path = self.make_path("buffertest.bin") with self.open(file_path, "wb", buffering=512) as f: f.write(b"a" * 500) with self.open(file_path, "rb") as r: x = r.read() # buffer not filled - not written self.assertEqual(0, len(x)) f.write(b"a" * 400) with self.open(file_path, "rb") as r: x = r.read() # buffer exceeded, but new buffer (400) not - previous written self.assertEqual(500, len(x)) f.write(b"a" * 100) with self.open(file_path, "rb") as r: x = r.read() # buffer not full (500) not written self.assertEqual(500, len(x)) f.write(b"a" * 100) with self.open(file_path, "rb") as r: x = r.read() # buffer exceeded (600) -> write previous # new buffer not full (100) - not written self.assertEqual(1000, len(x)) f.write(b"a" * 600) with self.open(file_path, "rb") as r: x = r.read() # new buffer exceeded (600) -> all written self.assertEqual(1700, len(x)) def test_writing_text_with_line_buffer(self): file_path = self.make_path("buffertest.bin") with self.open(file_path, "w", buffering=1) as f: f.write("test" * 100) with self.open(file_path, "r") as r: x = r.read() # no new line - not written self.assertEqual(0, len(x)) f.write("\ntest") with self.open(file_path, "r") as r: x = r.read() # new line - buffer written self.assertEqual(405, len(x)) f.write("test" * 10) with self.open(file_path, "r") as r: x = r.read() # buffer not filled - not written self.assertEqual(405, len(x)) f.write("\ntest") with self.open(file_path, "r") as r: x = r.read() # new line - buffer written self.assertEqual(450, len(x)) def test_writing_large_text_with_line_buffer(self): file_path = self.make_path("buffertest.bin") with self.open(file_path, "w", buffering=1) as f: f.write("test" * 4000) with self.open(file_path, "r") as r: x = r.read() # buffer larger than default - written self.assertEqual(16000, len(x)) f.write("test") with self.open(file_path, "r") as r: x = r.read() # buffer not filled - not written self.assertEqual(16000, len(x)) f.write("\ntest") with self.open(file_path, "r") as r: x = r.read() # new line - buffer written self.assertEqual(16009, len(x)) f.write("\ntest") with self.open(file_path, "r") as r: x = r.read() # another new line - buffer written self.assertEqual(16014, len(x)) def test_writing_text_with_default_buffer(self): file_path = self.make_path("buffertest.txt") with self.open(file_path, "w") as f: f.write("test" * 5) with self.open(file_path, "r") as r: x = r.read() # buffer not filled - not written self.assertEqual(0, len(x)) f.write("\ntest") with self.open(file_path, "r") as r: x = r.read() # buffer exceeded, but new buffer (400) not - previous written self.assertEqual(0, len(x)) f.write("test" * 10) with self.open(file_path, "r") as r: x = r.read() # buffer not filled - not written self.assertEqual(0, len(x)) f.write("\ntest") with self.open(file_path, "r") as r: x = r.read() self.assertEqual(0, len(x)) def test_writing_text_with_specific_buffer(self): file_path = self.make_path("buffertest.txt") with self.open(file_path, "w", buffering=2) as f: f.write("a" * 8000) with self.open(file_path, "r") as r: x = r.read() # buffer not filled - not written self.assertEqual(0, len(x)) f.write("test") with self.open(file_path, "r") as r: x = r.read() # buffer exceeded, but new buffer (400) not - previous written self.assertEqual(0, len(x)) f.write("test") with self.open(file_path, "r") as r: x = r.read() # buffer not filled - not written self.assertEqual(0, len(x)) f.write("test") with self.open(file_path, "r") as r: x = r.read() self.assertEqual(0, len(x)) # with self.open(file_path, "r") as r: # x = r.read() # self.assertEqual(35, len(x)) def test_append_with_specific_buffer(self): file_path = self.make_path("buffertest.bin") with self.open(file_path, "wb", buffering=512) as f: f.write(b"a" * 500) with self.open(file_path, "ab", buffering=512) as f: f.write(b"a" * 500) with self.open(file_path, "rb") as r: x = r.read() # buffer not filled - not written self.assertEqual(500, len(x)) f.write(b"a" * 400) with self.open(file_path, "rb") as r: x = r.read() # buffer exceeded, but new buffer (400) not - previous written self.assertEqual(1000, len(x)) f.write(b"a" * 100) with self.open(file_path, "rb") as r: x = r.read() # buffer not full (500) not written self.assertEqual(1000, len(x)) f.write(b"a" * 100) with self.open(file_path, "rb") as r: x = r.read() # buffer exceeded (600) -> write previous # new buffer not full (100) - not written self.assertEqual(1500, len(x)) f.write(b"a" * 600) with self.open(file_path, "rb") as r: x = r.read() # new buffer exceeded (600) -> all written self.assertEqual(2200, len(x)) def test_failed_flush_does_not_truncate_file(self): # regression test for #548 self.skip_real_fs() # cannot set fs size in real fs self.filesystem.set_disk_usage(100) self.os.makedirs("foo") file_path = self.os.path.join("foo", "bar.txt") with self.open(file_path, "wb") as f: f.write(b"a" * 50) f.flush() with self.open(file_path, "rb") as r: x = r.read() self.assertTrue(x.startswith(b"a" * 50)) with self.assertRaises(OSError): f.write(b"b" * 200) f.flush() with self.open(file_path, "rb") as r: x = r.read() self.assertTrue(x.startswith(b"a" * 50)) f.truncate(50) def test_failed_write_does_not_truncate_file(self): # test the same with no buffering and no flush self.skip_real_fs() # cannot set fs size in real fs self.filesystem.set_disk_usage(100) self.os.makedirs("foo") file_path = self.os.path.join("foo", "bar.txt") with self.open(file_path, "wb", buffering=0) as f: f.write(b"a" * 50) with self.open(file_path, "rb") as r: x = r.read() self.assertEqual(b"a" * 50, x) with self.assertRaises(OSError): f.write(b"b" * 200) with self.open(file_path, "rb") as r: x = r.read() self.assertEqual(b"a" * 50, x) class RealBufferingTest(BufferingModeTest): def use_real_fs(self): return True class OpenFileWithEncodingTest(FakeFileOpenTestBase): """Tests that are similar to some open file tests above but using an explicit text encoding.""" def setUp(self): super(OpenFileWithEncodingTest, self).setUp() self.file_path = self.make_path("foo") def test_write_str_read_bytes(self): str_contents = "علي بابا" with self.open(self.file_path, "w", encoding="arabic") as f: f.write(str_contents) with self.open(self.file_path, "rb") as f: contents = f.read() self.assertEqual(str_contents, contents.decode("arabic")) def test_write_str_error_modes(self): str_contents = "علي بابا" with self.open(self.file_path, "w", encoding="cyrillic") as f: with self.assertRaises(UnicodeEncodeError): f.write(str_contents) with self.open( self.file_path, "w", encoding="ascii", errors="xmlcharrefreplace" ) as f: f.write(str_contents) with self.open(self.file_path, "r", encoding="ascii") as f: contents = f.read() self.assertEqual("علي بابا", contents) with self.open( self.file_path, "w", encoding="ascii", errors="namereplace" ) as f: f.write(str_contents) with self.open(self.file_path, "r", encoding="ascii") as f: contents = f.read() self.assertEqual( r"\N{ARABIC LETTER AIN}\N{ARABIC LETTER LAM}\N" r"{ARABIC LETTER YEH} \N{ARABIC LETTER BEH}\N" r"{ARABIC LETTER ALEF}\N{ARABIC LETTER BEH}" r"\N{ARABIC LETTER ALEF}", contents, ) def test_read_str_error_modes(self): str_contents = "علي بابا" with self.open(self.file_path, "w", encoding="arabic") as f: f.write(str_contents) # default strict encoding with self.open(self.file_path, encoding="ascii") as f: with self.assertRaises(UnicodeDecodeError): f.read() with self.open(self.file_path, encoding="ascii", errors="replace") as f: contents = f.read() self.assertNotEqual(str_contents, contents) with self.open( self.file_path, encoding="ascii", errors="backslashreplace" ) as f: contents = f.read() self.assertEqual(r"\xd9\xe4\xea \xc8\xc7\xc8\xc7", contents) def test_write_and_read_str(self): str_contents = "علي بابا" with self.open(self.file_path, "w", encoding="arabic") as f: f.write(str_contents) with self.open(self.file_path, "r", encoding="arabic") as f: contents = f.read() self.assertEqual(str_contents, contents) def test_create_file_with_append(self): contents = [ "Allons enfants de la Patrie," "Le jour de gloire est arrivé!", "Contre nous de la tyrannie,", "L’étendard sanglant est levé.", ] with self.open(self.file_path, "a", encoding="utf-8") as fake_file: for line in contents: fake_file.write(line + "\n") with self.open(self.file_path, encoding="utf-8") as fake_file: result = [line.rstrip() for line in fake_file] self.assertEqual(contents, result) def test_append_existing_file(self): contents = [ "Оригинальное содержание" "Дополнительное содержание", ] self.create_file(self.file_path, contents=contents[0], encoding="cyrillic") with self.open(self.file_path, "a", encoding="cyrillic") as fake_file: for line in contents[1:]: fake_file.write(line + "\n") with self.open(self.file_path, encoding="cyrillic") as fake_file: result = [line.rstrip() for line in fake_file] self.assertEqual(contents, result) def test_open_with_wplus(self): self.create_file( self.file_path, contents="старое содержание", encoding="cyrillic" ) with self.open(self.file_path, "r", encoding="cyrillic") as fake_file: self.assertEqual("старое содержание", fake_file.read()) with self.open(self.file_path, "w+", encoding="cyrillic") as fake_file: fake_file.write("новое содержание") fake_file.seek(0) self.assertTrue("новое содержание", fake_file.read()) def test_open_with_append_flag(self): contents = ["Калинка,\n", "калинка,\n", "калинка моя,\n"] additional_contents = ["В саду ягода-малинка,\n", "малинка моя.\n"] self.create_file( self.file_path, contents="".join(contents), encoding="cyrillic" ) with self.open(self.file_path, "a", encoding="cyrillic") as fake_file: with self.assertRaises(io.UnsupportedOperation): fake_file.read(0) with self.assertRaises(io.UnsupportedOperation): fake_file.readline() self.assertEqual(len("".join(contents)), fake_file.tell()) fake_file.seek(0) self.assertEqual(0, fake_file.tell()) fake_file.writelines(additional_contents) with self.open(self.file_path, encoding="cyrillic") as fake_file: self.assertEqual(contents + additional_contents, fake_file.readlines()) def test_append_with_aplus(self): self.create_file( self.file_path, contents="старое содержание", encoding="cyrillic" ) fake_file = self.open(self.file_path, "r", encoding="cyrillic") fake_file.close() with self.open(self.file_path, "a+", encoding="cyrillic") as fake_file: self.assertEqual(17, fake_file.tell()) fake_file.write("новое содержание") self.assertEqual(33, fake_file.tell()) fake_file.seek(0) self.assertEqual("старое содержаниеновое содержание", fake_file.read()) def test_read_with_rplus(self): self.create_file( self.file_path, contents="старое содержание здесь", encoding="cyrillic", ) fake_file = self.open(self.file_path, "r", encoding="cyrillic") fake_file.close() with self.open(self.file_path, "r+", encoding="cyrillic") as fake_file: self.assertEqual("старое содержание здесь", fake_file.read()) fake_file.seek(0) fake_file.write("новое содержание") fake_file.seek(0) self.assertEqual("новое содержание здесь", fake_file.read()) class OpenRealFileWithEncodingTest(OpenFileWithEncodingTest): def use_real_fs(self): return True class FakeFileOpenLineEndingTest(FakeFileOpenTestBase): def setUp(self): super(FakeFileOpenLineEndingTest, self).setUp() def test_read_default_newline_mode(self): file_path = self.make_path("some_file") for contents in (b"1\n2", b"1\r\n2", b"1\r2"): self.create_file(file_path, contents=contents) with self.open(file_path, mode="r") as f: self.assertEqual(["1\n", "2"], f.readlines()) with self.open(file_path, mode="r") as f: self.assertEqual("1\n2", f.read()) with self.open(file_path, mode="rb") as f: self.assertEqual(contents, f.read()) def test_write_universal_newline_mode(self): file_path = self.make_path("some_file") with self.open(file_path, "w") as f: f.write("1\n2") with self.open(file_path, mode="rb") as f: self.assertEqual(b"1" + self.os.linesep.encode() + b"2", f.read()) with self.open(file_path, "w") as f: f.write("1\r\n2") with self.open(file_path, mode="rb") as f: self.assertEqual(b"1\r" + self.os.linesep.encode() + b"2", f.read()) def test_read_with_newline_arg(self): file_path = self.make_path("some_file") file_contents = b"1\r\n2\n3\r4" self.create_file(file_path, contents=file_contents) with self.open(file_path, mode="r", newline="") as f: self.assertEqual("1\r\n2\n3\r4", f.read()) with self.open(file_path, mode="r", newline="\r") as f: self.assertEqual("1\r\n2\n3\r4", f.read()) with self.open(file_path, mode="r", newline="\n") as f: self.assertEqual("1\r\n2\n3\r4", f.read()) with self.open(file_path, mode="r", newline="\r\n") as f: self.assertEqual("1\r\n2\n3\r4", f.read()) def test_readlines_with_newline_arg(self): file_path = self.make_path("some_file") file_contents = b"1\r\n2\n3\r4" self.create_file(file_path, contents=file_contents) with self.open(file_path, mode="r", newline="") as f: self.assertEqual(["1\r\n", "2\n", "3\r", "4"], f.readlines()) with self.open(file_path, mode="r", newline="\r") as f: self.assertEqual(["1\r", "\n2\n3\r", "4"], f.readlines()) with self.open(file_path, mode="r", newline="\n") as f: self.assertEqual(["1\r\n", "2\n", "3\r4"], f.readlines()) with self.open(file_path, mode="r", newline="\r\n") as f: self.assertEqual(["1\r\n", "2\n3\r4"], f.readlines()) @unittest.skipIf(sys.version_info >= (3, 10), "U flag no longer supported") def test_read_with_ignored_universal_newlines_flag(self): file_path = self.make_path("some_file") file_contents = b"1\r\n2\n3\r4" self.create_file(file_path, contents=file_contents) with self.open(file_path, mode="r", newline="\r") as f: self.assertEqual("1\r\n2\n3\r4", f.read()) with self.open(file_path, mode="r", newline="\r") as f: self.assertEqual("1\r\n2\n3\r4", f.read()) with self.open(file_path, mode="U", newline="\r") as f: self.assertEqual("1\r\n2\n3\r4", f.read()) @unittest.skipIf(sys.version_info < (3, 11), "U flag still supported") def test_universal_newlines_flag_not_supported(self): file_path = self.make_path("some_file") file_contents = b"1\r\n2\n3\r4" self.create_file(file_path, contents=file_contents) with self.assertRaises(ValueError): self.open(file_path, mode="U", newline="\r") def test_write_with_newline_arg(self): file_path = self.make_path("some_file") with self.open(file_path, "w", newline="") as f: f.write("1\r\n2\n3\r4") with self.open(file_path, mode="rb") as f: self.assertEqual(b"1\r\n2\n3\r4", f.read()) with self.open(file_path, "w", newline="\n") as f: f.write("1\r\n2\n3\r4") with self.open(file_path, mode="rb") as f: self.assertEqual(b"1\r\n2\n3\r4", f.read()) with self.open(file_path, "w", newline="\r\n") as f: f.write("1\r\n2\n3\r4") with self.open(file_path, mode="rb") as f: self.assertEqual(b"1\r\r\n2\r\n3\r4", f.read()) with self.open(file_path, "w", newline="\r") as f: f.write("1\r\n2\n3\r4") with self.open(file_path, mode="rb") as f: self.assertEqual(b"1\r\r2\r3\r4", f.read()) def test_binary_readline(self): file_path = self.make_path("some_file") file_contents = b"\x80\n\x80\r\x80\r\n\x80" def chunk_line(): px = 0 while px < len(file_contents): ix = file_contents.find(b"\n", px) if ix == -1: yield file_contents[px:] return yield file_contents[px : ix + 1] px = ix + 1 chunked_contents = list(chunk_line()) self.create_file(file_path, contents=file_contents) with self.open(file_path, mode="rb") as f: self.assertEqual(chunked_contents, list(f)) class RealFileOpenLineEndingTest(FakeFileOpenLineEndingTest): def use_real_fs(self): return True class FakeFileOpenLineEndingWithEncodingTest(FakeFileOpenTestBase): def setUp(self): super(FakeFileOpenLineEndingWithEncodingTest, self).setUp() def test_read_standard_newline_mode(self): file_path = self.make_path("some_file") for contents in ("раз\nдва", "раз\r\nдва", "раз\rдва"): self.create_file(file_path, contents=contents, encoding="cyrillic") with self.open(file_path, mode="r", encoding="cyrillic") as fake_file: self.assertEqual(["раз\n", "два"], fake_file.readlines()) with self.open(file_path, mode="r", encoding="cyrillic") as fake_file: self.assertEqual("раз\nдва", fake_file.read()) def test_write_universal_newline_mode(self): file_path = self.make_path("some_file") with self.open(file_path, "w", encoding="cyrillic") as f: f.write("раз\nдва") with self.open(file_path, mode="rb") as f: self.assertEqual( "раз".encode("cyrillic") + self.os.linesep.encode() + "два".encode("cyrillic"), f.read(), ) with self.open(file_path, "w", encoding="cyrillic") as f: f.write("раз\r\nдва") with self.open(file_path, mode="rb") as f: self.assertEqual( "раз\r".encode("cyrillic") + self.os.linesep.encode() + "два".encode("cyrillic"), f.read(), ) def test_read_with_newline_arg(self): file_path = self.make_path("some_file") file_contents = "раз\r\nдва\nтри\rчетыре" self.create_file(file_path, contents=file_contents, encoding="cyrillic") with self.open(file_path, mode="r", newline="", encoding="cyrillic") as f: self.assertEqual("раз\r\nдва\nтри\rчетыре", f.read()) with self.open(file_path, mode="r", newline="\r", encoding="cyrillic") as f: self.assertEqual("раз\r\nдва\nтри\rчетыре", f.read()) with self.open(file_path, mode="r", newline="\n", encoding="cyrillic") as f: self.assertEqual("раз\r\nдва\nтри\rчетыре", f.read()) with self.open(file_path, mode="r", newline="\r\n", encoding="cyrillic") as f: self.assertEqual("раз\r\nдва\nтри\rчетыре", f.read()) def test_readlines_with_newline_arg(self): file_path = self.make_path("some_file") file_contents = "раз\r\nдва\nтри\rчетыре" self.create_file(file_path, contents=file_contents, encoding="cyrillic") with self.open(file_path, mode="r", newline="", encoding="cyrillic") as f: self.assertEqual(["раз\r\n", "два\n", "три\r", "четыре"], f.readlines()) with self.open(file_path, mode="r", newline="\r", encoding="cyrillic") as f: self.assertEqual(["раз\r", "\nдва\nтри\r", "четыре"], f.readlines()) with self.open(file_path, mode="r", newline="\n", encoding="cyrillic") as f: self.assertEqual(["раз\r\n", "два\n", "три\rчетыре"], f.readlines()) with self.open(file_path, mode="r", newline="\r\n", encoding="cyrillic") as f: self.assertEqual(["раз\r\n", "два\nтри\rчетыре"], f.readlines()) def test_write_with_newline_arg(self): file_path = self.make_path("some_file") with self.open(file_path, "w", newline="", encoding="cyrillic") as f: f.write("раз\r\nдва\nтри\rчетыре") with self.open(file_path, mode="rb") as f: self.assertEqual("раз\r\nдва\nтри\rчетыре".encode("cyrillic"), f.read()) with self.open(file_path, "w", newline="\n", encoding="cyrillic") as f: f.write("раз\r\nдва\nтри\rчетыре") with self.open(file_path, mode="rb") as f: self.assertEqual("раз\r\nдва\nтри\rчетыре".encode("cyrillic"), f.read()) with self.open(file_path, "w", newline="\r\n", encoding="cyrillic") as f: f.write("раз\r\nдва\nтри\rчетыре") with self.open(file_path, mode="rb") as f: self.assertEqual("раз\r\r\nдва\r\nтри\rчетыре".encode("cyrillic"), f.read()) with self.open(file_path, "w", newline="\r", encoding="cyrillic") as f: f.write("раз\r\nдва\nтри\rчетыре") with self.open(file_path, mode="rb") as f: self.assertEqual("раз\r\rдва\rтри\rчетыре".encode("cyrillic"), f.read()) class RealFileOpenLineEndingWithEncodingTest(FakeFileOpenLineEndingWithEncodingTest): def use_real_fs(self): return True class OpenWithFileDescriptorTest(FakeFileOpenTestBase): def test_open_with_file_descriptor(self): file_path = self.make_path("this", "file") self.create_file(file_path) fd = self.os.open(file_path, os.O_CREAT) self.assertEqual(fd, self.open(fd, "r").fileno()) def test_closefd_with_file_descriptor(self): file_path = self.make_path("this", "file") self.create_file(file_path) fd = self.os.open(file_path, os.O_CREAT) fh = self.open(fd, "r", closefd=False) fh.close() self.assertIsNotNone(self.filesystem.open_files[fd]) fh = self.open(fd, "r", closefd=True) fh.close() self.assertIsNone(self.filesystem.open_files[fd]) class OpenWithRealFileDescriptorTest(FakeFileOpenTestBase): def use_real_fs(self): return True class OpenWithFlagsTestBase(FakeFileOpenTestBase): def setUp(self): super(OpenWithFlagsTestBase, self).setUp() self.file_path = self.make_path("some_file") self.file_contents = None def open_file(self, mode): return self.open(self.file_path, mode=mode) def open_file_and_seek(self, mode): fake_file = self.open(self.file_path, mode=mode) fake_file.seek(0, 2) return fake_file def write_and_reopen_file(self, fake_file, mode="r", encoding=None): fake_file.write(self.file_contents) fake_file.close() args = {"mode": mode} if encoding: args["encoding"] = encoding return self.open(self.file_path, **args) class OpenWithBinaryFlagsTest(OpenWithFlagsTestBase): def setUp(self): super(OpenWithBinaryFlagsTest, self).setUp() self.file_contents = b"real binary contents: \x1f\x8b" self.create_file(self.file_path, contents=self.file_contents) def test_read_binary(self): with self.open_file("rb") as fake_file: self.assertEqual(self.file_contents, fake_file.read()) def test_write_binary(self): with self.open_file_and_seek("wb") as f: self.assertEqual(0, f.tell()) with self.write_and_reopen_file(f, mode="rb") as f1: self.assertEqual(self.file_contents, f1.read()) # Attempt to reopen the file in text mode with self.open_file("wb") as f2: with self.write_and_reopen_file( f2, mode="r", encoding="ascii" ) as f3: with self.assertRaises(UnicodeDecodeError): f3.read() def test_write_and_read_binary(self): with self.open_file_and_seek("w+b") as f: self.assertEqual(0, f.tell()) with self.write_and_reopen_file(f, mode="rb") as f1: self.assertEqual(self.file_contents, f1.read()) class RealOpenWithBinaryFlagsTest(OpenWithBinaryFlagsTest): def use_real_fs(self): return True class OpenWithTextModeFlagsTest(OpenWithFlagsTestBase): def setUp(self): super(OpenWithTextModeFlagsTest, self).setUp() self.setUpFileSystem() def setUpFileSystem(self): self.file_path = self.make_path("some_file") self.file_contents = b"two\r\nlines" self.original_contents = "two\r\nlines" self.converted_contents = "two\nlines" self.create_file(self.file_path, contents=self.file_contents) def test_read_text(self): """Test that text mode flag is ignored""" self.check_windows_only() with self.open_file("r") as f: self.assertEqual(self.converted_contents, f.read()) with self.open_file("rt") as f: self.assertEqual(self.converted_contents, f.read()) def test_mixed_text_and_binary_flags(self): with self.assertRaises(ValueError): self.open_file_and_seek("w+bt") class RealOpenWithTextModeFlagsTest(OpenWithTextModeFlagsTest): def use_real_fs(self): return True class OpenWithInvalidFlagsTest(FakeFileOpenTestBase): def test_capital_r(self): with self.assertRaises(ValueError): self.open("some_file", "R") def test_capital_w(self): with self.assertRaises(ValueError): self.open("some_file", "W") def test_capital_a(self): with self.assertRaises(ValueError): self.open("some_file", "A") def test_lower_u(self): with self.assertRaises(ValueError): self.open("some_file", "u") def test_lower_rw(self): with self.assertRaises(ValueError): self.open("some_file", "rw") class OpenWithInvalidFlagsRealFsTest(OpenWithInvalidFlagsTest): def use_real_fs(self): return True class ResolvePathTest(FakeFileOpenTestBase): def write_to_file(self, file_name): with self.open(file_name, "w") as fh: fh.write("x") def test_none_filepath_raises_type_error(self): with self.assertRaises(TypeError): self.open(None, "w") def test_empty_filepath_raises_io_error(self): with self.assertRaises(OSError): self.open("", "w") def test_normal_path(self): file_path = self.make_path("foo") self.write_to_file(file_path) self.assertTrue(self.os.path.exists(file_path)) def test_link_within_same_directory(self): self.skip_if_symlink_not_supported() final_target = self.make_path("foo", "baz") link_path = self.make_path("foo", "bar") self.create_symlink(link_path, "baz") self.write_to_file(link_path) self.assertTrue(self.os.path.exists(final_target)) self.assertEqual(1, self.os.stat(final_target)[stat.ST_SIZE]) def test_link_to_sub_directory(self): self.skip_if_symlink_not_supported() final_target = self.make_path("foo", "baz", "bip") dir_path = self.make_path("foo", "baz") self.create_dir(dir_path) link_path = self.make_path("foo", "bar") target_path = self.os.path.join("baz", "bip") self.create_symlink(link_path, target_path) self.write_to_file(link_path) self.assertTrue(self.os.path.exists(final_target)) self.assertEqual(1, self.os.stat(final_target)[stat.ST_SIZE]) self.assertTrue(self.os.path.exists(dir_path)) # Make sure that intermediate directory got created. self.assertTrue(self.os.stat(dir_path)[stat.ST_MODE] & stat.S_IFDIR) def test_link_to_parent_directory(self): self.skip_if_symlink_not_supported() final_target = self.make_path("baz", "bip") self.create_dir(self.make_path("foo")) self.create_dir(self.make_path("baz")) link_path = self.make_path("foo", "bar") self.create_symlink(link_path, self.os.path.join("..", "baz")) self.write_to_file(self.make_path("foo", "bar", "bip")) self.assertTrue(self.os.path.exists(final_target)) self.assertEqual(1, self.os.stat(final_target)[stat.ST_SIZE]) self.assertTrue(self.os.path.exists(link_path)) def test_link_to_absolute_path(self): self.skip_if_symlink_not_supported() final_target = self.make_path("foo", "baz", "bip") self.create_dir(self.make_path("foo", "baz")) link_path = self.make_path("foo", "bar") self.create_symlink(link_path, final_target) self.write_to_file(link_path) self.assertTrue(self.os.path.exists(final_target)) def test_relative_links_work_after_chdir(self): self.skip_if_symlink_not_supported() final_target = self.make_path("foo", "baz", "bip") self.create_dir(self.make_path("foo", "baz")) link_path = self.make_path("foo", "bar") self.create_symlink(link_path, self.os.path.join(".", "baz", "bip")) if not self.is_windows: self.assert_equal_paths(final_target, self.os.path.realpath(link_path)) self.assertTrue(self.os.path.islink(link_path)) self.os.chdir(self.make_path("foo")) self.assert_equal_paths(self.make_path("foo"), self.os.getcwd()) self.assertTrue(self.os.path.islink("bar")) if not self.is_windows: self.assert_equal_paths(final_target, self.os.path.realpath("bar")) self.write_to_file(link_path) self.assertTrue(self.os.path.exists(final_target)) def test_absolute_links_work_after_chdir(self): self.skip_if_symlink_not_supported() final_target = self.make_path("foo", "baz", "bip") self.create_dir(self.make_path("foo", "baz")) link_path = self.make_path("foo", "bar") self.create_symlink(link_path, final_target) if not self.is_windows: self.assert_equal_paths(final_target, self.os.path.realpath(link_path)) self.assertTrue(self.os.path.islink(link_path)) self.os.chdir(self.make_path("foo")) self.assert_equal_paths(self.make_path("foo"), self.os.getcwd()) self.assertTrue(self.os.path.islink("bar")) if not self.is_windows: self.assert_equal_paths(final_target, self.os.path.realpath("bar")) self.write_to_file(link_path) self.assertTrue(self.os.path.exists(final_target)) def test_chdir_through_relative_link(self): self.check_posix_only() dir1_path = self.make_path("x", "foo") dir2_path = self.make_path("x", "bar") self.create_dir(dir1_path) self.create_dir(dir2_path) link_path = self.make_path("x", "foo", "bar") self.create_symlink(link_path, self.os.path.join("..", "bar")) self.assert_equal_paths(dir2_path, self.os.path.realpath(link_path)) self.os.chdir(dir1_path) self.assert_equal_paths(dir1_path, self.os.getcwd()) self.assert_equal_paths(dir2_path, self.os.path.realpath("bar")) self.os.chdir("bar") self.assert_equal_paths(dir2_path, self.os.getcwd()) def test_chdir_uses_open_fd_as_path(self): self.check_posix_only() if self.is_pypy: # unclear behavior with PyPi self.skip_real_fs() self.assert_raises_os_error([errno.ENOTDIR, errno.EBADF], self.os.chdir, 500) dir_path = self.make_path("foo", "bar") self.create_dir(dir_path) path_des = self.os.open(dir_path, os.O_RDONLY) self.os.chdir(path_des) self.os.close(path_des) self.assert_equal_paths(dir_path, self.os.getcwd()) def test_read_link_to_link(self): # Write into the final link target and read back from a file which will # point to that. self.skip_if_symlink_not_supported() link_path = self.make_path("foo", "bar") self.create_symlink(link_path, "link") self.create_symlink(self.make_path("foo", "link"), "baz") self.write_to_file(self.make_path("foo", "baz")) fh = self.open(link_path, "r") self.assertEqual("x", fh.read()) def test_write_link_to_link(self): self.skip_if_symlink_not_supported() final_target = self.make_path("foo", "baz") link_path = self.make_path("foo", "bar") self.create_symlink(link_path, "link") self.create_symlink(self.make_path("foo", "link"), "baz") self.write_to_file(link_path) self.assertTrue(self.os.path.exists(final_target)) def test_multiple_links(self): self.skip_if_symlink_not_supported() self.os.makedirs(self.make_path("a", "link1", "c", "link2")) self.create_symlink(self.make_path("a", "b"), "link1") if not self.is_windows: self.assert_equal_paths( self.make_path("a", "link1"), self.os.path.realpath(self.make_path("a", "b")), ) self.assert_equal_paths( self.make_path("a", "link1", "c"), self.os.path.realpath(self.make_path("a", "b", "c")), ) link_path = self.make_path("a", "link1", "c", "d") self.create_symlink(link_path, "link2") self.assertTrue(self.os.path.exists(link_path)) self.assertTrue(self.os.path.exists(self.make_path("a", "b", "c", "d"))) final_target = self.make_path("a", "link1", "c", "link2", "e") self.assertFalse(self.os.path.exists(final_target)) self.write_to_file(self.make_path("a", "b", "c", "d", "e")) self.assertTrue(self.os.path.exists(final_target)) def test_utime_link(self): """os.utime() and os.stat() via symbolic link (issue #49)""" self.skip_if_symlink_not_supported() self.create_dir(self.make_path("foo", "baz")) target_path = self.make_path("foo", "baz", "bip") self.write_to_file(target_path) link_name = self.make_path("foo", "bar") self.create_symlink(link_name, target_path) self.os.utime(link_name, (1, 2)) st = self.os.stat(link_name) self.assertEqual(1, st.st_atime) self.assertEqual(2, st.st_mtime) self.os.utime(link_name, (3, 4)) st = self.os.stat(link_name) self.assertEqual(3, st.st_atime) self.assertEqual(4, st.st_mtime) def test_too_many_links(self): self.check_posix_only() link_path = self.make_path("a", "loop") self.create_symlink(link_path, "loop") self.assertFalse(self.os.path.exists(link_path)) def test_that_drive_letters_are_preserved(self): self.check_windows_only() self.skip_real_fs() self.assertEqual("C:!foo!bar", self.filesystem.resolve_path("C:!foo!!bar")) def test_that_unc_paths_are_preserved(self): self.check_windows_only() self.skip_real_fs() self.assertEqual( "!!foo!bar!baz", self.filesystem.resolve_path("!!foo!bar!baz!!") ) class RealResolvePathTest(ResolvePathTest): def use_real_fs(self): return True if __name__ == "__main__": unittest.main() tests/fake_os_test.py000064400000703062150043321530010732 0ustar00# # Copyright 2009 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Unit tests for fake_os.FakeOsModule.""" import errno import os import stat import sys import unittest from pyfakefs.helpers import IN_DOCKER, IS_PYPY, get_uid, get_gid from pyfakefs import fake_filesystem, fake_os, fake_open, fake_file from pyfakefs.fake_filesystem import ( FakeFileOpen, is_root, set_uid, set_gid, ) from pyfakefs.extra_packages import ( use_scandir, use_scandir_package, use_builtin_scandir, ) from pyfakefs.tests.test_utils import TestCase, RealFsTestCase class FakeOsModuleTestBase(RealFsTestCase): def createTestFile(self, path): self.create_file(path) self.assertTrue(self.os.path.exists(path)) st = self.os.stat(path) self.assertEqual(0o666, stat.S_IMODE(st.st_mode)) self.assertTrue(st.st_mode & stat.S_IFREG) self.assertFalse(st.st_mode & stat.S_IFDIR) def createTestDirectory(self, path): self.create_dir(path) self.assertTrue(self.os.path.exists(path)) st = self.os.stat(path) self.assertEqual(0o777, stat.S_IMODE(st.st_mode)) self.assertFalse(st.st_mode & stat.S_IFREG) self.assertTrue(st.st_mode & stat.S_IFDIR) class FakeOsModuleTest(FakeOsModuleTestBase): def setUp(self): super(FakeOsModuleTest, self).setUp() self.rwx = self.os.R_OK | self.os.W_OK | self.os.X_OK self.rw = self.os.R_OK | self.os.W_OK def test_chdir(self): """chdir should work on a directory.""" directory = self.make_path("foo") self.create_dir(directory) self.os.chdir(directory) def test_chdir_fails_non_exist(self): """chdir should raise OSError if the target does not exist.""" directory = self.make_path("no", "such", "directory") self.assert_raises_os_error(errno.ENOENT, self.os.chdir, directory) def test_chdir_fails_non_directory(self): """chdir should raise OSError if the target is not a directory.""" filename = self.make_path("foo", "bar") self.create_file(filename) self.assert_raises_os_error(errno.ENOTDIR, self.os.chdir, filename) def test_consecutive_chdir(self): """Consecutive relative chdir calls should work.""" dir1 = self.make_path("foo") dir2 = "bar" full_dirname = self.os.path.join(dir1, dir2) self.create_dir(full_dirname) self.os.chdir(dir1) self.os.chdir(dir2) # use real path to handle symlink /var to /private/var in MacOs self.assertEqual( os.path.realpath(self.os.getcwd()), os.path.realpath(full_dirname) ) def test_backwards_chdir(self): """chdir into '..' should behave appropriately.""" # skipping real fs test - can't test root dir self.skip_real_fs() rootdir = self.os.getcwd() dirname = "foo" abs_dirname = self.os.path.abspath(dirname) self.filesystem.create_dir(dirname) self.os.chdir(dirname) self.assertEqual(abs_dirname, self.os.getcwd()) self.os.chdir("..") self.assertEqual(rootdir, self.os.getcwd()) self.os.chdir(self.os.path.join(dirname, "..")) self.assertEqual(rootdir, self.os.getcwd()) def test_get_cwd(self): # skipping real fs test - can't test root dir self.skip_real_fs() dirname = self.make_path("foo", "bar") self.create_dir(dirname) self.assertEqual(self.filesystem.root_dir_name, self.os.getcwd()) self.os.chdir(dirname) self.assertEqual(dirname, self.os.getcwd()) def test_listdir(self): self.assert_raises_os_error( errno.ENOENT, self.os.listdir, "non_existing/fake_dir" ) directory = self.make_path("xyzzy", "plugh") files = ["foo", "bar", "baz"] for f in files: self.create_file(self.os.path.join(directory, f)) files.sort() self.assertEqual(files, sorted(self.os.listdir(directory))) def test_listdir_uses_open_fd_as_path(self): self.check_posix_only() if os.listdir not in os.supports_fd: self.skip_real_fs() self.assert_raises_os_error(errno.EBADF, self.os.listdir, 500) dir_path = self.make_path("xyzzy", "plugh") files = ["foo", "bar", "baz"] for f in files: self.create_file(self.os.path.join(dir_path, f)) files.sort() path_des = self.os.open(dir_path, os.O_RDONLY) self.assertEqual(files, sorted(self.os.listdir(path_des))) def test_listdir_returns_list(self): directory_root = self.make_path("xyzzy") self.os.mkdir(directory_root) directory = self.os.path.join(directory_root, "bug") self.os.mkdir(directory) self.create_file(self.make_path(directory, "foo")) self.assertEqual(["foo"], self.os.listdir(directory)) def test_listdir_on_symlink(self): self.skip_if_symlink_not_supported() directory = self.make_path("xyzzy") files = ["foo", "bar", "baz"] for f in files: self.create_file(self.make_path(directory, f)) self.create_symlink(self.make_path("symlink"), self.make_path("xyzzy")) files.sort() self.assertEqual(files, sorted(self.os.listdir(self.make_path("symlink")))) def test_listdir_error(self): file_path = self.make_path("foo", "bar", "baz") self.create_file(file_path) self.assert_raises_os_error(errno.ENOTDIR, self.os.listdir, file_path) def test_exists_current_dir(self): self.assertTrue(self.os.path.exists(".")) def test_listdir_current(self): files = ["foo", "bar", "baz"] for f in files: self.create_file(self.make_path(f)) files.sort() self.assertEqual(files, sorted(self.os.listdir(self.base_path))) def test_fdopen(self): file_path1 = self.make_path("some_file1") self.create_file(file_path1, contents="contents here1") with self.open(file_path1, "r") as fake_file1: fileno = fake_file1.fileno() fake_file2 = self.os.fdopen(fileno) self.assertNotEqual(fake_file2, fake_file1) with self.assertRaises(TypeError): self.os.fdopen(None) with self.assertRaises(TypeError): self.os.fdopen("a string") def test_out_of_range_fdopen(self): # test some file descriptor that is clearly out of range self.assert_raises_os_error(errno.EBADF, self.os.fdopen, 500) def test_closed_file_descriptor(self): first_path = self.make_path("some_file1") second_path = self.make_path("some_file2") third_path = self.make_path("some_file3") self.create_file(first_path, contents="contents here1") self.create_file(second_path, contents="contents here2") self.create_file(third_path, contents="contents here3") fake_file1 = self.open(first_path, "r") fake_file2 = self.open(second_path, "r") fake_file3 = self.open(third_path, "r") fileno1 = fake_file1.fileno() fileno2 = fake_file2.fileno() fileno3 = fake_file3.fileno() self.os.close(fileno2) self.assert_raises_os_error(errno.EBADF, self.os.close, fileno2) self.assertEqual(fileno1, fake_file1.fileno()) self.assertEqual(fileno3, fake_file3.fileno()) with self.os.fdopen(fileno1) as f: self.assertFalse(f is fake_file1) with self.os.fdopen(fileno3) as f: self.assertFalse(f is fake_file3) self.assert_raises_os_error(errno.EBADF, self.os.fdopen, fileno2) def test_fdopen_mode(self): self.skip_real_fs() file_path1 = self.make_path("some_file1") self.create_file(file_path1, contents="contents here1") self.os.chmod(file_path1, (stat.S_IFREG | 0o666) ^ stat.S_IWRITE) fake_file1 = self.open(file_path1, "r") fileno1 = fake_file1.fileno() self.os.fdopen(fileno1) self.os.fdopen(fileno1, "r") if not is_root(): with self.assertRaises(OSError): self.os.fdopen(fileno1, "w") else: self.os.fdopen(fileno1, "w") self.os.close(fileno1) def test_fstat(self): directory = self.make_path("xyzzy") file_path = self.os.path.join(directory, "plugh") self.create_file(file_path, contents="ABCDE") with self.open(file_path) as file_obj: fileno = file_obj.fileno() self.assertTrue(stat.S_IFREG & self.os.fstat(fileno)[stat.ST_MODE]) self.assertTrue(stat.S_IFREG & self.os.fstat(fileno).st_mode) self.assertEqual(5, self.os.fstat(fileno)[stat.ST_SIZE]) def test_stat(self): directory = self.make_path("xyzzy") file_path = self.os.path.join(directory, "plugh") self.create_file(file_path, contents="ABCDE") self.assertTrue(stat.S_IFDIR & self.os.stat(directory)[stat.ST_MODE]) self.assertTrue(stat.S_IFREG & self.os.stat(file_path)[stat.ST_MODE]) self.assertTrue(stat.S_IFREG & self.os.stat(file_path).st_mode) self.assertEqual(5, self.os.stat(file_path)[stat.ST_SIZE]) def test_st_blocks(self): self.check_posix_only() file_path = self.make_path("foo1") self.create_file(file_path, contents=b"") self.assertEqual(0, self.os.stat(file_path).st_blocks) file_path = self.make_path("foo2") self.create_file(file_path, contents=b"t") self.assertEqual(8, self.os.stat(file_path).st_blocks) file_path = self.make_path("foo3") self.create_file(file_path, contents=b"t" * 4095) self.assertEqual(8, self.os.stat(file_path).st_blocks) file_path = self.make_path("foo4") self.create_file(file_path, contents=b"t" * 4096) self.assertEqual(8, self.os.stat(file_path).st_blocks) file_path = self.make_path("foo5") self.create_file(file_path, contents=b"t" * 4097) self.assertEqual(16, self.os.stat(file_path).st_blocks) def test_no_st_blocks_in_windows(self): self.check_windows_only() file_path = self.make_path("foo") self.create_file(file_path, contents=b"") with self.assertRaises(AttributeError): self.os.stat(file_path).st_blocks def test_stat_with_unc_path(self): self.skip_real_fs() self.check_windows_only() directory = "//root/share/dir" file_path = self.os.path.join(directory, "plugh") self.create_file(file_path, contents="ABCDE") self.assertTrue(stat.S_IFDIR & self.os.stat(directory)[stat.ST_MODE]) self.assertTrue(stat.S_IFREG & self.os.stat(file_path)[stat.ST_MODE]) self.assertTrue(stat.S_IFREG & self.os.stat(file_path).st_mode) self.assertEqual(5, self.os.stat(file_path)[stat.ST_SIZE]) def test_stat_with_drive(self): self.skip_real_fs() self.check_windows_only() directory = "C:/foo/dir" file_path = self.os.path.join(directory, "plugh") self.create_file(file_path, contents="ABCDE") self.assertTrue(stat.S_IFDIR & self.os.stat(directory)[stat.ST_MODE]) self.assertTrue(stat.S_IFREG & self.os.stat(file_path)[stat.ST_MODE]) self.assertTrue(stat.S_IFREG & self.os.stat(file_path).st_mode) self.assertEqual(5, self.os.stat(file_path)[stat.ST_SIZE]) def test_stat_uses_open_fd_as_path(self): self.skip_real_fs() self.assert_raises_os_error(errno.EBADF, self.os.stat, 5) file_path = self.make_path("foo", "bar") self.create_file(file_path) with self.open(file_path) as f: self.assertTrue(stat.S_IFREG & self.os.stat(f.filedes)[stat.ST_MODE]) def test_stat_no_follow_symlinks_posix(self): """Test that stat with follow_symlinks=False behaves like lstat.""" self.check_posix_only() directory = self.make_path("xyzzy") base_name = "plugh" file_contents = "frobozz" # Just make sure we didn't accidentally make our test data meaningless. self.assertNotEqual(len(base_name), len(file_contents)) file_path = self.os.path.join(directory, base_name) link_path = self.os.path.join(directory, "link") self.create_file(file_path, contents=file_contents) self.create_symlink(link_path, base_name) self.assertEqual( len(file_contents), self.os.stat(file_path, follow_symlinks=False)[stat.ST_SIZE], ) self.assertEqual( len(base_name), self.os.stat(link_path, follow_symlinks=False)[stat.ST_SIZE], ) def test_stat_no_follow_symlinks_windows(self): """Test that stat with follow_symlinks=False behaves like lstat.""" self.check_windows_only() self.skip_if_symlink_not_supported() directory = self.make_path("xyzzy") base_name = "plugh" file_contents = "frobozz" # Just make sure we didn't accidentally make our test data meaningless. self.assertNotEqual(len(base_name), len(file_contents)) file_path = self.os.path.join(directory, base_name) link_path = self.os.path.join(directory, "link") self.create_file(file_path, contents=file_contents) self.create_symlink(link_path, base_name) self.assertEqual( len(file_contents), self.os.stat(file_path, follow_symlinks=False)[stat.ST_SIZE], ) self.assertEqual( 0, self.os.stat(link_path, follow_symlinks=False)[stat.ST_SIZE] ) def test_lstat_size_posix(self): self.check_posix_only() directory = self.make_path("xyzzy") base_name = "plugh" file_contents = "frobozz" # Just make sure we didn't accidentally make our test data meaningless. self.assertNotEqual(len(base_name), len(file_contents)) file_path = self.os.path.join(directory, base_name) link_path = self.os.path.join(directory, "link") self.create_file(file_path, contents=file_contents) self.create_symlink(link_path, base_name) self.assertEqual(len(file_contents), self.os.lstat(file_path)[stat.ST_SIZE]) self.assertEqual(len(base_name), self.os.lstat(link_path)[stat.ST_SIZE]) def test_lstat_size_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() directory = self.make_path("xyzzy") base_name = "plugh" file_contents = "frobozz" # Just make sure we didn't accidentally make our test data meaningless. self.assertNotEqual(len(base_name), len(file_contents)) file_path = self.os.path.join(directory, base_name) link_path = self.os.path.join(directory, "link") self.create_file(file_path, contents=file_contents) self.create_symlink(link_path, base_name) self.assertEqual(len(file_contents), self.os.lstat(file_path)[stat.ST_SIZE]) self.assertEqual(0, self.os.lstat(link_path)[stat.ST_SIZE]) def test_lstat_trailing_sep(self): # regression test for #342 stat_result = self.os.lstat(self.base_path) self.assertEqual( stat_result, self.os.lstat(self.base_path + self.path_separator()) ) self.assertEqual( stat_result, self.os.lstat( self.base_path + self.path_separator() + self.path_separator() ), ) def test_stat_with_byte_string(self): stat_str = self.os.stat(self.base_path) base_path_bytes = self.base_path.encode("utf8") stat_bytes = self.os.stat(base_path_bytes) self.assertEqual(stat_bytes, stat_str) def test_lstat_with_byte_string(self): stat_str = self.os.lstat(self.base_path) base_path_bytes = self.base_path.encode("utf8") stat_bytes = self.os.lstat(base_path_bytes) self.assertEqual(stat_bytes, stat_str) def test_stat_with_current_dir(self): # regression test for #516 stat_result = self.os.stat(".") lstat_result = self.os.lstat(".") self.assertEqual(stat_result, lstat_result) def test_exists_with_trailing_sep(self): # regression test for #364 file_path = self.make_path("alpha") self.create_file(file_path) self.assertFalse(self.os.path.exists(file_path + self.os.sep)) def test_mkdir_with_trailing_sep(self): # regression test for #367 dir_path = self.make_path("foo") self.os.mkdir(dir_path + self.os.sep + self.os.sep) self.assertTrue(self.os.path.exists(dir_path)) def test_readlink_empty_path(self): self.check_posix_only() self.assert_raises_os_error(errno.ENOENT, self.os.readlink, "") def test_readlink_ending_with_sep_posix(self): # regression test for #359 self.check_posix_only() link_path = self.make_path("foo") self.os.symlink(self.base_path, link_path) self.assert_raises_os_error( errno.EINVAL, self.os.readlink, link_path + self.os.sep ) def test_lstat_symlink_with_trailing_sep_linux(self): # regression test for #366 self.check_linux_only() self.skip_if_symlink_not_supported() link_path = self.make_path("foo") self.os.symlink(self.base_path, link_path) # used to raise self.assertTrue(self.os.lstat(link_path + self.os.sep).st_mode) def test_lstat_symlink_with_trailing_sep_macos(self): # regression test for #366 self.check_macos_only() self.skip_if_symlink_not_supported() link_path = self.make_path("foo") self.os.symlink(self.base_path, link_path) # used to raise self.assertTrue(self.os.lstat(link_path + self.os.sep).st_mode) def test_readlink_ending_with_sep_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() link_path = self.make_path("foo") self.os.symlink(self.base_path, link_path) self.assert_equal_paths( self.base_path, self.os.readlink(link_path + self.os.sep) ) def test_islink_with_trailing_sep_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() link_path = self.make_path("foo") self.os.symlink(self.base_path, link_path) self.assertTrue(self.os.path.islink(link_path + self.os.path.sep)) def test_islink_with_trailing_sep_linux(self): self.check_linux_only() link_path = self.make_path("foo") self.os.symlink(self.base_path, link_path) self.assertFalse(self.os.path.islink(link_path + self.os.sep)) def test_islink_with_trailing_sep_macos(self): self.check_macos_only() link_path = self.make_path("foo") self.os.symlink(self.base_path, link_path) self.assertFalse(self.os.path.islink(link_path + self.os.sep)) def check_getsize_raises_with_trailing_separator(self, error_nr): file_path = self.make_path("bar") self.create_file(file_path) self.assert_raises_os_error( error_nr, self.os.path.getsize, file_path + self.os.sep ) def test_getsize_raises_with_trailing_separator_posix(self): self.check_posix_only() self.check_getsize_raises_with_trailing_separator(errno.ENOTDIR) def test_getsize_raises_with_trailing_separator_windows(self): self.check_windows_only() self.check_getsize_raises_with_trailing_separator(errno.EINVAL) def check_remove_link_ending_with_sep(self, error_nr): # regression test for #360 link_path = self.make_path("foo") self.os.symlink(self.base_path, link_path) self.assert_raises_os_error(error_nr, self.os.remove, link_path + self.os.sep) def test_remove_link_ending_with_sep_linux(self): self.check_linux_only() self.check_remove_link_ending_with_sep(errno.ENOTDIR) def test_remove_link_ending_with_sep_macos(self): self.check_macos_only() self.check_remove_link_ending_with_sep(errno.EPERM) def test_remove_link_ending_with_sep_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() self.check_remove_link_ending_with_sep(errno.EACCES) def test_lstat_uses_open_fd_as_path(self): self.skip_if_symlink_not_supported() if os.lstat not in os.supports_fd: self.skip_real_fs() self.assert_raises_os_error(errno.EBADF, self.os.lstat, 5) file_path = self.make_path("foo", "bar") link_path = self.make_path("foo", "link") file_contents = b"contents" self.create_file(file_path, contents=file_contents) self.create_symlink(link_path, file_path) with self.open(file_path) as f: self.assertEqual(len(file_contents), self.os.lstat(f.filedes)[stat.ST_SIZE]) def test_stat_non_existent_file(self): # set up file_path = self.make_path("non", "existent", "file") self.assertFalse(self.os.path.exists(file_path)) # actual tests try: # Use try-catch to check exception attributes. self.os.stat(file_path) self.fail("Exception is expected.") # COV_NF_LINE except OSError as os_error: self.assertEqual(errno.ENOENT, os_error.errno) self.assertEqual(file_path, os_error.filename) def check_open_raises_with_trailing_separator(self, error_nr): file_path = self.make_path("bar") + self.os.sep self.assert_raises_os_error( error_nr, self.os.open, file_path, os.O_CREAT | os.O_WRONLY | os.O_TRUNC, ) def test_open_raises_with_trailing_separator_linux(self): self.check_linux_only() self.check_open_raises_with_trailing_separator(errno.EISDIR) def test_open_raises_with_trailing_separator_macos(self): self.check_macos_only() self.check_open_raises_with_trailing_separator(errno.ENOENT) def test_open_raises_with_trailing_separator_windows(self): self.check_windows_only() self.check_open_raises_with_trailing_separator(errno.EINVAL) def test_lexists_with_trailing_separator_linux_windows(self): self.check_linux_and_windows() self.skip_if_symlink_not_supported() file_path = self.make_path("foo") self.os.symlink(file_path, file_path) self.assertFalse(self.os.path.lexists(file_path + self.os.sep)) def test_lexists_with_trailing_separator_macos(self): # regression test for #373 self.check_macos_only() file_path = self.make_path("foo") self.os.symlink(file_path, file_path) self.assertTrue(self.os.path.lexists(file_path + self.os.sep)) def test_islink_with_trailing_separator_linux_windows(self): self.check_linux_and_windows() self.skip_if_symlink_not_supported() file_path = self.make_path("foo") self.os.symlink(file_path, file_path) self.assertFalse(self.os.path.islink(file_path + self.os.sep)) def test_islink_with_trailing_separator_macos(self): # regression test for #373 self.check_macos_only() file_path = self.make_path("foo") self.os.symlink(file_path, file_path) self.assertTrue(self.os.path.islink(file_path + self.os.sep)) def test_isfile_with_trailing_separator_linux_windows(self): self.check_linux_and_windows() file_path = self.make_path("foo") self.create_file(file_path) self.assertFalse(self.os.path.isfile(file_path + self.os.sep)) def test_isfile_with_trailing_separator_macos(self): # regression test for #374 self.check_macos_only() file_path = self.make_path("foo") self.create_file(file_path) self.assertFalse(self.os.path.isfile(file_path + self.os.sep)) def test_isfile_not_readable_file(self): file_path = self.make_path("foo") self.create_file(file_path, perm=0) self.assertTrue(self.os.path.isfile(file_path)) def check_stat_with_trailing_separator(self, error_nr): # regression test for #376 file_path = self.make_path("foo") self.create_file(file_path) self.assert_raises_os_error(error_nr, self.os.stat, file_path + self.os.sep) def test_stat_with_trailing_separator_posix(self): self.check_posix_only() self.check_stat_with_trailing_separator(errno.ENOTDIR) def test_stat_with_trailing_separator_windows(self): self.check_windows_only() self.check_stat_with_trailing_separator(errno.EINVAL) def check_remove_with_trailing_separator(self, error_nr): # regression test for #377 file_path = self.make_path("foo") self.create_file(file_path) self.assert_raises_os_error(error_nr, self.os.remove, file_path + self.os.sep) def test_remove_with_trailing_separator_posix(self): self.check_posix_only() self.check_remove_with_trailing_separator(errno.ENOTDIR) def test_remove_with_trailing_separator_windows(self): self.check_windows_only() self.check_remove_with_trailing_separator(errno.EINVAL) def test_readlink(self): self.skip_if_symlink_not_supported() link_path = self.make_path("foo", "bar", "baz") target = self.make_path("tarJAY") self.create_symlink(link_path, target) self.assert_equal_paths(self.os.readlink(link_path), target) def check_readlink_raises_if_path_is_not_a_link(self): file_path = self.make_path("foo", "bar", "eleventyone") self.create_file(file_path) self.assert_raises_os_error(errno.EINVAL, self.os.readlink, file_path) def test_readlink_raises_if_path_is_not_a_link_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() self.check_readlink_raises_if_path_is_not_a_link() def test_readlink_raises_if_path_is_not_a_link_posix(self): self.check_posix_only() self.check_readlink_raises_if_path_is_not_a_link() def check_readlink_raises_if_path_has_file(self, error_subtype): self.create_file(self.make_path("a_file")) file_path = self.make_path("a_file", "foo") self.assert_raises_os_error(error_subtype, self.os.readlink, file_path) file_path = self.make_path("a_file", "foo", "bar") self.assert_raises_os_error(error_subtype, self.os.readlink, file_path) def test_readlink_raises_if_path_has_file_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() self.check_readlink_raises_if_path_has_file(errno.ENOENT) def test_readlink_raises_if_path_has_file_posix(self): self.check_posix_only() self.check_readlink_raises_if_path_has_file(errno.ENOTDIR) def test_readlink_raises_if_path_does_not_exist(self): self.skip_if_symlink_not_supported() self.assert_raises_os_error( errno.ENOENT, self.os.readlink, "/this/path/does/not/exist" ) def test_readlink_raises_if_path_is_none(self): self.skip_if_symlink_not_supported() with self.assertRaises(TypeError): self.os.readlink(None) def test_broken_symlink_with_trailing_separator_linux(self): self.check_linux_only() file_path = self.make_path("foo") link_path = self.make_path("link") self.os.symlink(file_path, link_path) self.assert_raises_os_error( errno.EEXIST, self.os.symlink, link_path + self.os.sep, link_path + self.os.sep, ) def test_broken_symlink_with_trailing_separator_macos(self): # regression test for #371 self.check_macos_only() file_path = self.make_path("foo") link_path = self.make_path("link") self.os.symlink(file_path, link_path) self.os.symlink(link_path + self.os.sep, link_path + self.os.sep) def test_broken_symlink_with_trailing_separator_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() file_path = self.make_path("foo") link_path = self.make_path("link") self.os.symlink(file_path, link_path) self.assert_raises_os_error( errno.EINVAL, self.os.symlink, link_path + self.os.sep, link_path + self.os.sep, ) def test_circular_readlink_with_trailing_separator_linux(self): # Regression test for #372 self.check_linux_only() file_path = self.make_path("foo") self.os.symlink(file_path, file_path) self.assert_raises_os_error( errno.ELOOP, self.os.readlink, file_path + self.os.sep ) def test_circular_readlink_with_trailing_separator_macos(self): # Regression test for #372 self.check_macos_only() file_path = self.make_path("foo") self.os.symlink(file_path, file_path) self.os.readlink(file_path + self.os.sep) def test_circular_readlink_with_trailing_separator_windows(self): # Regression test for #372 self.check_windows_only() self.skip_if_symlink_not_supported() file_path = self.make_path("foo") self.os.symlink(file_path, file_path) self.assert_raises_os_error( errno.EINVAL, self.os.readlink, file_path + self.os.sep ) def test_readlink_with_links_in_path(self): self.skip_if_symlink_not_supported() self.create_symlink( self.make_path("meyer", "lemon", "pie"), self.make_path("yum") ) self.create_symlink(self.make_path("geo", "metro"), self.make_path("meyer")) self.assert_equal_paths( self.make_path("yum"), self.os.readlink(self.make_path("geo", "metro", "lemon", "pie")), ) def test_readlink_with_chained_links_in_path(self): self.skip_if_symlink_not_supported() self.create_symlink( self.make_path("eastern", "european", "wolfhounds", "chase"), self.make_path("cats"), ) self.create_symlink( self.make_path("russian"), self.make_path("eastern", "european") ) self.create_symlink( self.make_path("dogs"), self.make_path("russian", "wolfhounds") ) self.assert_equal_paths( self.make_path("cats"), self.os.readlink(self.make_path("dogs", "chase")), ) def check_remove_dir(self, dir_error): directory = self.make_path("xyzzy") dir_path = self.os.path.join(directory, "plugh") self.create_dir(dir_path) self.assertTrue(self.os.path.exists(dir_path)) self.assert_raises_os_error(dir_error, self.os.remove, dir_path) self.assertTrue(self.os.path.exists(dir_path)) self.os.chdir(directory) self.assert_raises_os_error(dir_error, self.os.remove, dir_path) self.assertTrue(self.os.path.exists(dir_path)) self.assert_raises_os_error(errno.ENOENT, self.os.remove, "/plugh") def test_remove_dir_linux(self): self.check_linux_only() self.check_remove_dir(errno.EISDIR) def test_remove_dir_mac_os(self): self.check_macos_only() self.check_remove_dir(errno.EPERM) def test_remove_dir_windows(self): self.check_windows_only() self.check_remove_dir(errno.EACCES) def test_remove_dir_with_drive(self): # regression test for issue #337 self.check_windows_only() self.skip_real_fs() dir_path = self.os.path.join("C:", "test") self.filesystem.create_dir(dir_path) self.assert_raises_os_error(errno.EACCES, self.os.remove, dir_path) def test_remove_file(self): directory = self.make_path("zzy") file_path = self.os.path.join(directory, "plugh") self.create_file(file_path) self.assertTrue(self.os.path.exists(file_path)) self.os.remove(file_path) self.assertFalse(self.os.path.exists(file_path)) def test_remove_file_no_directory(self): directory = self.make_path("zzy") file_name = "plugh" file_path = self.os.path.join(directory, file_name) self.create_file(file_path) self.assertTrue(self.os.path.exists(file_path)) self.os.chdir(directory) self.os.remove(file_name) self.assertFalse(self.os.path.exists(file_path)) def test_remove_file_with_read_permission_raises_in_windows(self): self.check_windows_only() path = self.make_path("foo", "bar") self.create_file(path) self.os.chmod(path, 0o444) self.assert_raises_os_error(errno.EACCES, self.os.remove, path) self.os.chmod(path, 0o666) def test_remove_file_with_read_permission_shall_succeed_in_posix(self): self.check_posix_only() path = self.make_path("foo", "bar") self.create_file(path) self.os.chmod(path, 0o444) self.os.remove(path) self.assertFalse(self.os.path.exists(path)) def test_remove_file_without_parent_permission_raises_in_posix(self): self.check_posix_only() parent_dir = self.make_path("foo") path = self.os.path.join(parent_dir, "bar") self.create_file(path) self.os.chmod(parent_dir, 0o666) # missing execute permission if not is_root(): self.assert_raises_os_error(errno.EACCES, self.os.remove, path) else: self.os.remove(path) self.assertFalse(self.os.path.exists(path)) self.create_file(path) self.os.chmod(parent_dir, 0o555) # missing write permission if not is_root(): self.assert_raises_os_error(errno.EACCES, self.os.remove, path) else: self.os.remove(path) self.assertFalse(self.os.path.exists(path)) self.create_file(path) self.os.chmod(parent_dir, 0o333) self.os.remove(path) self.assertFalse(self.os.path.exists(path)) def test_remove_open_file_fails_under_windows(self): self.check_windows_only() path = self.make_path("foo", "bar") self.create_file(path) with self.open(path, "r"): self.assert_raises_os_error(errno.EACCES, self.os.remove, path) self.assertTrue(self.os.path.exists(path)) def test_remove_open_file_possible_under_posix(self): self.check_posix_only() path = self.make_path("foo", "bar") self.create_file(path) self.open(path, "r") self.os.remove(path) self.assertFalse(self.os.path.exists(path)) def test_remove_file_relative_path(self): self.skip_real_fs() original_dir = self.os.getcwd() directory = self.make_path("zzy") subdirectory = self.os.path.join(directory, "zzy") file_name = "plugh" file_path = self.os.path.join(directory, file_name) file_path_relative = self.os.path.join("..", file_name) self.create_file(file_path) self.assertTrue(self.os.path.exists(file_path)) self.create_dir(subdirectory) self.assertTrue(self.os.path.exists(subdirectory)) self.os.chdir(subdirectory) self.os.remove(file_path_relative) self.assertFalse(self.os.path.exists(file_path_relative)) self.os.chdir(original_dir) self.assertFalse(self.os.path.exists(file_path)) def check_remove_dir_raises_error(self, dir_error): directory = self.make_path("zzy") self.create_dir(directory) self.assert_raises_os_error(dir_error, self.os.remove, directory) def test_remove_dir_raises_error_linux(self): self.check_linux_only() self.check_remove_dir_raises_error(errno.EISDIR) def test_remove_dir_raises_error_mac_os(self): self.check_macos_only() self.check_remove_dir_raises_error(errno.EPERM) def test_remove_dir_raises_error_windows(self): self.check_windows_only() self.check_remove_dir_raises_error(errno.EACCES) def test_remove_symlink_to_dir(self): self.skip_if_symlink_not_supported() directory = self.make_path("zzy") link = self.make_path("link_to_dir") self.create_dir(directory) self.os.symlink(directory, link) self.assertTrue(self.os.path.exists(directory)) self.assertTrue(self.os.path.exists(link)) self.os.remove(link) self.assertTrue(self.os.path.exists(directory)) self.assertFalse(self.os.path.exists(link)) def test_unlink_raises_if_not_exist(self): file_path = self.make_path("file", "does", "not", "exist") self.assertFalse(self.os.path.exists(file_path)) self.assert_raises_os_error(errno.ENOENT, self.os.unlink, file_path) def test_rename_to_nonexistent_file(self): """Can rename a file to an unused name.""" directory = self.make_path("xyzzy") old_file_path = self.os.path.join(directory, "plugh_old") new_file_path = self.os.path.join(directory, "plugh_new") self.create_file(old_file_path, contents="test contents") self.assertTrue(self.os.path.exists(old_file_path)) self.assertFalse(self.os.path.exists(new_file_path)) self.os.rename(old_file_path, new_file_path) self.assertFalse(self.os.path.exists(old_file_path)) self.assertTrue(self.os.path.exists(new_file_path)) self.check_contents(new_file_path, "test contents") def test_rename_dir_to_symlink_posix(self): self.check_posix_only() link_path = self.make_path("link") dir_path = self.make_path("dir") link_target = self.os.path.join(dir_path, "link_target") self.create_dir(dir_path) self.os.symlink(link_target, link_path) self.assert_raises_os_error(errno.ENOTDIR, self.os.rename, dir_path, link_path) def test_rename_dir_to_symlink_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() link_path = self.make_path("link") dir_path = self.make_path("dir") link_target = self.os.path.join(dir_path, "link_target") self.create_dir(dir_path) self.os.symlink(link_target, link_path) self.assert_raises_os_error(errno.EEXIST, self.os.rename, dir_path, link_path) def test_rename_file_to_symlink(self): self.check_posix_only() link_path = self.make_path("file_link") file_path = self.make_path("file") self.os.symlink(file_path, link_path) self.create_file(file_path) self.os.rename(file_path, link_path) self.assertFalse(self.os.path.exists(file_path)) self.assertTrue(self.os.path.exists(link_path)) self.assertTrue(self.os.path.isfile(link_path)) def test_rename_symlink_to_symlink(self): self.check_posix_only() base_path = self.make_path("foo", "bar") self.create_dir(base_path) link_path1 = self.os.path.join(base_path, "link1") link_path2 = self.os.path.join(base_path, "link2") self.os.symlink(base_path, link_path1) self.os.symlink(base_path, link_path2) self.os.rename(link_path1, link_path2) self.assertFalse(self.os.path.exists(link_path1)) self.assertTrue(self.os.path.exists(link_path2)) def test_rename_symlink_to_symlink_for_parent_raises(self): self.check_posix_only() dir_link = self.make_path("dir_link") dir_path = self.make_path("dir") dir_in_dir_path = self.os.path.join(dir_link, "inner_dir") self.create_dir(dir_path) self.os.symlink(dir_path, dir_link) self.create_dir(dir_in_dir_path) self.assert_raises_os_error( errno.EINVAL, self.os.rename, dir_path, dir_in_dir_path ) def check_rename_case_with_symlink(self, result): self.skip_if_symlink_not_supported() self.check_case_insensitive_fs() dir_path_lower = self.make_path("beta") self.create_dir(dir_path_lower) link_path = self.make_path("b") self.os.symlink(self.base_path, link_path) path1 = self.os.path.join(link_path, "Beta") dir_path_upper = self.make_path("Beta") self.os.rename(path1, dir_path_upper) self.assertEqual(result, sorted(self.os.listdir(self.base_path))) def test_rename_case_with_symlink_mac(self): # Regression test for #322 self.check_macos_only() self.check_rename_case_with_symlink(["b", "beta"]) def test_rename_case_with_symlink_windows(self): self.check_windows_only() self.check_rename_case_with_symlink(["Beta", "b"]) def test_recursive_rename_raises(self): self.check_posix_only() base_path = self.make_path("foo", "bar") self.create_dir(base_path) new_path = self.os.path.join(base_path, "new_dir") self.assert_raises_os_error(errno.EINVAL, self.os.rename, base_path, new_path) def test_rename_file_to_parent_dir_file(self): # Regression test for issue 230 dir_path = self.make_path("dir") self.create_dir(dir_path) file_path = self.make_path("old_file") new_file_path = self.os.path.join(dir_path, "new_file") self.create_file(file_path) self.os.rename(file_path, new_file_path) def test_rename_with_target_parent_file_raises_posix(self): self.check_posix_only() file_path = self.make_path("foo", "baz") self.create_file(file_path) self.assert_raises_os_error( errno.ENOTDIR, self.os.rename, file_path, file_path + "/new" ) def test_rename_with_target_parent_file_raises_windows(self): self.check_windows_only() file_path = self.make_path("foo", "baz") self.create_file(file_path) self.assert_raises_os_error( errno.EACCES, self.os.rename, file_path, self.os.path.join(file_path, "new"), ) def test_rename_symlink_to_source(self): self.check_posix_only() base_path = self.make_path("foo") link_path = self.os.path.join(base_path, "slink") file_path = self.os.path.join(base_path, "file") self.create_file(file_path) self.os.symlink(file_path, link_path) self.os.rename(link_path, file_path) self.assertFalse(self.os.path.exists(file_path)) def test_rename_symlink_to_dir_raises(self): self.check_posix_only() base_path = self.make_path("foo", "bar") link_path = self.os.path.join(base_path, "dir_link") dir_path = self.os.path.join(base_path, "dir") self.create_dir(dir_path) self.os.symlink(dir_path, link_path) self.assert_raises_os_error(errno.EISDIR, self.os.rename, link_path, dir_path) def test_rename_broken_symlink(self): self.check_posix_only() base_path = self.make_path("foo") self.create_dir(base_path) link_path = self.os.path.join(base_path, "slink") file_path = self.os.path.join(base_path, "file") self.os.symlink(file_path, link_path) self.os.rename(link_path, file_path) self.assertFalse(self.os.path.exists(file_path)) self.assertTrue(self.os.path.lexists(file_path)) self.assertFalse(self.os.path.exists(link_path)) def test_rename_directory(self): """Can rename a directory to an unused name.""" for old_path, new_path in [("wxyyw", "xyzzy"), ("abccb", "cdeed")]: old_path = self.make_path(old_path) new_path = self.make_path(new_path) self.create_file(self.os.path.join(old_path, "plugh"), contents="test") self.assertTrue(self.os.path.exists(old_path)) self.assertFalse(self.os.path.exists(new_path)) self.os.rename(old_path, new_path) self.assertFalse(self.os.path.exists(old_path)) self.assertTrue(self.os.path.exists(new_path)) self.check_contents(self.os.path.join(new_path, "plugh"), "test") if not self.use_real_fs(): self.assertEqual(3, self.filesystem.get_object(new_path).st_nlink) def check_rename_directory_to_existing_file_raises(self, error_nr): dir_path = self.make_path("dir") file_path = self.make_path("file") self.create_dir(dir_path) self.create_file(file_path) self.assert_raises_os_error(error_nr, self.os.rename, dir_path, file_path) def test_rename_directory_to_existing_file_raises_posix(self): self.check_posix_only() self.check_rename_directory_to_existing_file_raises(errno.ENOTDIR) def test_rename_directory_to_existing_file_raises_windows(self): self.check_windows_only() self.check_rename_directory_to_existing_file_raises(errno.EEXIST) def test_rename_to_existing_directory_should_raise_under_windows(self): """Renaming to an existing directory raises OSError under Windows.""" self.check_windows_only() old_path = self.make_path("foo", "bar") new_path = self.make_path("foo", "baz") self.create_dir(old_path) self.create_dir(new_path) self.assert_raises_os_error(errno.EEXIST, self.os.rename, old_path, new_path) def test_rename_to_a_hardlink_of_same_file_should_do_nothing(self): self.skip_real_fs_failure(skip_posix=False) self.skip_if_symlink_not_supported() file_path = self.make_path("dir", "file") self.create_file(file_path) link_path = self.make_path("link") self.os.link(file_path, link_path) self.os.rename(file_path, link_path) self.assertTrue(self.os.path.exists(file_path)) self.assertTrue(self.os.path.exists(link_path)) def test_hardlink_works_with_symlink(self): self.skip_if_symlink_not_supported() base_path = self.make_path("foo") self.create_dir(base_path) symlink_path = self.os.path.join(base_path, "slink") self.os.symlink(base_path, symlink_path) file_path = self.os.path.join(base_path, "slink", "beta") self.create_file(file_path) link_path = self.os.path.join(base_path, "slink", "gamma") self.os.link(file_path, link_path) self.assertTrue(self.os.path.exists(link_path)) self.assertFalse(self.os.path.islink(link_path)) def test_replace_existing_directory_should_raise_under_windows(self): """Renaming to an existing directory raises OSError under Windows.""" self.check_windows_only() old_path = self.make_path("foo", "bar") new_path = self.make_path("foo", "baz") self.create_dir(old_path) self.create_dir(new_path) self.assert_raises_os_error(errno.EACCES, self.os.replace, old_path, new_path) def test_rename_to_existing_directory_under_posix(self): """Renaming to an existing directory changes the existing directory under Posix.""" self.check_posix_only() old_path = self.make_path("foo", "bar") new_path = self.make_path("xyzzy") self.create_dir(self.os.path.join(old_path, "sub")) self.create_dir(new_path) self.os.rename(old_path, new_path) self.assertTrue(self.os.path.exists(self.os.path.join(new_path, "sub"))) self.assertFalse(self.os.path.exists(old_path)) def test_rename_file_to_existing_directory_raises_under_posix(self): self.check_posix_only() file_path = self.make_path("foo", "bar", "baz") new_path = self.make_path("xyzzy") self.create_file(file_path) self.create_dir(new_path) self.assert_raises_os_error(errno.EISDIR, self.os.rename, file_path, new_path) def test_rename_to_existing_dir_under_posix_raises_if_not_empty(self): """Renaming to an existing directory changes the existing directory under Posix.""" self.check_posix_only() old_path = self.make_path("foo", "bar") new_path = self.make_path("foo", "baz") self.create_dir(self.os.path.join(old_path, "sub")) self.create_dir(self.os.path.join(new_path, "sub")) # not testing specific subtype: # raises errno.ENOTEMPTY under Ubuntu 16.04, MacOS and pyfakefs # but raises errno.EEXIST at least under Ubunto 14.04 with self.assertRaises(OSError): self.os.rename(old_path, new_path) def test_rename_to_another_device_should_raise(self): """Renaming to another filesystem device raises OSError.""" self.skip_real_fs() self.filesystem.add_mount_point("/mount") old_path = "/foo/bar" new_path = "/mount/bar" self.filesystem.create_file(old_path) self.assert_raises_os_error(errno.EXDEV, self.os.rename, old_path, new_path) def test_rename_to_existent_file_posix(self): """Can rename a file to a used name under Unix.""" self.check_posix_only() directory = self.make_path("xyzzy") old_file_path = self.os.path.join(directory, "plugh_old") new_file_path = self.os.path.join(directory, "plugh_new") self.create_file(old_file_path, contents="test contents 1") self.create_file(new_file_path, contents="test contents 2") self.assertTrue(self.os.path.exists(old_file_path)) self.assertTrue(self.os.path.exists(new_file_path)) self.os.rename(old_file_path, new_file_path) self.assertFalse(self.os.path.exists(old_file_path)) self.assertTrue(self.os.path.exists(new_file_path)) self.check_contents(new_file_path, "test contents 1") def test_rename_to_existent_file_windows(self): """Renaming a file to a used name raises OSError under Windows.""" self.check_windows_only() directory = self.make_path("xyzzy") old_file_path = self.os.path.join(directory, "plugh_old") new_file_path = self.os.path.join(directory, "plugh_new") self.create_file(old_file_path, contents="test contents 1") self.create_file(new_file_path, contents="test contents 2") self.assertTrue(self.os.path.exists(old_file_path)) self.assertTrue(self.os.path.exists(new_file_path)) self.assert_raises_os_error( errno.EEXIST, self.os.rename, old_file_path, new_file_path ) def test_replace_to_existent_file(self): """Replaces an existing file (does not work with `rename()` under Windows).""" directory = self.make_path("xyzzy") old_file_path = self.os.path.join(directory, "plugh_old") new_file_path = self.os.path.join(directory, "plugh_new") self.create_file(old_file_path, contents="test contents 1") self.create_file(new_file_path, contents="test contents 2") self.assertTrue(self.os.path.exists(old_file_path)) self.assertTrue(self.os.path.exists(new_file_path)) self.os.replace(old_file_path, new_file_path) self.assertFalse(self.os.path.exists(old_file_path)) self.assertTrue(self.os.path.exists(new_file_path)) self.check_contents(new_file_path, "test contents 1") def test_rename_to_nonexistent_dir(self): """Can rename a file to a name in a nonexistent dir.""" directory = self.make_path("xyzzy") old_file_path = self.os.path.join(directory, "plugh_old") new_file_path = self.os.path.join(directory, "no_such_path", "plugh_new") self.create_file(old_file_path, contents="test contents") self.assertTrue(self.os.path.exists(old_file_path)) self.assertFalse(self.os.path.exists(new_file_path)) self.assert_raises_os_error( errno.ENOENT, self.os.rename, old_file_path, new_file_path ) self.assertTrue(self.os.path.exists(old_file_path)) self.assertFalse(self.os.path.exists(new_file_path)) self.check_contents(old_file_path, "test contents") def test_rename_nonexistent_file_should_raise_error(self): """Can't rename a file that doesn't exist.""" self.assert_raises_os_error( errno.ENOENT, self.os.rename, "nonexistent-foo", "doesn't-matter-bar", ) def test_rename_empty_dir(self): """Test a rename of an empty directory.""" directory = self.make_path("xyzzy") before_dir = self.os.path.join(directory, "empty") after_dir = self.os.path.join(directory, "unused") self.create_dir(before_dir) self.assertTrue(self.os.path.exists(self.os.path.join(before_dir, "."))) self.assertFalse(self.os.path.exists(after_dir)) self.os.rename(before_dir, after_dir) self.assertFalse(self.os.path.exists(before_dir)) self.assertTrue(self.os.path.exists(self.os.path.join(after_dir, "."))) def test_rename_symlink(self): self.check_posix_only() base_path = self.make_path("foo", "bar") self.create_dir(base_path) link_path = self.os.path.join(base_path, "link") self.os.symlink(base_path, link_path) file_path = self.os.path.join(link_path, "file") new_file_path = self.os.path.join(link_path, "new") self.create_file(file_path) self.os.rename(file_path, new_file_path) self.assertFalse(self.os.path.exists(file_path)) self.assertTrue(self.os.path.exists(new_file_path)) def check_append_mode_tell_after_truncate(self, tell_result): file_path = self.make_path("baz") with self.open(file_path, "w") as f0: with self.open(file_path, "a") as f1: f1.write("abcde") f0.seek(2) f0.truncate() self.assertEqual(tell_result, f1.tell()) with self.open(file_path, mode="rb") as f: self.assertEqual(b"\0\0abcde", f.read()) def test_append_mode_tell_linux_windows(self): # Regression test for #300 self.check_linux_and_windows() self.check_append_mode_tell_after_truncate(7) def test_append_mode_tell_macos(self): # Regression test for #300 self.check_macos_only() self.check_append_mode_tell_after_truncate(7) def test_tell_after_seek_in_append_mode(self): # Regression test for #363 file_path = self.make_path("foo") with self.open(file_path, "a") as f: f.seek(1) self.assertEqual(1, f.tell()) def test_tell_after_seekback_in_append_mode(self): # Regression test for #414 file_path = self.make_path("foo") with self.open(file_path, "a") as f: f.write("aa") f.seek(1) self.assertEqual(1, f.tell()) def test_dir_with_trailing_sep_is_dir(self): # regression test for #387 self.assertTrue(self, self.os.path.isdir(self.base_path + self.os.sep)) def check_rename_dir_with_trailing_sep(self, error): dir_path = self.make_path("dir") + self.os.sep self.os.mkdir(dir_path) self.assert_raises_os_error(error, self.os.rename, dir_path, self.base_path) def test_rename_dir_with_trailing_sep_posix(self): # regression test for #406 self.check_posix_only() self.check_rename_dir_with_trailing_sep(errno.ENOTEMPTY) def test_rename_dir_with_trailing_sep_windows(self): self.check_windows_only() self.check_rename_dir_with_trailing_sep(errno.EEXIST) def test_rename_dir(self): """Test a rename of a directory.""" directory = self.make_path("xyzzy") before_dir = self.os.path.join(directory, "before") before_file = self.os.path.join(directory, "before", "file") after_dir = self.os.path.join(directory, "after") after_file = self.os.path.join(directory, "after", "file") self.create_dir(before_dir) self.create_file(before_file, contents="payload") self.assertTrue(self.os.path.exists(before_dir)) self.assertTrue(self.os.path.exists(before_file)) self.assertFalse(self.os.path.exists(after_dir)) self.assertFalse(self.os.path.exists(after_file)) self.os.rename(before_dir, after_dir) self.assertFalse(self.os.path.exists(before_dir)) self.assertFalse(self.os.path.exists(before_file)) self.assertTrue(self.os.path.exists(after_dir)) self.assertTrue(self.os.path.exists(after_file)) self.check_contents(after_file, "payload") def test_rename_preserves_stat(self): """Test if rename preserves mtime.""" self.check_posix_only() self.skip_real_fs() directory = self.make_path("xyzzy") old_file_path = self.os.path.join(directory, "plugh_old") new_file_path = self.os.path.join(directory, "plugh_new") self.create_file(old_file_path) old_file = self.filesystem.get_object(old_file_path) old_file.st_mtime = old_file.st_mtime - 3600 self.os.chown(old_file_path, 200, 200) self.os.chmod(old_file_path, 0o222) self.create_file(new_file_path) new_file = self.filesystem.get_object(new_file_path) self.assertNotEqual(new_file.st_mtime, old_file.st_mtime) self.os.rename(old_file_path, new_file_path) new_file = self.filesystem.get_object(new_file_path, check_read_perm=False) self.assertEqual(new_file.st_mtime, old_file.st_mtime) self.assertEqual(new_file.st_mode, old_file.st_mode) self.assertEqual(new_file.st_uid, old_file.st_uid) self.assertEqual(new_file.st_gid, old_file.st_gid) def test_rename_same_filenames(self): """Test renaming when old and new names are the same.""" directory = self.make_path("xyzzy") file_contents = "Spam eggs" file_path = self.os.path.join(directory, "eggs") self.create_file(file_path, contents=file_contents) self.os.rename(file_path, file_path) self.check_contents(file_path, file_contents) def test_rmdir(self): """Can remove a directory.""" directory = self.make_path("xyzzy") sub_dir = self.make_path("xyzzy", "abccd") other_dir = self.make_path("xyzzy", "cdeed") self.create_dir(directory) self.assertTrue(self.os.path.exists(directory)) self.os.rmdir(directory) self.assertFalse(self.os.path.exists(directory)) self.create_dir(sub_dir) self.create_dir(other_dir) self.os.chdir(sub_dir) self.os.rmdir("../cdeed") self.assertFalse(self.os.path.exists(other_dir)) self.os.chdir("..") self.os.rmdir("abccd") self.assertFalse(self.os.path.exists(sub_dir)) def test_rmdir_raises_if_not_empty(self): """Raises an exception if the target directory is not empty.""" directory = self.make_path("xyzzy") file_path = self.os.path.join(directory, "plugh") self.create_file(file_path) self.assertTrue(self.os.path.exists(file_path)) self.assert_raises_os_error(errno.ENOTEMPTY, self.os.rmdir, directory) def check_rmdir_raises_if_not_directory(self, error_nr): """Raises an exception if the target is not a directory.""" directory = self.make_path("xyzzy") file_path = self.os.path.join(directory, "plugh") self.create_file(file_path) self.assertTrue(self.os.path.exists(file_path)) self.assert_raises_os_error(errno.ENOTDIR, self.os.rmdir, file_path) self.assert_raises_os_error(error_nr, self.os.rmdir, ".") def test_rmdir_raises_if_not_directory_posix(self): self.check_posix_only() self.check_rmdir_raises_if_not_directory(errno.EINVAL) def test_rmdir_raises_if_not_directory_windows(self): self.check_windows_only() self.check_rmdir_raises_if_not_directory(errno.EACCES) def test_rmdir_raises_if_not_exist(self): """Raises an exception if the target does not exist.""" directory = self.make_path("xyzzy") self.assertFalse(self.os.path.exists(directory)) self.assert_raises_os_error(errno.ENOENT, self.os.rmdir, directory) def test_rmdir_via_symlink(self): self.check_windows_only() self.skip_if_symlink_not_supported() base_path = self.make_path("foo", "bar") dir_path = self.os.path.join(base_path, "alpha") self.create_dir(dir_path) link_path = self.os.path.join(base_path, "beta") self.os.symlink(base_path, link_path) self.os.rmdir(link_path + "/alpha") self.assertFalse(self.os.path.exists(dir_path)) def remove_dirs_check(self, directory): self.assertTrue(self.os.path.exists(directory)) self.os.removedirs(directory) return not self.os.path.exists(directory) def test_removedirs(self): # no exception raised self.skip_real_fs() data = [ "test1", ("test1", "test2"), ("test1", "extra"), ("test1", "test2", "test3"), ] for directory in data: self.create_dir(self.make_path(directory)) self.assertTrue(self.os.path.exists(self.make_path(directory))) self.assert_raises_os_error( errno.ENOTEMPTY, self.remove_dirs_check, self.make_path(data[0]) ) self.assert_raises_os_error( errno.ENOTEMPTY, self.remove_dirs_check, self.make_path(data[1]) ) self.assertTrue(self.remove_dirs_check(self.make_path(data[3]))) self.assertTrue(self.os.path.exists(self.make_path(data[0]))) self.assertFalse(self.os.path.exists(self.make_path(data[1]))) self.assertTrue(self.os.path.exists(self.make_path(data[2]))) # Should raise because '/test1/extra' is all that is left, and # removedirs('/test1/extra') will eventually try to rmdir('/'). self.assert_raises_os_error( errno.EBUSY, self.remove_dirs_check, self.make_path(data[2]) ) # However, it will still delete '/test1') in the process. self.assertFalse(self.os.path.exists(self.make_path(data[0]))) self.create_dir(self.make_path("test1", "test2")) # Add this to the root directory to avoid raising an exception. self.filesystem.create_dir(self.make_path("test3")) self.assertTrue(self.remove_dirs_check(self.make_path("test1", "test2"))) self.assertFalse(self.os.path.exists(self.make_path("test1", "test2"))) self.assertFalse(self.os.path.exists(self.make_path("test1"))) def test_removedirs_raises_if_removing_root(self): """Raises exception if asked to remove '/'.""" self.skip_real_fs() self.os.rmdir(self.base_path) directory = self.os.path.splitdrive(self.base_path)[0] + self.os.path.sep self.assertTrue(self.os.path.exists(directory)) self.assert_raises_os_error(errno.EBUSY, self.os.removedirs, directory) def test_removedirs_raises_if_cascade_removing_root(self): """Raises exception if asked to remove '/' as part of a larger operation. All of other directories should still be removed, though. """ self.skip_real_fs() directory = self.make_path("foo", "bar") self.create_dir(directory) self.assertTrue(self.os.path.exists(directory)) self.assert_raises_os_error(errno.EBUSY, self.os.removedirs, directory) head, unused_tail = self.os.path.split(directory) while self.os.path.splitdrive(head)[1] != self.os.path.sep: self.assertFalse(self.os.path.exists(directory)) head, unused_tail = self.os.path.split(head) def test_removedirs_with_trailing_slash(self): """removedirs works on directory names with trailing slashes.""" # separate this case from the removing-root-directory case self.create_dir(self.make_path("baz")) directory = self.make_path("foo", "bar") self.create_dir(directory) self.assertTrue(self.os.path.exists(directory)) self.os.removedirs(directory) self.assertFalse(self.os.path.exists(directory)) def test_remove_dirs_with_top_symlink_fails(self): self.check_posix_only() dir_path = self.make_path("dir") dir_link = self.make_path("dir_link") self.create_dir(dir_path) self.os.symlink(dir_path, dir_link) self.assert_raises_os_error(errno.ENOTDIR, self.os.removedirs, dir_link) def test_remove_dirs_with_non_top_symlink_succeeds(self): self.check_posix_only() dir_path = self.make_path("dir") dir_link = self.make_path("dir_link") self.create_dir(dir_path) self.os.symlink(dir_path, dir_link) dir_in_dir = self.os.path.join(dir_link, "dir2") self.create_dir(dir_in_dir) self.os.removedirs(dir_in_dir) self.assertFalse(self.os.path.exists(dir_in_dir)) # ensure that the symlink is not removed self.assertTrue(self.os.path.exists(dir_link)) def test_mkdir(self): """mkdir can create a relative directory.""" self.skip_real_fs() directory = "xyzzy" self.assertFalse(self.filesystem.exists(directory)) self.os.mkdir(directory) self.assertTrue(self.filesystem.exists("/%s" % directory)) self.os.chdir(directory) self.os.mkdir(directory) self.assertTrue(self.filesystem.exists("/%s/%s" % (directory, directory))) self.os.chdir(directory) self.os.mkdir("../abccb") self.assertTrue(self.os.path.exists("/%s/abccb" % directory)) def test_mkdir_with_trailing_slash(self): """mkdir can create a directory named with a trailing slash.""" directory = self.make_path("foo") self.assertFalse(self.os.path.exists(directory)) self.os.mkdir(directory) self.assertTrue(self.os.path.exists(directory)) self.assertTrue(self.os.path.exists(self.make_path("foo"))) def test_mkdir_raises_if_empty_directory_name(self): """mkdir raises exeption if creating directory named ''.""" directory = "" self.assert_raises_os_error(errno.ENOENT, self.os.mkdir, directory) def test_mkdir_raises_if_no_parent(self): """mkdir raises exception if parent directory does not exist.""" parent = "xyzzy" directory = "%s/foo" % (parent,) self.assertFalse(self.os.path.exists(parent)) self.assert_raises_os_error(errno.ENOENT, self.os.mkdir, directory) def test_mkdir_raises_on_symlink_in_posix(self): self.check_posix_only() base_path = self.make_path("foo", "bar") link_path = self.os.path.join(base_path, "link_to_dir") dir_path = self.os.path.join(base_path, "dir") self.create_dir(dir_path) self.os.symlink(dir_path, link_path) self.assert_raises_os_error(errno.ENOTDIR, self.os.rmdir, link_path) def test_mkdir_removes_symlink_in_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() base_path = self.make_path("foo", "bar") link_path = self.os.path.join(base_path, "link_to_dir") dir_path = self.os.path.join(base_path, "dir") self.create_dir(dir_path) self.os.symlink(dir_path, link_path) self.os.rmdir(link_path) self.assertFalse(self.os.path.exists(link_path)) self.assertTrue(self.os.path.exists(dir_path)) def test_mkdir_raises_if_directory_exists(self): """mkdir raises exception if directory already exists.""" directory = self.make_path("xyzzy") self.create_dir(directory) self.assertTrue(self.os.path.exists(directory)) self.assert_raises_os_error(errno.EEXIST, self.os.mkdir, directory) def test_mkdir_raises_if_file_exists(self): """mkdir raises exception if name already exists as a file.""" directory = self.make_path("xyzzy") file_path = self.os.path.join(directory, "plugh") self.create_file(file_path) self.assertTrue(self.os.path.exists(file_path)) self.assert_raises_os_error(errno.EEXIST, self.os.mkdir, file_path) def check_mkdir_raises_if_parent_is_file(self, error_type): """mkdir raises exception if name already exists as a file.""" directory = self.make_path("xyzzy") file_path = self.os.path.join(directory, "plugh") self.create_file(file_path) self.assert_raises_os_error( error_type, self.os.mkdir, self.os.path.join(file_path, "ff") ) def test_mkdir_raises_if_parent_is_file_posix(self): self.check_posix_only() self.check_mkdir_raises_if_parent_is_file(errno.ENOTDIR) def test_mkdir_raises_if_parent_is_file_windows(self): self.check_windows_only() self.check_mkdir_raises_if_parent_is_file(errno.ENOENT) def test_mkdir_raises_with_slash_dot_posix(self): """mkdir raises exception if mkdir foo/. (trailing /.).""" self.check_posix_only() self.assert_raises_os_error(errno.EEXIST, self.os.mkdir, self.os.sep + ".") directory = self.make_path("xyzzy", ".") self.assert_raises_os_error(errno.ENOENT, self.os.mkdir, directory) self.create_dir(self.make_path("xyzzy")) self.assert_raises_os_error(errno.EEXIST, self.os.mkdir, directory) def test_mkdir_raises_with_slash_dot_windows(self): """mkdir raises exception if mkdir foo/. (trailing /.).""" self.check_windows_only() self.assert_raises_os_error(errno.EACCES, self.os.mkdir, self.os.sep + ".") directory = self.make_path("xyzzy", ".") self.os.mkdir(directory) self.create_dir(self.make_path("xyzzy")) self.assert_raises_os_error(errno.EEXIST, self.os.mkdir, directory) def test_mkdir_raises_with_double_dots_posix(self): """mkdir raises exception if mkdir foo/foo2/../foo3.""" self.check_posix_only() self.assert_raises_os_error(errno.EEXIST, self.os.mkdir, self.os.sep + "..") directory = self.make_path("xyzzy", "dir1", "dir2", "..", "..", "dir3") self.assert_raises_os_error(errno.ENOENT, self.os.mkdir, directory) self.create_dir(self.make_path("xyzzy")) self.assert_raises_os_error(errno.ENOENT, self.os.mkdir, directory) self.create_dir(self.make_path("xyzzy", "dir1")) self.assert_raises_os_error(errno.ENOENT, self.os.mkdir, directory) self.create_dir(self.make_path("xyzzy", "dir1", "dir2")) self.os.mkdir(directory) self.assertTrue(self.os.path.exists(directory)) directory = self.make_path("xyzzy", "dir1", "..") self.assert_raises_os_error(errno.EEXIST, self.os.mkdir, directory) def test_mkdir_raises_with_double_dots_windows(self): """mkdir raises exception if mkdir foo/foo2/../foo3.""" self.check_windows_only() self.assert_raises_os_error(errno.EACCES, self.os.mkdir, self.os.sep + "..") directory = self.make_path("xyzzy", "dir1", "dir2", "..", "..", "dir3") self.assert_raises_os_error(errno.ENOENT, self.os.mkdir, directory) self.create_dir(self.make_path("xyzzy")) self.os.mkdir(directory) self.assertTrue(self.os.path.exists(directory)) directory = self.make_path("xyzzy", "dir1", "..") self.assert_raises_os_error(errno.EEXIST, self.os.mkdir, directory) def test_mkdir_raises_if_parent_is_read_only(self): """mkdir raises exception if parent is read only.""" self.check_posix_only() directory = self.make_path("a") self.os.mkdir(directory) # Change directory permissions to be read only. self.os.chmod(directory, 0o400) directory = self.make_path("a", "b") if not is_root(): self.assert_raises_os_error(errno.EACCES, self.os.mkdir, directory) else: self.os.mkdir(directory) self.assertTrue(self.os.path.exists(directory)) def test_mkdir_with_with_symlink_parent(self): self.check_posix_only() dir_path = self.make_path("foo", "bar") self.create_dir(dir_path) link_path = self.make_path("foo", "link") self.os.symlink(dir_path, link_path) new_dir = self.os.path.join(link_path, "new_dir") self.os.mkdir(new_dir) self.assertTrue(self.os.path.exists(new_dir)) def test_makedirs(self): """makedirs can create a directory even if parent does not exist.""" parent = self.make_path("xyzzy") directory = self.os.path.join(parent, "foo") self.assertFalse(self.os.path.exists(parent)) self.os.makedirs(directory) self.assertTrue(self.os.path.exists(directory)) def check_makedirs_raises_if_parent_is_file(self, error_type): """makedirs raises exception if a parent component exists as a file.""" file_path = self.make_path("xyzzy") directory = self.os.path.join(file_path, "plugh") self.create_file(file_path) self.assertTrue(self.os.path.exists(file_path)) self.assert_raises_os_error(error_type, self.os.makedirs, directory) def test_makedirs_raises_if_parent_is_file_posix(self): self.check_posix_only() self.check_makedirs_raises_if_parent_is_file(errno.ENOTDIR) def test_makedirs_raises_if_parent_is_file_windows(self): self.check_windows_only() self.check_makedirs_raises_if_parent_is_file(errno.ENOENT) def test_makedirs_raises_if_parent_is_broken_link(self): self.check_posix_only() link_path = self.make_path("broken_link") self.os.symlink(self.make_path("bogus"), link_path) self.assert_raises_os_error( errno.ENOENT, self.os.makedirs, self.os.path.join(link_path, "newdir"), ) def test_makedirs_raises_if_parent_is_looping_link(self): self.skip_if_symlink_not_supported() link_path = self.make_path("link") link_target = self.os.path.join(link_path, "link") self.os.symlink(link_target, link_path) self.assert_raises_os_error(errno.EEXIST, self.os.makedirs, link_path) def test_makedirs_if_parent_is_symlink(self): self.check_posix_only() base_dir = self.make_path("foo", "bar") self.create_dir(base_dir) link_dir = self.os.path.join(base_dir, "linked") self.os.symlink(base_dir, link_dir) new_dir = self.os.path.join(link_dir, "f") self.os.makedirs(name=new_dir) self.assertTrue(self.os.path.exists(new_dir)) def test_makedirs_raises_if_access_denied(self): """makedirs raises exception if access denied.""" self.check_posix_only() directory = self.make_path("a") self.os.mkdir(directory) # Change directory permissions to be read only. self.os.chmod(directory, 0o400) directory = self.make_path("a", "b") if not is_root(): with self.assertRaises(OSError): self.os.makedirs(directory) else: self.os.makedirs(directory) self.assertTrue(self.os.path.exists(directory)) def test_makedirs_exist_ok(self): """makedirs uses the exist_ok argument""" directory = self.make_path("xyzzy", "foo") self.create_dir(directory) self.assertTrue(self.os.path.exists(directory)) self.assert_raises_os_error(errno.EEXIST, self.os.makedirs, directory) self.os.makedirs(directory, exist_ok=True) self.assertTrue(self.os.path.exists(directory)) def test_makedirs_in_write_protected_dir(self): self.check_posix_only() directory = self.make_path("foo") self.os.mkdir(directory, mode=0o555) subdir = self.os.path.join(directory, "bar") if not is_root(): self.assert_raises_os_error( errno.EACCES, self.os.makedirs, subdir, exist_ok=True ) self.assert_raises_os_error( errno.EACCES, self.os.makedirs, subdir, exist_ok=False ) else: self.os.makedirs(subdir) self.assertTrue(self.os.path.exists(subdir)) def test_makedirs_raises_on_empty_path(self): self.assert_raises_os_error(errno.ENOENT, self.os.makedirs, "", exist_ok=False) self.assert_raises_os_error(errno.ENOENT, self.os.makedirs, "", exist_ok=True) # test fsync and fdatasync def test_fsync_raises_on_non_int(self): with self.assertRaises(TypeError): self.os.fsync("zero") def test_fdatasync_raises_on_non_int(self): self.check_linux_only() self.assertRaises(TypeError, self.os.fdatasync, "zero") def test_fsync_raises_on_invalid_fd(self): self.assert_raises_os_error(errno.EBADF, self.os.fsync, 500) def test_fdatasync_raises_on_invalid_fd(self): # No open files yet self.check_linux_only() self.assert_raises_os_error(errno.EINVAL, self.os.fdatasync, 0) self.assert_raises_os_error(errno.EBADF, self.os.fdatasync, 500) def test_fsync_pass_posix(self): self.check_posix_only() test_file_path = self.make_path("test_file") self.create_file(test_file_path, contents="dummy file contents") with self.open(test_file_path, "r") as test_file: test_fd = test_file.fileno() # Test that this doesn't raise anything self.os.fsync(test_fd) # And just for sanity, double-check that this still raises self.assert_raises_os_error(errno.EBADF, self.os.fsync, test_fd + 500) def test_fsync_pass_windows(self): self.check_windows_only() test_file_path = self.make_path("test_file") self.create_file(test_file_path, contents="dummy file contents") with self.open(test_file_path, "r+") as test_file: test_fd = test_file.fileno() # Test that this doesn't raise anything self.os.fsync(test_fd) # And just for sanity, double-check that this still raises self.assert_raises_os_error(errno.EBADF, self.os.fsync, test_fd + 500) with self.open(test_file_path, "r") as test_file: test_fd = test_file.fileno() self.assert_raises_os_error(errno.EBADF, self.os.fsync, test_fd) def test_fdatasync_pass(self): # setup self.check_linux_only() test_file_path = self.make_path("test_file") self.create_file(test_file_path, contents="dummy file contents") test_file = self.open(test_file_path, "r") test_fd = test_file.fileno() # Test that this doesn't raise anything self.os.fdatasync(test_fd) # And just for sanity, double-check that this still raises self.assert_raises_os_error(errno.EBADF, self.os.fdatasync, test_fd + 500) def test_access700(self): # set up self.check_posix_only() path = self.make_path("some_file") self.createTestFile(path) self.os.chmod(path, 0o700) self.assert_mode_equal(0o700, self.os.stat(path).st_mode) # actual tests self.assertTrue(self.os.access(path, self.os.F_OK)) self.assertTrue(self.os.access(path, self.os.R_OK)) self.assertTrue(self.os.access(path, self.os.W_OK)) self.assertTrue(self.os.access(path, self.os.X_OK)) self.assertTrue(self.os.access(path, self.rwx)) def test_access600(self): # set up self.check_posix_only() path = self.make_path("some_file") self.createTestFile(path) self.os.chmod(path, 0o600) self.assert_mode_equal(0o600, self.os.stat(path).st_mode) # actual tests self.assertTrue(self.os.access(path, self.os.F_OK)) self.assertTrue(self.os.access(path, self.os.R_OK)) self.assertTrue(self.os.access(path, self.os.W_OK)) self.assertFalse(self.os.access(path, self.os.X_OK)) self.assertFalse(self.os.access(path, self.rwx)) self.assertTrue(self.os.access(path, self.rw)) def test_access400(self): # set up self.check_posix_only() path = self.make_path("some_file") self.createTestFile(path) self.os.chmod(path, 0o400) self.assert_mode_equal(0o400, self.os.stat(path).st_mode) # actual tests self.assertTrue(self.os.access(path, self.os.F_OK)) self.assertTrue(self.os.access(path, self.os.R_OK)) self.assertFalse(self.os.access(path, self.os.X_OK)) self.assertFalse(self.os.access(path, self.rwx)) if is_root(): self.assertTrue(self.os.access(path, self.os.W_OK)) self.assertTrue(self.os.access(path, self.rw)) else: self.assertFalse(self.os.access(path, self.os.W_OK)) self.assertFalse(self.os.access(path, self.rw)) def test_access_symlink(self): self.skip_if_symlink_not_supported() self.skip_real_fs() path = self.make_path("some_file") self.createTestFile(path) link_path = self.make_path("link_to_some_file") self.create_symlink(link_path, path) self.os.chmod(link_path, 0o400) # test file self.assertTrue(self.os.access(link_path, self.os.F_OK)) self.assertTrue(self.os.access(link_path, self.os.R_OK)) if is_root(): self.assertTrue(self.os.access(link_path, self.os.W_OK)) self.assertTrue(self.os.access(link_path, self.rw)) else: self.assertFalse(self.os.access(link_path, self.os.W_OK)) self.assertFalse(self.os.access(link_path, self.rw)) self.assertFalse(self.os.access(link_path, self.os.X_OK)) self.assertFalse(self.os.access(link_path, self.rwx)) # test link itself self.assertTrue(self.os.access(link_path, self.os.F_OK, follow_symlinks=False)) self.assertTrue(self.os.access(link_path, self.os.R_OK, follow_symlinks=False)) self.assertTrue(self.os.access(link_path, self.os.W_OK, follow_symlinks=False)) self.assertTrue(self.os.access(link_path, self.os.X_OK, follow_symlinks=False)) self.assertTrue(self.os.access(link_path, self.rwx, follow_symlinks=False)) self.assertTrue(self.os.access(link_path, self.rw, follow_symlinks=False)) def test_access_non_existent_file(self): # set up path = self.make_path("non", "existent", "file") self.assertFalse(self.os.path.exists(path)) # actual tests self.assertFalse(self.os.access(path, self.os.F_OK)) self.assertFalse(self.os.access(path, self.os.R_OK)) self.assertFalse(self.os.access(path, self.os.W_OK)) self.assertFalse(self.os.access(path, self.os.X_OK)) self.assertFalse(self.os.access(path, self.rwx)) self.assertFalse(self.os.access(path, self.rw)) def test_effective_ids_not_supported_under_windows(self): self.check_windows_only() path = self.make_path("foo", "bar") with self.assertRaises(NotImplementedError): self.os.access(path, self.os.F_OK, effective_ids=True) def test_chmod(self): # set up self.check_posix_only() self.skip_real_fs() path = self.make_path("some_file") self.createTestFile(path) # actual tests self.os.chmod(path, 0o6543) st = self.os.stat(path) self.assert_mode_equal(0o6543, st.st_mode) self.assertTrue(st.st_mode & stat.S_IFREG) self.assertFalse(st.st_mode & stat.S_IFDIR) def test_chmod_uses_open_fd_as_path(self): self.check_posix_only() self.skip_real_fs() self.assert_raises_os_error(errno.EBADF, self.os.chmod, 5, 0o6543) path = self.make_path("some_file") self.createTestFile(path) with self.open(path) as f: self.os.chmod(f.filedes, 0o6543) st = self.os.stat(path) self.assert_mode_equal(0o6543, st.st_mode) def test_chmod_follow_symlink(self): self.check_posix_only() path = self.make_path("some_file") self.createTestFile(path) link_path = self.make_path("link_to_some_file") self.create_symlink(link_path, path) self.os.chmod(link_path, 0o6543) st = self.os.stat(link_path) self.assert_mode_equal(0o6543, st.st_mode) st = self.os.stat(link_path, follow_symlinks=False) # the exact mode depends on OS and Python version self.assertEqual(stat.S_IMODE(0o700), stat.S_IMODE(st.st_mode) & 0o700) def test_chmod_no_follow_symlink(self): self.check_posix_only() path = self.make_path("some_file") self.createTestFile(path) link_path = self.make_path("link_to_some_file") self.create_symlink(link_path, path) if self.os.chmod not in self.os.supports_follow_symlinks or IS_PYPY: with self.assertRaises(NotImplementedError): self.os.chmod(link_path, 0o6543, follow_symlinks=False) else: self.os.chmod(link_path, 0o6543, follow_symlinks=False) st = self.os.stat(link_path) self.assert_mode_equal(0o666, st.st_mode) st = self.os.stat(link_path, follow_symlinks=False) self.assert_mode_equal(0o6543, st.st_mode) def test_lchmod(self): """lchmod shall behave like chmod with follow_symlinks=True.""" self.check_posix_only() self.skip_real_fs() path = self.make_path("some_file") self.createTestFile(path) link_path = self.make_path("link_to_some_file") self.create_symlink(link_path, path) self.os.lchmod(link_path, 0o6543) st = self.os.stat(link_path) self.assert_mode_equal(0o666, st.st_mode) st = self.os.lstat(link_path) self.assert_mode_equal(0o6543, st.st_mode) def test_chmod_dir(self): # set up self.check_posix_only() self.skip_real_fs() path = self.make_path("some_dir") self.createTestDirectory(path) # actual tests self.os.chmod(path, 0o1434) st = self.os.stat(path) self.assert_mode_equal(0o1434, st.st_mode) self.assertFalse(st.st_mode & stat.S_IFREG) self.assertTrue(st.st_mode & stat.S_IFDIR) def test_chmod_non_existent(self): # set up path = self.make_path("non", "existent", "file") self.assertFalse(self.os.path.exists(path)) # actual tests try: # Use try-catch to check exception attributes. self.os.chmod(path, 0o777) self.fail("Exception is expected.") # COV_NF_LINE except OSError as os_error: self.assertEqual(errno.ENOENT, os_error.errno) self.assertEqual(path, os_error.filename) def test_chown_existing_file(self): # set up self.skip_real_fs() file_path = self.make_path("some_file") self.create_file(file_path) # first set it make sure it's set self.os.chown(file_path, 100, 101) st = self.os.stat(file_path) self.assertEqual(st[stat.ST_UID], 100) self.assertEqual(st[stat.ST_GID], 101) # we can make sure it changed self.os.chown(file_path, 200, 201) st = self.os.stat(file_path) self.assertEqual(st[stat.ST_UID], 200) self.assertEqual(st[stat.ST_GID], 201) # setting a value to -1 leaves it unchanged self.os.chown(file_path, -1, -1) st = self.os.stat(file_path) self.assertEqual(st[stat.ST_UID], 200) self.assertEqual(st[stat.ST_GID], 201) def test_chown_uses_open_fd_as_path(self): self.check_posix_only() self.skip_real_fs() self.assert_raises_os_error(errno.EBADF, self.os.chown, 5, 100, 101) file_path = self.make_path("foo", "bar") self.create_file(file_path) with self.open(file_path) as f: self.os.chown(f.filedes, 100, 101) st = self.os.stat(file_path) self.assertEqual(st[stat.ST_UID], 100) def test_chown_follow_symlink(self): self.skip_real_fs() file_path = self.make_path("some_file") self.create_file(file_path) link_path = self.make_path("link_to_some_file") self.create_symlink(link_path, file_path) self.os.chown(link_path, 100, 101) st = self.os.stat(link_path) self.assertEqual(st[stat.ST_UID], 100) self.assertEqual(st[stat.ST_GID], 101) st = self.os.stat(link_path, follow_symlinks=False) self.assertNotEqual(st[stat.ST_UID], 100) self.assertNotEqual(st[stat.ST_GID], 101) def test_chown_no_follow_symlink(self): self.skip_real_fs() file_path = self.make_path("some_file") self.create_file(file_path) link_path = self.make_path("link_to_some_file") self.create_symlink(link_path, file_path) self.os.chown(link_path, 100, 101, follow_symlinks=False) st = self.os.stat(link_path) self.assertNotEqual(st[stat.ST_UID], 100) self.assertNotEqual(st[stat.ST_GID], 101) st = self.os.stat(link_path, follow_symlinks=False) self.assertEqual(st[stat.ST_UID], 100) self.assertEqual(st[stat.ST_GID], 101) def test_chown_bad_arguments(self): """os.chown() with bad args (Issue #30)""" self.check_posix_only() file_path = self.make_path("some_file") self.create_file(file_path) self.assertRaises(TypeError, self.os.chown, file_path, "username", -1) self.assertRaises(TypeError, self.os.chown, file_path, -1, "groupname") def test_chown_nonexisting_file_should_raise_os_error(self): self.check_posix_only() file_path = self.make_path("some_file") self.assertFalse(self.os.path.exists(file_path)) self.assert_raises_os_error(errno.ENOENT, self.os.chown, file_path, 100, 100) def test_classify_directory_contents(self): """Directory classification should work correctly.""" root_directory = self.make_path("foo") test_directories = ["bar1", "baz2"] test_files = ["baz1", "bar2", "baz3"] self.create_dir(root_directory) for directory in test_directories: directory = self.os.path.join(root_directory, directory) self.create_dir(directory) for test_file in test_files: test_file = self.os.path.join(root_directory, test_file) self.create_file(test_file) test_directories.sort() test_files.sort() generator = self.os.walk(root_directory) root, dirs, files = next(generator) dirs.sort() files.sort() self.assertEqual(root_directory, root) self.assertEqual(test_directories, dirs) self.assertEqual(test_files, files) # os.mknod does not work under MacOS due to permission issues # so we test it under Linux only def test_mk_nod_can_create_a_file(self): self.check_linux_only() filename = self.make_path("foo") self.assertFalse(self.os.path.exists(filename)) self.os.mknod(filename) self.assertTrue(self.os.path.exists(filename)) self.assertEqual(stat.S_IFREG | 0o600, self.os.stat(filename).st_mode) def test_mk_nod_raises_if_empty_file_name(self): self.check_linux_only() filename = "" self.assert_raises_os_error(errno.ENOENT, self.os.mknod, filename) def test_mk_nod_raises_if_parent_dir_doesnt_exist(self): self.check_linux_only() parent = self.make_path("xyzzy") filename = self.os.path.join(parent, "foo") self.assertFalse(self.os.path.exists(parent)) self.assert_raises_os_error(errno.ENOENT, self.os.mknod, filename) def test_mk_nod_raises_if_file_exists(self): self.check_linux_only() filename = self.make_path("tmp", "foo") self.create_file(filename) self.assertTrue(self.os.path.exists(filename)) self.assert_raises_os_error(errno.EEXIST, self.os.mknod, filename) def test_mk_nod_raises_if_filename_is_dot(self): self.check_linux_only() filename = self.make_path("tmp", ".") self.assert_raises_os_error(errno.ENOENT, self.os.mknod, filename) def test_mk_nod_raises_if_filename_is_double_dot(self): self.check_linux_only() filename = self.make_path("tmp", "..") self.assert_raises_os_error(errno.ENOENT, self.os.mknod, filename) def test_mknod_empty_tail_for_existing_file_raises(self): self.check_linux_only() filename = self.make_path("foo") self.create_file(filename) self.assertTrue(self.os.path.exists(filename)) self.assert_raises_os_error(errno.EEXIST, self.os.mknod, filename) def test_mknod_empty_tail_for_nonexistent_file_raises(self): self.check_linux_only() filename = self.make_path("tmp", "foo") self.assert_raises_os_error(errno.ENOENT, self.os.mknod, filename) def test_mknod_raises_if_filename_is_empty_string(self): self.check_linux_only() filename = "" self.assert_raises_os_error(errno.ENOENT, self.os.mknod, filename) def test_mknod_raises_if_unsupported_options(self): self.check_posix_only() # behavior seems to have changed in ubuntu-20.04, version 20210606.1 # skipping real fs tests for now self.skip_real_fs() filename = "abcde" if not is_root(): self.assert_raises_os_error( errno.EPERM, self.os.mknod, filename, stat.S_IFCHR ) else: self.os.mknod(filename, stat.S_IFCHR) self.os.remove(filename) def test_mknod_raises_if_parent_is_not_a_directory(self): self.check_linux_only() filename1 = self.make_path("foo") self.create_file(filename1) self.assertTrue(self.os.path.exists(filename1)) filename2 = self.make_path("foo", "bar") self.assert_raises_os_error(errno.ENOTDIR, self.os.mknod, filename2) def test_symlink(self): self.skip_if_symlink_not_supported() file_path = self.make_path("foo", "bar", "baz") self.create_dir(self.make_path("foo", "bar")) self.os.symlink("bogus", file_path) self.assertTrue(self.os.path.lexists(file_path)) self.assertFalse(self.os.path.exists(file_path)) self.create_file(self.make_path("foo", "bar", "bogus")) self.assertTrue(self.os.path.lexists(file_path)) self.assertTrue(self.os.path.exists(file_path)) def test_symlink_on_nonexisting_path_raises(self): self.check_posix_only() dir_path = self.make_path("bar") link_path = self.os.path.join(dir_path, "bar") self.assert_raises_os_error(errno.ENOENT, self.os.symlink, link_path, link_path) self.assert_raises_os_error(errno.ENOENT, self.os.symlink, dir_path, link_path) def test_symlink_with_path_ending_with_sep_in_posix(self): self.check_posix_only() dir_path = self.make_path("dir") self.create_dir(dir_path) self.assert_raises_os_error( errno.EEXIST, self.os.symlink, self.base_path, dir_path + self.os.sep, ) dir_path = self.make_path("bar") self.assert_raises_os_error( errno.ENOENT, self.os.symlink, self.base_path, dir_path + self.os.sep, ) def test_symlink_with_path_ending_with_sep_in_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() dir_path = self.make_path("dir") self.create_dir(dir_path) self.assert_raises_os_error( errno.EEXIST, self.os.symlink, self.base_path, dir_path + self.os.sep, ) dir_path = self.make_path("bar") # does not raise under Windows self.os.symlink(self.base_path, dir_path + self.os.sep) def test_broken_symlink_with_trailing_sep_posix(self): # Regression test for #390 self.check_linux_only() path0 = self.make_path("foo") + self.os.sep self.assert_raises_os_error(errno.ENOENT, self.os.symlink, path0, path0) def test_broken_symlink_with_trailing_sep_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() path0 = self.make_path("foo") + self.os.sep self.assert_raises_os_error(errno.EINVAL, self.os.symlink, path0, path0) def test_rename_symlink_with_trailing_sep_linux(self): # Regression test for #391 self.check_linux_only() path = self.make_path("foo") self.os.symlink(self.base_path, path) self.assert_raises_os_error( errno.ENOTDIR, self.os.rename, path + self.os.sep, self.base_path ) def test_rename_symlink_with_trailing_sep_macos(self): # Regression test for #391 self.check_macos_only() path = self.make_path("foo") self.os.symlink(self.base_path, path) self.os.rename(path + self.os.sep, self.base_path) def test_rename_symlink_with_trailing_sep_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() path = self.make_path("foo") self.os.symlink(self.base_path, path) self.assert_raises_os_error( errno.EEXIST, self.os.rename, path + self.os.sep, self.base_path ) def test_rename_symlink_to_other_case(self): # Regression test for #389 self.skip_if_symlink_not_supported() link_path = self.make_path("foo") self.os.symlink(self.base_path, link_path) link_to_link_path = self.make_path("BAR") self.os.symlink(link_path, link_to_link_path) new_link_to_link_path = self.os.path.join(link_path, "bar") self.os.rename(link_to_link_path, new_link_to_link_path) self.assertEqual(["bar", "foo"], sorted(self.os.listdir(new_link_to_link_path))) def create_broken_link_path_with_trailing_sep(self): # Regression tests for #396 self.skip_if_symlink_not_supported() link_path = self.make_path("link") target_path = self.make_path("target") self.os.symlink(target_path, link_path) link_path += self.os.sep return link_path def test_lstat_broken_link_with_trailing_sep_linux(self): self.check_linux_only() link_path = self.create_broken_link_path_with_trailing_sep() self.assert_raises_os_error(errno.ENOENT, self.os.lstat, link_path) def test_lstat_broken_link_with_trailing_sep_macos(self): self.check_macos_only() link_path = self.create_broken_link_path_with_trailing_sep() self.assert_raises_os_error(errno.ENOENT, self.os.lstat, link_path) def test_lstat_broken_link_with_trailing_sep_windows(self): self.check_windows_only() link_path = self.create_broken_link_path_with_trailing_sep() self.assert_raises_os_error(errno.EINVAL, self.os.lstat, link_path) def test_mkdir_broken_link_with_trailing_sep_linux_windows(self): self.check_linux_and_windows() link_path = self.create_broken_link_path_with_trailing_sep() self.assert_raises_os_error(errno.EEXIST, self.os.mkdir, link_path) self.assert_raises_os_error(errno.EEXIST, self.os.makedirs, link_path) def test_mkdir_broken_link_with_trailing_sep_macos(self): self.check_macos_only() link_path = self.create_broken_link_path_with_trailing_sep() self.os.mkdir(link_path) # no error def test_makedirs_broken_link_with_trailing_sep_macos(self): self.check_macos_only() link_path = self.create_broken_link_path_with_trailing_sep() self.os.makedirs(link_path) # no error def test_remove_broken_link_with_trailing_sep_linux(self): self.check_linux_only() link_path = self.create_broken_link_path_with_trailing_sep() self.assert_raises_os_error(errno.ENOTDIR, self.os.remove, link_path) def test_remove_broken_link_with_trailing_sep_macos(self): self.check_macos_only() link_path = self.create_broken_link_path_with_trailing_sep() self.assert_raises_os_error(errno.ENOENT, self.os.remove, link_path) def test_remove_broken_link_with_trailing_sep_windows(self): self.check_windows_only() link_path = self.create_broken_link_path_with_trailing_sep() self.assert_raises_os_error(errno.EINVAL, self.os.remove, link_path) def test_rename_broken_link_with_trailing_sep_linux(self): self.check_linux_only() link_path = self.create_broken_link_path_with_trailing_sep() self.assert_raises_os_error( errno.ENOTDIR, self.os.rename, link_path, self.make_path("target") ) def test_rename_broken_link_with_trailing_sep_macos(self): self.check_macos_only() link_path = self.create_broken_link_path_with_trailing_sep() self.assert_raises_os_error( errno.ENOENT, self.os.rename, link_path, self.make_path("target") ) def test_rename_broken_link_with_trailing_sep_windows(self): self.check_windows_only() link_path = self.create_broken_link_path_with_trailing_sep() self.assert_raises_os_error( errno.EINVAL, self.os.rename, link_path, self.make_path("target") ) def test_readlink_broken_link_with_trailing_sep_posix(self): self.check_posix_only() link_path = self.create_broken_link_path_with_trailing_sep() self.assert_raises_os_error(errno.ENOENT, self.os.readlink, link_path) def test_readlink_broken_link_with_trailing_sep_windows(self): self.check_windows_only() link_path = self.create_broken_link_path_with_trailing_sep() self.assert_raises_os_error(errno.EINVAL, self.os.readlink, link_path) def test_islink_broken_link_with_trailing_sep(self): link_path = self.create_broken_link_path_with_trailing_sep() self.assertFalse(self.os.path.islink(link_path)) def test_lexists_broken_link_with_trailing_sep(self): link_path = self.create_broken_link_path_with_trailing_sep() self.assertFalse(self.os.path.lexists(link_path)) def test_rename_link_with_trailing_sep_to_self_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() path = self.make_path("foo") self.os.symlink(self.base_path, path) self.os.rename(path + self.os.sep, path) # no error def test_rename_link_with_trailing_sep_to_self_posix(self): # Regression test for #395 self.check_posix_only() path = self.make_path("foo") self.os.symlink(self.base_path, path) self.assert_raises_os_error( errno.ENOTDIR, self.os.rename, path + self.os.sep, path ) def check_open_broken_symlink_to_path_with_trailing_sep(self, error): # Regression tests for #397 self.skip_if_symlink_not_supported() target_path = self.make_path("target") + self.os.sep link_path = self.make_path("link") self.os.symlink(target_path, link_path) self.assert_raises_os_error(error, self.open, link_path, "a") self.assert_raises_os_error(error, self.open, link_path, "w") def test_open_broken_symlink_to_path_with_trailing_sep_linux(self): self.check_linux_only() self.check_open_broken_symlink_to_path_with_trailing_sep(errno.EISDIR) def test_open_broken_symlink_to_path_with_trailing_sep_macos(self): self.check_macos_only() self.check_open_broken_symlink_to_path_with_trailing_sep(errno.ENOENT) def test_open_broken_symlink_to_path_with_trailing_sep_windows(self): self.check_windows_only() self.check_open_broken_symlink_to_path_with_trailing_sep(errno.EINVAL) def check_link_path_ending_with_sep(self, error): # Regression tests for #399 self.skip_if_symlink_not_supported() file_path = self.make_path("foo") link_path = self.make_path("link") with self.open(file_path, "w"): self.assert_raises_os_error( error, self.os.link, file_path + self.os.sep, link_path ) def test_link_path_ending_with_sep_posix(self): self.check_posix_only() self.check_link_path_ending_with_sep(errno.ENOTDIR) def test_link_path_ending_with_sep_windows(self): self.check_windows_only() self.check_link_path_ending_with_sep(errno.EINVAL) def test_link_to_path_ending_with_sep_posix(self): # regression test for #407 self.check_posix_only() path0 = self.make_path("foo") + self.os.sep path1 = self.make_path("bar") with self.open(path1, "w"): self.assert_raises_os_error(errno.ENOENT, self.os.link, path1, path0) def test_link_to_path_ending_with_sep_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() path0 = self.make_path("foo") + self.os.sep path1 = self.make_path("bar") with self.open(path1, "w"): self.os.link(path1, path0) self.assertTrue(self.os.path.exists(path1)) def check_rename_to_path_ending_with_sep(self, error): # Regression tests for #400 file_path = self.make_path("foo") with self.open(file_path, "w"): self.assert_raises_os_error( error, self.os.rename, file_path + self.os.sep, file_path ) def test_rename_to_path_ending_with_sep_posix(self): self.check_posix_only() self.check_rename_to_path_ending_with_sep(errno.ENOTDIR) def test_rename_to_path_ending_with_sep_windows(self): self.check_windows_only() self.check_rename_to_path_ending_with_sep(errno.EINVAL) def test_rmdir_link_with_trailing_sep_linux(self): self.check_linux_only() dir_path = self.make_path("foo") self.os.mkdir(dir_path) link_path = self.make_path("link") self.os.symlink(dir_path, link_path) self.assert_raises_os_error( errno.ENOTDIR, self.os.rmdir, link_path + self.os.sep ) def test_rmdir_link_with_trailing_sep_macos(self): # Regression test for #398 self.check_macos_only() dir_path = self.make_path("foo") self.os.mkdir(dir_path) link_path = self.make_path("link") self.os.symlink(dir_path, link_path) self.os.rmdir(link_path + self.os.sep) self.assertFalse(self.os.path.exists(link_path)) def test_rmdir_link_with_trailing_sep_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() dir_path = self.make_path("foo") self.os.mkdir(dir_path) link_path = self.make_path("link") self.os.symlink(dir_path, link_path) self.os.rmdir(link_path + self.os.sep) self.assertFalse(self.os.path.exists(link_path)) def test_readlink_circular_link_with_trailing_sep_linux(self): self.check_linux_only() path1 = self.make_path("foo") path0 = self.make_path("bar") self.os.symlink(path0, path1) self.os.symlink(path1, path0) self.assert_raises_os_error(errno.ELOOP, self.os.readlink, path0 + self.os.sep) def test_readlink_circular_link_with_trailing_sep_macos(self): # Regression test for #392 self.check_macos_only() path1 = self.make_path("foo") path0 = self.make_path("bar") self.os.symlink(path0, path1) self.os.symlink(path1, path0) self.assertEqual(path0, self.os.readlink(path0 + self.os.sep)) def test_readlink_circular_link_with_trailing_sep_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() path1 = self.make_path("foo") path0 = self.make_path("bar") self.os.symlink(path0, path1) self.os.symlink(path1, path0) self.assert_raises_os_error(errno.EINVAL, self.os.readlink, path0 + self.os.sep) # hard link related tests def test_link_bogus(self): # trying to create a link from a non-existent file should fail self.skip_if_symlink_not_supported() self.assert_raises_os_error( errno.ENOENT, self.os.link, "/nonexistent_source", "/link_dest" ) def test_link_delete(self): self.skip_if_symlink_not_supported() file1_path = self.make_path("test_file1") file2_path = self.make_path("test_file2") contents1 = "abcdef" # Create file self.create_file(file1_path, contents=contents1) # link to second file self.os.link(file1_path, file2_path) # delete first file self.os.unlink(file1_path) # assert that second file exists, and its contents are the same self.assertTrue(self.os.path.exists(file2_path)) with self.open(file2_path) as f: self.assertEqual(f.read(), contents1) def test_link_update(self): self.skip_if_symlink_not_supported() file1_path = self.make_path("test_file1") file2_path = self.make_path("test_file2") contents1 = "abcdef" contents2 = "ghijkl" # Create file and link self.create_file(file1_path, contents=contents1) self.os.link(file1_path, file2_path) # assert that the second file contains contents1 with self.open(file2_path) as f: self.assertEqual(f.read(), contents1) # update the first file with self.open(file1_path, "w") as f: f.write(contents2) # assert that second file contains contents2 with self.open(file2_path) as f: self.assertEqual(f.read(), contents2) def test_link_non_existent_parent(self): self.skip_if_symlink_not_supported() file1_path = self.make_path("test_file1") breaking_link_path = self.make_path("nonexistent", "test_file2") contents1 = "abcdef" # Create file and link self.create_file(file1_path, contents=contents1) # trying to create a link under a non-existent directory should fail self.assert_raises_os_error( errno.ENOENT, self.os.link, file1_path, breaking_link_path ) def test_link_is_existing_file(self): self.skip_if_symlink_not_supported() file_path = self.make_path("foo", "bar") self.create_file(file_path) self.assert_raises_os_error(errno.EEXIST, self.os.link, file_path, file_path) def test_link_target_is_dir_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() dir_path = self.make_path("foo", "bar") link_path = self.os.path.join(dir_path, "link") self.create_dir(dir_path) self.assert_raises_os_error(errno.EACCES, self.os.link, dir_path, link_path) def test_link_target_is_dir_posix(self): self.check_posix_only() dir_path = self.make_path("foo", "bar") link_path = self.os.path.join(dir_path, "link") self.create_dir(dir_path) self.assert_raises_os_error(errno.EPERM, self.os.link, dir_path, link_path) def test_link_count1(self): """Test that hard link counts are updated correctly.""" self.skip_if_symlink_not_supported() file1_path = self.make_path("test_file1") file2_path = self.make_path("test_file2") file3_path = self.make_path("test_file3") self.create_file(file1_path) # initial link count should be one self.assertEqual(self.os.stat(file1_path).st_nlink, 1) self.os.link(file1_path, file2_path) # the count should be incremented for each hard link created self.assertEqual(self.os.stat(file1_path).st_nlink, 2) self.assertEqual(self.os.stat(file2_path).st_nlink, 2) # Check that the counts are all updated together self.os.link(file2_path, file3_path) self.assertEqual(self.os.stat(file1_path).st_nlink, 3) self.assertEqual(self.os.stat(file2_path).st_nlink, 3) self.assertEqual(self.os.stat(file3_path).st_nlink, 3) # Counts should be decremented when links are removed self.os.unlink(file3_path) self.assertEqual(self.os.stat(file1_path).st_nlink, 2) self.assertEqual(self.os.stat(file2_path).st_nlink, 2) # check that it gets decremented correctly again self.os.unlink(file1_path) self.assertEqual(self.os.stat(file2_path).st_nlink, 1) def test_nlink_for_directories(self): self.skip_real_fs() self.create_dir(self.make_path("foo", "bar")) self.create_file(self.make_path("foo", "baz")) self.assertEqual( 2, self.filesystem.get_object(self.make_path("foo", "bar")).st_nlink, ) self.assertEqual(4, self.filesystem.get_object(self.make_path("foo")).st_nlink) self.create_file(self.make_path("foo", "baz2")) self.assertEqual(5, self.filesystem.get_object(self.make_path("foo")).st_nlink) def test_umask(self): self.check_posix_only() umask = os.umask(0o22) os.umask(umask) self.assertEqual(umask, self.os.umask(0o22)) def test_mkdir_umask_applied(self): """mkdir creates a directory with umask applied.""" self.check_posix_only() self.os.umask(0o22) dir1 = self.make_path("dir1") self.os.mkdir(dir1) self.assert_mode_equal(0o755, self.os.stat(dir1).st_mode) self.os.umask(0o67) dir2 = self.make_path("dir2") self.os.mkdir(dir2) self.assert_mode_equal(0o710, self.os.stat(dir2).st_mode) def test_makedirs_umask_applied(self): """makedirs creates a directories with umask applied.""" self.check_posix_only() self.os.umask(0o22) self.os.makedirs(self.make_path("p1", "dir1")) self.assert_mode_equal(0o755, self.os.stat(self.make_path("p1")).st_mode) self.assert_mode_equal( 0o755, self.os.stat(self.make_path("p1", "dir1")).st_mode ) self.os.umask(0o67) self.os.makedirs(self.make_path("p2", "dir2")) self.assert_mode_equal(0o710, self.os.stat(self.make_path("p2")).st_mode) self.assert_mode_equal( 0o710, self.os.stat(self.make_path("p2", "dir2")).st_mode ) def test_mknod_umask_applied(self): """mkdir creates a device with umask applied.""" # skipping MacOs due to mknod permission issues self.check_linux_only() self.os.umask(0o22) node1 = self.make_path("nod1") self.os.mknod(node1, stat.S_IFREG | 0o666) self.assert_mode_equal(0o644, self.os.stat(node1).st_mode) self.os.umask(0o27) node2 = self.make_path("nod2") self.os.mknod(node2, stat.S_IFREG | 0o666) self.assert_mode_equal(0o640, self.os.stat(node2).st_mode) def test_open_umask_applied(self): """open creates a file with umask applied.""" self.check_posix_only() self.os.umask(0o22) file1 = self.make_path("file1") self.open(file1, "w").close() self.assert_mode_equal(0o644, self.os.stat(file1).st_mode) self.os.umask(0o27) file2 = self.make_path("file2") self.open(file2, "w").close() self.assert_mode_equal(0o640, self.os.stat(file2).st_mode) def test_open_pipe(self): read_fd, write_fd = self.os.pipe() self.os.close(read_fd) self.os.close(write_fd) def test_open_pipe_with_existing_fd(self): file1 = self.make_path("file1") fd = self.os.open(file1, os.O_CREAT) read_fd, write_fd = self.os.pipe() self.assertGreater(read_fd, fd) self.os.close(fd) self.os.close(read_fd) self.os.close(write_fd) def test_open_file_with_existing_pipe(self): read_fd, write_fd = self.os.pipe() file1 = self.make_path("file1") fd = self.os.open(file1, os.O_CREAT) self.assertGreater(fd, write_fd) self.os.close(read_fd) self.os.close(write_fd) self.os.close(fd) def test_read_write_pipe(self): read_fd, write_fd = self.os.pipe() self.assertEqual(4, self.os.write(write_fd, b"test")) self.assertEqual(b"test", self.os.read(read_fd, 4)) self.os.close(read_fd) self.os.close(write_fd) def test_open_existing_pipe(self): # create some regular files to ensure that real and fake fd # are out of sync (see #581) fds = [] for i in range(5): path = self.make_path("file" + str(i)) fds.append(self.os.open(path, os.O_CREAT)) file_path = self.make_path("file.txt") self.create_file(file_path) with self.open(file_path): read_fd, write_fd = self.os.pipe() with self.open(write_fd, "wb") as f: self.assertEqual(4, f.write(b"test")) with self.open(read_fd, "rb") as f: self.assertEqual(b"test", f.read()) for fd in fds: self.os.close(fd) def test_write_to_pipe(self): read_fd, write_fd = self.os.pipe() self.os.write(write_fd, b"test") self.assertEqual(b"test", self.os.read(read_fd, 4)) self.os.close(read_fd) self.os.close(write_fd) @unittest.skipIf( sys.platform not in ("win32", "darwin", "linux"), "Pipe implementation may differ on other platforms", ) def test_write_to_read_fd(self): read_fd, write_fd = self.os.pipe() self.assert_raises_os_error(errno.EBADF, self.os.write, read_fd, b"test") self.os.close(read_fd) self.os.close(write_fd) def test_truncate(self): file_path = self.make_path("foo", "bar") self.create_file(file_path, contents="012345678901234567") self.os.truncate(file_path, 10) with self.open(file_path) as f: self.assertEqual("0123456789", f.read()) def test_truncate_non_existing(self): self.assert_raises_os_error(errno.ENOENT, self.os.truncate, "foo", 10) def test_truncate_to_larger(self): file_path = self.make_path("foo", "bar") self.create_file(file_path, contents="0123456789") fd = self.os.open(file_path, os.O_RDWR) self.os.truncate(fd, 20) self.assertEqual(20, self.os.stat(file_path).st_size) with self.open(file_path) as f: self.assertEqual("0123456789" + "\0" * 10, f.read()) def test_truncate_with_fd(self): if os.truncate not in os.supports_fd: self.skip_real_fs() self.assert_raises_os_error(errno.EBADF, self.os.ftruncate, 50, 10) file_path = self.make_path("some_file") self.create_file(file_path, contents="01234567890123456789") fd = self.os.open(file_path, os.O_RDWR) self.os.truncate(fd, 10) self.assertEqual(10, self.os.stat(file_path).st_size) with self.open(file_path) as f: self.assertEqual("0123456789", f.read()) def test_ftruncate(self): if self.is_pypy: # not correctly supported self.skip_real_fs() self.assert_raises_os_error(errno.EBADF, self.os.ftruncate, 50, 10) file_path = self.make_path("some_file") self.create_file(file_path, contents="0123456789012345") fd = self.os.open(file_path, os.O_RDWR) self.os.truncate(fd, 10) self.assertEqual(10, self.os.stat(file_path).st_size) with self.open(file_path) as f: self.assertEqual("0123456789", f.read()) def test_capabilities(self): """Make sure that the fake capabilities are the same as the real ones.""" self.assertEqual( self.os.stat in self.os.supports_follow_symlinks, os.stat in os.supports_follow_symlinks, ) self.assertEqual(self.os.stat in self.os.supports_fd, os.stat in os.supports_fd) self.assertEqual( self.os.stat in self.os.supports_dir_fd, os.stat in os.supports_dir_fd ) self.assertEqual( self.os.stat in self.os.supports_effective_ids, os.stat in os.supports_effective_ids, ) class RealOsModuleTest(FakeOsModuleTest): def use_real_fs(self): return True class FakeOsModuleTestCaseInsensitiveFS(FakeOsModuleTestBase): def setUp(self): super(FakeOsModuleTestCaseInsensitiveFS, self).setUp() self.check_case_insensitive_fs() self.rwx = self.os.R_OK | self.os.W_OK | self.os.X_OK self.rw = self.os.R_OK | self.os.W_OK def test_chdir_fails_non_directory(self): """chdir should raise OSError if the target is not a directory.""" filename = self.make_path("foo", "bar") self.create_file(filename) filename1 = self.make_path("Foo", "Bar") self.assert_raises_os_error(errno.ENOTDIR, self.os.chdir, filename1) def test_listdir_returns_list(self): directory_root = self.make_path("xyzzy") self.os.mkdir(directory_root) directory = self.os.path.join(directory_root, "bug") self.os.mkdir(directory) directory_upper = self.make_path("XYZZY", "BUG") self.create_file(self.make_path(directory, "foo")) self.assertEqual(["foo"], self.os.listdir(directory_upper)) def test_listdir_on_symlink(self): self.skip_if_symlink_not_supported() directory = self.make_path("xyzzy") files = ["foo", "bar", "baz"] for f in files: self.create_file(self.make_path(directory, f)) self.create_symlink(self.make_path("symlink"), self.make_path("xyzzy")) files.sort() self.assertEqual(files, sorted(self.os.listdir(self.make_path("SymLink")))) def test_fdopen_mode(self): self.skip_real_fs() file_path1 = self.make_path("some_file1") file_path2 = self.make_path("Some_File1") file_path3 = self.make_path("SOME_file1") self.create_file(file_path1, contents="contents here1") self.os.chmod(file_path2, (stat.S_IFREG | 0o666) ^ stat.S_IWRITE) fake_file1 = self.open(file_path3, "r") fileno1 = fake_file1.fileno() self.os.fdopen(fileno1) self.os.fdopen(fileno1, "r") if not is_root(): self.assertRaises(OSError, self.os.fdopen, fileno1, "w") else: self.os.fdopen(fileno1, "w") def test_stat(self): directory = self.make_path("xyzzy") directory1 = self.make_path("XYZZY") file_path = self.os.path.join(directory, "plugh") self.create_file(file_path, contents="ABCDE") self.assertTrue(stat.S_IFDIR & self.os.stat(directory1)[stat.ST_MODE]) file_path1 = self.os.path.join(directory1, "Plugh") self.assertTrue(stat.S_IFREG & self.os.stat(file_path1)[stat.ST_MODE]) self.assertTrue(stat.S_IFREG & self.os.stat(file_path1).st_mode) self.assertEqual(5, self.os.stat(file_path1)[stat.ST_SIZE]) def test_stat_no_follow_symlinks_posix(self): """Test that stat with follow_symlinks=False behaves like lstat.""" self.check_posix_only() directory = self.make_path("xyzzy") base_name = "plugh" file_contents = "frobozz" # Just make sure we didn't accidentally make our test data meaningless. self.assertNotEqual(len(base_name), len(file_contents)) file_path = self.os.path.join(directory, base_name) link_path = self.os.path.join(directory, "link") self.create_file(file_path, contents=file_contents) self.create_symlink(link_path, base_name) self.assertEqual( len(file_contents), self.os.stat(file_path.upper(), follow_symlinks=False)[stat.ST_SIZE], ) self.assertEqual( len(base_name), self.os.stat(link_path.upper(), follow_symlinks=False)[stat.ST_SIZE], ) def test_lstat_posix(self): self.check_posix_only() directory = self.make_path("xyzzy") base_name = "plugh" file_contents = "frobozz" # Just make sure we didn't accidentally make our test data meaningless. self.assertNotEqual(len(base_name), len(file_contents)) file_path = self.os.path.join(directory, base_name) link_path = self.os.path.join(directory, "link") self.create_file(file_path, contents=file_contents) self.create_symlink(link_path, base_name) self.assertEqual( len(file_contents), self.os.lstat(file_path.upper())[stat.ST_SIZE] ) self.assertEqual(len(base_name), self.os.lstat(link_path.upper())[stat.ST_SIZE]) def test_readlink(self): self.skip_if_symlink_not_supported() link_path = self.make_path("foo", "bar", "baz") target = self.make_path("tarJAY") self.create_symlink(link_path, target) self.assert_equal_paths(self.os.readlink(link_path.upper()), target) def check_readlink_raises_if_path_not_a_link(self): file_path = self.make_path("foo", "bar", "eleventyone") self.create_file(file_path) self.assert_raises_os_error(errno.EINVAL, self.os.readlink, file_path.upper()) def test_readlink_raises_if_path_not_a_link_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() self.check_readlink_raises_if_path_not_a_link() def test_readlink_raises_if_path_not_a_link_posix(self): self.check_posix_only() self.check_readlink_raises_if_path_not_a_link() def check_readlink_raises_if_path_has_file(self, error_subtype): self.create_file(self.make_path("a_file")) file_path = self.make_path("a_file", "foo") self.assert_raises_os_error(error_subtype, self.os.readlink, file_path.upper()) file_path = self.make_path("a_file", "foo", "bar") self.assert_raises_os_error(error_subtype, self.os.readlink, file_path.upper()) def test_readlink_raises_if_path_has_file_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() self.check_readlink_raises_if_path_has_file(errno.ENOENT) def test_readlink_raises_if_path_has_file_posix(self): self.check_posix_only() self.check_readlink_raises_if_path_has_file(errno.ENOTDIR) def test_readlink_with_links_in_path(self): self.skip_if_symlink_not_supported() self.create_symlink( self.make_path("meyer", "lemon", "pie"), self.make_path("yum") ) self.create_symlink(self.make_path("geo", "metro"), self.make_path("Meyer")) self.assert_equal_paths( self.make_path("yum"), self.os.readlink(self.make_path("Geo", "Metro", "Lemon", "Pie")), ) def test_readlink_with_chained_links_in_path(self): self.skip_if_symlink_not_supported() self.create_symlink( self.make_path("eastern", "european", "wolfhounds", "chase"), self.make_path("cats"), ) self.create_symlink( self.make_path("russian"), self.make_path("Eastern", "European") ) self.create_symlink( self.make_path("dogs"), self.make_path("Russian", "Wolfhounds") ) self.assert_equal_paths( self.make_path("cats"), self.os.readlink(self.make_path("DOGS", "Chase")), ) def check_remove_dir(self, dir_error): directory = self.make_path("xyzzy") dir_path = self.os.path.join(directory, "plugh") self.create_dir(dir_path) dir_path = dir_path.upper() self.assertTrue(self.os.path.exists(dir_path.upper())) self.assert_raises_os_error(dir_error, self.os.remove, dir_path) self.assertTrue(self.os.path.exists(dir_path)) self.os.chdir(directory) self.assert_raises_os_error(dir_error, self.os.remove, dir_path) self.assertTrue(self.os.path.exists(dir_path)) self.assert_raises_os_error(errno.ENOENT, self.os.remove, "/Plugh") def test_remove_dir_mac_os(self): self.check_macos_only() self.check_remove_dir(errno.EPERM) def test_remove_dir_windows(self): self.check_windows_only() self.check_remove_dir(errno.EACCES) def test_remove_file(self): directory = self.make_path("zzy") file_path = self.os.path.join(directory, "plugh") self.create_file(file_path) self.assertTrue(self.os.path.exists(file_path.upper())) self.os.remove(file_path.upper()) self.assertFalse(self.os.path.exists(file_path)) def test_remove_file_no_directory(self): directory = self.make_path("zzy") file_name = "plugh" file_path = self.os.path.join(directory, file_name) self.create_file(file_path) self.assertTrue(self.os.path.exists(file_path)) self.os.chdir(directory.upper()) self.os.remove(file_name.upper()) self.assertFalse(self.os.path.exists(file_path)) def test_remove_open_file_fails_under_windows(self): self.check_windows_only() path = self.make_path("foo", "bar") self.create_file(path) with self.open(path, "r"): self.assert_raises_os_error(errno.EACCES, self.os.remove, path.upper()) self.assertTrue(self.os.path.exists(path)) def test_remove_open_file_possible_under_posix(self): self.check_posix_only() path = self.make_path("foo", "bar") self.create_file(path) self.open(path, "r") self.os.remove(path.upper()) self.assertFalse(self.os.path.exists(path)) def test_remove_file_relative_path(self): self.skip_real_fs() original_dir = self.os.getcwd() directory = self.make_path("zzy") subdirectory = self.os.path.join(directory, "zzy") file_name = "plugh" file_path = self.os.path.join(directory, file_name) file_path_relative = self.os.path.join("..", file_name) self.create_file(file_path.upper()) self.assertTrue(self.os.path.exists(file_path)) self.create_dir(subdirectory) self.assertTrue(self.os.path.exists(subdirectory)) self.os.chdir(subdirectory.upper()) self.os.remove(file_path_relative.upper()) self.assertFalse(self.os.path.exists(file_path_relative)) self.os.chdir(original_dir.upper()) self.assertFalse(self.os.path.exists(file_path)) def check_remove_dir_raises_error(self, dir_error): directory = self.make_path("zzy") self.create_dir(directory) self.assert_raises_os_error(dir_error, self.os.remove, directory.upper()) def test_remove_dir_raises_error_mac_os(self): self.check_macos_only() self.check_remove_dir_raises_error(errno.EPERM) def test_remove_dir_raises_error_windows(self): self.check_windows_only() self.check_remove_dir_raises_error(errno.EACCES) def test_remove_symlink_to_dir(self): self.skip_if_symlink_not_supported() directory = self.make_path("zzy") link = self.make_path("link_to_dir") self.create_dir(directory) self.os.symlink(directory, link) self.assertTrue(self.os.path.exists(directory)) self.assertTrue(self.os.path.exists(link)) self.os.remove(link.upper()) self.assertTrue(self.os.path.exists(directory)) self.assertFalse(self.os.path.exists(link)) def test_rename_dir_to_symlink_posix(self): self.check_posix_only() link_path = self.make_path("link") dir_path = self.make_path("dir") link_target = self.os.path.join(dir_path, "link_target") self.create_dir(dir_path) self.os.symlink(link_target.upper(), link_path.upper()) self.assert_raises_os_error(errno.ENOTDIR, self.os.rename, dir_path, link_path) def test_rename_dir_to_symlink_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() link_path = self.make_path("link") dir_path = self.make_path("dir") link_target = self.os.path.join(dir_path, "link_target") self.create_dir(dir_path) self.os.symlink(link_target.upper(), link_path.upper()) self.assert_raises_os_error(errno.EEXIST, self.os.rename, dir_path, link_path) def test_rename_dir_to_existing_dir(self): # Regression test for #317 self.check_posix_only() dest_dir_path = self.make_path("Dest") # seems to behave differently under different MacOS versions self.skip_real_fs() new_dest_dir_path = self.make_path("dest") self.os.mkdir(dest_dir_path) source_dir_path = self.make_path("src") self.os.mkdir(source_dir_path) self.os.rename(source_dir_path, new_dest_dir_path) self.assertEqual(["dest"], self.os.listdir(self.base_path)) def test_rename_file_to_symlink(self): self.check_posix_only() link_path = self.make_path("file_link") file_path = self.make_path("file") self.os.symlink(file_path, link_path) self.create_file(file_path) self.os.rename(file_path.upper(), link_path) self.assertFalse(self.os.path.exists(file_path)) self.assertTrue(self.os.path.exists(link_path.upper())) self.assertTrue(self.os.path.isfile(link_path.upper())) def test_rename_symlink_to_symlink(self): self.check_posix_only() base_path = self.make_path("foo", "bar") self.create_dir(base_path) link_path1 = self.os.path.join(base_path, "link1") link_path2 = self.os.path.join(base_path, "link2") self.os.symlink(base_path.upper(), link_path1) self.os.symlink(base_path, link_path2) self.os.rename(link_path1.upper(), link_path2.upper()) self.assertFalse(self.os.path.exists(link_path1)) self.assertTrue(self.os.path.exists(link_path2)) def test_rename_symlink_to_symlink_for_parent_raises(self): self.check_posix_only() dir_link = self.make_path("dir_link") dir_path = self.make_path("dir") dir_in_dir_path = self.os.path.join(dir_link, "inner_dir") self.create_dir(dir_path) self.os.symlink(dir_path.upper(), dir_link) self.create_dir(dir_in_dir_path) self.assert_raises_os_error( errno.EINVAL, self.os.rename, dir_path, dir_in_dir_path.upper() ) def test_rename_directory_to_linked_dir(self): # Regression test for #314 self.skip_if_symlink_not_supported() link_path = self.make_path("link") self.os.symlink(self.base_path, link_path) link_subdir = self.os.path.join(link_path, "dir") dir_path = self.make_path("Dir") self.os.mkdir(dir_path) self.os.rename(dir_path, link_subdir) self.assertEqual(["dir", "link"], sorted(self.os.listdir(self.base_path))) def test_recursive_rename_raises(self): self.check_posix_only() base_path = self.make_path("foo", "bar") self.create_dir(base_path) new_path = self.os.path.join(base_path, "new_dir") self.assert_raises_os_error( errno.EINVAL, self.os.rename, base_path.upper(), new_path ) def test_rename_with_target_parent_file_raises_posix(self): self.check_posix_only() file_path = self.make_path("foo", "baz") self.create_file(file_path) self.assert_raises_os_error( errno.ENOTDIR, self.os.rename, file_path, file_path.upper() + "/new", ) def test_rename_with_target_parent_file_raises_windows(self): self.check_windows_only() file_path = self.make_path("foo", "baz") self.create_file(file_path) self.assert_raises_os_error( errno.EACCES, self.os.rename, file_path, self.os.path.join(file_path.upper(), "new"), ) def test_rename_looping_symlink(self): # Regression test for #315 self.skip_if_symlink_not_supported() path_lower = self.make_path("baz") path_upper = self.make_path("BAZ") self.os.symlink(path_lower, path_upper) self.os.rename(path_upper, path_lower) self.assertEqual(["baz"], self.os.listdir(self.base_path)) def test_rename_symlink_to_source(self): self.check_posix_only() base_path = self.make_path("foo") link_path = self.os.path.join(base_path, "slink") file_path = self.os.path.join(base_path, "file") self.create_file(file_path) self.os.symlink(file_path, link_path) self.os.rename(link_path.upper(), file_path.upper()) self.assertFalse(self.os.path.exists(file_path)) def test_rename_symlink_to_dir_raises(self): self.check_posix_only() base_path = self.make_path("foo", "bar") link_path = self.os.path.join(base_path, "dir_link") dir_path = self.os.path.join(base_path, "dir") self.create_dir(dir_path) self.os.symlink(dir_path, link_path.upper()) self.assert_raises_os_error( errno.EISDIR, self.os.rename, link_path, dir_path.upper() ) def test_rename_broken_symlink(self): self.check_posix_only() base_path = self.make_path("foo") self.create_dir(base_path) link_path = self.os.path.join(base_path, "slink") file_path = self.os.path.join(base_path, "file") self.os.symlink(file_path.upper(), link_path) self.os.rename(link_path.upper(), file_path) self.assertFalse(self.os.path.exists(file_path)) self.assertTrue(self.os.path.lexists(file_path)) self.assertFalse(self.os.path.exists(link_path)) def test_change_case_in_case_insensitive_file_system(self): """Can use `rename()` to change filename case in a case-insensitive file system.""" old_file_path = self.make_path("fileName") new_file_path = self.make_path("FileNAME") self.create_file(old_file_path, contents="test contents") self.assertEqual(["fileName"], self.os.listdir(self.base_path)) self.os.rename(old_file_path, new_file_path) self.assertTrue(self.os.path.exists(old_file_path)) self.assertTrue(self.os.path.exists(new_file_path)) self.assertEqual(["FileNAME"], self.os.listdir(self.base_path)) def test_rename_symlink_with_changed_case(self): # Regression test for #313 self.skip_if_symlink_not_supported() link_path = self.make_path("link") self.os.symlink(self.base_path, link_path) link_path = self.os.path.join(link_path, "link") link_path_upper = self.make_path("link", "LINK") self.os.rename(link_path_upper, link_path) def test_rename_directory(self): """Can rename a directory to an unused name.""" for old_path, new_path in [("wxyyw", "xyzzy"), ("abccb", "cdeed")]: old_path = self.make_path(old_path) new_path = self.make_path(new_path) self.create_file(self.os.path.join(old_path, "plugh"), contents="test") self.assertTrue(self.os.path.exists(old_path)) self.assertFalse(self.os.path.exists(new_path)) self.os.rename(old_path.upper(), new_path.upper()) self.assertFalse(self.os.path.exists(old_path)) self.assertTrue(self.os.path.exists(new_path)) self.check_contents(self.os.path.join(new_path, "plugh"), "test") if not self.use_real_fs(): self.assertEqual(3, self.filesystem.get_object(new_path).st_nlink) def check_rename_directory_to_existing_file_raises(self, error_nr): dir_path = self.make_path("dir") file_path = self.make_path("file") self.create_dir(dir_path) self.create_file(file_path) self.assert_raises_os_error( error_nr, self.os.rename, dir_path, file_path.upper() ) def test_rename_directory_to_existing_file_raises_posix(self): self.check_posix_only() self.check_rename_directory_to_existing_file_raises(errno.ENOTDIR) def test_rename_directory_to_existing_file_raises_windows(self): self.check_windows_only() self.check_rename_directory_to_existing_file_raises(errno.EEXIST) def test_rename_to_existing_directory_should_raise_under_windows(self): """Renaming to an existing directory raises OSError under Windows.""" self.check_windows_only() old_path = self.make_path("foo", "bar") new_path = self.make_path("foo", "baz") self.create_dir(old_path) self.create_dir(new_path) self.assert_raises_os_error( errno.EEXIST, self.os.rename, old_path.upper(), new_path.upper() ) def test_rename_to_a_hardlink_of_same_file_should_do_nothing(self): self.skip_real_fs_failure(skip_posix=False) self.skip_if_symlink_not_supported() file_path = self.make_path("dir", "file") self.create_file(file_path) link_path = self.make_path("link") self.os.link(file_path.upper(), link_path) self.os.rename(file_path, link_path.upper()) self.assertTrue(self.os.path.exists(file_path)) self.assertTrue(self.os.path.exists(link_path)) def test_rename_with_incorrect_source_case(self): # Regression test for #308 base_path = self.make_path("foo") path0 = self.os.path.join(base_path, "bar") path1 = self.os.path.join(base_path, "Bar") self.create_dir(path0) self.os.rename(path1, path0) self.assertTrue(self.os.path.exists(path0)) def test_rename_symlink_to_other_case_does_nothing_in_mac_os(self): # Regression test for #318 self.check_macos_only() path0 = self.make_path("beta") self.os.symlink(self.base_path, path0) path0 = self.make_path("beta", "Beta") path1 = self.make_path("Beta") self.os.rename(path0, path1) self.assertEqual(["beta"], sorted(self.os.listdir(path0))) def test_rename_symlink_to_other_case_works_in_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() path0 = self.make_path("beta") self.os.symlink(self.base_path, path0) path0 = self.make_path("beta", "Beta") path1 = self.make_path("Beta") self.os.rename(path0, path1) self.assertEqual(["Beta"], sorted(self.os.listdir(path0))) def test_renames_creates_missing_dirs(self): old_path = self.make_path("foo.txt") self.create_file(old_path) new_path = self.make_path("new", "dir", "bar.txt") self.os.renames(old_path, new_path) self.assertTrue(self.os.path.exists(new_path)) self.assertFalse(self.os.path.exists(old_path)) def test_renames_removes_empty_dirs(self): old_base_path = self.make_path("old") old_path = self.make_path("old", "dir1", "dir2", "foo.txt") other_file = self.os.path.join(old_base_path, "foo.png") self.create_file(old_path) self.create_file(other_file) new_path = self.make_path("new", "bar.txt") self.os.renames(old_path, new_path) self.assertTrue(self.os.path.exists(new_path)) self.assertFalse(self.os.path.exists(old_path)) self.assertTrue(self.os.path.exists(old_base_path)) removed_path = self.os.path.join(old_base_path, "dir1") self.assertFalse(self.os.path.exists(removed_path)) def test_stat_with_mixed_case(self): # Regression test for #310 self.skip_if_symlink_not_supported() base_path = self.make_path("foo") path = self.os.path.join(base_path, "bar") self.create_dir(path) path = self.os.path.join(path, "Bar") self.os.symlink(base_path, path) path = self.os.path.join(path, "Bar") # used to raise self.os.stat(path) def test_hardlink_works_with_symlink(self): self.skip_if_symlink_not_supported() base_path = self.make_path("foo") self.create_dir(base_path) symlink_path = self.os.path.join(base_path, "slink") self.os.symlink(base_path.upper(), symlink_path) file_path = self.os.path.join(base_path, "slink", "beta") self.create_file(file_path) link_path = self.os.path.join(base_path, "Slink", "gamma") self.os.link(file_path, link_path) self.assertTrue(self.os.path.exists(link_path)) def test_replace_existing_directory_should_raise_under_windows(self): """Renaming to an existing directory raises OSError under Windows.""" self.check_windows_only() old_path = self.make_path("foo", "bar") new_path = self.make_path("foo", "baz") self.create_dir(old_path) self.create_dir(new_path) self.assert_raises_os_error( errno.EACCES, self.os.replace, old_path, new_path.upper() ) def test_rename_to_existing_directory_under_posix(self): """Renaming to an existing directory changes the existing directory under Posix.""" self.check_posix_only() old_path = self.make_path("foo", "bar") new_path = self.make_path("xyzzy") self.create_dir(self.os.path.join(old_path, "sub")) self.create_dir(new_path) self.os.rename(old_path.upper(), new_path.upper()) self.assertTrue(self.os.path.exists(self.os.path.join(new_path, "sub"))) self.assertFalse(self.os.path.exists(old_path)) def test_rename_file_to_existing_directory_raises_under_posix(self): self.check_posix_only() file_path = self.make_path("foo", "bar", "baz") new_path = self.make_path("xyzzy") self.create_file(file_path) self.create_dir(new_path) self.assert_raises_os_error( errno.EISDIR, self.os.rename, file_path.upper(), new_path.upper() ) def test_rename_to_existent_file_posix(self): """Can rename a file to a used name under Unix.""" self.check_posix_only() directory = self.make_path("xyzzy") old_file_path = self.os.path.join(directory, "plugh_old") new_file_path = self.os.path.join(directory, "plugh_new") self.create_file(old_file_path, contents="test contents 1") self.create_file(new_file_path, contents="test contents 2") self.assertTrue(self.os.path.exists(old_file_path)) self.assertTrue(self.os.path.exists(new_file_path)) self.os.rename(old_file_path.upper(), new_file_path.upper()) self.assertFalse(self.os.path.exists(old_file_path)) self.assertTrue(self.os.path.exists(new_file_path)) self.check_contents(new_file_path, "test contents 1") def test_rename_to_existent_file_windows(self): """Renaming a file to a used name raises OSError under Windows.""" self.check_windows_only() directory = self.make_path("xyzzy") old_file_path = self.os.path.join(directory, "plugh_old") new_file_path = self.os.path.join(directory, "plugh_new") self.create_file(old_file_path, contents="test contents 1") self.create_file(new_file_path, contents="test contents 2") self.assertTrue(self.os.path.exists(old_file_path)) self.assertTrue(self.os.path.exists(new_file_path)) self.assert_raises_os_error( errno.EEXIST, self.os.rename, old_file_path.upper(), new_file_path.upper(), ) def test_replace_to_existent_file(self): """Replaces an existing file (does not work with `rename()` under Windows).""" directory = self.make_path("xyzzy") old_file_path = self.os.path.join(directory, "plugh_old") new_file_path = self.os.path.join(directory, "plugh_new") self.create_file(old_file_path, contents="test contents 1") self.create_file(new_file_path, contents="test contents 2") self.assertTrue(self.os.path.exists(old_file_path)) self.assertTrue(self.os.path.exists(new_file_path)) self.os.replace(old_file_path.upper(), new_file_path.upper()) self.assertFalse(self.os.path.exists(old_file_path)) self.assertTrue(self.os.path.exists(new_file_path)) self.check_contents(new_file_path, "test contents 1") def test_rename_to_nonexistent_dir(self): """Can rename a file to a name in a nonexistent dir.""" directory = self.make_path("xyzzy") old_file_path = self.os.path.join(directory, "plugh_old") new_file_path = self.os.path.join(directory, "no_such_path", "plugh_new") self.create_file(old_file_path, contents="test contents") self.assertTrue(self.os.path.exists(old_file_path)) self.assertFalse(self.os.path.exists(new_file_path)) self.assert_raises_os_error( errno.ENOENT, self.os.rename, old_file_path.upper(), new_file_path.upper(), ) self.assertTrue(self.os.path.exists(old_file_path)) self.assertFalse(self.os.path.exists(new_file_path)) self.check_contents(old_file_path, "test contents") def check_rename_case_only_with_symlink_parent(self): # Regression test for #319 self.os.symlink(self.base_path, self.make_path("link")) dir_upper = self.make_path("link", "Alpha") self.os.mkdir(dir_upper) dir_lower = self.make_path("alpha") self.os.rename(dir_upper, dir_lower) self.assertEqual(["alpha", "link"], sorted(self.os.listdir(self.base_path))) def test_rename_case_only_with_symlink_parent_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() self.check_rename_case_only_with_symlink_parent() def test_rename_case_only_with_symlink_parent_macos(self): self.check_macos_only() self.check_rename_case_only_with_symlink_parent() def test_rename_dir(self): """Test a rename of a directory.""" directory = self.make_path("xyzzy") before_dir = self.os.path.join(directory, "before") before_file = self.os.path.join(directory, "before", "file") after_dir = self.os.path.join(directory, "after") after_file = self.os.path.join(directory, "after", "file") self.create_dir(before_dir) self.create_file(before_file, contents="payload") self.assertTrue(self.os.path.exists(before_dir.upper())) self.assertTrue(self.os.path.exists(before_file.upper())) self.assertFalse(self.os.path.exists(after_dir.upper())) self.assertFalse(self.os.path.exists(after_file.upper())) self.os.rename(before_dir.upper(), after_dir) self.assertFalse(self.os.path.exists(before_dir.upper())) self.assertFalse(self.os.path.exists(before_file.upper())) self.assertTrue(self.os.path.exists(after_dir.upper())) self.assertTrue(self.os.path.exists(after_file.upper())) self.check_contents(after_file, "payload") def test_rename_same_filenames(self): """Test renaming when old and new names are the same.""" directory = self.make_path("xyzzy") file_contents = "Spam eggs" file_path = self.os.path.join(directory, "eggs") self.create_file(file_path, contents=file_contents) self.os.rename(file_path, file_path.upper()) self.check_contents(file_path, file_contents) def test_rmdir(self): """Can remove a directory.""" directory = self.make_path("xyzzy") sub_dir = self.make_path("xyzzy", "abccd") other_dir = self.make_path("xyzzy", "cdeed") self.create_dir(directory) self.assertTrue(self.os.path.exists(directory)) self.os.rmdir(directory) self.assertFalse(self.os.path.exists(directory)) self.create_dir(sub_dir) self.create_dir(other_dir) self.os.chdir(sub_dir) self.os.rmdir("../CDEED") self.assertFalse(self.os.path.exists(other_dir)) self.os.chdir("..") self.os.rmdir("AbcCd") self.assertFalse(self.os.path.exists(sub_dir)) def test_rmdir_via_symlink(self): self.check_windows_only() self.skip_if_symlink_not_supported() base_path = self.make_path("foo", "bar") dir_path = self.os.path.join(base_path, "alpha") self.create_dir(dir_path) link_path = self.os.path.join(base_path, "beta") self.os.symlink(base_path, link_path) self.os.rmdir(link_path + "/Alpha") self.assertFalse(self.os.path.exists(dir_path)) def test_remove_dirs_with_non_top_symlink_succeeds(self): self.check_posix_only() dir_path = self.make_path("dir") dir_link = self.make_path("dir_link") self.create_dir(dir_path) self.os.symlink(dir_path, dir_link) dir_in_dir = self.os.path.join(dir_link, "dir2") self.create_dir(dir_in_dir) self.os.removedirs(dir_in_dir.upper()) self.assertFalse(self.os.path.exists(dir_in_dir)) # ensure that the symlink is not removed self.assertTrue(self.os.path.exists(dir_link)) def test_mkdir_raises_on_symlink_in_posix(self): self.check_posix_only() base_path = self.make_path("foo", "bar") link_path = self.os.path.join(base_path, "link_to_dir") dir_path = self.os.path.join(base_path, "dir") self.create_dir(dir_path) self.os.symlink(dir_path.upper(), link_path.upper()) self.assert_raises_os_error(errno.ENOTDIR, self.os.rmdir, link_path) def test_mkdir_removes_symlink_in_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() base_path = self.make_path("foo", "bar") link_path = self.os.path.join(base_path, "link_to_dir") dir_path = self.os.path.join(base_path, "dir") self.create_dir(dir_path) self.os.symlink(dir_path.upper(), link_path.upper()) self.os.rmdir(link_path) self.assertFalse(self.os.path.exists(link_path)) self.assertTrue(self.os.path.exists(dir_path)) def test_mkdir_raises_if_directory_exists(self): """mkdir raises exception if directory already exists.""" directory = self.make_path("xyzzy") self.create_dir(directory) self.assertTrue(self.os.path.exists(directory)) self.assert_raises_os_error(errno.EEXIST, self.os.mkdir, directory.upper()) def test_mkdir_raises_if_file_exists(self): """mkdir raises exception if name already exists as a file.""" directory = self.make_path("xyzzy") file_path = self.os.path.join(directory, "plugh") self.create_file(file_path) self.assertTrue(self.os.path.exists(file_path)) self.assert_raises_os_error(errno.EEXIST, self.os.mkdir, file_path.upper()) def test_mkdir_raises_if_symlink_exists(self): # Regression test for #309 self.skip_if_symlink_not_supported() path1 = self.make_path("baz") self.os.symlink(path1, path1) path2 = self.make_path("Baz") self.assert_raises_os_error(errno.EEXIST, self.os.mkdir, path2) def check_mkdir_raises_if_parent_is_file(self, error_type): """mkdir raises exception if name already exists as a file.""" directory = self.make_path("xyzzy") file_path = self.os.path.join(directory, "plugh") self.create_file(file_path) self.assert_raises_os_error( error_type, self.os.mkdir, self.os.path.join(file_path.upper(), "ff"), ) def test_mkdir_raises_if_parent_is_file_posix(self): self.check_posix_only() self.check_mkdir_raises_if_parent_is_file(errno.ENOTDIR) def test_mkdir_raises_if_parent_is_file_windows(self): self.check_windows_only() self.check_mkdir_raises_if_parent_is_file(errno.ENOENT) def test_makedirs(self): """makedirs can create a directory even if parent does not exist.""" parent = self.make_path("xyzzy") directory = self.os.path.join(parent, "foo") self.assertFalse(self.os.path.exists(parent)) self.os.makedirs(directory.upper()) self.assertTrue(self.os.path.exists(directory)) def check_makedirs_raises_if_parent_is_file(self, error_type): """makedirs raises exception if a parent component exists as a file.""" file_path = self.make_path("xyzzy") directory = self.os.path.join(file_path, "plugh") self.create_file(file_path) self.assertTrue(self.os.path.exists(file_path)) self.assert_raises_os_error(error_type, self.os.makedirs, directory.upper()) def test_makedirs_raises_if_parent_is_file_posix(self): self.check_posix_only() self.check_makedirs_raises_if_parent_is_file(errno.ENOTDIR) def test_makedirs_raises_if_parent_is_file_windows(self): self.check_windows_only() self.check_makedirs_raises_if_parent_is_file(errno.ENOENT) def test_makedirs_raises_if_parent_is_broken_link(self): self.check_posix_only() link_path = self.make_path("broken_link") self.os.symlink(self.make_path("bogus"), link_path) self.assert_raises_os_error( errno.ENOENT, self.os.makedirs, self.os.path.join(link_path.upper(), "newdir"), ) def test_makedirs_exist_ok(self): """makedirs uses the exist_ok argument""" directory = self.make_path("xyzzy", "foo") self.create_dir(directory) self.assertTrue(self.os.path.exists(directory)) self.assert_raises_os_error(errno.EEXIST, self.os.makedirs, directory.upper()) self.os.makedirs(directory.upper(), exist_ok=True) self.assertTrue(self.os.path.exists(directory)) # test fsync and fdatasync def test_fsync_pass(self): test_file_path = self.make_path("test_file") self.create_file(test_file_path, contents="dummy file contents") test_file = self.open(test_file_path.upper(), "r+") test_fd = test_file.fileno() # Test that this doesn't raise anything self.os.fsync(test_fd) # And just for sanity, double-check that this still raises self.assert_raises_os_error(errno.EBADF, self.os.fsync, test_fd + 10) test_file.close() def test_chmod(self): # set up self.check_posix_only() self.skip_real_fs() path = self.make_path("some_file") self.createTestFile(path) # actual tests self.os.chmod(path.upper(), 0o6543) st = self.os.stat(path) self.assert_mode_equal(0o6543, st.st_mode) self.assertTrue(st.st_mode & stat.S_IFREG) self.assertFalse(st.st_mode & stat.S_IFDIR) def test_symlink(self): self.skip_if_symlink_not_supported() file_path = self.make_path("foo", "bar", "baz") self.create_dir(self.make_path("foo", "bar")) self.os.symlink("bogus", file_path.upper()) self.assertTrue(self.os.path.lexists(file_path)) self.assertFalse(self.os.path.exists(file_path)) self.create_file(self.make_path("Foo", "Bar", "Bogus")) self.assertTrue(self.os.path.lexists(file_path)) self.assertTrue(self.os.path.exists(file_path)) # hard link related tests def test_link_delete(self): self.skip_if_symlink_not_supported() file1_path = self.make_path("test_file1") file2_path = self.make_path("test_file2") contents1 = "abcdef" # Create file self.create_file(file1_path, contents=contents1) # link to second file self.os.link(file1_path.upper(), file2_path) # delete first file self.os.unlink(file1_path) # assert that second file exists, and its contents are the same self.assertTrue(self.os.path.exists(file2_path)) with self.open(file2_path.upper()) as f: self.assertEqual(f.read(), contents1) def test_link_is_existing_file(self): self.skip_if_symlink_not_supported() file_path = self.make_path("foo", "bar") self.create_file(file_path) self.assert_raises_os_error( errno.EEXIST, self.os.link, file_path.upper(), file_path.upper() ) def test_link_is_broken_symlink(self): # Regression test for #311 self.skip_if_symlink_not_supported() self.check_case_insensitive_fs() file_path = self.make_path("baz") self.create_file(file_path) path_lower = self.make_path("foo") self.os.symlink(path_lower, path_lower) path_upper = self.make_path("Foo") self.assert_raises_os_error(errno.EEXIST, self.os.link, file_path, path_upper) def test_link_with_changed_case(self): # Regression test for #312 self.skip_if_symlink_not_supported() self.check_case_insensitive_fs() link_path = self.make_path("link") self.os.symlink(self.base_path, link_path) link_path = self.os.path.join(link_path, "Link") self.assertTrue(self.os.lstat(link_path)) class RealOsModuleTestCaseInsensitiveFS(FakeOsModuleTestCaseInsensitiveFS): def use_real_fs(self): return True class FakeOsModuleTimeTest(FakeOsModuleTestBase): def test_chmod_st_ctime(self): with self.mock_time(start=200): file_path = "some_file" self.filesystem.create_file(file_path) self.assertTrue(self.os.path.exists(file_path)) st = self.os.stat(file_path) self.assertEqual(200, st.st_ctime) # tests self.os.chmod(file_path, 0o765) st = self.os.stat(file_path) self.assertEqual(220, st.st_ctime) def test_utime_sets_current_time_if_args_is_none(self): path = self.make_path("some_file") self.createTestFile(path) with self.mock_time(start=200): self.os.utime(path, times=None) st = self.os.stat(path) self.assertEqual(200, st.st_atime) self.assertEqual(200, st.st_mtime) def test_utime_sets_specified_time(self): # set up path = self.make_path("some_file") self.createTestFile(path) self.os.stat(path) # actual tests self.os.utime(path, times=(1, 2)) st = self.os.stat(path) self.assertEqual(1, st.st_atime) self.assertEqual(2, st.st_mtime) def test_utime_dir(self): # set up path = "/some_dir" self.createTestDirectory(path) # actual tests self.os.utime(path, times=(1.0, 2.0)) st = self.os.stat(path) self.assertEqual(1.0, st.st_atime) self.assertEqual(2.0, st.st_mtime) def test_utime_follow_symlinks(self): path = self.make_path("some_file") self.createTestFile(path) link_path = "/link_to_some_file" self.filesystem.create_symlink(link_path, path) self.os.utime(link_path, times=(1, 2)) st = self.os.stat(link_path) self.assertEqual(1, st.st_atime) self.assertEqual(2, st.st_mtime) def test_utime_no_follow_symlinks(self): path = self.make_path("some_file") self.createTestFile(path) link_path = "/link_to_some_file" self.filesystem.create_symlink(link_path, path) self.os.utime(link_path, times=(1, 2), follow_symlinks=False) st = self.os.stat(link_path) self.assertNotEqual(1, st.st_atime) self.assertNotEqual(2, st.st_mtime) st = self.os.stat(link_path, follow_symlinks=False) self.assertEqual(1, st.st_atime) self.assertEqual(2, st.st_mtime) def test_utime_non_existent(self): path = "/non/existent/file" self.assertFalse(self.os.path.exists(path)) self.assert_raises_os_error(errno.ENOENT, self.os.utime, path, (1, 2)) def test_utime_invalid_times_arg_raises(self): path = "/some_dir" self.createTestDirectory(path) # the error message differs with different Python versions # we don't expect the same message here self.assertRaises(TypeError, self.os.utime, path, (1, 2, 3)) self.assertRaises(TypeError, self.os.utime, path, (1, "str")) def test_utime_sets_specified_time_in_ns(self): # set up path = self.make_path("some_file") self.createTestFile(path) self.os.stat(path) # actual tests self.os.utime(path, ns=(200000000, 400000000)) st = self.os.stat(path) self.assertEqual(0.2, st.st_atime) self.assertEqual(0.4, st.st_mtime) def test_utime_incorrect_ns_argument_raises(self): file_path = "some_file" self.filesystem.create_file(file_path) self.assertRaises(TypeError, self.os.utime, file_path, ns=200000000) self.assertRaises(TypeError, self.os.utime, file_path, ns=("a", "b")) self.assertRaises( ValueError, self.os.utime, file_path, times=(1, 2), ns=(100, 200) ) def test_utime_uses_open_fd_as_path(self): if os.utime not in os.supports_fd: self.skip_real_fs() self.assert_raises_os_error(errno.EBADF, self.os.utime, 5, (1, 2)) path = self.make_path("some_file") self.createTestFile(path) with FakeFileOpen(self.filesystem)(path) as f: self.os.utime(f.filedes, times=(1, 2)) st = self.os.stat(path) self.assertEqual(1, st.st_atime) self.assertEqual(2, st.st_mtime) class FakeOsModuleLowLevelFileOpTest(FakeOsModuleTestBase): """Test low level functions `os.open()`, `os.read()` and `os.write()`.""" def setUp(self): os.umask(0o022) super(FakeOsModuleLowLevelFileOpTest, self).setUp() def test_open_read_only(self): file_path = self.make_path("file1") self.create_file(file_path, contents=b"contents") file_des = self.os.open(file_path, os.O_RDONLY) self.assertEqual(b"contents", self.os.read(file_des, 8)) self.assert_raises_os_error(errno.EBADF, self.os.write, file_des, b"test") self.os.close(file_des) def test_open_read_only_write_zero_bytes_posix(self): self.check_posix_only() file_path = self.make_path("file1") self.create_file(file_path, contents=b"contents") file_des = self.os.open(file_path, os.O_RDONLY) self.assert_raises_os_error(errno.EBADF, self.os.write, file_des, b"test") self.os.close(file_des) def test_open_read_only_write_zero_bytes_windows(self): # under Windows, writing an empty string to a read only file # is not an error self.check_windows_only() file_path = self.make_path("file1") self.create_file(file_path, contents=b"contents") file_des = self.os.open(file_path, os.O_RDONLY) self.assertEqual(0, self.os.write(file_des, b"")) self.os.close(file_des) def test_open_write_only(self): file_path = self.make_path("file1") self.create_file(file_path, contents=b"contents") file_des = self.os.open(file_path, os.O_WRONLY) self.assertEqual(4, self.os.write(file_des, b"test")) self.check_contents(file_path, b"testents") self.os.close(file_des) def test_open_write_only_raises_on_read(self): file_path = self.make_path("file1") self.create_file(file_path, contents=b"contents") file_des = self.os.open(file_path, os.O_WRONLY) self.assert_raises_os_error(errno.EBADF, self.os.read, file_des, 5) self.os.close(file_des) file_des = self.os.open(file_path, os.O_WRONLY | os.O_TRUNC) self.assert_raises_os_error(errno.EBADF, self.os.read, file_des, 5) self.os.close(file_des) file_path2 = self.make_path("file2") file_des = self.os.open(file_path2, os.O_CREAT | os.O_WRONLY) self.assert_raises_os_error(errno.EBADF, self.os.read, file_des, 5) self.os.close(file_des) file_des = self.os.open(file_path2, os.O_CREAT | os.O_WRONLY | os.O_TRUNC) self.assert_raises_os_error(errno.EBADF, self.os.read, file_des, 5) self.os.close(file_des) def test_open_write_only_read_zero_bytes_posix(self): self.check_posix_only() file_path = self.make_path("file1") file_des = self.os.open(file_path, os.O_CREAT | os.O_WRONLY) self.assert_raises_os_error(errno.EBADF, self.os.read, file_des, 0) self.os.close(file_des) def test_open_write_only_read_zero_bytes_windows(self): # under Windows, reading 0 bytes from a write only file is not an error self.check_windows_only() file_path = self.make_path("file1") file_des = self.os.open(file_path, os.O_CREAT | os.O_WRONLY) self.assertEqual(b"", self.os.read(file_des, 0)) self.os.close(file_des) def test_open_read_write(self): file_path = self.make_path("file1") self.create_file(file_path, contents=b"contents") file_des = self.os.open(file_path, os.O_RDWR) self.assertEqual(4, self.os.write(file_des, b"test")) self.check_contents(file_path, b"testents") self.os.close(file_des) def test_open_create_is_read_only(self): file_path = self.make_path("file1") file_des = self.os.open(file_path, os.O_CREAT) self.assertEqual(b"", self.os.read(file_des, 1)) self.assert_raises_os_error(errno.EBADF, self.os.write, file_des, b"foo") self.os.close(file_des) def test_open_create_truncate_is_read_only(self): file_path = self.make_path("file1") file_des = self.os.open(file_path, os.O_CREAT | os.O_TRUNC) self.assertEqual(b"", self.os.read(file_des, 1)) self.assert_raises_os_error(errno.EBADF, self.os.write, file_des, b"foo") self.os.close(file_des) def test_open_raises_if_does_not_exist(self): file_path = self.make_path("file1") self.assert_raises_os_error(errno.ENOENT, self.os.open, file_path, os.O_RDONLY) self.assert_raises_os_error(errno.ENOENT, self.os.open, file_path, os.O_WRONLY) self.assert_raises_os_error(errno.ENOENT, self.os.open, file_path, os.O_RDWR) def test_exclusive_open_raises_without_create_mode(self): self.skip_real_fs() file_path = self.make_path("file1") self.assertRaises(NotImplementedError, self.os.open, file_path, os.O_EXCL) self.assertRaises( NotImplementedError, self.os.open, file_path, os.O_EXCL | os.O_WRONLY, ) self.assertRaises( NotImplementedError, self.os.open, file_path, os.O_EXCL | os.O_RDWR ) self.assertRaises( NotImplementedError, self.os.open, file_path, os.O_EXCL | os.O_TRUNC | os.O_APPEND, ) def test_open_raises_if_parent_does_not_exist(self): path = self.make_path("alpha", "alpha") self.assert_raises_os_error( errno.ENOENT, self.os.open, path, os.O_CREAT | os.O_WRONLY | os.O_TRUNC, ) def test_open_truncate(self): file_path = self.make_path("file1") self.create_file(file_path, contents=b"contents") file_des = self.os.open(file_path, os.O_RDWR | os.O_TRUNC) self.assertEqual(b"", self.os.read(file_des, 8)) self.assertEqual(4, self.os.write(file_des, b"test")) self.check_contents(file_path, b"test") self.os.close(file_des) @unittest.skipIf(not TestCase.is_windows, "O_TEMPORARY only present in Windows") def test_temp_file(self): file_path = self.make_path("file1") fd = self.os.open(file_path, os.O_CREAT | os.O_RDWR | os.O_TEMPORARY) self.assertTrue(self.os.path.exists(file_path)) self.os.close(fd) self.assertFalse(self.os.path.exists(file_path)) def test_open_append(self): file_path = self.make_path("file1") self.create_file(file_path, contents=b"contents") file_des = self.os.open(file_path, os.O_WRONLY | os.O_APPEND) self.assertEqual(4, self.os.write(file_des, b"test")) self.check_contents(file_path, b"contentstest") self.os.close(file_des) def test_open_create(self): file_path = self.make_path("file1") file_des = self.os.open(file_path, os.O_RDWR | os.O_CREAT) self.assertTrue(self.os.path.exists(file_path)) self.assertEqual(4, self.os.write(file_des, b"test")) self.check_contents(file_path, "test") self.os.close(file_des) def test_can_read_after_create_exclusive(self): self.check_posix_only() path1 = self.make_path("alpha") file_des = self.os.open(path1, os.O_CREAT | os.O_EXCL) self.assertEqual(b"", self.os.read(file_des, 0)) self.assert_raises_os_error(errno.EBADF, self.os.write, file_des, b"") self.os.close(file_des) def test_open_create_mode_posix(self): self.check_posix_only() file_path = self.make_path("file1") file_des = self.os.open(file_path, os.O_WRONLY | os.O_CREAT, 0o700) self.assertTrue(self.os.path.exists(file_path)) self.assert_raises_os_error(errno.EBADF, self.os.read, file_des, 5) self.assertEqual(4, self.os.write(file_des, b"test")) self.assert_mode_equal(0o700, self.os.stat(file_path).st_mode) self.os.close(file_des) def test_open_create_mode_windows(self): self.check_windows_only() file_path = self.make_path("file1") file_des = self.os.open(file_path, os.O_WRONLY | os.O_CREAT, 0o700) self.assertTrue(self.os.path.exists(file_path)) self.assert_raises_os_error(errno.EBADF, self.os.read, file_des, 5) self.assertEqual(4, self.os.write(file_des, b"test")) self.assert_mode_equal(0o666, self.os.stat(file_path).st_mode) self.os.close(file_des) def testOpenCreateMode444Windows(self): self.check_windows_only() file_path = self.make_path("file1") file_des = self.os.open(file_path, os.O_WRONLY | os.O_CREAT, 0o442) self.assert_mode_equal(0o444, self.os.stat(file_path).st_mode) self.os.close(file_des) self.os.chmod(file_path, 0o666) def testOpenCreateMode666Windows(self): self.check_windows_only() file_path = self.make_path("file1") file_des = self.os.open(file_path, os.O_WRONLY | os.O_CREAT, 0o224) self.assert_mode_equal(0o666, self.os.stat(file_path).st_mode) self.os.close(file_des) def test_open_exclusive(self): file_path = self.make_path("file1") file_des = self.os.open(file_path, os.O_RDWR | os.O_EXCL | os.O_CREAT) self.assertTrue(self.os.path.exists(file_path)) self.os.close(file_des) def test_open_exclusive_raises_if_file_exists(self): file_path = self.make_path("file1") self.create_file(file_path, contents=b"contents") self.assert_raises_os_error( errno.EEXIST, self.os.open, file_path, os.O_RDWR | os.O_EXCL | os.O_CREAT, ) self.assert_raises_os_error( errno.EEXIST, self.os.open, file_path, os.O_RDWR | os.O_EXCL | os.O_CREAT, ) def test_open_exclusive_raises_if_symlink_exists_in_posix(self): self.check_posix_only() link_path = self.make_path("link") link_target = self.make_path("link_target") self.os.symlink(link_target, link_path) self.assert_raises_os_error( errno.EEXIST, self.os.open, link_path, os.O_CREAT | os.O_WRONLY | os.O_TRUNC | os.O_EXCL, ) def test_open_exclusive_if_symlink_exists_works_in_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() link_path = self.make_path("link") link_target = self.make_path("link_target") self.os.symlink(link_target, link_path) fd = self.os.open(link_path, os.O_CREAT | os.O_WRONLY | os.O_TRUNC | os.O_EXCL) self.os.close(fd) def test_open_directory_raises_under_windows(self): self.check_windows_only() dir_path = self.make_path("dir") self.create_dir(dir_path) self.assert_raises_os_error(errno.EACCES, self.os.open, dir_path, os.O_RDONLY) self.assert_raises_os_error(errno.EACCES, self.os.open, dir_path, os.O_WRONLY) self.assert_raises_os_error(errno.EACCES, self.os.open, dir_path, os.O_RDWR) def test_open_directory_for_writing_raises_under_posix(self): self.check_posix_only() dir_path = self.make_path("dir") self.create_dir(dir_path) self.assert_raises_os_error(errno.EISDIR, self.os.open, dir_path, os.O_WRONLY) self.assert_raises_os_error(errno.EISDIR, self.os.open, dir_path, os.O_RDWR) def test_open_directory_read_only_under_posix(self): self.check_posix_only() self.skip_real_fs() dir_path = self.make_path("dir") self.create_dir(dir_path) file_des = self.os.open(dir_path, os.O_RDONLY) self.assertEqual(3, file_des) self.os.close(file_des) def test_opening_existing_directory_in_creation_mode(self): self.check_linux_only() dir_path = self.make_path("alpha") self.os.mkdir(dir_path) self.assert_raises_os_error(errno.EISDIR, self.os.open, dir_path, os.O_CREAT) def test_writing_to_existing_directory(self): self.check_macos_only() dir_path = self.make_path("alpha") self.os.mkdir(dir_path) fd = self.os.open(dir_path, os.O_CREAT) self.assert_raises_os_error(errno.EBADF, self.os.write, fd, b"") def test_opening_existing_directory_in_write_mode(self): self.check_posix_only() dir_path = self.make_path("alpha") self.os.mkdir(dir_path) self.assert_raises_os_error(errno.EISDIR, self.os.open, dir_path, os.O_WRONLY) def test_open_mode_posix(self): self.check_posix_only() self.skip_real_fs() file_path = self.make_path("baz") file_des = self.os.open(file_path, os.O_CREAT | os.O_WRONLY | os.O_TRUNC) stat0 = self.os.fstat(file_des) # not a really good test as this replicates the code, # but we don't know the umask at the test system self.assertEqual(0o100777 & ~self.os._umask(), stat0.st_mode) self.os.close(file_des) def test_open_mode_windows(self): self.check_windows_only() file_path = self.make_path("baz") file_des = self.os.open(file_path, os.O_CREAT | os.O_WRONLY | os.O_TRUNC) stat0 = self.os.fstat(file_des) self.assertEqual(0o100666, stat0.st_mode) self.os.close(file_des) def test_write_read(self): file_path = self.make_path("file1") self.create_file(file_path, contents=b"orig contents") new_contents = b"1234567890abcdef" with self.open(file_path, "wb") as fh: fileno = fh.fileno() self.assertEqual(len(new_contents), self.os.write(fileno, new_contents)) self.check_contents(file_path, new_contents) with self.open(file_path, "rb") as fh: fileno = fh.fileno() self.assertEqual(b"", self.os.read(fileno, 0)) self.assertEqual(new_contents[0:2], self.os.read(fileno, 2)) self.assertEqual(new_contents[2:10], self.os.read(fileno, 8)) self.assertEqual(new_contents[10:], self.os.read(fileno, 100)) self.assertEqual(b"", self.os.read(fileno, 10)) self.assert_raises_os_error(errno.EBADF, self.os.write, fileno, new_contents) self.assert_raises_os_error(errno.EBADF, self.os.read, fileno, 10) def test_write_from_different_f_ds(self): # Regression test for #211 file_path = self.make_path("baz") fd0 = self.os.open(file_path, os.O_CREAT | os.O_WRONLY | os.O_TRUNC) fd1 = self.os.open(file_path, os.O_CREAT | os.O_WRONLY | os.O_TRUNC) self.os.write(fd0, b"aaaa") self.os.write(fd1, b"bb") self.assertEqual(4, self.os.path.getsize(file_path)) self.check_contents(file_path, b"bbaa") self.os.close(fd1) self.os.close(fd0) def test_write_from_different_fds_with_append(self): # Regression test for #268 file_path = self.make_path("baz") fd0 = self.os.open(file_path, os.O_CREAT | os.O_WRONLY | os.O_TRUNC) fd1 = self.os.open(file_path, os.O_WRONLY | os.O_APPEND) self.os.write(fd0, b"aaa") self.os.write(fd1, b"bbb") self.assertEqual(6, self.os.path.getsize(file_path)) self.check_contents(file_path, b"aaabbb") self.os.close(fd1) self.os.close(fd0) def test_read_only_read_after_write(self): # Regression test for #269 self.check_posix_only() file_path = self.make_path("foo", "bar", "baz") self.create_file(file_path, contents=b"test") fd0 = self.os.open(file_path, os.O_CREAT) fd1 = self.os.open(file_path, os.O_CREAT | os.O_WRONLY | os.O_TRUNC) self.assertEqual(b"", self.os.read(fd0, 0)) self.os.close(fd1) self.os.close(fd0) def test_read_after_closing_write_descriptor(self): # Regression test for #271 file_path = self.make_path("baz") fd0 = self.os.open(file_path, os.O_CREAT | os.O_WRONLY | os.O_TRUNC) fd1 = self.os.open(file_path, os.O_CREAT | os.O_WRONLY | os.O_TRUNC) fd2 = self.os.open(file_path, os.O_CREAT) self.os.write(fd1, b"abc") self.os.close(fd0) self.assertEqual(b"abc", self.os.read(fd2, 3)) self.os.close(fd2) self.os.close(fd1) def test_writing_behind_end_of_file(self): # Regression test for #273 file_path = self.make_path("baz") fd1 = self.os.open(file_path, os.O_CREAT) fd2 = self.os.open(file_path, os.O_RDWR) self.os.write(fd2, b"m") fd3 = self.os.open(file_path, os.O_CREAT | os.O_WRONLY | os.O_TRUNC) self.assertEqual(b"", self.os.read(fd2, 1)) self.os.write(fd2, b"m") self.assertEqual(b"\x00m", self.os.read(fd1, 2)) self.os.close(fd1) self.os.close(fd2) self.os.close(fd3) def test_devnull_posix(self): self.check_posix_only() # make sure os.devnull is correctly set after changing the filesystem self.setup_fake_fs() self.assertTrue(self.os.path.exists(self.os.devnull)) def test_devnull_windows(self): self.check_windows_only() # make sure os.devnull is correctly set after changing the filesystem self.setup_fake_fs() if sys.version_info < (3, 8): self.assertFalse(self.os.path.exists(self.os.devnull)) else: self.assertTrue(self.os.path.exists(self.os.devnull)) def test_write_devnull(self): fd = self.os.open(self.os.devnull, os.O_RDWR) self.assertEqual(4, self.os.write(fd, b"test")) self.assertEqual(b"", self.os.read(fd, 4)) self.os.close(fd) fd = self.os.open(self.os.devnull, os.O_RDONLY) self.assertEqual(b"", self.os.read(fd, 4)) self.os.close(fd) def test_sendfile_with_invalid_fd(self): self.check_linux_only() self.assert_raises_os_error(errno.EBADF, self.os.sendfile, 100, 101, 0, 100) src_file_path = self.make_path("foo") dst_file_path = self.make_path("bar") self.create_file(src_file_path, "testcontent") self.create_file(dst_file_path) fd1 = self.os.open(src_file_path, os.O_RDONLY) fd2 = self.os.open(dst_file_path, os.O_RDONLY) self.assert_raises_os_error(errno.EBADF, self.os.sendfile, fd2, fd1, 0, 4) def test_sendfile_no_offset(self): self.check_linux_only() src_file_path = self.make_path("foo") dst_file_path = self.make_path("bar") self.create_file(src_file_path, "testcontent") self.create_file(dst_file_path) fd1 = self.os.open(src_file_path, os.O_RDONLY) fd2 = self.os.open(dst_file_path, os.O_RDWR) self.os.sendfile(fd2, fd1, 0, 3) self.os.close(fd2) self.os.close(fd1) with self.open(dst_file_path) as f: self.assertEqual("tes", f.read()) def test_sendfile_with_offset(self): self.check_linux_only() src_file_path = self.make_path("foo") dst_file_path = self.make_path("bar") self.create_file(src_file_path, "testcontent") self.create_file(dst_file_path) fd1 = self.os.open(src_file_path, os.O_RDONLY) fd2 = self.os.open(dst_file_path, os.O_RDWR) self.os.sendfile(fd2, fd1, 4, 4) self.os.close(fd2) self.os.close(fd1) with self.open(dst_file_path) as f: self.assertEqual("cont", f.read()) def test_sendfile_twice(self): self.check_linux_only() src_file_path = self.make_path("foo") dst_file_path = self.make_path("bar") self.create_file(src_file_path, "testcontent") self.create_file(dst_file_path) fd1 = self.os.open(src_file_path, os.O_RDONLY) fd2 = self.os.open(dst_file_path, os.O_RDWR) self.os.sendfile(fd2, fd1, 4, 4) self.os.sendfile(fd2, fd1, 4, 4) self.os.close(fd2) self.os.close(fd1) with self.open(dst_file_path) as f: self.assertEqual("contcont", f.read()) def test_sendfile_offset_none(self): self.check_linux_only() src_file_path = self.make_path("foo") dst_file_path = self.make_path("bar") self.create_file(src_file_path, "testcontent") self.create_file(dst_file_path) fd1 = self.os.open(src_file_path, os.O_RDONLY) fd2 = self.os.open(dst_file_path, os.O_RDWR) self.os.sendfile(fd2, fd1, None, 4) self.os.sendfile(fd2, fd1, None, 3) self.os.close(fd2) self.os.close(fd1) with self.open(dst_file_path) as f: self.assertEqual("testcon", f.read()) @unittest.skipIf(not TestCase.is_macos, "Testing MacOs only behavior") def test_no_sendfile_to_regular_file_under_macos(self): src_file_path = self.make_path("foo") dst_file_path = self.make_path("bar") self.create_file(src_file_path, "testcontent") self.create_file(dst_file_path) fd1 = self.os.open(src_file_path, os.O_RDONLY) fd2 = self.os.open(dst_file_path, os.O_RDWR) # raises socket operation on non-socket self.assertRaises(OSError, self.os.sendfile, fd2, fd1, 0, 3) self.os.close(fd2) self.os.close(fd1) class RealOsModuleLowLevelFileOpTest(FakeOsModuleLowLevelFileOpTest): def use_real_fs(self): return True class FakeOsModuleWalkTest(FakeOsModuleTestBase): def assertWalkResults(self, expected, top, topdown=True, followlinks=False): # as the result of walk is unsorted, we have to check against # sorted results result = list( step for step in self.os.walk(top, topdown=topdown, followlinks=followlinks) ) result = sorted(result, key=lambda lst: lst[0]) expected = sorted(expected, key=lambda lst: lst[0]) self.assertEqual(len(expected), len(result)) for entry, expected_entry in zip(result, expected): self.assertEqual(expected_entry[0], entry[0]) self.assertEqual(expected_entry[1], sorted(entry[1])) self.assertEqual(expected_entry[2], sorted(entry[2])) def ResetErrno(self): """Reset the last seen errno.""" self.last_errno = False def StoreErrno(self, os_error): """Store the last errno we saw.""" self.last_errno = os_error.errno def GetErrno(self): """Return the last errno we saw.""" return self.last_errno def test_walk_top_down(self): """Walk down ordering is correct.""" base_dir = self.make_path("foo") self.create_file(self.os.path.join(base_dir, "1.txt")) self.create_file(self.os.path.join(base_dir, "bar1", "2.txt")) self.create_file(self.os.path.join(base_dir, "bar1", "baz", "3.txt")) self.create_file(self.os.path.join(base_dir, "bar2", "4.txt")) expected = [ (base_dir, ["bar1", "bar2"], ["1.txt"]), (self.os.path.join(base_dir, "bar1"), ["baz"], ["2.txt"]), (self.os.path.join(base_dir, "bar1", "baz"), [], ["3.txt"]), (self.os.path.join(base_dir, "bar2"), [], ["4.txt"]), ] self.assertWalkResults(expected, base_dir) def test_walk_bottom_up(self): """Walk up ordering is correct.""" base_dir = self.make_path("foo") self.create_file(self.os.path.join(base_dir, "bar1", "baz", "1.txt")) self.create_file(self.os.path.join(base_dir, "bar1", "2.txt")) self.create_file(self.os.path.join(base_dir, "bar2", "3.txt")) self.create_file(self.os.path.join(base_dir, "4.txt")) expected = [ (self.os.path.join(base_dir, "bar1", "baz"), [], ["1.txt"]), (self.os.path.join(base_dir, "bar1"), ["baz"], ["2.txt"]), (self.os.path.join(base_dir, "bar2"), [], ["3.txt"]), (base_dir, ["bar1", "bar2"], ["4.txt"]), ] self.assertWalkResults(expected, self.make_path("foo"), topdown=False) def test_walk_raises_if_non_existent(self): """Raises an exception when attempting to walk non-existent directory.""" directory = self.make_path("foo", "bar") self.assertEqual(False, self.os.path.exists(directory)) generator = self.os.walk(directory) self.assertRaises(StopIteration, next, generator) def test_walk_raises_if_not_directory(self): """Raises an exception when attempting to walk a non-directory.""" filename = self.make_path("foo", "bar") self.create_file(filename) generator = self.os.walk(filename) self.assertRaises(StopIteration, next, generator) def test_walk_calls_on_error_if_non_existent(self): """Calls onerror with correct errno when walking non-existent directory.""" self.ResetErrno() directory = self.make_path("foo", "bar") self.assertEqual(False, self.os.path.exists(directory)) # Calling os.walk on a non-existent directory should trigger # a call to the onerror method. # We do not actually care what, if anything, is returned. for _ in self.os.walk(directory, onerror=self.StoreErrno): pass self.assertTrue(self.GetErrno() in (errno.ENOTDIR, errno.ENOENT)) def test_walk_calls_on_error_if_not_directory(self): """Calls onerror with correct errno when walking non-directory.""" self.ResetErrno() filename = self.make_path("foo" "bar") self.create_file(filename) self.assertEqual(True, self.os.path.exists(filename)) # Calling `os.walk` on a file should trigger a call to the # `onerror` method. # We do not actually care what, if anything, is returned. for _ in self.os.walk(filename, onerror=self.StoreErrno): pass self.assertTrue(self.GetErrno() in (errno.ENOTDIR, errno.EACCES)) def test_walk_skips_removed_directories(self): """Caller can modify list of directories to visit while walking.""" root = self.make_path("foo") visit = "visit" no_visit = "no_visit" self.create_file(self.os.path.join(root, "bar")) self.create_file(self.os.path.join(root, visit, "1.txt")) self.create_file(self.os.path.join(root, visit, "2.txt")) self.create_file(self.os.path.join(root, no_visit, "3.txt")) self.create_file(self.os.path.join(root, no_visit, "4.txt")) generator = self.os.walk(self.make_path("foo")) root_contents = next(generator) root_contents[1].remove(no_visit) visited_visit_directory = False for root, _dirs, _files in iter(generator): self.assertEqual(False, root.endswith(self.os.path.sep + no_visit)) if root.endswith(self.os.path.sep + visit): visited_visit_directory = True self.assertEqual(True, visited_visit_directory) def test_walk_followsymlink_disabled(self): self.check_posix_only() base_dir = self.make_path("foo") link_dir = self.make_path("linked") self.create_file(self.os.path.join(link_dir, "subfile")) self.create_file(self.os.path.join(base_dir, "bar", "baz")) self.create_file(self.os.path.join(base_dir, "bar", "xyzzy", "plugh")) self.create_symlink(self.os.path.join(base_dir, "created_link"), link_dir) expected = [ (base_dir, ["bar", "created_link"], []), (self.os.path.join(base_dir, "bar"), ["xyzzy"], ["baz"]), (self.os.path.join(base_dir, "bar", "xyzzy"), [], ["plugh"]), ] self.assertWalkResults(expected, base_dir, followlinks=False) expected = [(self.os.path.join(base_dir, "created_link"), [], ["subfile"])] self.assertWalkResults( expected, self.os.path.join(base_dir, "created_link"), followlinks=False, ) def test_walk_followsymlink_enabled(self): self.check_posix_only() base_dir = self.make_path("foo") link_dir = self.make_path("linked") self.create_file(self.os.path.join(link_dir, "subfile")) self.create_file(self.os.path.join(base_dir, "bar", "baz")) self.create_file(self.os.path.join(base_dir, "bar", "xyzzy", "plugh")) self.create_symlink( self.os.path.join(base_dir, "created_link"), self.os.path.join(link_dir), ) expected = [ (base_dir, ["bar", "created_link"], []), (self.os.path.join(base_dir, "bar"), ["xyzzy"], ["baz"]), (self.os.path.join(base_dir, "bar", "xyzzy"), [], ["plugh"]), (self.os.path.join(base_dir, "created_link"), [], ["subfile"]), ] self.assertWalkResults(expected, base_dir, followlinks=True) expected = [(self.os.path.join(base_dir, "created_link"), [], ["subfile"])] self.assertWalkResults( expected, self.os.path.join(base_dir, "created_link"), followlinks=True, ) def test_walk_linked_file_in_subdir(self): # regression test for #559 (tested for link on incomplete path) self.check_posix_only() # need to have a top-level link to reproduce the bug - skip real fs self.skip_real_fs() file_path = "/foo/bar/baz" self.create_file(file_path) self.create_symlink("bar", file_path) expected = [("/foo", ["bar"], []), ("/foo/bar", [], ["baz"])] self.assertWalkResults(expected, "/foo") def test_base_dirpath(self): # regression test for #512 file_path = self.make_path("foo", "bar", "baz") self.create_file(file_path) variants = [ self.make_path("foo", "bar"), self.make_path("foo", "..", "foo", "bar"), self.make_path("foo", "..", "foo", "bar") + self.os.path.sep * 3, self.make_path("foo") + self.os.path.sep * 3 + "bar", ] for base_dir in variants: for dirpath, _dirnames, _filenames in self.os.walk(base_dir): self.assertEqual(dirpath, base_dir) file_path = self.make_path("foo", "bar", "dir", "baz") self.create_file(file_path) for base_dir in variants: for dirpath, _dirnames, _filenames in self.os.walk(base_dir): self.assertTrue(dirpath.startswith(base_dir)) class RealOsModuleWalkTest(FakeOsModuleWalkTest): def use_real_fs(self): return True class FakeOsModuleDirFdTest(FakeOsModuleTestBase): def setUp(self): super(FakeOsModuleDirFdTest, self).setUp() self.os.supports_dir_fd.clear() self.filesystem.is_windows_fs = False self.filesystem.create_dir("/foo/bar") self.dir_fd = self.os.open("/foo", os.O_RDONLY) self.filesystem.create_file("/foo/baz") def test_access(self): self.assertRaises( NotImplementedError, self.os.access, "baz", self.os.F_OK, dir_fd=self.dir_fd, ) self.os.supports_dir_fd.add(self.os.access) self.assertTrue(self.os.access("baz", self.os.F_OK, dir_fd=self.dir_fd)) def test_chmod(self): self.assertRaises( NotImplementedError, self.os.chmod, "baz", 0o6543, dir_fd=self.dir_fd, ) self.os.supports_dir_fd.add(self.os.chmod) self.os.chmod("baz", 0o6543, dir_fd=self.dir_fd) st = self.os.stat("/foo/baz") self.assert_mode_equal(0o6543, st.st_mode) @unittest.skipIf(not hasattr(os, "chown"), "chown not on all platforms available") def test_chown(self): self.assertRaises( NotImplementedError, self.os.chown, "baz", 100, 101, dir_fd=self.dir_fd, ) self.os.supports_dir_fd.add(self.os.chown) self.os.chown("baz", 100, 101, dir_fd=self.dir_fd) st = self.os.stat("/foo/baz") self.assertEqual(st[stat.ST_UID], 100) self.assertEqual(st[stat.ST_GID], 101) def test_link_src_fd(self): self.assertRaises( NotImplementedError, self.os.link, "baz", "/bat", src_dir_fd=self.dir_fd, ) self.os.supports_dir_fd.add(self.os.link) self.os.link("baz", "/bat", src_dir_fd=self.dir_fd) self.assertTrue(self.os.path.exists("/bat")) def test_link_dst_fd(self): self.assertRaises( NotImplementedError, self.os.link, "baz", "/bat", dst_dir_fd=self.dir_fd, ) self.os.supports_dir_fd.add(self.os.link) self.os.link("/foo/baz", "bat", dst_dir_fd=self.dir_fd) self.assertTrue(self.os.path.exists("/foo/bat")) def test_symlink(self): self.assertRaises( NotImplementedError, self.os.symlink, "baz", "/bat", dir_fd=self.dir_fd, ) self.os.supports_dir_fd.add(self.os.symlink) self.os.symlink("baz", "/bat", dir_fd=self.dir_fd) self.assertTrue(self.os.path.exists("/bat")) def test_readlink(self): self.skip_if_symlink_not_supported() self.filesystem.create_symlink("/meyer/lemon/pie", "/foo/baz") self.filesystem.create_symlink("/geo/metro", "/meyer") self.assertRaises( NotImplementedError, self.os.readlink, "/geo/metro/lemon/pie", dir_fd=self.dir_fd, ) self.os.supports_dir_fd.add(self.os.readlink) self.assertEqual( "/foo/baz", self.os.readlink("/geo/metro/lemon/pie", dir_fd=self.dir_fd), ) def test_stat(self): self.assertRaises(NotImplementedError, self.os.stat, "baz", dir_fd=self.dir_fd) self.os.supports_dir_fd.add(self.os.stat) st = self.os.stat("baz", dir_fd=self.dir_fd) self.assertEqual(st.st_mode, 0o100666) def test_lstat(self): self.assertRaises(NotImplementedError, self.os.lstat, "baz", dir_fd=self.dir_fd) self.os.supports_dir_fd.add(self.os.lstat) st = self.os.lstat("baz", dir_fd=self.dir_fd) self.assertEqual(st.st_mode, 0o100666) def test_mkdir(self): self.assertRaises( NotImplementedError, self.os.mkdir, "newdir", dir_fd=self.dir_fd ) self.os.supports_dir_fd.add(self.os.mkdir) self.os.mkdir("newdir", dir_fd=self.dir_fd) self.assertTrue(self.os.path.exists("/foo/newdir")) def test_rmdir(self): self.assertRaises(NotImplementedError, self.os.rmdir, "bar", dir_fd=self.dir_fd) self.os.supports_dir_fd.add(self.os.rmdir) self.os.rmdir("bar", dir_fd=self.dir_fd) self.assertFalse(self.os.path.exists("/foo/bar")) @unittest.skipIf(not hasattr(os, "mknod"), "mknod not on all platforms available") def test_mknod(self): self.assertRaises( NotImplementedError, self.os.mknod, "newdir", dir_fd=self.dir_fd ) self.os.supports_dir_fd.add(self.os.mknod) self.os.mknod("newdir", dir_fd=self.dir_fd) self.assertTrue(self.os.path.exists("/foo/newdir")) def test_rename_src_fd(self): self.assertRaises( NotImplementedError, self.os.rename, "baz", "/foo/batz", src_dir_fd=self.dir_fd, ) self.os.supports_dir_fd.add(self.os.rename) self.os.rename("bar", "/foo/batz", src_dir_fd=self.dir_fd) self.assertTrue(self.os.path.exists("/foo/batz")) def test_rename_dst_fd(self): self.assertRaises( NotImplementedError, self.os.rename, "baz", "/foo/batz", dst_dir_fd=self.dir_fd, ) self.os.supports_dir_fd.add(self.os.rename) self.os.rename("/foo/bar", "batz", dst_dir_fd=self.dir_fd) self.assertTrue(self.os.path.exists("/foo/batz")) def test_replace_src_fd(self): self.assertRaises( NotImplementedError, self.os.rename, "baz", "/foo/batz", src_dir_fd=self.dir_fd, ) self.os.supports_dir_fd.add(self.os.rename) self.os.replace("bar", "/foo/batz", src_dir_fd=self.dir_fd) self.assertTrue(self.os.path.exists("/foo/batz")) def test_replace_dst_fd(self): self.assertRaises( NotImplementedError, self.os.rename, "baz", "/foo/batz", dst_dir_fd=self.dir_fd, ) self.os.supports_dir_fd.add(self.os.rename) self.os.replace("/foo/bar", "batz", dst_dir_fd=self.dir_fd) self.assertTrue(self.os.path.exists("/foo/batz")) def test_remove(self): self.assertRaises( NotImplementedError, self.os.remove, "baz", dir_fd=self.dir_fd ) self.os.supports_dir_fd.add(self.os.remove) self.os.remove("baz", dir_fd=self.dir_fd) self.assertFalse(self.os.path.exists("/foo/baz")) def test_unlink(self): self.assertRaises( NotImplementedError, self.os.unlink, "baz", dir_fd=self.dir_fd ) self.os.supports_dir_fd.add(self.os.unlink) self.os.unlink("baz", dir_fd=self.dir_fd) self.assertFalse(self.os.path.exists("/foo/baz")) def test_utime(self): self.assertRaises( NotImplementedError, self.os.utime, "baz", (1, 2), dir_fd=self.dir_fd, ) self.os.supports_dir_fd.add(self.os.utime) self.os.utime("baz", times=(1, 2), dir_fd=self.dir_fd) st = self.os.stat("/foo/baz") self.assertEqual(1, st.st_atime) self.assertEqual(2, st.st_mtime) def test_open(self): self.assertRaises( NotImplementedError, self.os.open, "baz", os.O_RDONLY, dir_fd=self.dir_fd, ) self.os.supports_dir_fd.add(self.os.open) fd = self.os.open("baz", os.O_RDONLY, dir_fd=self.dir_fd) self.assertLess(0, fd) class StatPropagationTest(TestCase): def setUp(self): self.filesystem = fake_filesystem.FakeFilesystem(path_separator="/") self.os = fake_os.FakeOsModule(self.filesystem) self.open = fake_open.FakeFileOpen(self.filesystem) def test_file_size_updated_via_close(self): """test that file size gets updated via close().""" file_dir = "xyzzy" file_path = "xyzzy/close" content = "This is a test." self.os.mkdir(file_dir) fh = self.open(file_path, "w") self.assertEqual(0, self.os.stat(file_path)[stat.ST_SIZE]) self.assertEqual("", self.filesystem.get_object(file_path).contents) fh.write(content) self.assertEqual(0, self.os.stat(file_path)[stat.ST_SIZE]) self.assertEqual("", self.filesystem.get_object(file_path).contents) fh.close() self.assertEqual(len(content), self.os.stat(file_path)[stat.ST_SIZE]) self.assertEqual(content, self.filesystem.get_object(file_path).contents) def test_file_size_not_reset_after_close(self): file_dir = "xyzzy" file_path = "xyzzy/close" self.os.mkdir(file_dir) size = 1234 # The file has size, but no content. When the file is opened for # reading, its size should be preserved. self.filesystem.create_file(file_path, st_size=size) fh = self.open(file_path, "r") fh.close() self.assertEqual(size, self.open(file_path, "r").size()) def test_file_size_after_write(self): file_path = "test_file" original_content = "abcdef" original_size = len(original_content) self.filesystem.create_file(file_path, contents=original_content) added_content = "foo bar" expected_size = original_size + len(added_content) fh = self.open(file_path, "a") fh.write(added_content) self.assertEqual(original_size, fh.size()) fh.close() self.assertEqual(expected_size, self.open(file_path, "r").size()) def test_large_file_size_after_write(self): file_path = "test_file" original_content = "abcdef" original_size = len(original_content) self.filesystem.create_file(file_path, st_size=original_size) added_content = "foo bar" fh = self.open(file_path, "a") self.assertRaises( fake_file.FakeLargeFileIoException, lambda: fh.write(added_content), ) def test_file_size_updated_via_flush(self): """test that file size gets updated via flush().""" file_dir = "xyzzy" file_name = "flush" file_path = self.os.path.join(file_dir, file_name) content = "This might be a test." self.os.mkdir(file_dir) fh = self.open(file_path, "w") self.assertEqual(0, self.os.stat(file_path)[stat.ST_SIZE]) self.assertEqual("", self.filesystem.get_object(file_path).contents) fh.write(content) self.assertEqual(0, self.os.stat(file_path)[stat.ST_SIZE]) self.assertEqual("", self.filesystem.get_object(file_path).contents) fh.flush() self.assertEqual(len(content), self.os.stat(file_path)[stat.ST_SIZE]) self.assertEqual(content, self.filesystem.get_object(file_path).contents) fh.close() self.assertEqual(len(content), self.os.stat(file_path)[stat.ST_SIZE]) self.assertEqual(content, self.filesystem.get_object(file_path).contents) def test_file_size_truncation(self): """test that file size gets updated via open().""" file_dir = "xyzzy" file_path = "xyzzy/truncation" content = "AAA content." # pre-create file with content self.os.mkdir(file_dir) fh = self.open(file_path, "w") fh.write(content) fh.close() self.assertEqual(len(content), self.os.stat(file_path)[stat.ST_SIZE]) self.assertEqual(content, self.filesystem.get_object(file_path).contents) # test file truncation fh = self.open(file_path, "w") self.assertEqual(0, self.os.stat(file_path)[stat.ST_SIZE]) self.assertEqual("", self.filesystem.get_object(file_path).contents) fh.close() @unittest.skipIf(not use_scandir, "only run if scandir is available") class FakeScandirTest(FakeOsModuleTestBase): FILE_SIZE = 50 LINKED_FILE_SIZE = 10 def setUp(self): super(FakeScandirTest, self).setUp() self.supports_symlinks = not self.is_windows or not self.use_real_fs() if use_scandir_package: if self.use_real_fs(): from scandir import scandir else: import pyfakefs.fake_scandir def fake_scan_dir(p): return pyfakefs.fake_scandir.scandir(self.filesystem, p) scandir = fake_scan_dir else: scandir = self.os.scandir self.scandir = scandir self.directory = self.make_path("xyzzy", "plugh") link_dir = self.make_path("linked", "plugh") self.linked_file_path = self.os.path.join(link_dir, "file") self.linked_dir_path = self.os.path.join(link_dir, "dir") self.rel_linked_dir_path = self.os.path.join( "..", "..", "linked", "plugh", "dir" ) self.rel_linked_file_path = self.os.path.join( "..", "..", "linked", "plugh", "file" ) self.dir_path = self.os.path.join(self.directory, "dir") self.file_path = self.os.path.join(self.directory, "file") self.file_link_path = self.os.path.join(self.directory, "link_file") self.dir_link_path = self.os.path.join(self.directory, "link_dir") self.file_rel_link_path = self.os.path.join(self.directory, "rel_link_file") self.dir_rel_link_path = self.os.path.join(self.directory, "rel_link_dir") self.create_dir(self.dir_path) self.create_file(self.file_path, contents=b"b" * self.FILE_SIZE) if self.supports_symlinks: self.create_dir(self.linked_dir_path) self.create_file( self.linked_file_path, contents=b"a" * self.LINKED_FILE_SIZE ), self.create_symlink(self.dir_link_path, self.linked_dir_path) self.create_symlink(self.file_link_path, self.linked_file_path) self.create_symlink(self.dir_rel_link_path, self.rel_linked_dir_path) self.create_symlink(self.file_rel_link_path, self.rel_linked_file_path) # Changing the working directory below is to make sure relative paths # to the files and directories created above are reasonable. # Corner-cases about relative paths are better checked in tests created # for that purpose. # # WARNING: This is self.pretest_cwd and not self.cwd as the latter is # used by superclass RealFsTestCase. self.pretest_cwd = self.os.getcwd() self.os.chdir(self.base_path) self.dir_entries = list(self.do_scandir()) self.dir_entries.sort(key=lambda entry: entry.name) def tearDown(self): self.os.chdir(self.pretest_cwd) super().tearDown() def do_scandir(self): """Hook to override how scandir is called.""" return self.scandir(self.directory) def scandir_path(self): """Hook to override the expected scandir() path in DirEntry.path.""" return self.directory def test_paths(self): sorted_names = ["dir", "file"] if self.supports_symlinks: sorted_names.extend( ["link_dir", "link_file", "rel_link_dir", "rel_link_file"] ) self.assertEqual(len(sorted_names), len(self.dir_entries)) self.assertEqual(sorted_names, [entry.name for entry in self.dir_entries]) sorted_paths = [ self.os.path.join(self.scandir_path(), name) for name in sorted_names ] self.assertEqual(sorted_paths, [entry.path for entry in self.dir_entries]) def test_isfile(self): self.assertFalse(self.dir_entries[0].is_file()) self.assertTrue(self.dir_entries[1].is_file()) if self.supports_symlinks: self.assertFalse(self.dir_entries[2].is_file()) self.assertFalse(self.dir_entries[2].is_file(follow_symlinks=False)) self.assertTrue(self.dir_entries[3].is_file()) self.assertFalse(self.dir_entries[3].is_file(follow_symlinks=False)) self.assertFalse(self.dir_entries[4].is_file()) self.assertFalse(self.dir_entries[4].is_file(follow_symlinks=False)) self.assertTrue(self.dir_entries[5].is_file()) self.assertFalse(self.dir_entries[5].is_file(follow_symlinks=False)) def test_isdir(self): self.assertTrue(self.dir_entries[0].is_dir()) self.assertFalse(self.dir_entries[1].is_dir()) if self.supports_symlinks: self.assertTrue(self.dir_entries[2].is_dir()) self.assertFalse(self.dir_entries[2].is_dir(follow_symlinks=False)) self.assertFalse(self.dir_entries[3].is_dir()) self.assertFalse(self.dir_entries[3].is_dir(follow_symlinks=False)) self.assertTrue(self.dir_entries[4].is_dir()) self.assertFalse(self.dir_entries[4].is_dir(follow_symlinks=False)) self.assertFalse(self.dir_entries[5].is_dir()) self.assertFalse(self.dir_entries[5].is_dir(follow_symlinks=False)) def test_is_link(self): if self.supports_symlinks: self.assertFalse(self.dir_entries[0].is_symlink()) self.assertFalse(self.dir_entries[1].is_symlink()) self.assertTrue(self.dir_entries[2].is_symlink()) self.assertTrue(self.dir_entries[3].is_symlink()) self.assertTrue(self.dir_entries[4].is_symlink()) self.assertTrue(self.dir_entries[5].is_symlink()) def test_path_links_not_resolved(self): # regression test for #350 self.skip_if_symlink_not_supported() dir_path = self.make_path("A", "B", "C") self.os.makedirs(self.os.path.join(dir_path, "D")) link_path = self.make_path("A", "C") self.os.symlink(dir_path, link_path) self.assertEqual( [self.os.path.join(link_path, "D")], [f.path for f in self.scandir(link_path)], ) def test_inode(self): if use_scandir and self.use_real_fs(): if self.is_windows: self.skipTest("inode seems not to work in scandir module under Windows") if IN_DOCKER: self.skipTest("inode seems not to work in a Docker container") self.assertEqual( self.os.stat(self.dir_path).st_ino, self.dir_entries[0].inode() ) self.assertEqual( self.os.stat(self.file_path).st_ino, self.dir_entries[1].inode() ) if self.supports_symlinks: self.assertEqual( self.os.lstat(self.dir_link_path).st_ino, self.dir_entries[2].inode(), ) self.assertEqual( self.os.lstat(self.file_link_path).st_ino, self.dir_entries[3].inode(), ) self.assertEqual( self.os.lstat(self.dir_rel_link_path).st_ino, self.dir_entries[4].inode(), ) self.assertEqual( self.os.lstat(self.file_rel_link_path).st_ino, self.dir_entries[5].inode(), ) def test_scandir_stat_nlink(self): # regression test for #350 stat_nlink = self.os.stat(self.file_path).st_nlink self.assertEqual(1, stat_nlink) dir_iter = self.scandir(self.directory) for item in dir_iter: if item.path == self.file_path: scandir_stat_nlink = item.stat().st_nlink if self.is_windows_fs: self.assertEqual(0, scandir_stat_nlink) else: self.assertEqual(1, scandir_stat_nlink) self.assertEqual(1, self.os.stat(self.file_path).st_nlink) @unittest.skipIf(not hasattr(os, "O_DIRECTORY"), "opening directory not supported") @unittest.skipIf(sys.version_info < (3, 7), "fd not supported for scandir") def test_scandir_with_fd(self): # regression test for #723 temp_dir = self.make_path("tmp", "dir") self.create_dir(temp_dir) self.create_file(self.os.path.join(temp_dir, "file1")) self.create_file(self.os.path.join(temp_dir, "file2")) self.create_dir(self.os.path.join(temp_dir, "subdir")) self.os.chdir(temp_dir) fd = self.os.open(temp_dir, flags=os.O_RDONLY | os.O_DIRECTORY) children = [dir_entry.name for dir_entry in self.os.scandir(fd)] assert sorted(children) == ["file1", "file2", "subdir"] def check_stat( self, absolute_symlink_expected_size, relative_symlink_expected_size ): self.assertEqual(self.FILE_SIZE, self.dir_entries[1].stat().st_size) if not self.is_windows_fs or sys.version_info < (3, 12): # behavior of st_ctime changed in 3.12, to be adapted later self.assertEqual( int(self.os.stat(self.dir_path).st_ctime), int(self.dir_entries[0].stat().st_ctime), ) if self.supports_symlinks: self.assertEqual(self.LINKED_FILE_SIZE, self.dir_entries[3].stat().st_size) self.assertEqual( absolute_symlink_expected_size, self.dir_entries[3].stat(follow_symlinks=False).st_size, ) self.assertEqual( int(self.os.stat(self.linked_dir_path).st_mtime), int(self.dir_entries[2].stat().st_mtime), ) self.assertEqual(self.LINKED_FILE_SIZE, self.dir_entries[5].stat().st_size) self.assertEqual( relative_symlink_expected_size, self.dir_entries[5].stat(follow_symlinks=False).st_size, ) self.assertEqual( int(self.os.stat(self.linked_dir_path).st_mtime), int(self.dir_entries[4].stat().st_mtime), ) @unittest.skipIf(TestCase.is_windows, "POSIX specific behavior") def test_stat_posix(self): self.check_stat(len(self.linked_file_path), len(self.rel_linked_file_path)) @unittest.skipIf(not TestCase.is_windows, "Windows specific behavior") def test_stat_windows(self): self.check_stat(0, 0) def test_index_access_to_stat_times_returns_int(self): if not self.is_windows_fs or sys.version_info < (3, 12): # behavior of st_ctime changed in 3.12, to be adapted later self.assertEqual( self.os.stat(self.dir_path)[stat.ST_CTIME], int(self.dir_entries[0].stat().st_ctime), ) if self.supports_symlinks: self.assertEqual( self.os.stat(self.linked_dir_path)[stat.ST_MTIME], int(self.dir_entries[2].stat().st_mtime), ) self.assertEqual( self.os.stat(self.linked_dir_path)[stat.ST_MTIME], int(self.dir_entries[4].stat().st_mtime), ) def test_stat_ino_dev(self): if self.supports_symlinks: file_stat = self.os.stat(self.linked_file_path) self.assertEqual(file_stat.st_ino, self.dir_entries[3].stat().st_ino) self.assertEqual(file_stat.st_dev, self.dir_entries[3].stat().st_dev) self.assertEqual(file_stat.st_ino, self.dir_entries[5].stat().st_ino) self.assertEqual(file_stat.st_dev, self.dir_entries[5].stat().st_dev) @unittest.skipIf( sys.version_info < (3, 6) or not use_builtin_scandir, "Path-like objects have been introduced in Python 3.6", ) def test_path_like(self): self.assertTrue(isinstance(self.dir_entries[0], os.PathLike)) self.assertEqual( self.os.path.join(self.scandir_path(), "dir"), os.fspath(self.dir_entries[0]), ) self.assertEqual( self.os.path.join(self.scandir_path(), "file"), os.fspath(self.dir_entries[1]), ) def test_non_existing_dir(self): # behaves differently in different systems, so we skip the real fs test self.skip_real_fs() self.assert_raises_os_error(errno.ENOENT, self.scandir, "non_existing/fake_dir") class RealScandirTest(FakeScandirTest): def use_real_fs(self): return True class FakeScandirRelTest(FakeScandirTest): def scandir_path(self): # When scandir is called with a relative path, that relative path is # used in the path attribute of the DirEntry objects. return self.os.path.relpath(self.directory) def do_scandir(self): return self.scandir(self.os.path.relpath(self.directory)) class RealScandirRelTest(FakeScandirRelTest): def use_real_fs(self): return True @unittest.skipIf(TestCase.is_windows, "dir_fd not supported for os.scandir in Windows") @unittest.skipIf(use_scandir_package, "no dir_fd support for scandir package") class FakeScandirFdTest(FakeScandirTest): def tearDown(self): self.os.close(self.dir_fd) super(FakeScandirFdTest, self).tearDown() def scandir_path(self): # When scandir is called with a filedescriptor, only the name of the # entry is returned in the path attribute of the DirEntry objects. return "" def do_scandir(self): self.dir_fd = self.os.open(self.directory, os.O_RDONLY) return self.scandir(self.dir_fd) class RealScandirFdTest(FakeScandirFdTest): def use_real_fs(self): return True class FakeScandirFdRelTest(FakeScandirFdTest): def do_scandir(self): self.dir_fd = self.os.open(self.os.path.relpath(self.directory), os.O_RDONLY) return self.scandir(self.dir_fd) class RealScandirFdRelTest(FakeScandirFdRelTest): def use_real_fs(self): return True class FakeExtendedAttributeTest(FakeOsModuleTestBase): def setUp(self): super(FakeExtendedAttributeTest, self).setUp() self.check_linux_only() self.dir_path = self.make_path("foo") self.file_path = self.os.path.join(self.dir_path, "bar") self.create_file(self.file_path) def test_empty_xattr(self): self.assertEqual([], self.os.listxattr(self.dir_path)) self.assertEqual([], self.os.listxattr(self.file_path)) def test_setxattr(self): self.assertRaises(TypeError, self.os.setxattr, self.file_path, "test", "value") self.assert_raises_os_error( errno.EEXIST, self.os.setxattr, self.file_path, "test", b"value", self.os.XATTR_REPLACE, ) self.os.setxattr(self.file_path, "test", b"value") self.assertEqual(b"value", self.os.getxattr(self.file_path, "test")) self.assert_raises_os_error( errno.ENODATA, self.os.setxattr, self.file_path, "test", b"value", self.os.XATTR_CREATE, ) def test_removeattr(self): self.os.removexattr(self.file_path, "test") self.assertEqual([], self.os.listxattr(self.file_path)) self.os.setxattr(self.file_path, b"test", b"value") self.assertEqual(["test"], self.os.listxattr(self.file_path)) self.assertEqual(b"value", self.os.getxattr(self.file_path, "test")) self.os.removexattr(self.file_path, "test") self.assertEqual([], self.os.listxattr(self.file_path)) self.assertIsNone(self.os.getxattr(self.file_path, "test")) def test_default_path(self): self.os.chdir(self.dir_path) self.os.setxattr(self.dir_path, b"test", b"value") self.assertEqual(["test"], self.os.listxattr()) self.assertEqual(b"value", self.os.getxattr(self.dir_path, "test")) class FakeOsUnreadableDirTest(FakeOsModuleTestBase): def setUp(self): if self.use_real_fs(): # unreadable dirs in Windows are only simulated # and cannot be created in the real OS using file system # functions only self.check_posix_only() super(FakeOsUnreadableDirTest, self).setUp() self.dir_path = self.make_path("some_dir") self.file_path = self.os.path.join(self.dir_path, "some_file") self.create_file(self.file_path) self.chmod(self.dir_path, 0o000) def chmod(self, path, mode): if self.is_windows_fs: self.filesystem.chmod(path, mode, force_unix_mode=True) else: self.os.chmod(path, mode) def test_getuid(self): self.skip_real_fs() # won't change user in real fs self.check_posix_only() uid = self.os.getuid() set_uid(uid + 10) self.assertEqual(uid + 10, self.os.getuid()) self.assertEqual(uid + 10, get_uid()) set_uid(uid) self.assertEqual(uid, self.os.getuid()) def test_getgid(self): self.skip_real_fs() # won't change group in real fs self.check_posix_only() gid = self.os.getgid() set_gid(gid + 10) self.assertEqual(gid + 10, self.os.getgid()) self.assertEqual(gid + 10, get_gid()) set_gid(gid) self.assertEqual(gid, self.os.getgid()) def test_listdir_unreadable_dir(self): if not is_root(): self.assert_raises_os_error(errno.EACCES, self.os.listdir, self.dir_path) else: self.assertEqual(["some_file"], self.os.listdir(self.dir_path)) def test_listdir_user_readable_dir(self): self.chmod(self.dir_path, 0o600) self.assertEqual(["some_file"], self.os.listdir(self.dir_path)) self.chmod(self.dir_path, 0o000) def test_listdir_user_readable_dir_from_other_user(self): self.skip_real_fs() # won't change user in real fs self.check_posix_only() user_id = get_uid() set_uid(user_id + 1) dir_path = self.make_path("dir1") self.create_dir(dir_path, perm=0o600) self.assertTrue(self.os.path.exists(dir_path)) set_uid(user_id) if not is_root(): with self.assertRaises(PermissionError): self.os.listdir(dir_path) else: self.assertEqual(["some_file"], self.os.listdir(self.dir_path)) def test_listdir_group_readable_dir_from_other_user(self): self.skip_real_fs() # won't change user in real fs user_id = get_uid() set_uid(user_id + 1) dir_path = self.make_path("dir1") self.create_dir(dir_path, perm=0o660) self.assertTrue(self.os.path.exists(dir_path)) set_uid(user_id) self.assertEqual([], self.os.listdir(dir_path)) def test_listdir_group_readable_dir_from_other_group(self): self.skip_real_fs() # won't change user in real fs self.check_posix_only() group_id = self.os.getgid() set_gid(group_id + 1) dir_path = self.make_path("dir1") self.create_dir(dir_path, perm=0o060) self.assertTrue(self.os.path.exists(dir_path)) set_gid(group_id) if not is_root(): with self.assertRaises(PermissionError): self.os.listdir(dir_path) else: self.assertEqual([], self.os.listdir(dir_path)) def test_listdir_other_readable_dir_from_other_group(self): self.skip_real_fs() # won't change user in real fs group_id = get_gid() set_gid(group_id + 1) dir_path = self.make_path("dir1") self.create_dir(dir_path, perm=0o004) self.assertTrue(self.os.path.exists(dir_path)) set_gid(group_id) self.assertEqual([], self.os.listdir(dir_path)) def test_stat_unreadable_dir(self): self.assertEqual(0, self.os.stat(self.dir_path).st_mode & 0o666) def test_chmod_unreadable_dir(self): self.chmod(self.dir_path, 0o666) self.assertEqual(0o666, self.os.stat(self.dir_path).st_mode & 0o666) self.chmod(self.dir_path, 0o000) self.assertEqual(0, self.os.stat(self.dir_path).st_mode & 0o666) def test_stat_file_in_unreadable_dir(self): if not is_root(): self.assert_raises_os_error(errno.EACCES, self.os.stat, self.file_path) else: self.assertEqual(0, self.os.stat(self.file_path).st_size) def test_remove_unreadable_dir(self): self.check_posix_only() dir_path = self.make_path("dir1") self.create_dir(dir_path, perm=0o000) self.assertTrue(self.os.path.exists(dir_path)) self.os.rmdir(dir_path) self.assertFalse(self.os.path.exists(dir_path)) def test_remove_unreadable_dir_from_other_user(self): self.skip_real_fs() # won't change user in real fs user_id = get_uid() set_uid(user_id + 1) dir_path = self.make_path("dir1") self.create_dir(dir_path, perm=0o000) self.assertTrue(self.os.path.exists(dir_path)) set_uid(user_id) if not is_root(): with self.assertRaises(PermissionError): self.os.rmdir(dir_path) self.assertTrue(self.os.path.exists(dir_path)) else: self.os.rmdir(dir_path) self.assertFalse(self.os.path.exists(dir_path)) class RealOsUnreadableDirTest(FakeOsUnreadableDirTest): def use_real_fs(self): return True tests/fake_pathlib_test.py000064400000137255150043321530011741 0ustar00# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """ Unittests for fake_pathlib. As most of fake_pathlib is a wrapper around fake_filesystem methods, the tests are there mostly to ensure basic functionality. Note that many of the tests are directly taken from examples in the python docs. """ import errno import os import pathlib import stat import sys import unittest from collections import namedtuple from unittest import mock from pyfakefs import fake_pathlib, fake_filesystem, fake_filesystem_unittest, fake_os from pyfakefs.fake_filesystem import OSType from pyfakefs.helpers import IS_PYPY, is_root from pyfakefs.tests.test_utils import RealFsTestMixin is_windows = sys.platform == "win32" class RealPathlibTestCase(fake_filesystem_unittest.TestCase, RealFsTestMixin): is_windows = sys.platform == "win32" def __init__(self, methodName="runTest"): fake_filesystem_unittest.TestCase.__init__(self, methodName) RealFsTestMixin.__init__(self) def setUp(self): RealFsTestMixin.setUp(self) self.filesystem = None self.real_os = os if not self.use_real_fs(): self.setUpPyfakefs() self.filesystem = self.fs self.create_basepath() self.pathlib = pathlib self.path = pathlib.Path self.os = os self.open = open def use_real_fs(self): return False class FakePathlibInitializationTest(RealPathlibTestCase): def test_initialization_type(self): """Make sure tests for class type will work""" path = self.path("/test") if is_windows: self.assertTrue(isinstance(path, self.pathlib.WindowsPath)) self.assertTrue(isinstance(path, self.pathlib.PureWindowsPath)) self.assertTrue(self.pathlib.PurePosixPath()) # in fake fs, we allow to use the other OS implementation if self.use_real_fs(): with self.assertRaises(NotImplementedError): self.pathlib.PosixPath() else: self.assertTrue(self.pathlib.PosixPath()) else: self.assertTrue(isinstance(path, self.pathlib.PosixPath)) self.assertTrue(isinstance(path, self.pathlib.PurePosixPath)) self.assertTrue(self.pathlib.PureWindowsPath()) if self.use_real_fs(): with self.assertRaises(NotImplementedError): self.pathlib.WindowsPath() else: self.assertTrue(self.pathlib.WindowsPath()) def test_init_with_segments(self): """Basic initialization tests - taken from pathlib.Path documentation. """ self.assertEqual(self.path("/", "foo", "bar", "baz"), self.path("/foo/bar/baz")) self.assertEqual(self.path(), self.path(".")) self.assertEqual( self.path(self.path("foo"), self.path("bar")), self.path("foo/bar") ) self.assertEqual( self.path("/etc") / "init.d" / "reboot", self.path("/etc/init.d/reboot"), ) def test_init_collapse(self): """Tests for collapsing path during initialization. Taken from pathlib.PurePath documentation. """ self.assertEqual(self.path("foo//bar"), self.path("foo/bar")) self.assertEqual(self.path("foo/./bar"), self.path("foo/bar")) self.assertNotEqual(self.path("foo/../bar"), self.path("foo/bar")) self.assertEqual(self.path("/etc", "/usr", "lib64"), self.path("/usr/lib64")) def test_path_parts(self): sep = self.os.path.sep path = self.path(sep + self.os.path.join("foo", "bar", "setup.py")) self.assertEqual(path.parts, (sep, "foo", "bar", "setup.py")) self.assertEqual(path.drive, "") self.assertEqual(path.root, sep) self.assertEqual(path.anchor, sep) self.assertEqual(path.name, "setup.py") self.assertEqual(path.stem, "setup") self.assertEqual(path.suffix, ".py") self.assertEqual(path.parent, self.path(sep + self.os.path.join("foo", "bar"))) self.assertEqual( path.parents[0], self.path(sep + self.os.path.join("foo", "bar")) ) self.assertEqual(path.parents[1], self.path(sep + "foo")) self.assertEqual(path.parents[2], self.path(sep)) @unittest.skipIf(is_windows, "POSIX specific behavior") def test_is_absolute_posix(self): self.assertTrue(self.path("/a/b").is_absolute()) self.assertFalse(self.path("a/b").is_absolute()) self.assertFalse(self.path("d:/b").is_absolute()) @unittest.skipIf(not is_windows, "Windows specific behavior") def test_is_absolute_windows(self): self.assertFalse(self.path("/a/b").is_absolute()) self.assertFalse(self.path("a/b").is_absolute()) self.assertTrue(self.path("d:/b").is_absolute()) class RealPathlibInitializationTest(FakePathlibInitializationTest): def use_real_fs(self): return True @unittest.skipIf(not is_windows, "Windows specific behavior") class FakePathlibInitializationWithDriveTest(RealPathlibTestCase): def test_init_with_segments(self): """Basic initialization tests - taken from pathlib.Path documentation""" self.assertEqual( self.path("c:/", "foo", "bar", "baz"), self.path("c:/foo/bar/baz") ) self.assertEqual(self.path(), self.path(".")) self.assertEqual( self.path(self.path("foo"), self.path("bar")), self.path("foo/bar") ) self.assertEqual( self.path("c:/Users") / "john" / "data", self.path("c:/Users/john/data"), ) def test_init_collapse(self): """Tests for collapsing path during initialization. Taken from pathlib.PurePath documentation. """ self.assertEqual(self.path("c:/Windows", "d:bar"), self.path("d:bar")) self.assertEqual( self.path("c:/Windows", "/Program Files"), self.path("c:/Program Files"), ) def test_path_parts(self): path = self.path(self.os.path.join("d:", "python scripts", "setup.py")) self.assertEqual(path.parts, ("d:", "python scripts", "setup.py")) self.assertEqual(path.drive, "d:") self.assertEqual(path.root, "") self.assertEqual(path.anchor, "d:") self.assertEqual(path.name, "setup.py") self.assertEqual(path.stem, "setup") self.assertEqual(path.suffix, ".py") self.assertEqual( path.parent, self.path(self.os.path.join("d:", "python scripts")) ) self.assertEqual( path.parents[0], self.path(self.os.path.join("d:", "python scripts")), ) self.assertEqual(path.parents[1], self.path("d:")) @unittest.skipIf(not is_windows, "Windows-specifc behavior") def test_is_absolute(self): self.assertTrue(self.path("c:/a/b").is_absolute()) self.assertFalse(self.path("/a/b").is_absolute()) self.assertFalse(self.path("c:").is_absolute()) self.assertTrue(self.path("//some/share").is_absolute()) class RealPathlibInitializationWithDriveTest(FakePathlibInitializationWithDriveTest): def use_real_fs(self): return True class FakePathlibPurePathTest(RealPathlibTestCase): """Tests functionality present in PurePath class.""" def test_is_reserved_posix(self): self.check_posix_only() self.assertFalse(self.path("/dev").is_reserved()) self.assertFalse(self.path("/").is_reserved()) self.assertFalse(self.path("COM1").is_reserved()) self.assertFalse(self.path("nul.txt").is_reserved()) @unittest.skipIf(not is_windows, "Windows specific behavior") def test_is_reserved_windows(self): self.check_windows_only() self.assertFalse(self.path("/dev").is_reserved()) self.assertFalse(self.path("/").is_reserved()) self.assertTrue(self.path("COM1").is_reserved()) self.assertTrue(self.path("nul.txt").is_reserved()) def test_joinpath(self): self.assertEqual(self.path("/etc").joinpath("passwd"), self.path("/etc/passwd")) self.assertEqual( self.path("/etc").joinpath(self.path("passwd")), self.path("/etc/passwd"), ) self.assertEqual( self.path("/foo").joinpath("bar", "baz"), self.path("/foo/bar/baz") ) def test_joinpath_drive(self): self.check_windows_only() self.assertEqual( self.path("c:").joinpath("/Program Files"), self.path("c:/Program Files"), ) def test_match(self): self.assertTrue(self.path("a/b.py").match("*.py")) self.assertTrue(self.path("/a/b/c.py").match("b/*.py")) self.assertFalse(self.path("/a/b/c.py").match("a/*.py")) self.assertTrue(self.path("/a.py").match("/*.py")) self.assertFalse(self.path("a/b.py").match("/*.py")) def test_relative_to(self): self.assertEqual( self.path("/etc/passwd").relative_to("/"), self.path("etc/passwd") ) self.assertEqual( self.path("/etc/passwd").relative_to("/"), self.path("etc/passwd") ) with self.assertRaises(ValueError): self.path("passwd").relative_to("/usr") @unittest.skipIf(sys.version_info < (3, 9), "is_relative_to new in Python 3.9") def test_is_relative_to(self): path = self.path("/etc/passwd") self.assertTrue(path.is_relative_to("/etc")) self.assertFalse(path.is_relative_to("/src")) def test_with_name(self): self.check_windows_only() self.assertEqual( self.path("c:/Downloads/pathlib.tar.gz").with_name("setup.py"), self.path("c:/Downloads/setup.py"), ) with self.assertRaises(ValueError): self.path("c:/").with_name("setup.py") def test_with_suffix(self): self.assertEqual( self.path("c:/Downloads/pathlib.tar.gz").with_suffix(".bz2"), self.path("c:/Downloads/pathlib.tar.bz2"), ) self.assertEqual( self.path("README").with_suffix(".txt"), self.path("README.txt") ) class RealPathlibPurePathTest(FakePathlibPurePathTest): def use_real_fs(self): return True class FakePathlibFileObjectPropertyTest(RealPathlibTestCase): def setUp(self): super(FakePathlibFileObjectPropertyTest, self).setUp() self.file_path = self.make_path("home", "jane", "test.py") self.create_file(self.file_path, contents=b"a" * 100) self.create_dir(self.make_path("home", "john")) try: self.skip_if_symlink_not_supported() except unittest.SkipTest: return self.create_symlink(self.make_path("john"), self.make_path("home", "john")) self.file_link_path = self.make_path("test.py") self.create_symlink(self.file_link_path, self.file_path) self.create_symlink( self.make_path("broken_dir_link"), self.make_path("home", "none") ) self.create_symlink( self.make_path("broken_file_link"), self.make_path("home", "none", "test.py"), ) def test_exists(self): self.skip_if_symlink_not_supported() self.assertTrue(self.path(self.file_path).exists()) self.assertTrue(self.path(self.make_path("home", "jane")).exists()) self.assertFalse(self.path(self.make_path("home", "jane", "test")).exists()) self.assertTrue(self.path(self.make_path("john")).exists()) self.assertTrue(self.path(self.file_link_path).exists()) self.assertFalse(self.path(self.make_path("broken_dir_link")).exists()) self.assertFalse(self.path(self.make_path("broken_file_link")).exists()) def test_is_dir(self): self.skip_if_symlink_not_supported() self.assertFalse(self.path(self.file_path).is_dir()) self.assertTrue(self.path(self.make_path("home/jane")).is_dir()) self.assertTrue(self.path(self.make_path("john")).is_dir()) self.assertFalse(self.path(self.file_link_path).is_dir()) self.assertFalse(self.path(self.make_path("broken_dir_link")).is_dir()) self.assertFalse(self.path(self.make_path("broken_file_link")).is_dir()) def test_is_file(self): self.skip_if_symlink_not_supported() self.assertTrue(self.path(self.make_path("home/jane/test.py")).is_file()) self.assertFalse(self.path(self.make_path("home/jane")).is_file()) self.assertFalse(self.path(self.make_path("john")).is_file()) self.assertTrue(self.path(self.file_link_path).is_file()) self.assertFalse(self.path(self.make_path("broken_dir_link")).is_file()) self.assertFalse(self.path(self.make_path("broken_file_link")).is_file()) def test_is_symlink(self): self.skip_if_symlink_not_supported() self.assertFalse(self.path(self.make_path("home/jane/test.py")).is_symlink()) self.assertFalse(self.path(self.make_path("home/jane")).is_symlink()) self.assertTrue(self.path(self.make_path("john")).is_symlink()) self.assertTrue(self.path(self.file_link_path).is_symlink()) self.assertTrue(self.path(self.make_path("broken_dir_link")).is_symlink()) self.assertTrue(self.path(self.make_path("broken_file_link")).is_symlink()) def test_stat(self): self.skip_if_symlink_not_supported() file_stat = self.os.stat(self.file_path) stat_result = self.path(self.file_link_path).stat() self.assertFalse(stat_result.st_mode & stat.S_IFDIR) self.assertTrue(stat_result.st_mode & stat.S_IFREG) self.assertEqual(stat_result.st_ino, file_stat.st_ino) self.assertEqual(stat_result.st_size, 100) self.assertEqual(stat_result.st_mtime, file_stat.st_mtime) self.assertEqual(stat_result[stat.ST_MTIME], int(file_stat.st_mtime)) def check_lstat(self, expected_size): self.skip_if_symlink_not_supported() link_stat = self.os.lstat(self.file_link_path) stat_result = self.path(self.file_link_path).lstat() self.assertTrue(stat_result.st_mode & stat.S_IFREG) self.assertTrue(stat_result.st_mode & stat.S_IFLNK) self.assertEqual(stat_result.st_ino, link_stat.st_ino) self.assertEqual(stat_result.st_size, expected_size) self.assertEqual(stat_result.st_mtime, link_stat.st_mtime) @unittest.skipIf(is_windows, "POSIX specific behavior") def test_lstat_posix(self): self.check_lstat(len(self.file_path)) @unittest.skipIf(not is_windows, "Windows specific behavior") def test_lstat_windows(self): self.skip_if_symlink_not_supported() self.check_lstat(0) @unittest.skipIf(is_windows, "Linux specific behavior") def test_chmod(self): self.check_linux_only() file_stat = self.os.stat(self.file_path) self.assertEqual(file_stat.st_mode, stat.S_IFREG | 0o666) link_stat = self.os.lstat(self.file_link_path) # we get stat.S_IFLNK | 0o755 under MacOs self.assertEqual(link_stat.st_mode, stat.S_IFLNK | 0o777) def test_lchmod(self): self.skip_if_symlink_not_supported() file_stat = self.os.stat(self.file_path) link_stat = self.os.lstat(self.file_link_path) if not hasattr(self.real_os, "lchmod"): with self.assertRaises(NotImplementedError): self.path(self.file_link_path).lchmod(0o444) else: self.path(self.file_link_path).lchmod(0o444) self.assertEqual(file_stat.st_mode, stat.S_IFREG | 0o666) # the exact mode depends on OS and Python version self.assertEqual(link_stat.st_mode & 0o777700, stat.S_IFLNK | 0o700) @unittest.skipIf( sys.version_info < (3, 10), "follow_symlinks argument new in Python 3.10", ) def test_chmod_no_followsymlinks(self): self.skip_if_symlink_not_supported() file_stat = self.os.stat(self.file_path) link_stat = self.os.lstat(self.file_link_path) if self.os.chmod not in self.os.supports_follow_symlinks or IS_PYPY: with self.assertRaises(NotImplementedError): self.path(self.file_link_path).chmod(0o444, follow_symlinks=False) else: self.path(self.file_link_path).chmod(0o444, follow_symlinks=False) self.assertEqual(file_stat.st_mode, stat.S_IFREG | 0o666) # the exact mode depends on OS and Python version self.assertEqual(link_stat.st_mode & 0o777700, stat.S_IFLNK | 0o700) def test_resolve(self): self.create_dir(self.make_path("antoine", "docs")) self.create_file(self.make_path("antoine", "setup.py")) self.os.chdir(self.make_path("antoine")) # use real path to handle symlink /var to /private/var in MacOs self.assert_equal_paths( self.path().resolve(), self.path(self.os.path.realpath(self.make_path("antoine"))), ) self.assert_equal_paths( self.path(self.os.path.join("docs", "..", "setup.py")).resolve(), self.path(self.os.path.realpath(self.make_path("antoine", "setup.py"))), ) def test_stat_file_in_unreadable_dir(self): self.check_posix_only() dir_path = self.make_path("some_dir") file_path = self.os.path.join(dir_path, "some_file") self.create_file(file_path) self.os.chmod(dir_path, 0o000) if not is_root(): self.assert_raises_os_error(errno.EACCES, self.path(file_path).stat) else: self.assertEqual(0, self.path(file_path).stat().st_size) def test_iterdir_in_unreadable_dir(self): self.check_posix_only() dir_path = self.make_path("some_dir") file_path = self.os.path.join(dir_path, "some_file") self.create_file(file_path) self.os.chmod(dir_path, 0o000) it = self.path(dir_path).iterdir() if not is_root(): self.assert_raises_os_error(errno.EACCES, list, it) else: path = str(list(it)[0]) self.assertTrue(path.endswith("some_file")) def test_resolve_nonexisting_file(self): path = self.path(self.make_path("/path", "to", "file", "this can not exist")) self.assertEqual(path, path.resolve()) def test_cwd(self): dir_path = self.make_path("jane") self.create_dir(dir_path) self.os.chdir(dir_path) self.assert_equal_paths( self.path.cwd(), self.path(self.os.path.realpath(dir_path)) ) def test_expanduser(self): if is_windows: self.assertEqual( self.path("~").expanduser(), self.path(os.environ["USERPROFILE"].replace("\\", "/")), ) else: self.assertEqual(self.path("~").expanduser(), self.path(os.environ["HOME"])) def test_home(self): if is_windows: self.assertEqual( self.path(os.environ["USERPROFILE"].replace("\\", "/")), self.path.home(), ) else: self.assertEqual(self.path(os.environ["HOME"]), self.path.home()) class RealPathlibFileObjectPropertyTest(FakePathlibFileObjectPropertyTest): def use_real_fs(self): return True class FakePathlibPathFileOperationTest(RealPathlibTestCase): """Tests methods related to file and directory handling.""" def test_exists(self): self.skip_if_symlink_not_supported() self.create_file(self.make_path("home", "jane", "test.py")) self.create_dir(self.make_path("home", "john")) self.create_symlink(self.make_path("john"), self.make_path("home", "john")) self.create_symlink(self.make_path("none"), self.make_path("home", "none")) self.assertTrue(self.path(self.make_path("home", "jane", "test.py")).exists()) self.assertTrue(self.path(self.make_path("home", "jane")).exists()) self.assertTrue(self.path(self.make_path("john")).exists()) self.assertFalse(self.path(self.make_path("none")).exists()) self.assertFalse(self.path(self.make_path("home", "jane", "test")).exists()) def test_open(self): self.create_dir(self.make_path("foo")) with self.assertRaises(OSError): self.path(self.make_path("foo", "bar.txt")).open() self.path(self.make_path("foo", "bar.txt")).open("w").close() self.assertTrue(self.os.path.exists(self.make_path("foo", "bar.txt"))) def test_read_text(self): self.create_file(self.make_path("text_file"), contents="foo") file_path = self.path(self.make_path("text_file")) self.assertEqual(file_path.read_text(), "foo") @unittest.skipIf( sys.version_info < (3, 12), "is_junction method new in Python 3.12", ) def test_is_junction(self): self.create_file(self.make_path("text_file"), contents="foo") file_path = self.path(self.make_path("text_file")) self.assertFalse(file_path.is_junction()) def test_read_text_with_encoding(self): self.create_file( self.make_path("text_file"), contents="ерунда", encoding="cyrillic" ) file_path = self.path(self.make_path("text_file")) self.assertEqual(file_path.read_text(encoding="cyrillic"), "ерунда") def test_write_text(self): path_name = self.make_path("text_file") file_path = self.path(path_name) file_path.write_text(str("foo")) self.assertTrue(self.os.path.exists(path_name)) self.check_contents(path_name, "foo") def test_write_text_with_encoding(self): path_name = self.make_path("text_file") file_path = self.path(path_name) file_path.write_text("ανοησίες", encoding="greek") self.assertTrue(self.os.path.exists(path_name)) self.check_contents(path_name, "ανοησίες".encode("greek")) @unittest.skipIf(sys.version_info < (3, 10), "newline argument new in Python 3.10") def test_write_with_newline_arg(self): path = self.path(self.make_path("some_file")) path.write_text("1\r\n2\n3\r4", newline="") self.check_contents(path, b"1\r\n2\n3\r4") path.write_text("1\r\n2\n3\r4", newline="\n") self.check_contents(path, b"1\r\n2\n3\r4") path.write_text("1\r\n2\n3\r4", newline="\r\n") self.check_contents(path, b"1\r\r\n2\r\n3\r4") path.write_text("1\r\n2\n3\r4", newline="\r") self.check_contents(path, b"1\r\r2\r3\r4") def test_read_bytes(self): path_name = self.make_path("binary_file") self.create_file(path_name, contents=b"Binary file contents") file_path = self.path(path_name) self.assertEqual(file_path.read_bytes(), b"Binary file contents") def test_write_bytes(self): path_name = self.make_path("binary_file") file_path = self.path(path_name) file_path.write_bytes(b"Binary file contents") self.assertTrue(self.os.path.exists(path_name)) self.check_contents(path_name, b"Binary file contents") def test_rename(self): file_name = self.make_path("foo", "bar.txt") self.create_file(file_name, contents="test") new_file_name = self.make_path("foo", "baz.txt") self.path(file_name).rename(new_file_name) self.assertFalse(self.os.path.exists(file_name)) self.check_contents(new_file_name, "test") def test_replace(self): self.create_file(self.make_path("foo", "bar.txt"), contents="test") self.create_file(self.make_path("bar", "old.txt"), contents="replaced") self.path(self.make_path("bar", "old.txt")).replace( self.make_path("foo", "bar.txt") ) self.assertFalse(self.os.path.exists(self.make_path("bar", "old.txt"))) self.check_contents(self.make_path("foo", "bar.txt"), "replaced") def test_unlink(self): file_path = self.make_path("foo", "bar.txt") self.create_file(file_path, contents="test") self.assertTrue(self.os.path.exists(file_path)) self.path(file_path).unlink() self.assertFalse(self.os.path.exists(file_path)) def test_touch_non_existing(self): self.create_dir(self.make_path("foo")) file_name = self.make_path("foo", "bar.txt") self.path(file_name).touch(mode=0o444) self.check_contents(file_name, "") self.assertTrue(self.os.stat(file_name).st_mode, stat.S_IFREG | 0o444) self.os.chmod(file_name, mode=0o666) def test_touch_existing(self): file_name = self.make_path("foo", "bar.txt") self.create_file(file_name, contents="test") file_path = self.path(file_name) self.assert_raises_os_error(errno.EEXIST, file_path.touch, exist_ok=False) file_path.touch() self.check_contents(file_name, "test") def test_samefile(self): file_name = self.make_path("foo", "bar.txt") self.create_file(file_name) file_name2 = self.make_path("foo", "baz.txt") self.create_file(file_name2) with self.assertRaises(OSError): self.path(self.make_path("foo", "other")).samefile( self.make_path("foo", "other.txt") ) path = self.path(file_name) other_name = self.make_path("foo", "other.txt") with self.assertRaises(OSError): path.samefile(other_name) with self.assertRaises(OSError): path.samefile(self.path(other_name)) self.assertFalse(path.samefile(file_name2)) self.assertFalse(path.samefile(self.path(file_name2))) self.assertTrue(path.samefile(self.make_path("foo", "..", "foo", "bar.txt"))) self.assertTrue( path.samefile(self.path(self.make_path("foo", "..", "foo", "bar.txt"))) ) def test_symlink_to(self): self.skip_if_symlink_not_supported() file_name = self.make_path("foo", "bar.txt") self.create_file(file_name) link_name = self.make_path("link_to_bar") path = self.path(link_name) path.symlink_to(file_name) self.assertTrue(self.os.path.exists(link_name)) self.assertTrue(path.is_symlink()) @unittest.skipIf(sys.version_info < (3, 8), "link_to new in Python 3.8") @unittest.skipIf(sys.version_info >= (3, 12), "link_to removed in Python 3.12") def test_link_to(self): self.skip_if_symlink_not_supported() file_name = self.make_path("foo", "bar.txt") self.create_file(file_name) self.assertEqual(1, self.os.stat(file_name).st_nlink) link_name = self.make_path("link_to_bar") path = self.path(file_name) path.link_to(link_name) self.assertTrue(self.os.path.exists(link_name)) self.assertFalse(path.is_symlink()) self.assertEqual(2, self.os.stat(file_name).st_nlink) @unittest.skipIf(sys.version_info < (3, 10), "hardlink_to new in Python 3.10") def test_hardlink_to(self): self.skip_if_symlink_not_supported() file_name = self.make_path("foo", "bar.txt") self.create_file(file_name) self.assertEqual(1, self.os.stat(file_name).st_nlink) link_path = self.path(self.make_path("link_to_bar")) path = self.path(file_name) link_path.hardlink_to(path) self.assertTrue(self.os.path.exists(link_path)) self.assertFalse(path.is_symlink()) self.assertEqual(2, self.os.stat(file_name).st_nlink) @unittest.skipIf(sys.version_info < (3, 9), "readlink new in Python 3.9") def test_readlink(self): self.skip_if_symlink_not_supported() link_path = self.make_path("foo", "bar", "baz") target = self.make_path("tarJAY") self.create_symlink(link_path, target) path = self.path(link_path) self.assert_equal_paths(path.readlink(), self.path(target)) def test_mkdir(self): dir_name = self.make_path("foo", "bar") self.assert_raises_os_error(errno.ENOENT, self.path(dir_name).mkdir) self.path(dir_name).mkdir(parents=True) self.assertTrue(self.os.path.exists(dir_name)) self.assert_raises_os_error(errno.EEXIST, self.path(dir_name).mkdir) def test_mkdir_exist_ok(self): dir_name = self.make_path("foo", "bar") self.create_dir(dir_name) self.path(dir_name).mkdir(exist_ok=True) file_name = self.os.path.join(dir_name, "baz") self.create_file(file_name) self.assert_raises_os_error( errno.EEXIST, self.path(file_name).mkdir, exist_ok=True ) def test_rmdir(self): dir_name = self.make_path("foo", "bar") self.create_dir(dir_name) self.path(dir_name).rmdir() self.assertFalse(self.os.path.exists(dir_name)) self.assertTrue(self.os.path.exists(self.make_path("foo"))) self.create_file(self.make_path("foo", "baz")) with self.assertRaises(OSError): self.path(self.make_path("foo")).rmdir() self.assertTrue(self.os.path.exists(self.make_path("foo"))) def test_iterdir(self): self.create_file(self.make_path("foo", "bar", "file1")) self.create_file(self.make_path("foo", "bar", "file2")) self.create_file(self.make_path("foo", "bar", "file3")) path = self.path(self.make_path("foo", "bar")) contents = [entry for entry in path.iterdir()] self.assertEqual(3, len(contents)) self.assertIn(self.path(self.make_path("foo", "bar", "file2")), contents) def test_glob(self): self.create_file(self.make_path("foo", "setup.py")) self.create_file(self.make_path("foo", "all_tests.py")) self.create_file(self.make_path("foo", "README.md")) self.create_file(self.make_path("foo", "setup.pyc")) path = self.path(self.make_path("foo")) self.assertEqual( sorted(path.glob("*.py")), [ self.path(self.make_path("foo", "all_tests.py")), self.path(self.make_path("foo", "setup.py")), ], ) @unittest.skipIf(not is_windows, "Windows specific test") def test_glob_case_windows(self): self.create_file(self.make_path("foo", "setup.py")) self.create_file(self.make_path("foo", "all_tests.PY")) self.create_file(self.make_path("foo", "README.md")) self.create_file(self.make_path("foo", "example.Py")) path = self.path(self.make_path("foo")) self.assertEqual( sorted(path.glob("*.py")), [ self.path(self.make_path("foo", "all_tests.PY")), self.path(self.make_path("foo", "example.Py")), self.path(self.make_path("foo", "setup.py")), ], ) @unittest.skipIf(is_windows, "Posix specific test") def test_glob_case_posix(self): self.check_posix_only() self.create_file(self.make_path("foo", "setup.py")) self.create_file(self.make_path("foo", "all_tests.PY")) self.create_file(self.make_path("foo", "README.md")) self.create_file(self.make_path("foo", "example.Py")) path = self.path(self.make_path("foo")) self.assertEqual( sorted(path.glob("*.py")), [self.path(self.make_path("foo", "setup.py"))], ) class RealPathlibPathFileOperationTest(FakePathlibPathFileOperationTest): def use_real_fs(self): return True class FakePathlibUsageInOsFunctionsTest(RealPathlibTestCase): """Test that many os / os.path functions accept a path-like object since Python 3.6. The functionality of these functions is tested elsewhere, we just check that they accept a fake path object as an argument. """ def test_join(self): dir1 = "foo" dir2 = "bar" dir = self.os.path.join(dir1, dir2) self.assertEqual(dir, self.os.path.join(self.path(dir1), dir2)) self.assertEqual(dir, self.os.path.join(dir1, self.path(dir2))) self.assertEqual(dir, self.os.path.join(self.path(dir1), self.path(dir2))) def test_normcase(self): dir1 = self.make_path("Foo", "Bar", "Baz") self.assertEqual( self.os.path.normcase(dir1), self.os.path.normcase(self.path(dir1)) ) def test_normpath(self): dir1 = self.make_path("foo", "bar", "..", "baz") self.assertEqual( self.os.path.normpath(dir1), self.os.path.normpath(self.path(dir1)) ) def test_realpath(self): dir1 = self.make_path("foo", "bar", "..", "baz") self.assertEqual( self.os.path.realpath(dir1), self.os.path.realpath(self.path(dir1)) ) def test_relpath(self): path_foo = self.make_path("path", "to", "foo") path_bar = self.make_path("path", "to", "bar") rel_path = self.os.path.relpath(path_foo, path_bar) self.assertEqual(rel_path, self.os.path.relpath(self.path(path_foo), path_bar)) self.assertEqual(rel_path, self.os.path.relpath(path_foo, self.path(path_bar))) self.assertEqual( rel_path, self.os.path.relpath(self.path(path_foo), self.path(path_bar)), ) def test_split(self): dir1 = self.make_path("Foo", "Bar", "Baz") self.assertEqual(self.os.path.split(dir1), self.os.path.split(self.path(dir1))) def test_splitdrive(self): dir1 = self.make_path("C:", "Foo", "Bar", "Baz") self.assertEqual( self.os.path.splitdrive(dir1), self.os.path.splitdrive(self.path(dir1)), ) def test_abspath(self): dir1 = self.make_path("foo", "bar", "..", "baz") self.assertEqual( self.os.path.abspath(dir1), self.os.path.abspath(self.path(dir1)) ) def test_exists(self): dir1 = self.make_path("foo", "bar", "..", "baz") self.assertEqual( self.os.path.exists(dir1), self.os.path.exists(self.path(dir1)) ) def test_lexists(self): dir1 = self.make_path("foo", "bar", "..", "baz") self.assertEqual( self.os.path.lexists(dir1), self.os.path.lexists(self.path(dir1)) ) def test_expanduser(self): dir1 = self.os.path.join("~", "foo") self.assertEqual( self.os.path.expanduser(dir1), self.os.path.expanduser(self.path(dir1)), ) def test_getmtime(self): self.skip_real_fs() dir1 = self.make_path("foo", "bar1.txt") path_obj = self.filesystem.create_file(dir1) path_obj._st_mtime = 24 self.assertEqual( self.os.path.getmtime(dir1), self.os.path.getmtime(self.path(dir1)) ) def test_getctime(self): self.skip_real_fs() dir1 = self.make_path("foo", "bar1.txt") path_obj = self.filesystem.create_file(dir1) path_obj.st_ctime = 42 self.assertEqual( self.os.path.getctime(dir1), self.os.path.getctime(self.path(dir1)) ) def test_getatime(self): self.skip_real_fs() dir1 = self.make_path("foo", "bar1.txt") path_obj = self.filesystem.create_file(dir1) path_obj.st_atime = 11 self.assertEqual( self.os.path.getatime(dir1), self.os.path.getatime(self.path(dir1)) ) def test_getsize(self): path = self.make_path("foo", "bar", "baz") self.create_file(path, contents="1234567") self.assertEqual( self.os.path.getsize(path), self.os.path.getsize(self.path(path)) ) def test_isabs(self): path = self.make_path("foo", "bar", "..", "baz") self.assertEqual(self.os.path.isabs(path), self.os.path.isabs(self.path(path))) def test_isfile(self): path = self.make_path("foo", "bar", "baz") self.create_file(path) self.assertEqual( self.os.path.isfile(path), self.os.path.isfile(self.path(path)) ) def test_isfile_not_readable(self): path = self.make_path("foo", "bar", "baz") self.create_file(path, perm=0) self.assertEqual( self.os.path.isfile(path), self.os.path.isfile(self.path(path)) ) def test_islink(self): path = self.make_path("foo", "bar", "baz") self.create_file(path) self.assertEqual( self.os.path.islink(path), self.os.path.islink(self.path(path)) ) def test_isdir(self): path = self.make_path("foo", "bar", "baz") self.create_file(path) self.assertEqual(self.os.path.isdir(path), self.os.path.isdir(self.path(path))) def test_ismount(self): path = self.os.path.sep self.assertEqual( self.os.path.ismount(path), self.os.path.ismount(self.path(path)) ) def test_access(self): path = self.make_path("foo", "bar", "baz") self.create_file(path, contents="1234567") self.assertEqual( self.os.access(path, os.R_OK), self.os.access(self.path(path), os.R_OK), ) def test_chdir(self): path = self.make_path("foo", "bar", "baz") self.create_dir(path) self.os.chdir(self.path(path)) # use real path to handle symlink /var to /private/var in MacOs self.assert_equal_paths(self.os.path.realpath(path), self.os.getcwd()) def test_chmod(self): path = self.make_path("some_file") self.create_file(path) self.os.chmod(self.path(path), 0o444) self.assertEqual(stat.S_IMODE(0o444), stat.S_IMODE(self.os.stat(path).st_mode)) self.os.chmod(self.path(path), 0o666) def test_link(self): self.skip_if_symlink_not_supported() file1_path = self.make_path("test_file1") file2_path = self.make_path("test_file2") self.create_file(file1_path) self.os.link(self.path(file1_path), file2_path) self.assertTrue(self.os.path.exists(file2_path)) self.os.unlink(file2_path) self.os.link(self.path(file1_path), self.path(file2_path)) self.assertTrue(self.os.path.exists(file2_path)) self.os.unlink(file2_path) self.os.link(file1_path, self.path(file2_path)) self.assertTrue(self.os.path.exists(file2_path)) def test_listdir(self): path = self.make_path("foo", "bar") self.create_dir(path) self.create_file(path + "baz.txt") self.assertEqual(self.os.listdir(path), self.os.listdir(self.path(path))) def test_mkdir(self): path = self.make_path("foo") self.os.mkdir(self.path(path)) self.assertTrue(self.os.path.exists(path)) def test_makedirs(self): path = self.make_path("foo", "bar") self.os.makedirs(self.path(path)) self.assertTrue(self.os.path.exists(path)) @unittest.skipIf( is_windows and sys.version_info < (3, 8), "os.readlink does not to support path-like objects " "under Windows before Python 3.8", ) def test_readlink(self): self.skip_if_symlink_not_supported() link_path = self.make_path("foo", "bar", "baz") target = self.make_path("tarJAY") self.create_symlink(link_path, target) self.assert_equal_paths(self.os.readlink(self.path(link_path)), target) @unittest.skipIf( is_windows and sys.version_info < (3, 8), "os.readlink does not to support path-like objects " "under Windows before Python 3.8", ) def test_readlink_bytes(self): self.skip_if_symlink_not_supported() link_path = self.make_path(b"foo", b"bar", b"baz") target = self.make_path(b"tarJAY") self.create_symlink(link_path, target) self.assert_equal_paths(self.os.readlink(self.path(link_path)), target) def test_remove(self): path = self.make_path("test.txt") self.create_file(path) self.os.remove(self.path(path)) self.assertFalse(self.os.path.exists(path)) def test_rename(self): path1 = self.make_path("test1.txt") path2 = self.make_path("test2.txt") self.create_file(path1) self.os.rename(self.path(path1), path2) self.assertTrue(self.os.path.exists(path2)) self.os.rename(self.path(path2), self.path(path1)) self.assertTrue(self.os.path.exists(path1)) def test_replace(self): path1 = self.make_path("test1.txt") path2 = self.make_path("test2.txt") self.create_file(path1) self.os.replace(self.path(path1), path2) self.assertTrue(self.os.path.exists(path2)) self.os.replace(self.path(path2), self.path(path1)) self.assertTrue(self.os.path.exists(path1)) def test_rmdir(self): path = self.make_path("foo", "bar") self.create_dir(path) self.os.rmdir(self.path(path)) self.assertFalse(self.os.path.exists(path)) def test_scandir(self): directory = self.make_path("xyzzy", "plugh") self.create_dir(directory) self.create_file(self.os.path.join(directory, "test.txt")) dir_entries = [entry for entry in self.os.scandir(self.path(directory))] self.assertEqual(1, len(dir_entries)) def test_symlink(self): self.skip_if_symlink_not_supported() file_path = self.make_path("test_file1") link_path = self.make_path("link") self.create_file(file_path) self.os.symlink(self.path(file_path), link_path) self.assertTrue(self.os.path.exists(link_path)) self.os.remove(link_path) self.os.symlink(self.path(file_path), self.path(link_path)) self.assertTrue(self.os.path.exists(link_path)) def test_stat(self): path = self.make_path("foo", "bar", "baz") self.create_file(path, contents="1234567") self.assertEqual(self.os.stat(path), self.path(path).stat()) @unittest.skipIf(sys.version_info < (3, 10), "New in Python 3.10") def test_stat_follow_symlinks(self): self.check_posix_only() directory = self.make_path("foo") base_name = "bar" file_path = self.path(self.os.path.join(directory, base_name)) link_path = self.path(self.os.path.join(directory, "link")) contents = "contents" self.create_file(file_path, contents=contents) self.create_symlink(link_path, base_name) self.assertEqual( len(contents), link_path.stat(follow_symlinks=True)[stat.ST_SIZE] ) self.assertEqual( len(base_name), link_path.stat(follow_symlinks=False)[stat.ST_SIZE] ) def test_utime(self): path = self.make_path("some_file") self.create_file(path, contents="test") self.os.utime(self.path(path), times=(1, 2)) st = self.os.stat(path) self.assertEqual(1, st.st_atime) self.assertEqual(2, st.st_mtime) def test_truncate(self): path = self.make_path("some_file") self.create_file(path, contents="test_test") self.os.truncate(self.path(path), length=4) st = self.os.stat(path) self.assertEqual(4, st.st_size) @unittest.skipIf(sys.platform == "win32", "no pwd and grp modules in Windows") def test_owner_and_group_posix(self): path = self.make_path("some_file") self.create_file(path) self.assertTrue(self.path(path).owner()) self.assertTrue(self.path(path).group()) @unittest.skipIf(sys.platform == "win32", "no pwd and grp modules in Windows") def test_changed_owner_and_group(self): def fake_getpwuid(uid): if uid == 42: user_struct = namedtuple("user", "pw_name, pw_uid") user_struct.pw_name = "NewUser" return user_struct raise KeyError def fake_getgrgid(uid): if uid == 5: group_struct = namedtuple("group", "gr_name, gr_gid") group_struct.gr_name = "NewGroup" return group_struct raise KeyError self.skip_real_fs() path = self.make_path("some_file") self.create_file(path) self.os.chown(path, 42, 5) with mock.patch("pwd.getpwuid", fake_getpwuid): with mock.patch("grp.getgrgid", fake_getgrgid): self.assertEqual("NewUser", self.path(path).owner()) self.assertEqual("NewGroup", self.path(path).group()) def test_owner_and_group_windows(self): self.check_windows_only() path = self.make_path("some_file") self.create_file(path) with self.assertRaises(NotImplementedError): self.path(path).owner() with self.assertRaises(NotImplementedError): self.path(path).group() class RealPathlibUsageInOsFunctionsTest(FakePathlibUsageInOsFunctionsTest): def use_real_fs(self): return True class FakeFilesystemPathLikeObjectTest(unittest.TestCase): def setUp(self): self.filesystem = fake_filesystem.FakeFilesystem(path_separator="/") self.pathlib = fake_pathlib.FakePathlibModule(self.filesystem) self.os = fake_os.FakeOsModule(self.filesystem) def test_create_dir_with_pathlib_path(self): dir_path_string = "foo/bar/baz" dir_path = self.pathlib.Path(dir_path_string) self.filesystem.create_dir(dir_path) self.assertTrue(self.os.path.exists(dir_path_string)) self.assertEqual( stat.S_IFDIR, self.os.stat(dir_path_string).st_mode & stat.S_IFDIR ) def test_create_file_with_pathlib_path(self): file_path_string = "foo/bar/baz" file_path = self.pathlib.Path(file_path_string) self.filesystem.create_file(file_path) self.assertTrue(self.os.path.exists(file_path_string)) self.assertEqual( stat.S_IFREG, self.os.stat(file_path_string).st_mode & stat.S_IFREG ) def test_create_symlink_with_pathlib_path(self): file_path = self.pathlib.Path("foo/bar/baz") link_path_string = "foo/link" link_path = self.pathlib.Path(link_path_string) self.filesystem.create_symlink(link_path, file_path) self.assertTrue(self.os.path.lexists(link_path_string)) self.assertEqual( stat.S_IFLNK, self.os.lstat(link_path_string).st_mode & stat.S_IFLNK, ) def test_add_existing_real_file_with_pathlib_path(self): real_file_path_string = os.path.abspath(__file__) real_file_path = self.pathlib.Path(real_file_path_string) self.filesystem.add_real_file(real_file_path) fake_filepath_string = real_file_path_string.replace(os.sep, self.os.sep) self.assertTrue(self.os.path.exists(fake_filepath_string)) self.assertEqual( stat.S_IFREG, self.os.stat(fake_filepath_string).st_mode & stat.S_IFREG, ) def test_add_existing_real_directory_with_pathlib_path(self): real_dirpath_string = os.path.dirname(os.path.abspath(__file__)) real_dir_path = self.pathlib.Path(real_dirpath_string) self.filesystem.add_real_directory(real_dir_path) fake_dirpath_string = real_dirpath_string.replace(os.sep, self.os.sep) self.assertTrue(self.os.path.exists(fake_dirpath_string)) self.assertEqual( stat.S_IFDIR, self.os.stat(fake_dirpath_string).st_mode & stat.S_IFDIR, ) class FakeFilesystemChmodTest(fake_filesystem_unittest.TestCase): def setUp(self) -> None: self.setUpPyfakefs() @unittest.skipIf(sys.platform != "win32", "Windows specific test") def test_is_file_for_unreadable_dir_windows(self): self.fs.os = OSType.WINDOWS path = pathlib.Path("/foo/bar") self.fs.create_file(path) # normal chmod does not really set the mode to 0 self.fs.chmod("/foo", 0o000) self.assertTrue(path.is_file()) # but it does in forced UNIX mode self.fs.chmod("/foo", 0o000, force_unix_mode=True) with self.assertRaises(PermissionError): path.is_file() if __name__ == "__main__": unittest.main(verbosity=2) tests/fake_stat_time_test.py000064400000053423150043321530012301 0ustar00# Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Unit tests for file timestamp updates.""" import time import unittest from collections import namedtuple from pyfakefs.tests.test_utils import RealFsTestCase FileTime = namedtuple("FileTime", "st_ctime, st_atime, st_mtime") class FakeStatTestBase(RealFsTestCase): def setUp(self): super().setUp() # we disable the tests for MacOS to avoid very long builds due # to the 1s time resolution - we know that the functionality is # similar to Linux self.check_linux_and_windows() self.file_path = self.make_path("some_file") # MacOS has a timestamp resolution of 1 second self.sleep_time = 1.1 if self.is_macos else 0.01 self.mode = "" def stat_time(self, path): stat = self.os.stat(path) if self.use_real_fs(): # sleep a bit so in the next call the time has changed time.sleep(self.sleep_time) else: # calling time.time() advances mocked time time.time() return FileTime( st_ctime=stat.st_ctime, st_atime=stat.st_atime, st_mtime=stat.st_mtime, ) def assertLessExceptWindows(self, time1, time2): if self.is_windows_fs: self.assertLessEqual(time1, time2) else: self.assertLess(time1, time2) def assertLessExceptPosix(self, time1, time2): if self.is_windows_fs: self.assertLess(time1, time2) else: self.assertEqual(time1, time2) def open_close_new_file(self): with self.mock_time(): with self.open(self.file_path, self.mode): created = self.stat_time(self.file_path) closed = self.stat_time(self.file_path) return created, closed def open_write_close_new_file(self): with self.mock_time(): with self.open(self.file_path, self.mode) as f: created = self.stat_time(self.file_path) f.write("foo") written = self.stat_time(self.file_path) closed = self.stat_time(self.file_path) return created, written, closed def open_close(self): with self.mock_time(): self.create_file(self.file_path) before = self.stat_time(self.file_path) with self.open(self.file_path, self.mode): opened = self.stat_time(self.file_path) closed = self.stat_time(self.file_path) return before, opened, closed def open_write_close(self): with self.mock_time(): self.create_file(self.file_path) before = self.stat_time(self.file_path) with self.open(self.file_path, self.mode) as f: opened = self.stat_time(self.file_path) f.write("foo") written = self.stat_time(self.file_path) closed = self.stat_time(self.file_path) return before, opened, written, closed def open_flush_close(self): with self.mock_time(): self.create_file(self.file_path) before = self.stat_time(self.file_path) with self.open(self.file_path, self.mode) as f: opened = self.stat_time(self.file_path) f.flush() flushed = self.stat_time(self.file_path) closed = self.stat_time(self.file_path) return before, opened, flushed, closed def open_write_flush(self): with self.mock_time(): self.create_file(self.file_path) before = self.stat_time(self.file_path) with self.open(self.file_path, self.mode) as f: opened = self.stat_time(self.file_path) f.write("foo") written = self.stat_time(self.file_path) f.flush() flushed = self.stat_time(self.file_path) closed = self.stat_time(self.file_path) return before, opened, written, flushed, closed def open_read_flush(self): with self.mock_time(): self.create_file(self.file_path) before = self.stat_time(self.file_path) with self.open(self.file_path, "r") as f: opened = self.stat_time(self.file_path) f.read() read = self.stat_time(self.file_path) f.flush() flushed = self.stat_time(self.file_path) closed = self.stat_time(self.file_path) return before, opened, read, flushed, closed def open_read_close_new_file(self): with self.mock_time(): with self.open(self.file_path, self.mode) as f: created = self.stat_time(self.file_path) f.read() read = self.stat_time(self.file_path) closed = self.stat_time(self.file_path) return created, read, closed def open_read_close(self): with self.mock_time(): self.create_file(self.file_path) before = self.stat_time(self.file_path) with self.open(self.file_path, self.mode) as f: opened = self.stat_time(self.file_path) f.read() read = self.stat_time(self.file_path) closed = self.stat_time(self.file_path) return before, opened, read, closed def check_open_close_new_file(self): """ When a file is created on opening and closed again, no timestamps are updated on close. """ created, closed = self.open_close_new_file() self.assertEqual(created.st_ctime, closed.st_ctime) self.assertEqual(created.st_atime, closed.st_atime) self.assertEqual(created.st_mtime, closed.st_mtime) def check_open_write_close_new_file(self): """ When a file is created on opening, st_ctime is updated under Posix, and st_mtime is updated on close. """ created, written, closed = self.open_write_close_new_file() self.assertEqual(created.st_ctime, written.st_ctime) self.assertLessExceptWindows(written.st_ctime, closed.st_ctime) self.assertEqual(created.st_atime, written.st_atime) self.assertLessEqual(written.st_atime, closed.st_atime) self.assertEqual(created.st_mtime, written.st_mtime) self.assertLess(written.st_mtime, closed.st_mtime) def check_open_close_w_mode(self): """ When an existing file is opened with 'w' or 'w+' mode, st_ctime (Posix only) and st_mtime are updated on open (truncating), but not on close. """ before, opened, closed = self.open_close() self.assertLessExceptWindows(before.st_ctime, opened.st_ctime) self.assertEqual(opened.st_ctime, closed.st_ctime) self.assertLessEqual(before.st_atime, opened.st_atime) self.assertEqual(opened.st_atime, closed.st_atime) self.assertLess(before.st_mtime, opened.st_mtime) self.assertEqual(opened.st_mtime, closed.st_mtime) def check_open_close_non_w_mode(self): """ When an existing file is opened with any mode other than 'w' or 'w+', no timestamps are updated. """ before, opened, closed = self.open_close() self.assertEqual(before.st_ctime, opened.st_ctime) self.assertEqual(opened.st_ctime, closed.st_ctime) self.assertEqual(before.st_atime, opened.st_atime) self.assertEqual(opened.st_atime, closed.st_atime) self.assertEqual(before.st_mtime, opened.st_mtime) self.assertEqual(opened.st_mtime, closed.st_mtime) def check_open_write_close_w_mode(self): """ When an existing file is opened with 'w' or 'w+' mode and is then written to, st_ctime (Posix only) and st_mtime are updated on open (truncating) and again on close (flush), but not when written to. """ before, opened, written, closed = self.open_write_close() self.assertLessExceptWindows(before.st_ctime, opened.st_ctime) self.assertEqual(opened.st_ctime, written.st_ctime) self.assertLessExceptWindows(written.st_ctime, closed.st_ctime) self.assertLessEqual(before.st_atime, opened.st_atime) self.assertEqual(opened.st_atime, written.st_atime) self.assertLessEqual(written.st_atime, closed.st_atime) self.assertLess(before.st_mtime, opened.st_mtime) self.assertEqual(opened.st_mtime, written.st_mtime) self.assertLess(written.st_mtime, closed.st_mtime) def check_open_flush_close_w_mode(self): """ When an existing file is opened with 'w' or 'w+' mode (truncating), st_ctime (Posix only) and st_mtime are updated. No updates are done on flush or close. """ before, opened, flushed, closed = self.open_flush_close() self.assertLessExceptWindows(before.st_ctime, opened.st_ctime) self.assertEqual(opened.st_ctime, flushed.st_ctime) self.assertEqual(flushed.st_ctime, closed.st_ctime) self.assertLessEqual(before.st_atime, opened.st_atime) self.assertEqual(opened.st_atime, flushed.st_atime) self.assertEqual(flushed.st_atime, closed.st_atime) self.assertLess(before.st_mtime, opened.st_mtime) self.assertEqual(opened.st_mtime, flushed.st_mtime) self.assertEqual(flushed.st_mtime, closed.st_mtime) def check_open_flush_close_non_w_mode(self): """ When an existing file is opened with any mode other than 'w' or 'w+', flushed and closed, no timestamps are updated. """ before, opened, flushed, closed = self.open_flush_close() self.assertEqual(before.st_ctime, opened.st_ctime) self.assertEqual(opened.st_ctime, flushed.st_ctime) self.assertEqual(flushed.st_ctime, closed.st_ctime) self.assertEqual(before.st_atime, opened.st_atime) self.assertEqual(opened.st_atime, flushed.st_atime) self.assertEqual(flushed.st_atime, closed.st_atime) self.assertEqual(before.st_mtime, opened.st_mtime) self.assertEqual(opened.st_mtime, flushed.st_mtime) self.assertEqual(flushed.st_mtime, closed.st_mtime) def check_open_read_close_non_w_mode(self): """ Reading from a file opened with 'r', 'r+', or 'a+' mode updates st_atime under Posix. """ before, opened, read, closed = self.open_read_close() self.assertEqual(before.st_ctime, opened.st_ctime) self.assertEqual(opened.st_ctime, read.st_ctime) self.assertEqual(read.st_ctime, closed.st_ctime) self.assertEqual(before.st_atime, opened.st_atime) self.assertLessEqual(opened.st_atime, read.st_atime) self.assertEqual(read.st_atime, closed.st_atime) self.assertEqual(before.st_mtime, opened.st_mtime) self.assertEqual(opened.st_mtime, read.st_mtime) self.assertEqual(read.st_mtime, closed.st_mtime) def check_open_read_close_new_file(self): """ When a file is created with 'w+' or 'a+' mode and then read from, st_atime is updated under Posix. """ created, read, closed = self.open_read_close_new_file() self.assertEqual(created.st_ctime, read.st_ctime) self.assertEqual(read.st_ctime, closed.st_ctime) self.assertLessEqual(created.st_atime, read.st_atime) self.assertEqual(read.st_atime, closed.st_atime) self.assertEqual(created.st_mtime, read.st_mtime) self.assertEqual(read.st_mtime, closed.st_mtime) def check_open_write_close_non_w_mode(self): """ When an existing file is opened with 'a', 'a+' or 'r+' mode and is then written to, st_ctime (Posix only) and st_mtime are updated close (flush), but not on opening or when written to. """ before, opened, written, closed = self.open_write_close() self.assertEqual(before.st_ctime, opened.st_ctime) self.assertEqual(opened.st_ctime, written.st_ctime) self.assertLessExceptWindows(written.st_ctime, closed.st_ctime) self.assertEqual(before.st_atime, opened.st_atime) self.assertEqual(opened.st_atime, written.st_atime) self.assertLessEqual(written.st_atime, closed.st_atime) self.assertEqual(before.st_mtime, opened.st_mtime) self.assertEqual(opened.st_mtime, written.st_mtime) self.assertLess(written.st_mtime, closed.st_mtime) def check_open_write_flush_close_w_mode(self): """ When an existing file is opened with 'w' or 'w+' mode and is then written to, st_ctime (Posix only) and st_mtime are updated on open (truncating). Under Posix, st_mtime is updated on flush, under Windows, on close instead. """ before, opened, written, flushed, closed = self.open_write_flush() self.assertLessEqual(before.st_ctime, opened.st_ctime) self.assertLessEqual(written.st_ctime, flushed.st_ctime) self.assertEqual(opened.st_ctime, written.st_ctime) self.assertEqual(flushed.st_ctime, closed.st_ctime) self.assertLessEqual(before.st_atime, opened.st_atime) self.assertEqual(opened.st_atime, written.st_atime) self.assertLessEqual(written.st_atime, flushed.st_atime) self.assertLessEqual(flushed.st_atime, closed.st_atime) self.assertLess(before.st_mtime, opened.st_mtime) self.assertEqual(opened.st_mtime, written.st_mtime) self.assertLessExceptWindows(written.st_mtime, flushed.st_mtime) self.assertLessEqual(flushed.st_mtime, closed.st_mtime) def check_open_write_flush_close_non_w_mode(self): """ When an existing file is opened with 'a', 'a+' or 'r+' mode and is then written to, st_ctime and st_mtime are updated on flush under Posix. Under Windows, only st_mtime is updated on close instead. """ before, opened, written, flushed, closed = self.open_write_flush() self.assertEqual(before.st_ctime, opened.st_ctime) self.assertEqual(opened.st_ctime, written.st_ctime) self.assertLessExceptWindows(written.st_ctime, flushed.st_ctime) self.assertEqual(flushed.st_ctime, closed.st_ctime) self.assertEqual(before.st_atime, opened.st_atime) self.assertEqual(opened.st_atime, written.st_atime) self.assertLessEqual(written.st_atime, flushed.st_atime) self.assertLessEqual(flushed.st_atime, closed.st_atime) self.assertEqual(before.st_mtime, opened.st_mtime) self.assertEqual(opened.st_mtime, written.st_mtime) self.assertLessExceptWindows(written.st_mtime, flushed.st_mtime) self.assertLessEqual(flushed.st_mtime, closed.st_mtime) class TestFakeModeW(FakeStatTestBase): def setUp(self): super(TestFakeModeW, self).setUp() self.mode = "w" def test_open_close_new_file(self): self.check_open_close_new_file() def test_open_write_close_new_file(self): self.check_open_write_close_new_file() def test_open_close(self): self.check_open_close_w_mode() def test_open_write_close(self): self.check_open_write_close_w_mode() def test_open_flush_close(self): self.check_open_flush_close_w_mode() def test_open_write_flush_close(self): self.check_open_write_flush_close_w_mode() def test_read_raises(self): with self.open(self.file_path, "w") as f: with self.assertRaises(OSError): f.read() class TestRealModeW(TestFakeModeW): def use_real_fs(self): return True class TestFakeModeWPlus(FakeStatTestBase): def setUp(self): super(TestFakeModeWPlus, self).setUp() self.mode = "w+" def test_open_close_new_file(self): self.check_open_close_new_file() def test_open_write_close_new_file(self): self.check_open_write_close_new_file() def test_open_read_close_new_file(self): self.check_open_read_close_new_file() def test_open_close(self): self.check_open_close_w_mode() def test_open_write_close(self): self.check_open_write_close_w_mode() def test_open_read_close(self): """ When an existing file is opened with 'w+' mode and is then written to, st_ctime (Posix only) and st_mtime are updated on open (truncating) and again on close (flush). Under Posix, st_atime is updated on read. """ before, opened, read, closed = self.open_read_close() self.assertLessExceptWindows(before.st_ctime, opened.st_ctime) self.assertEqual(opened.st_ctime, read.st_ctime) self.assertEqual(read.st_ctime, closed.st_ctime) self.assertLessEqual(before.st_atime, opened.st_atime) self.assertLessEqual(opened.st_atime, read.st_atime) self.assertEqual(read.st_atime, closed.st_atime) self.assertLess(before.st_mtime, opened.st_mtime) self.assertEqual(opened.st_mtime, read.st_mtime) self.assertEqual(read.st_mtime, closed.st_mtime) def test_open_flush_close(self): self.check_open_flush_close_w_mode() def test_open_write_flush_close(self): self.check_open_write_flush_close_w_mode() class TestRealModeWPlus(TestFakeModeWPlus): def use_real_fs(self): return True class TestFakeModeA(FakeStatTestBase): def setUp(self): super(TestFakeModeA, self).setUp() self.mode = "a" def test_open_close_new_file(self): self.check_open_close_new_file() def test_open_write_close_new_file(self): self.check_open_write_close_new_file() def test_open_close(self): self.check_open_close_non_w_mode() def test_open_write_close(self): self.check_open_write_close_non_w_mode() def test_open_flush_close(self): self.check_open_flush_close_non_w_mode() def test_open_write_flush_close(self): self.check_open_write_flush_close_non_w_mode() def test_read_raises(self): with self.open(self.file_path, "a") as f: with self.assertRaises(OSError): f.read() class TestRealModeA(TestFakeModeA): def use_real_fs(self): return True class TestFakeModeAPlus(FakeStatTestBase): def setUp(self): super(TestFakeModeAPlus, self).setUp() self.mode = "a+" def test_open_close_new_file(self): self.check_open_close_new_file() def test_open_write_close_new_file(self): self.check_open_write_close_new_file() def test_open_read_close_new_file(self): self.check_open_read_close_new_file() def test_open_close(self): self.check_open_close_non_w_mode() def test_open_write_close(self): self.check_open_write_close_non_w_mode() def test_open_read_close(self): self.check_open_read_close_non_w_mode() def test_open_flush_close(self): self.check_open_flush_close_non_w_mode() def test_open_write_flush_close(self): self.check_open_write_flush_close_non_w_mode() class TestRealModeAPlus(TestFakeModeAPlus): def use_real_fs(self): return True class TestFakeModeR(FakeStatTestBase): def setUp(self): super(TestFakeModeR, self).setUp() self.mode = "r" def test_open_close(self): self.check_open_close_non_w_mode() def test_open_read_close(self): self.check_open_read_close_non_w_mode() def test_open_flush_close(self): self.check_open_flush_close_non_w_mode() def test_open_read_flush_close(self): """ When an existing file is opened with 'r' mode, read, flushed and closed, st_atime is updated after reading under Posix. """ before, opened, read, flushed, closed = self.open_read_flush() self.assertEqual(before.st_ctime, opened.st_ctime) self.assertEqual(opened.st_ctime, read.st_ctime) self.assertEqual(read.st_ctime, flushed.st_ctime) self.assertEqual(flushed.st_ctime, closed.st_ctime) self.assertEqual(before.st_atime, opened.st_atime) self.assertLessEqual(opened.st_atime, read.st_atime) self.assertEqual(read.st_atime, flushed.st_atime) self.assertEqual(flushed.st_atime, closed.st_atime) self.assertEqual(before.st_mtime, opened.st_mtime) self.assertEqual(opened.st_mtime, read.st_mtime) self.assertEqual(read.st_mtime, flushed.st_mtime) self.assertEqual(flushed.st_mtime, closed.st_mtime) def test_open_not_existing_raises(self): with self.assertRaises(OSError): with self.open(self.file_path, "r"): pass class TestRealModeR(TestFakeModeR): def use_real_fs(self): return True class TestFakeModeRPlus(FakeStatTestBase): def setUp(self): super(TestFakeModeRPlus, self).setUp() self.mode = "r+" def test_open_close(self): self.check_open_close_non_w_mode() def test_open_write_close(self): self.check_open_write_close_non_w_mode() def test_open_read_close(self): self.check_open_read_close_non_w_mode() def test_open_flush_close(self): self.check_open_flush_close_non_w_mode() def test_open_write_flush_close(self): self.check_open_write_flush_close_non_w_mode() def test_open_not_existing_raises(self): with self.assertRaises(OSError): with self.open(self.file_path, "r+"): pass class TestRealModeRPlus(TestFakeModeRPlus): def use_real_fs(self): return True if __name__ == "__main__": unittest.main() tests/fake_tempfile_test.py000064400000010126150043321530012106 0ustar00# Copyright 2009 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Tests that ensure that the `tempfile` module works with `fake_filesystem` if using `Patcher` (via `fake_filesystem_unittest`). """ import os import stat import tempfile import unittest from pyfakefs import fake_filesystem_unittest class FakeTempfileModuleTest(fake_filesystem_unittest.TestCase): """Test the 'tempfile' module with the fake file system.""" def setUp(self): self.setUpPyfakefs() def test_named_temporary_file(self): obj = tempfile.NamedTemporaryFile() self.assertTrue(self.fs.get_object(obj.name)) obj.close() with self.assertRaises(OSError): self.fs.get_object(obj.name) def test_named_temporary_file_no_delete(self): obj = tempfile.NamedTemporaryFile(delete=False) obj.write(b"foo") obj.close() file_obj = self.fs.get_object(obj.name) contents = file_obj.contents self.assertEqual("foo", contents) obj = tempfile.NamedTemporaryFile(mode="w", delete=False) obj.write("foo") obj.close() file_obj = self.fs.get_object(obj.name) self.assertEqual("foo", file_obj.contents) def test_mkstemp(self): next_fd = len(self.fs.open_files) temporary = tempfile.mkstemp() self.assertEqual(2, len(temporary)) self.assertTrue( temporary[1].startswith(os.path.join(tempfile.gettempdir(), "tmp")) ) self.assertEqual(next_fd, temporary[0]) self.assertTrue(self.fs.exists(temporary[1])) mode = 0o666 if self.fs.is_windows_fs else 0o600 self.assertEqual(self.fs.get_object(temporary[1]).st_mode, stat.S_IFREG | mode) fh = os.fdopen(temporary[0], "w+b") self.assertEqual(temporary[0], fh.fileno()) def test_mkstemp_dir(self): """test tempfile.mkstemp(dir=).""" # expect fail: /dir does not exist with self.assertRaises(OSError): tempfile.mkstemp(dir="/dir") # expect pass: /dir exists self.fs.create_dir("/dir") next_fd = len(self.fs.open_files) temporary = tempfile.mkstemp(dir="/dir") self.assertEqual(2, len(temporary)) self.assertEqual(next_fd, temporary[0]) self.assertTrue( temporary[1].startswith(os.path.join(self.fs.root_dir_name, "dir", "tmp")) ) self.assertTrue(self.fs.exists(temporary[1])) mode = 0o666 if self.fs.is_windows_fs else 0o600 self.assertEqual(self.fs.get_object(temporary[1]).st_mode, stat.S_IFREG | mode) def test_mkdtemp(self): dirname = tempfile.mkdtemp() self.assertTrue(dirname) self.assertTrue(self.fs.exists(dirname)) self.assertEqual(self.fs.get_object(dirname).st_mode, stat.S_IFDIR | 0o700) def test_temporary_directory(self): with tempfile.TemporaryDirectory() as tmpdir: self.assertTrue(tmpdir) self.assertTrue(self.fs.exists(tmpdir)) self.assertEqual(self.fs.get_object(tmpdir).st_mode, stat.S_IFDIR | 0o700) def test_temporary_file(self): with tempfile.TemporaryFile() as f: f.write(b"test") f.seek(0) self.assertEqual(b"test", f.read()) def test_temporay_file_with_dir(self): with self.assertRaises(FileNotFoundError): tempfile.TemporaryFile(dir="/parent") os.mkdir("/parent") with tempfile.TemporaryFile() as f: f.write(b"test") f.seek(0) self.assertEqual(b"test", f.read()) if __name__ == "__main__": unittest.main() tests/fixtures/__init__.py000064400000000000150043321530011652 0ustar00tests/fixtures/__pycache__/__init__.cpython-311.pyc000064400000000336150043321530016226 0ustar00 bgdS)Nrq/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/tests/fixtures/__init__.pyrsrtests/fixtures/__pycache__/config_module.cpython-311.pyc000064400000000411150043321530017273 0ustar00 bg% dZdS)z another valueN)configurable_valuev/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/tests/fixtures/config_module.pyrs$rtests/fixtures/__pycache__/deprecated_property.cpython-311.pyc000064400000002602150043321530020531 0ustar00 bgFdZddlZGddZGddZdS)zUsed for testing suppression of deprecation warnings while iterating over modules. The code is modeled after code in xmlbuilder.py in Python 3.6. See issue #542. NceZdZdZdS)DeprecatedPropertycvtjdtdtjdtd|S)Nzasync is deprecated) stacklevelzasync will be replaced)warningswarnDeprecationWarning FutureWarning)selfinstanceclss |/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/tests/fixtures/deprecated_property.py__get__zDeprecatedProperty.__get__s8 +-?ANNNN . !LLLLN)__name__ __module__ __qualname__rrrrrs#rrc8eZdZeed<dS)DeprecationTestasyncN)rrrrlocalsrrrrrs)**,,FFHHWrr)__doc__rrrrrrrst----------rtests/fixtures/__pycache__/module_with_attributes.cpython-311.pyc000064400000001665150043321530021263 0ustar00 bgdZdZdZdZdZdZdS)aThis module is for testing pyfakefs :py:class:`fake_filesystem_unittest.Patcher`. It defines attributes that have the same names as file modules, sudh as 'io` and `path`. Since these are not modules, :py:class:`fake_filesystem_unittest.Patcher` should not patch them. Whenever a new module is added to :py:meth:`fake_filesystem_unittest.Patcher._findModules`, the corresponding attribute should be added here and in the test :py:class:`fake_filesystem_unittest_test.TestAttributesWithFakeModuleNames`. zos attribute valuezpath attribute valuezpathlib attribute valuezshutil attribute valuezio attribute valueN)__doc__ospathpathlibshutilio/builddir/build/BUILD/cloudlinux-venv-1.0.7/venv/lib/python3.11/site-packages/pyfakefs/tests/fixtures/module_with_attributes.pyr s.   # !r tests/fixtures/config_module.py000064400000000045150043321530012736 0ustar00configurable_value = "another value" tests/fixtures/deprecated_property.py000064400000002027150043321530014172 0ustar00# Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Used for testing suppression of deprecation warnings while iterating over modules. The code is modeled after code in xmlbuilder.py in Python 3.6. See issue #542. """ import warnings class DeprecatedProperty: def __get__(self, instance, cls): warnings.warn("async is deprecated", DeprecationWarning, stacklevel=2) warnings.warn("async will be replaced", FutureWarning, stacklevel=2) return instance class DeprecationTest: locals()["async"] = DeprecatedProperty() tests/fixtures/module_with_attributes.py000064400000002333150043321530014714 0ustar00# Copyright 2017 John McGehee # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """This module is for testing pyfakefs :py:class:`fake_filesystem_unittest.Patcher`. It defines attributes that have the same names as file modules, sudh as 'io` and `path`. Since these are not modules, :py:class:`fake_filesystem_unittest.Patcher` should not patch them. Whenever a new module is added to :py:meth:`fake_filesystem_unittest.Patcher._findModules`, the corresponding attribute should be added here and in the test :py:class:`fake_filesystem_unittest_test.TestAttributesWithFakeModuleNames`. """ os = "os attribute value" path = "path attribute value" pathlib = "pathlib attribute value" shutil = "shutil attribute value" io = "io attribute value" tests/import_as_example.py000064400000006157150043321530011775 0ustar00# Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """ Example module that is used for testing modules that import file system modules to be patched under another name. """ import os as my_os import pathlib import sys from builtins import open as bltn_open from io import open as io_open from os import path from os import stat from os import stat as my_stat from os.path import exists, isfile, isdir, islink from os.path import exists as my_exists from pathlib import Path def check_if_exists1(filepath): # test patching module imported under other name return my_os.path.exists(filepath) def check_if_exists2(filepath): # tests patching path imported from os return path.exists(filepath) def check_if_exists3(filepath): # tests patching Path imported from pathlib return Path(filepath).exists() def check_if_exists4(filepath, file_exists=my_os.path.exists): return file_exists(filepath) def check_if_exists5(filepath): # tests patching `exists` imported from os.path return exists(filepath) def check_if_exists6(filepath): # tests patching `exists` imported from os.path as other name return my_exists(filepath) def check_if_exists7(filepath): # tests patching pathlib return pathlib.Path(filepath).exists() def check_if_isfile(filepath): # tests patching `isfile` imported from os.path return isfile(filepath) def check_if_isdir(filepath): # tests patching `isdir` imported from os.path return isdir(filepath) def check_if_islink(filepath): # tests patching `islink` imported from os.path return islink(filepath) def file_stat1(filepath): # tests patching `stat` imported from os return stat(filepath) def file_stat2(filepath): # tests patching `stat` imported from os as other name return my_stat(filepath) def system_stat(filepath): if sys.platform == "win32": from nt import stat as system_stat else: from posix import stat as system_stat return system_stat(filepath) def file_contents1(filepath): with bltn_open(filepath) as f: return f.read() def file_contents2(filepath): with io_open(filepath) as f: return f.read() def exists_this_file(): """Returns True in real fs only""" return exists(__file__) def open_this_file(): """Works only in real fs""" with open(__file__): pass def return_this_file_path(): """Works only in real fs""" return Path(__file__) class TestDefaultArg: def check_if_exists(self, filepath, file_exists=my_os.path.exists): # this is a similar case as in the tempfile implementation under Posix return file_exists(filepath) tests/logsio.py000064400000001500150043321530007544 0ustar00# Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """ Example module that is used for a regression test where a module with a name ending with "io" was skipped from patching (see #569). """ def file_contents(path): """Return the contents of the given path as byte array.""" with open(path, "rb") as f: return f.read() tests/mox3_stubout_example.py000064400000001574150043321530012451 0ustar00# Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """ Example module that is used for testing the functionality of :py:class`pyfakefs.mox_stubout.StubOutForTesting`. """ import datetime import math import os def check_if_exists(filepath): return os.path.exists(filepath) def fabs(x): return math.fabs(x) def tomorrow(): return datetime.date.today() + datetime.timedelta(days=1) tests/mox3_stubout_test.py000064400000012363150043321530011773 0ustar00# Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Unit tests for mox3_stubout.""" import datetime import math import os import unittest from os import path from pyfakefs import mox3_stubout from pyfakefs.tests import mox3_stubout_example class NoPanicMath: real_math = math @staticmethod def fabs(_x): return 42 def __getattr__(self, name): """Forwards any unfaked calls to the standard module.""" return getattr(self.real_math, name) class ExistingPath: real_path = path @staticmethod def exists(_path): return True def __getattr__(self, name): """Forwards any unfaked calls to the standard module.""" return getattr(self.real_path, name) class GroundhogDate(datetime.date): @classmethod def today(cls): return datetime.date(1993, 2, 2) class StubOutForTestingTest(unittest.TestCase): def setUp(self): super(StubOutForTestingTest, self).setUp() self.stubber = mox3_stubout.StubOutForTesting() def test_stubout_method_with_set(self): non_existing_path = "non_existing_path" self.assertFalse(mox3_stubout_example.check_if_exists(non_existing_path)) self.stubber.set(os.path, "exists", lambda x: True) self.assertTrue(mox3_stubout_example.check_if_exists(non_existing_path)) self.stubber.unset_all() self.assertFalse(mox3_stubout_example.check_if_exists(non_existing_path)) def test_stubout_class_with_set(self): self.assertGreater(mox3_stubout_example.tomorrow().year, 2000) self.stubber.set(datetime, "date", GroundhogDate) self.assertEqual(mox3_stubout_example.tomorrow(), datetime.date(1993, 2, 3)) self.stubber.unset_all() self.assertGreater(mox3_stubout_example.tomorrow().year, 2000) def test_stubout_module_with_set(self): self.assertEqual(10, mox3_stubout_example.fabs(-10)) self.stubber.set(mox3_stubout_example, "math", NoPanicMath) self.assertEqual(42, mox3_stubout_example.fabs(-10)) self.stubber.unset_all() self.assertEqual(10, mox3_stubout_example.fabs(-10)) def test_set_raise_if_unknown_attribute(self): self.assertRaises( AttributeError, self.stubber.set, os.path, "exists_not", lambda x: True, ) self.assertRaises( AttributeError, self.stubber.set, datetime, "tomorrow", GroundhogDate, ) self.assertRaises( AttributeError, self.stubber.set, mox3_stubout_example, "math1", NoPanicMath, ) def test_stubout_method_with_smart_set(self): non_existing_path = "non_existing_path" self.stubber.smart_set(os.path, "exists", lambda x: True) self.assertTrue(mox3_stubout_example.check_if_exists(non_existing_path)) self.stubber.smart_unset_all() self.assertFalse(mox3_stubout_example.check_if_exists(non_existing_path)) def test_stubout_class_with_smart_set(self): self.stubber.smart_set(datetime, "date", GroundhogDate) self.assertEqual(mox3_stubout_example.tomorrow(), datetime.date(1993, 2, 3)) self.stubber.smart_unset_all() self.assertGreater(mox3_stubout_example.tomorrow().year, 2000) def test_stubout_module_with_smart_set(self): self.assertEqual(10, mox3_stubout_example.fabs(-10)) self.stubber.smart_set(mox3_stubout_example, "math", NoPanicMath) self.assertEqual(42, mox3_stubout_example.fabs(-10)) self.stubber.smart_unset_all() self.assertEqual(10, mox3_stubout_example.fabs(-10)) def test_stubout_submodule_with_smart_set(self): # this one does not work with Set non_existing_path = "non_existing_path" self.assertFalse(mox3_stubout_example.check_if_exists(non_existing_path)) self.stubber.smart_set(os, "path", ExistingPath) self.assertTrue(mox3_stubout_example.check_if_exists(non_existing_path)) self.stubber.smart_unset_all() self.assertFalse(mox3_stubout_example.check_if_exists(non_existing_path)) def test_smart_set_raise_if_unknown_attribute(self): self.assertRaises( AttributeError, self.stubber.smart_set, os.path, "exists_not", lambda x: True, ) self.assertRaises( AttributeError, self.stubber.smart_set, datetime, "tomorrow", GroundhogDate, ) self.assertRaises( AttributeError, self.stubber.smart_set, mox3_stubout_example, "math1", NoPanicMath, ) if __name__ == "__main__": unittest.main() tests/patched_packages_test.py000064400000005011150043321530012556 0ustar00# Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """ Provides patches for some commonly used modules that enable them to work with pyfakefs. """ import os import sys import unittest from pyfakefs import fake_filesystem_unittest from pyfakefs.helpers import IS_PYPY try: import pandas as pd except ImportError: pd = None try: import xlrd except ImportError: xlrd = None try: import openpyxl except ImportError: openpyxl = None @unittest.skipIf( IS_PYPY and sys.version_info < (3, 8), "Has a problem with older PyPy versions" ) class TestPatchedPackages(fake_filesystem_unittest.TestCase): def setUp(self): self.setUpPyfakefs() if pd is not None: def test_read_csv(self): path = "/foo/bar.csv" self.fs.create_file(path, contents="1,2,3,4") df = pd.read_csv(path) assert (df.columns == ["1", "2", "3", "4"]).all() def test_read_table(self): path = "/foo/bar.csv" self.fs.create_file(path, contents="1|2|3|4") df = pd.read_table(path, delimiter="|") assert (df.columns == ["1", "2", "3", "4"]).all() if pd is not None and xlrd is not None: def test_read_excel(self): path = "/foo/bar.xlsx" src_path = os.path.dirname(os.path.abspath(__file__)) src_path = os.path.join(src_path, "fixtures", "excel_test.xlsx") # map the file into another location to be sure that # the real fs is not used self.fs.add_real_file(src_path, target_path=path) df = pd.read_excel(path) assert (df.columns == [1, 2, 3, 4]).all() if pd is not None and openpyxl is not None: def test_write_excel(self): self.fs.create_dir("/foo") path = "/foo/bar.xlsx" df = pd.DataFrame([[0, 1, 2, 3]]) with pd.ExcelWriter(path) as writer: df.to_excel(writer) df = pd.read_excel(path) assert (df.columns == ["Unnamed: 0", 0, 1, 2, 3]).all() tests/performance_test.py000064400000005074150043321530011622 0ustar00# Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Shall provide tests to check performance overhead of pyfakefs.""" import os import time import unittest from pyfakefs.fake_filesystem_unittest import TestCase from pyfakefs.helpers import IS_PYPY if os.environ.get("TEST_PERFORMANCE"): class SetupPerformanceTest(TestCase): @classmethod def setUpClass(cls) -> None: cls.start_time = time.time() @classmethod def tearDownClass(cls) -> None: cls.elapsed_time = time.time() - cls.start_time print( "Elapsed time per test for cached setup: {:.3f} ms".format( cls.elapsed_time * 10 ) ) def setUp(self) -> None: self.setUpPyfakefs() class SetupNoCachePerformanceTest(TestCase): @classmethod def setUpClass(cls) -> None: cls.start_time = time.time() @classmethod def tearDownClass(cls) -> None: cls.elapsed_time = time.time() - cls.start_time print( "Elapsed time per test for uncached setup: {:.3f} ms".format( cls.elapsed_time * 10 ) ) def setUp(self) -> None: self.setUpPyfakefs(use_cache=False) @unittest.skipIf(IS_PYPY, "PyPy times are not comparable") class TimePerformanceTest(TestCase): """Make sure performance degradation in setup is noticed. The numbers are related to the CI builds and may fail in local builds. """ def test_cached_time(self): self.assertLess(SetupPerformanceTest.elapsed_time, 0.4) def test_uncached_time(self): self.assertLess(SetupNoCachePerformanceTest.elapsed_time, 6) def test_setup(self): pass for n in range(100): test_name = "test_" + str(n) setattr(SetupPerformanceTest, test_name, test_setup) test_name = "test_nocache" + str(n) setattr(SetupNoCachePerformanceTest, test_name, test_setup) if __name__ == "__main__": unittest.main() tests/test_utils.py000064400000040716150043321530010463 0ustar00# Copyright 2009 Google Inc. All Rights Reserved. # Copyright 2015-2017 John McGehee # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Disable attribute errors - attributes not be found in mixin (shall be cleaned up...) # pytype: disable=attribute-error """Common helper classes used in tests, or as test class base.""" import os import platform import shutil import stat import sys import tempfile import unittest from contextlib import contextmanager from unittest import mock from pyfakefs import fake_filesystem, fake_open, fake_os from pyfakefs.helpers import is_byte_string, to_string class DummyTime: """Mock replacement for time.time. Increases returned time on access.""" def __init__(self, curr_time, increment): self.current_time = curr_time self.increment = increment def __call__(self, *args, **kwargs): current_time = self.current_time self.current_time += self.increment return current_time class DummyMock: def start(self): pass def stop(self): pass def __enter__(self): return self def __exit__(self, exc_type, exc_val, exc_tb): pass def time_mock(start=200, step=20): return mock.patch("pyfakefs.helpers.now", DummyTime(start, step)) class TestCase(unittest.TestCase): """Test base class with some convenience methods and attributes""" is_windows = sys.platform == "win32" is_cygwin = sys.platform == "cygwin" is_macos = sys.platform == "darwin" symlinks_can_be_tested = None def assert_mode_equal(self, expected, actual): return self.assertEqual(stat.S_IMODE(expected), stat.S_IMODE(actual)) @contextmanager def raises_os_error(self, subtype): try: yield self.fail("No exception was raised, OSError expected") except OSError as exc: if isinstance(subtype, list): self.assertIn(exc.errno, subtype) else: self.assertEqual(subtype, exc.errno) class RealFsTestMixin: """Test mixin to allow tests to run both in the fake filesystem and in the real filesystem. To run tests in the real filesystem, a new test class can be derived from the test class testing the fake filesystem which overwrites `use_real_fs()` to return `True`. All tests in the real file system operate inside the local temp path. In order to make a test able to run in the real FS, it must not use the fake filesystem functions directly. For access to `os` and `open`, the respective attributes must be used, which point either to the native or to the fake modules. A few convenience methods allow to compose paths, create files and directories. """ def __init__(self): self.filesystem = None self.open = open self.os = os self.base_path = None def setUp(self): if not os.environ.get("TEST_REAL_FS"): self.skip_real_fs() if self.use_real_fs(): self.base_path = tempfile.mkdtemp() def tearDown(self): if self.use_real_fs(): self.os.chdir(os.path.dirname(self.base_path)) shutil.rmtree(self.base_path, ignore_errors=True) os.chdir(self.cwd) @property def is_windows_fs(self): return TestCase.is_windows def set_windows_fs(self, value): if self.filesystem is not None: self.filesystem._is_windows_fs = value if value: self.filesystem._is_macos = False self.create_basepath() @property def is_macos(self): return TestCase.is_macos @property def is_pypy(self): return platform.python_implementation() == "PyPy" def use_real_fs(self): """Return True if the real file system shall be tested.""" return False def setUpFileSystem(self): pass def path_separator(self): """Can be overwritten to use a specific separator in the fake filesystem.""" if self.use_real_fs(): return os.path.sep return "/" def check_windows_only(self): """If called at test start, the real FS test is executed only under Windows, and the fake filesystem test emulates a Windows system. """ if self.use_real_fs(): if not TestCase.is_windows: raise unittest.SkipTest("Testing Windows specific functionality") else: self.set_windows_fs(True) def check_linux_only(self): """If called at test start, the real FS test is executed only under Linux, and the fake filesystem test emulates a Linux system. """ if self.use_real_fs(): if TestCase.is_macos or TestCase.is_windows: raise unittest.SkipTest("Testing Linux specific functionality") else: self.set_windows_fs(False) self.filesystem._is_macos = False def check_macos_only(self): """If called at test start, the real FS test is executed only under MacOS, and the fake filesystem test emulates a MacOS system. """ if self.use_real_fs(): if not TestCase.is_macos: raise unittest.SkipTest("Testing MacOS specific functionality") else: self.set_windows_fs(False) self.filesystem._is_macos = True def check_linux_and_windows(self): """If called at test start, the real FS test is executed only under Linux and Windows, and the fake filesystem test emulates a Linux system under MacOS. """ if self.use_real_fs(): if TestCase.is_macos: raise unittest.SkipTest("Testing non-MacOs functionality") else: self.filesystem._is_macos = False def check_case_insensitive_fs(self): """If called at test start, the real FS test is executed only in a case-insensitive FS (e.g. Windows or MacOS), and the fake filesystem test emulates a case-insensitive FS under the running OS. """ if self.use_real_fs(): if not TestCase.is_macos and not TestCase.is_windows: raise unittest.SkipTest( "Testing case insensitive specific functionality" ) else: self.filesystem.is_case_sensitive = False def check_case_sensitive_fs(self): """If called at test start, the real FS test is executed only in a case-sensitive FS (e.g. under Linux), and the fake file system test emulates a case-sensitive FS under the running OS. """ if self.use_real_fs(): if TestCase.is_macos or TestCase.is_windows: raise unittest.SkipTest("Testing case sensitive specific functionality") else: self.filesystem.is_case_sensitive = True def check_posix_only(self): """If called at test start, the real FS test is executed only under Linux and MacOS, and the fake filesystem test emulates a Linux system under Windows. """ if self.use_real_fs(): if TestCase.is_windows: raise unittest.SkipTest("Testing Posix specific functionality") else: self.set_windows_fs(False) def skip_real_fs(self): """If called at test start, no real FS test is executed.""" if self.use_real_fs(): raise unittest.SkipTest("Only tests fake FS") def skip_real_fs_failure( self, skip_windows=True, skip_posix=True, skip_macos=True, skip_linux=True, ): """If called at test start, no real FS test is executed for the given conditions. This is used to mark tests that do not pass correctly under certain systems and shall eventually be fixed. """ if True: if self.use_real_fs() and ( TestCase.is_windows and skip_windows or not TestCase.is_windows and skip_macos and skip_linux or TestCase.is_macos and skip_macos or not TestCase.is_windows and not TestCase.is_macos and skip_linux or not TestCase.is_windows and skip_posix ): raise unittest.SkipTest( "Skipping because FakeFS does not match real FS" ) def symlink_can_be_tested(self, force_real_fs=False): """Used to check if symlinks and hard links can be tested under Windows. All tests are skipped under Windows for Python versions not supporting links, and real tests are skipped if running without administrator rights. """ if not TestCase.is_windows or (not force_real_fs and not self.use_real_fs()): return True if TestCase.symlinks_can_be_tested is None: if force_real_fs: self.base_path = tempfile.mkdtemp() link_path = self.make_path("link") try: self.os.symlink(self.base_path, link_path) TestCase.symlinks_can_be_tested = True self.os.remove(link_path) except (OSError, NotImplementedError): TestCase.symlinks_can_be_tested = False if force_real_fs: self.base_path = None return TestCase.symlinks_can_be_tested def skip_if_symlink_not_supported(self, force_real_fs=False): """If called at test start, tests are skipped if symlinks are not supported.""" if not self.symlink_can_be_tested(force_real_fs): raise unittest.SkipTest("Symlinks under Windows need admin privileges") def make_path(self, *args): """Create a path with the given component(s). A base path is prepended to the path which represents a temporary directory in the real FS, and a fixed path in the fake filesystem. Always use to compose absolute paths for tests also running in the real FS. """ if isinstance(args[0], (list, tuple)): path = self.base_path for arg in args[0]: path = self.os.path.join(path, to_string(arg)) return path args = [to_string(arg) for arg in args] return self.os.path.join(self.base_path, *args) def create_dir(self, dir_path, perm=0o777): """Create the directory at `dir_path`, including subdirectories. `dir_path` shall be composed using `make_path()`. """ if not dir_path: return existing_path = dir_path components = [] while existing_path and not self.os.path.exists(existing_path): existing_path, component = self.os.path.split(existing_path) if not component and existing_path: # existing path is a drive or UNC root if not self.os.path.exists(existing_path): self.filesystem.add_mount_point(existing_path) break components.insert(0, component) for component in components: existing_path = self.os.path.join(existing_path, component) self.os.mkdir(existing_path) self.os.chmod(existing_path, 0o777) self.os.chmod(dir_path, perm) def create_file(self, file_path, contents=None, encoding=None, perm=0o666): """Create the given file at `file_path` with optional contents, including subdirectories. `file_path` shall be composed using `make_path()`. """ self.create_dir(self.os.path.dirname(file_path)) mode = "wb" if encoding is not None or is_byte_string(contents) else "w" if encoding is not None and contents is not None: contents = contents.encode(encoding) with self.open(file_path, mode) as f: if contents is not None: f.write(contents) self.os.chmod(file_path, perm) def create_symlink(self, link_path, target_path): """Create the path at `link_path`, and a symlink to this path at `target_path`. `link_path` shall be composed using `make_path()`. """ self.create_dir(self.os.path.dirname(link_path)) self.os.symlink(target_path, link_path) def check_contents(self, file_path, contents): """Compare `contents` with the contents of the file at `file_path`. Asserts equality. """ mode = "rb" if is_byte_string(contents) else "r" with self.open(file_path, mode) as f: self.assertEqual(contents, f.read()) def create_basepath(self): """Create the path used as base path in `make_path`.""" if self.filesystem is not None: old_base_path = self.base_path self.base_path = self.filesystem.path_separator + "basepath" if self.filesystem.is_windows_fs: self.base_path = "C:" + self.base_path if old_base_path != self.base_path: if old_base_path is not None: self.filesystem.reset() if not self.filesystem.exists(self.base_path): self.filesystem.create_dir(self.base_path) if old_base_path is not None: self.setUpFileSystem() def assert_equal_paths(self, actual, expected): if self.is_windows: actual = str(actual).replace("\\\\?\\", "") expected = str(expected).replace("\\\\?\\", "") if os.name == "nt" and self.use_real_fs(): # work around a problem that the user name, but not the full # path is shown as the short name self.assertEqual( self.path_with_short_username(actual), self.path_with_short_username(expected), ) else: self.assertEqual(actual, expected) elif self.is_macos: self.assertEqual( str(actual).replace("/private/var/", "/var/"), str(expected).replace("/private/var/", "/var/"), ) else: self.assertEqual(actual, expected) @staticmethod def path_with_short_username(path): components = path.split(os.sep) if len(components) >= 3: components[2] = components[2][:6].upper() + "~1" return os.sep.join(components) def mock_time(self, start=200, step=20): if not self.use_real_fs(): return time_mock(start, step) return DummyMock() def assert_raises_os_error(self, subtype, expression, *args, **kwargs): """Asserts that a specific subtype of OSError is raised.""" try: expression(*args, **kwargs) self.fail("No exception was raised, OSError expected") except OSError as exc: if isinstance(subtype, list): self.assertIn(exc.errno, subtype) else: self.assertEqual(subtype, exc.errno) class RealFsTestCase(TestCase, RealFsTestMixin): """Can be used as base class for tests also running in the real file system.""" def __init__(self, methodName="runTest"): TestCase.__init__(self, methodName) RealFsTestMixin.__init__(self) def setUp(self): RealFsTestMixin.setUp(self) self.cwd = os.getcwd() if not self.use_real_fs(): self.filesystem = fake_filesystem.FakeFilesystem( path_separator=self.path_separator() ) self.setup_fake_fs() self.setUpFileSystem() def setup_fake_fs(self): if not self.use_real_fs(): self.open = fake_open.FakeFileOpen(self.filesystem) self.os = fake_os.FakeOsModule(self.filesystem) self.create_basepath() def tearDown(self): RealFsTestMixin.tearDown(self) @property def is_windows_fs(self): if self.use_real_fs(): return self.is_windows return self.filesystem.is_windows_fs @property def is_macos(self): if self.use_real_fs(): return TestCase.is_macos return self.filesystem.is_macos