
    3j                        d Z ddlmZ ddlZddlZddlZddlZddlZddlZddl	Z	ddl
Z
ddlZddlmZ g dZej                   d        ZddZdddZej(                  ej*                  d	Zd
 Zd Zd Zedk(  rddlZ ej8                          yy)z
Tools for working with files
    )annotationsN)Music21Exception)readFileEncodingSafereadPickleGzipcdpreparePathClassesForUnpickling!restorePathClassesAfterUnpicklingrunSubprocessCapturingStderrc              #     K   t        j                         }	 t        j                  |        d t        j                  |       y# t        j                  |       w xY ww)z
    Useful for a temporary cd for use in a `with` statement:

         with cd('/Library/'):
              os.system(make)

    will switch temporarily, and then switch back when leaving.
    N)osgetcwdchdir)	targetDircwds     E/DATA/.local/lib/python3.12/site-packages/music21/common/fileTools.pyr   r   &   s=      ))+C

s   A!A A!AA!c                8   t                t        j                  | d      5 }	 |j                         }t	        j
                  |      }	 ddd       t                S # t        $ r'}t                t        dt        |       z         |d}~ww xY w# 1 sw Y   HxY w)zf
    Read a gzip-compressed pickle file, uncompress it, unpickle it, and
    return the contents.
    rbzCannot load file N)
r   gzipopenreadpickleloads	Exceptionr	   r   str)filePathpickledFileuncompressednewMdbes        r   r   r   9   s    
 $%	8T	"k	O&++-L\\,/F 
# &'M  	O ./"#6X#FGQN	O	 
#	"s(   B%A	B&"BBBBc                   	 t        j                  | d|      5 }|j                         }|cddd       S # 1 sw Y   yxY w# t        $ rr ddl}t        j                  | d      5 }|j                         }|j                  |      d   xs d}t        j                  ||      cddd       cY S # 1 sw Y   Y yxY ww xY w)ao  
    Slow, but will read a file of unknown encoding as safely as possible using
    the chardet package.  Mostly obsolete in the utf-8 world of today, but
    useful for older code

    Let's try to load the `music21.common.__init__.py` file as ascii --
    it has a copyright symbol near the top, so it won't load in Python3:

    >>> import os
    >>> c = str(common.getSourceFilePath() / 'common' / '__init__.py')
    >>> f = open(c, encoding='ascii')
    >>> data = f.read()
    Traceback (most recent call last):
    UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position ...:
        ordinal not in range(128)

    That won't do! Now I know that it is in utf-8, but maybe you don't. Or it could
    be an old Humdrum or Noteworthy file with Windows or unknown encoding.
    This will load it as safely as possible.

    >>> data = common.readFileEncodingSafe(c)
    >>> data[83:106]
    'Name:         common.py'

    Well, that's nothing, since the first guess here is utf-8, and it's right. So let's
    give a worse first guess:

    >>> data = common.readFileEncodingSafe(c, firstGuess='SHIFT_JIS')  # old Japanese standard
    >>> data[83:106]
    'Name:         common.py'

    It worked!

    Note that trying lots of encodings is slow enough when the first guess is wrong
    that the firstGuess should be set to something reasonable like 'utf-8' or 'ascii'.
    r)encodingNr   r   r"   ascii)ior   r   UnicodeDecodeErrorchardetdetectcodecsdecode)r   
firstGuessthisFiledatar&   thisFileBinary
dataBinaryr"   s           r   r   r   M   s    L	7WWXsZ8H==?D 988  7WWXt$',,.J~~j1*=HH==X6 %$$7s@   A 6	A ?A A #B=%>B/#
B=/B9	4B=9B=)	posixPathwindowsPathc                     ddl m}   |        }|dk(  rt        j                  t        _        yt        j                  t        _        y)z
    When we need to unpickle a function that might have relative paths
    (like some music21 stream options), Windows chokes if the PosixPath
    is not defined, but usually can still unpickle easily.
    r   getPlatformwinN)music21.common.miscr3   pathlibWindowsPath	PosixPathr3   platforms     r   r   r      s2     0}H5#//%//    c                 r    ddl m}   |        }|dk(  rt        d   t        _        yt        d   t        _        y)z0
    After unpickling, leave pathlib alone.
    r   r2   r4   r/   r0   N)r5   r3   _storedPathlibClassesr6   r8   r7   r9   s     r   r	   r	      s0     0}H51+>3MBr;   c                $   t        j                  | dd      }|j                  dk7  r=|j                  }	 ddl}|j                  |j                  d            }t        |      y# t        $ r  |j                  dd	      }Y t        |      w xY w)
zk
    Run a subprocess command, capturing stderr and
    only show the error if an exception is raised.
    TF)capture_outputcheckr   N)do_setlocaler#   ignore)errors)	
subprocessrun
returncodestderrlocaler)   getpreferredencodingr%   IOError)subprocessCommandcompleted_processstderr_bytesrH   
stderr_strs        r   r
   r
      s    
 #'8UZ[##q( )//	G%,,V-H-HV[-H-\]J j!! ) " 	G%,,WX,FJj!!	Gs   %A& &BB__main__)r   zstr | pathlib.Pathreturnzt.Any)zutf-8)rP   r   )__doc__
__future__r   r(   
contextlibr   r$   r6   r   r   rD   typingtmusic21.exceptions21r   __all__contextmanagerr   r   r   r8   r7   r=   r   r	   r
   __name__music21mainTest r;   r   <module>r]      s    #    	   	   1  $(/7f '.&7&7H[H[\ 0	C"( zG r;   