
    rh                       S SK Jr  / SQrS SKrS SKJr  S SKrS SKrS SKrS SK	r	\R                  " S\\R                  -  S9rSS jrSS jrSS	 jrSS
 jrSS jrSSS jjr\SS.   SS jj5       r\SS.   SS jj5       r\    SS j5       r\    SS j5       rSS.   SS jjr " S S\	R*                  5      r\S:X  a  S SKr\R2                  " \5        gg)    )annotations)getRootFilePathgetSourceFilePathgetMetadataCacheFilePathgetCorpusFilePathgetCorpusContentDirsrelativepath	cleanpathN)overload	StrOrPath)boundc                 ,   [         R                  " [        R                  " [        5      5      R                  5       n U R                  R                  nSUR                  5        Vs/ s H  o"R                  PM     sn;  a  [        SU 35      eU$ s  snf )z
Get the music21 directory that contains source files such as note.py, etc.
This is not the same as the
outermost package development directory.
streamz(cannot find expected music21 directory: )
pathlibPathinspectgetfiler   resolveparentiterdirnameFileNotFoundError)fpThis	fpMusic21xs      R/home/james-whalen/.local/lib/python3.13/site-packages/music21/common/pathTools.pyr   r   "   s|     \\'//*;<=EEGF$$I	(9(9(;<(;1(;<<6ykB
 	
 	 =s   &Bc                 "    [        5       S-  S-  $ )z
Get the stored music21 directory that contains the corpus metadata cache.

>>> fp = common.getMetadataCacheFilePath()
>>> fp.name == '_metadataCache' and fp.parent.name == 'corpus'
True
corpus_metadataCache)r        r   r   r   2   s     ),<<<r!   c                     SSK Jn   U R                  R                  5       nUR                  c  [        5       S-  $ [        R                  " UR                  5      $ )z
Get the stored music21 directory that contains the corpus metadata cache.

>>> fp = common.getCorpusFilePath()
>>> fp.name == 'corpus' and fp.parent.name == 'music21'
True
r   )r   r   )music21r   corpora
CoreCorpusmanualCoreCorpusPathr   r   r   )r   
coreCorpuss     r   r   r   =   sH     **,J&&. "X--<<
7788r!   c                    [        5       n / nSn[        [        R                  " U 5      5       HK  nUR	                  S5      (       a  M  UR                  S5      (       a  M3  X2;   a  M:  UR                  U5        MM     [        U5      $ )a  
Get all dirs that are found in the CoreCorpus that contain content;
that is, exclude dirs that have code or other resources.

>>> fp = common.getCorpusContentDirs()
>>> fp  # this list will be fragile, depending on composition of dirs
['airdsAirs', 'bach', 'beach', 'beethoven', 'chopin',
 'ciconia', 'corelli', 'cpebach',
 'demos', 'essenFolksong', 'handel', 'haydn', 'johnson_j_r', 'joplin', 'josquin',
 'leadSheet', 'liliuokalani', 'luca', 'lusitano',
 'miscFolk', 'monteverdi', 'mozart',
 'nottingham-dataset',
 'oneills1850', 'palestrina',
 'ryansMammoth', 'schoenberg', 'schubert', 'schumann_clara', 'schumann_robert',
 'theoryExercises', 'trecento', 'verdi', 'weber', 'webern']

Make sure that all corpus data has a directoryInformation tag in
CoreCorpus.

>>> cc = corpus.corpora.CoreCorpus()
>>> failed = []
>>> di = [d.directoryName for d in cc.directoryInformation]
>>> for f in fp:
...     if f not in di:
...         failed.append(f)
>>> failed
[]
)zlicense.txtr   __pycache__)z.pyz.pyc.)r   sortedoslistdirendswith
startswithappend)directoryNameresultexcludedNamesfilenames       r   r   r   L   s{    : &'MFM 2::m45_--  %%&h 6 &>r!   c                 2    [        5       n U R                  nU$ )z
Return the root directory for music21 -- outside the music21 namespace
which has directories such as "dist", "documentation", "music21"

>>> fp = common.getRootFilePath()
>>> #_DOCS_SHOW fp
PosixPath('/Users/florencePrice/git/music21')
)r   r   )r   fpParents     r   r   r   }   s     "#IHOr!   c                X    SSK nUS:X  a  U $ [        R                  R                  X5      $ )z
A cross-platform wrapper for `os.path.relpath()`, which returns `path` if
under Windows, otherwise returns the relative path of `path`.

This avoids problems under Windows when the current working directory is
on a different drive letter from `path`.
r   NWindows)platformr,   pathrelpath)r:   startr9   s      r   r	   r	      s'     977??4''r!   )returnPathlibc                   g Nr    r:   r=   s     r   r
   r
           r!   c                   g r?   r    r@   s     r   r
   r
      rA   r!   c                   g r?   r    r@   s     r   r
   r
      rA   r!   c                   g r?   r    r@   s     r   r
   r
      rA   r!   c                  [        U [        R                  5      (       a  [        U 5      n Uc  SnOUc  Sn[        R
                  R                  U 5      n [        R
                  R                  U 5      n [        R
                  R                  U 5      (       d  [        R
                  R                  U 5      n [        R
                  R                  U 5      n U(       d  U $ [        R                  " U 5      $ )a  
Normalizes the path by expanding ~user on Unix, ${var} environmental vars
(is this a good idea?), expanding %name% on Windows, normalizing path names
(Windows turns backslashes to forward slashes), and finally if that file
is not an absolute path, turns it from a relative path to an absolute path.

v5 -- returnPathlib -- None (default) does not convert. False, returns a string,
True, returns a pathlib.Path.
TF)
isinstancer   r   strr,   r:   
expandusernormpathisabsabspath
expandvarsr@   s     r   r
   r
      s     $%%4y  M		77d#D77D!D77==wwt$77d#D||D!!r!   c                      \ rS rSrS rSrg)Test   c                X    [        5       nU R                  U[        R                  5        g r?   )r   assertIsInstancer   r   )selffps     r   testGetSourcePathTest.testGetSourcePath   s     b',,/r!   r    N)__name__
__module____qualname____firstlineno__rT   __static_attributes__r    r!   r   rN   rN      s    0r!   rN   __main__)returnpathlib.Path)r\   z	list[str]r?   )r:   r   r<   z
str | Noner\   zStrOrPath | str)r:   r]   r=   t.Literal[None]r\   r]   )r:   rG   r=   r^   r\   rG   )r:   str | pathlib.Pathr=   zt.Literal[True]r\   r]   )r:   r_   r=   zt.Literal[False]r\   rG   )r:   r_   r=   zbool | Noner\   r_   )
__future__r   __all__typingtr   r   r,   r   unittestTypeVarrG   r   r   r   r   r   r   r   r	   r
   TestCaserN   rV   r#   mainTestr    r!   r   <module>rh      s?   #    	  IIkW\\)9:	 =9.b( 
/3,8D 
 
/3,8; 
 
,1= 
 
-25 

 *."&"2B":08 0 zT r!   