o $a,@sdZddlZddlZddlZddlZddlZddlZddlZddlm Z ddlm Z ddl m Z m Z mZmZmZmZddlmZzddlm ZWn eySdZYnwdZded efd d Zd ed efd dZdeded efddZded dfddZdeeded eefddZdeded dfddZdeded dfddZ deded dfd d!Z!e"d"Z#e"d#Z$d$ed efd%d&Z%d'ed efd(d)Z&ej'fded*ed efd+d,Z(e(Z)e*pe+Z,d-ed efd.d/Z-ej.d0ed e d1fd2d3Z/Gd4d5d5Z0ded dfd6d7Z1dS)8z sphinx.util.osutil ~~~~~~~~~~~~~~~~~~ Operating system-related utility functions for Sphinx. :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. N)StringIOpath)Any GeneratorIteratorListOptionalType)RemovedInSphinx50Warning/ canonicalpathreturncCs|ttjSN)replaceSEPrsep)r r4/usr/lib/python3/dist-packages/sphinx/util/osutil.pyos_path'sr nativepathcCs|tjtS)z"Return path in OS-independent form)rrrr)rrrr canon_path+srbasetocCs|tr|S|ddt}|ddt}t|dd|ddD]\}}||kr2n |d|dq(||krCdSt|dkrR|dgkrRdtSdtt|dt|S) z.Return a relative URL from ``base`` to ``to``.#rN.z..) startswithrsplitzippoplenjoin)rrb2t2xyrrr relative_uri0s "  r)rcCstj|dddS)zEnsure that a path exists.T)exist_okN)osmakedirsrrrr ensuredirGsr-dirnamessuffixc csf|D]-}t|D]%\}}}|D]}||r.z tt||VWqty-Yqwqq qdSr)r+walkendswithrgetmtimer$OSError)r.r/dirnamerootdirsfilessfilerrrmtimes_of_filesLs  r9sourcedestcCsNtjdtddtj|rzt|Wn tyYnwt||dS)z3Move a file, removing the destination if it exists.zYsphinx.util.osutil.movefile() is deprecated for removal. Please use os.replace() instead.) stacklevelN) warningswarnr r+rexistsunlinkr3renamer:r;rrrmovefileWs  rDcCs0t|}ttdrt||j|jfdSdS)z!Copy a file's modification times.utimeN)r+stathasattrrEst_atimest_mtime)r:r;strrr copytimesds  rKcCsLt|r t||s$t||zt||WdSty#YdSwdS)z{Copy a file and its modification times, if possible. Note: ``copyfile`` skips copying if the file has not been changedN)rr@filecmpcmpshutilcopyfilerKr3rCrrrrOks  rOz[^a-zA-Z0-9_-]z Documentation$stringcCstd|pdS)Nrsphinx)no_fn_resub)rPrrr make_filename|srTprojectcCsttd|S)Nr)rTproject_suffix_rerSlower)rUrrrmake_filename_from_projectsrXstartcCs(ztj||WSty|YSw)aReturn a relative filepath to *path* either from the current directory or from an optional *start* directory. This is an alternative of ``os.path.relpath()``. This returns original path if *path* and *start* are on different drives (for Windows platform). )r+rrelpath ValueError)rrYrrrrZs  rZpathdirc Csjtdur t|tr |St|}t|tr3z|t}W|Sty2}ztdt|d}~ww|S)NzAmultibyte filename not supported on this filesystem encoding (%r))Path isinstanceabspathrbytesdecode fs_encodingUnicodeDecodeError)r\excrrrr_s    r_ target_dir)NNNc cs8t}zt|dVWt|dSt|wr)r+getcwdchdir)recwdrrrcds  ric@sxeZdZdZdeddfddZdeddfdd Zdd d Zdd d Zde e de de de fddZ dede fddZdS)FileAvoidWriteaFile-like object that buffers output and only writes if content changed. Use this class like when writing to a file to avoid touching the original file if the content hasn't changed. This is useful in scenarios where file mtime is used to invalidate caches or trigger new behavior. When writing to this file handle, all writes are buffered until the object is closed. Objects can be used as context managers. rrNcCs||_d|_dSr)_path_io)selfrrrr__init__s zFileAvoidWrite.__init__datacCs|jst|_|j|dSr)rlrwrite)rmrorrrrpszFileAvoidWrite.writecCs|jstd|}|jz+t|jdd}|}||kr+ WdWdSWdn1s5wYWn tyDYnwt|jddd}||WddS1s^wYdS)z0Stop accepting writes and write file, if needed.z,FileAvoidWrite does not support empty files.zutf-8)encodingNw) rl Exceptiongetvaluecloseopenrkreadr3rp)rmbufold_f old_contentfrrrrus&   "zFileAvoidWrite.closecCs|Srr)rmrrr __enter__szFileAvoidWrite.__enter__exc_type exc_value tracebackcCs |dS)NT)ru)rmr}r~rrrr__exit__szFileAvoidWrite.__exit__namecCs|jstdt|j|S)Nz=Must write to FileAvoidWrite before other methods can be used)rlrsgetattr)rmrrrr __getattr__s zFileAvoidWrite.__getattr__)rN)rrj)__name__ __module__ __qualname____doc__strrnrprur|r rsrboolrrrrrrrjs   rjcCs(tj|r t|dSt|dSr)r+risdirrNrmtreeremoverrrrrs r)2r contextlibrLr+rerNsysr>iorrtypingrrrrr r sphinx.deprecationr sphinx.testing.pathr] ImportErrorrrrrr)r-floatr9rDrKrOcompilerRrVrTrXcurdirrZ safe_relpathgetfilesystemencodinggetdefaultencodingrbr_contextmanagerrirjrrrrrsL            8