§
    ƒØjUÆ  ã                  óÐ  — U d dl mZ g 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mZ d dlmZ d dlmZ d dlmZ d d	lmZ ej        rd d
lmZ d dlmZ  ej        d¦  «        Z G d„ dej        ¦  «        Z G d„ dej        ¦  «        Z G d„ dej        ¦  «        Zi Z de!d<   dd„Z" G d„ dej#        ¦  «        Z$eefZ%e&dk    rd dlZ ej'        e$¦  «         dS dS )é    )Úannotations)ÚMetadataEntryÚMetadataBundleÚMetadataBundleException)ÚOrderedDictN)Úcommon)ÚreadPickleGzip)Úenvironment)Úexceptions21)Úprebase)ÚIterable)ÚMetadatazmetadata.bundlesc                  ó   — e Zd ZdS )r   N)Ú__name__Ú
__module__Ú__qualname__© ó    ú�/Users/tedpeters/Documents/Projects/Claude Projects/Misc Tools/notename-sheets/.venv/lib/python3.11/site-packages/music21/metadata/bundles.pyr   r   .   s   € € € € € Ø€Dr   r   c                  óº   — e Zd ZdZ	 	 	 	 ddd„Zd„ Zd„ Zd„ Zd„ Zdd„Z	dd„Z
ed„ ¦   «         Zed„ ¦   «         Zed„ ¦   «         Zed„ ¦   «         Zed„ ¦   «         ZdS )r   aZ  
    An entry in a metadata bundle.

    The metadata entry holds information about the source of the metadata,
    and can be parsed to reconstitute the score object the metadata was
    derived from:

    >>> #_DOCS_SHOW coreBundle = corpus.corpora.CoreCorpus().metadataBundle
    >>> coreBundle = metadata.bundles.demo_bundle('core')  #_DOCS_HIDE
    >>> metadataEntry = coreBundle.search('bwv66.6')[0]
    >>> metadataEntry
    <music21.metadata.bundles.MetadataEntry 'bach_bwv66_6_mxl'>

    The sourcePath of the metadata entry refers to the file path at which its
    score file is found, but it is usually a relative path to the top of the corpus
    directory.  It is a pathlib object.

    >>> metadataEntry.sourcePath
    PosixPath('bach/bwv66.6.mxl')

    The metadata property contains its :class:`~music21.metadata.RichMetadata` object:

    >>> metadataEntry.metadata
    <music21.metadata.RichMetadata object at 0x...>

    Note that the id is not necessarily the current memory location.

    And the metadata entry can be parsed:

    >>> metadataEntry.parse()
    <music21.stream.Score ...>
    Ú NÚ
sourcePathústr | pathlib.PathÚnumberú
int | NoneÚmetadataPayloadúMetadata | NoneÚ
corpusNameÚstrc                óX   — t          |¦  «        | _        || _        || _        || _        d S ©N)r   Ú_sourcePathÚ_numberÚ_metadataPayloadÚ_corpusName)Úselfr   r   r   r   s        r   Ú__init__zMetadataEntry.__init__X   s/   € õ !$ J¡¤ˆÔØˆŒØ /ˆÔØ%ˆÔÐÐr   c                ó*   — | j         | j        | j        fS )zà
        This is all the information that is needed for pickling.
        Specifically do not include _corpusName.

        Note do not pickle Pathlib objects, so make sure to do ._sourcePath
        not .sourcePath
        )r"   Úmetadatar   ©r&   s    r   Ú__getnewargs__zMetadataEntry.__getnewargs__e   s   € ð ÔØŒMØŒKð
ð 	
r   c                ó*   — t          | j        ¦  «        S r!   )ÚreprÚ
corpusPathr*   s    r   Ú_reprInternalzMetadataEntry._reprInternals   s   € Ý�D”OÑ$Ô$Ð$r   c                ó   — | j         S )aI  
        Allows MetadataEntries to be used where file paths are being employed,
        so it can be used with opening and closing, etc.

        Returns self.sourcePath() as a string

        >>> mde1 = metadata.bundles.MetadataEntry(sourcePath='/tmp/myFile.xml')
        >>> mde1.__fspath__()
        '/tmp/myFile.xml'
        )r"   r*   s    r   Ú
__fspath__zMetadataEntry.__fspath__v   s   € ð ÔÐr   c                ó’   — ddl m} | j        �!|                     | j        | j        ¬¦  «        S |                     | j        ¦  «        S )Nr   ©Úcorpus)r   )Úmusic21r4   r   Úparser   )r&   r4   s     r   r6   zMetadataEntry.parse…   sJ   € Ø"Ð"Ð"Ð"Ð"Ð"ØŒ;Ð"Ø—<’< ¤¸¼�<ÑDÔDÐDà—<’< ¤Ñ0Ô0Ð0r   c                óX   — |                       ¦   «         }|                     |¦  «         d S r!   )r6   Úshow)r&   Ú
showFormatÚscores      r   r8   zMetadataEntry.showŒ   s'   € Ø—
’
‘”ˆØ�
Š
�:ÑÔÐÐÐr   c                ó*   —  | j         j        ||fi |¤ŽS r!   )r)   Úsearch)r&   ÚqueryÚfieldÚkeywordss       r   r<   zMetadataEntry.search�   s!   € à#ˆtŒ}Ô# E¨5Ð=Ð=°HÐ=Ð=Ð=r   c                óL   — t                                | j        | j        ¦  «        S )z^
        Returns the sourcePath as a string, with _number appended if it is not None.
        )r   ÚcorpusPathToKeyr   r   r*   s    r   r.   zMetadataEntry.corpusPath™   s   € õ
 ×-Ò-¨d¬o¸t¼{ÑKÔKÐKr   c                ó   — | j         S )zK
        Returns the Metadata object that is stored in the bundle.
        )r$   r*   s    r   r)   zMetadataEntry.metadata    s   € ð
 Ô$Ð$r   c                ó   — | j         S r!   )r#   r*   s    r   r   zMetadataEntry.number§   s
   € àŒ|Ðr   c                ó4   — t          j        | j        ¦  «        S r!   )ÚpathlibÚPathr"   r*   s    r   r   zMetadataEntry.sourcePath«   s   € åŒ|˜DÔ,Ñ-Ô-Ð-r   c                ó   — | j         S r!   )r%   r*   s    r   r   zMetadataEntry.corpusName¯   s   € àÔÐr   )r   NNr   )r   r   r   r   r   r   r   r   r!   ©NN)r   r   r   Ú__doc__r'   r+   r/   r1   r6   r8   r<   Úpropertyr.   r)   r   r   r   r   r   r   r   r   4   s4  € € € € € ðð ðH 13Ø$(Ø26Ø#%ð	
&ð 
&ð 
&ð 
&ð 
&ð
ð 
ð 
ð%ð %ð %ð ð  ð  ð1ð 1ð 1ðð ð ð ð>ð >ð >ð >ð ðLð Lñ „XðLð ð%ð %ñ „Xð%ð ðð ñ „Xðð ð.ð .ñ „Xð.ð ð ð  ñ „Xð ð  ð  r   r   c                  ó‚  — e Zd ZdZd:d;d„Zd<d„Zd„ Zd<d	„Zd
„ Zd<d„Z	d<d„Z
d„ Zd<d„Zd„ Zd„ Zd„ Zd„ Zd=d„Zd„ Zed„ ¦   «         Zej        d„ ¦   «         Zed>d„¦   «         Zed„ ¦   «         Z	 	 	 	 d?d„Zd „ Zed:d@d%„¦   «         ZdAd'„Zd(„ Zd)„ Zd*„ Zd+„ Z d,„ Z!ed-„ ¦   «         Z"d:d.„Z#	 	 dBd/d0œdCd5„Z$d6„ Z%d7„ Z&d8„ Z'd:d9„Z(dS )Dr   a   
    An object that provides access to, searches within, and stores and loads
    multiple Metadata objects.

    >>> #_DOCS_SHOW coreBundle = corpus.corpora.CoreCorpus().metadataBundle
    >>> coreBundle = metadata.bundles.demo_bundle('core')  #_DOCS_HIDE
    >>> coreBundle
    <music21.metadata.bundles.MetadataBundle 'core': {151... entries}>

    (The coreBundle has around 15100 entries; I've put '...' in the
    docs so I don't need to rewrite them every time we add a new piece)

    >>> #_DOCS_SHOW searchResults = coreBundle.search('bach', field='composer')
    >>> searchResults = metadata.bundles.demo_bundle('bach')  #_DOCS_HIDE
    >>> searchResults
    <music21.metadata.bundles.MetadataBundle {363 entries}>

    >>> resultsEntries = searchResults.search('3/4')
    >>> resultsEntries
    <music21.metadata.bundles.MetadataBundle {40 entries}>

    Results are ordered by their source path:

    >>> resultsEntries[0]
    <music21.metadata.bundles.MetadataEntry 'bach_bwv11_6_mxl'>

    To get a score out of the entry, call .parse()

    >>> resultsEntries[0].parse()
    <music21.stream.Score ...>

    Or pass it into converter:

    >>> converter.parse(resultsEntries[0])
    <music21.stream.Score ...>

    A metadata bundle can be instantiated in three ways, (1) from a ``Corpus`` instance,
    or (2) a string indicating which corpus name to draw from, and then calling
    .read() or (3) by calling
    .metadataBundle on a corpus object.  This
    calls `.read()` automatically:

    Method 1:

    >>> coreCorpus = corpus.corpora.CoreCorpus()
    >>> coreBundle = metadata.bundles.MetadataBundle(coreCorpus)
    >>> localCorpus = corpus.corpora.LocalCorpus()
    >>> localBundle = metadata.bundles.MetadataBundle(localCorpus)

    Method 2:

    >>> coreBundle = metadata.bundles.MetadataBundle('core')
    >>> localBundle = metadata.bundles.MetadataBundle('local')

    After calling these you'll need to call ``read()``:

    >>> coreBundle
    <music21.metadata.bundles.MetadataBundle 'core': {0 entries}>
    >>> coreBundle.read()
    <music21.metadata.bundles.MetadataBundle 'core': {151... entries}>
    >>> coreBundle
    <music21.metadata.bundles.MetadataBundle 'core': {151... entries}>

    Method 3:

    >>> coreBundle = corpus.corpora.CoreCorpus().metadataBundle
    >>> localBundle = corpus.corpora.LocalCorpus().metadataBundle

    >>> coreBundle
    <music21.metadata.bundles.MetadataBundle 'core': {151... entries}>

    Additionally, any two metadata bundles can be operated on together as
    though they were sets, allowing us to build up more complex searches:

    >>> #_DOCS_SHOW coreBundle = corpus.corpora.CoreCorpus().metadataBundle
    >>> coreBundle = metadata.bundles.demo_bundle('core')  #_DOCS_HIDE
    >>> #_DOCS_SHOW bachBundle = coreBundle.search('bach', 'composer')
    >>> bachBundle = metadata.bundles.demo_bundle('bach')  #_DOCS_HIDE
    >>> bachBundle
    <music21.metadata.bundles.MetadataBundle {363 entries}>
    >>> #_DOCS_SHOW tripleMeterBundle = coreBundle.search('3/4')
    >>> tripleMeterBundle = metadata.bundles.demo_bundle('3/4')  #_DOCS_HIDE
    >>> tripleMeterBundle
    <music21.metadata.bundles.MetadataBundle {1875 entries}>
    >>> bachBundle.intersection(tripleMeterBundle)
    <music21.metadata.bundles.MetadataBundle {40 entries}>

    Finally, a metadata bundle need not be associated with any corpus at all,
    and can be populated ad hoc:

    >>> anonymousBundle = metadata.bundles.MetadataBundle()
    >>> mdb = corpus.corpora.CoreCorpus().search('monteverdi')[:4]
    >>> paths = [common.getCorpusFilePath() / x.sourcePath for x in mdb]
    >>> failedPaths = anonymousBundle.addFromPaths(
    ...     paths, useMultiprocessing=False)
    >>> failedPaths
    []
    >>> anonymousBundle
    <music21.metadata.bundles.MetadataBundle {4 entries}>
    NÚexprú,'music21.corpus.corpora.Corpus' | str | Nonec                ó@  — ddl m} t          ¦   «         | _        t	          |t
          |j        j        t          d ¦  «        f¦  «        st          d¦  «        ‚d | _
        |  t	          ||j        j        ¦  «        r|j        | _        || _        d S || _        d | _        d S )Nr   r3   z4Need to take a string, corpus, or None as expression)r5   r4   r   Ú_metadataEntriesÚ
isinstancer   ÚcorporaÚCorpusÚtyper   Ú_corpusÚnameÚ_name)r&   rL   r4   s      r   r'   zMetadataBundle.__init__  sž   € Ø"Ð"Ð"Ð"Ð"Ð"åALÁÄˆÔÝ˜$¥ f¤nÔ&;½TÀ$¹Z¼ZÐ HÑIÔIð 	bÝ)Ð*`ÑaÔaÐaà37ˆŒØÐå�d˜FœNÔ1Ñ2Ô2ð 	ØœˆDŒJØˆDŒKˆKˆKàˆDŒJØˆDŒKˆKˆKr   ÚmetadataBundlec                ó.   — |                       |d¦  «        S )aU  
        Compute the set-wise `and` of two metadata bundles:

        >>> #_DOCS_SHOW coreBundle = corpus.corpora.CoreCorpus().metadataBundle
        >>> coreBundle = metadata.bundles.demo_bundle('core')  #_DOCS_HIDE
        >>> #_DOCS_SHOW bachBundle = coreBundle.search('bach', 'composer')
        >>> bachBundle = metadata.bundles.demo_bundle('bach')  #_DOCS_HIDE
        >>> bachBundle
        <music21.metadata.bundles.MetadataBundle {363 entries}>
        >>> #_DOCS_SHOW tripleMeterBundle = coreBundle.search('3/4')
        >>> tripleMeterBundle = metadata.bundles.demo_bundle('3/4')  #_DOCS_HIDE
        >>> tripleMeterBundle
        <music21.metadata.bundles.MetadataBundle {1875 entries}>
        >>> bachBundle & tripleMeterBundle
        <music21.metadata.bundles.MetadataBundle {40 entries}>

        Returns a new metadata bundle.
        Ú__and__©Ú_apply_set_operation©r&   rW   s     r   rY   zMetadataBundle.__and__2  s"   € ð& ×(Ò(ØØñ
ô 
ð 	
r   c                óJ   — t          |d¦  «        r| j        |j        k    rdS dS )a7  
        True if `expr` is of the same type, and contains an identical set of
        entries, otherwise false:

        >>> #_DOCS_SHOW coreBundle = corpus.corpora.CoreCorpus().metadataBundle
        >>> coreBundle = metadata.bundles.demo_bundle('core')  #_DOCS_HIDE
        >>> #_DOCS_SHOW bachBundle = coreBundle.search('bach', 'composer')
        >>> bachBundle = metadata.bundles.demo_bundle('bach')  #_DOCS_HIDE
        >>> #_DOCS_SHOW corelliBundle = coreBundle.search('corelli', 'composer')
        >>> corelliBundle = metadata.bundles.demo_bundle('corelli')  #_DOCS_HIDE
        >>> bachBundle == corelliBundle
        False
        >>> bachBundle == coreBundle.search(
        ...     'bach',
        ...     field='composer',
        ...     )
        True
        >>> bachBundle == 'foo'
        False

        rO   TF)ÚhasattrrO   )r&   Úothers     r   Ú__eq__zMetadataBundle.__eq__J  s2   € õ, �5Ð,Ñ-Ô-ð 	ØÔ$¨Ô(>Ò>Ð>Ø�tØˆur   c                ó.   — |                       |d¦  «        S )a9  
        True when one metadata bundle is either a superset or an identical set
        to another bundle:

        >>> #_DOCS_SHOW coreBundle = corpus.corpora.CoreCorpus().metadataBundle
        >>> coreBundle = metadata.bundles.demo_bundle('core')  #_DOCS_HIDE
        >>> #_DOCS_SHOW bachBundle = coreBundle.search('bach', 'composer')
        >>> bachBundle = metadata.bundles.demo_bundle('bach')  #_DOCS_HIDE
        >>> #_DOCS_SHOW corelliBundle = coreBundle.search('corelli', 'composer')
        >>> corelliBundle = metadata.bundles.demo_bundle('corelli')  #_DOCS_HIDE
        >>> bachBundle >= bachBundle
        True
        >>> bachBundle >= corelliBundle
        False
        >>> bachBundle >= coreBundle
        False
        >>> corelliBundle >= bachBundle
        False
        >>> corelliBundle >= corelliBundle
        True
        >>> corelliBundle >= coreBundle
        False
        >>> coreBundle >= bachBundle
        True
        >>> coreBundle >= corelliBundle
        True
        >>> coreBundle >= coreBundle
        True

        Returns boolean.
        Ú__ge__©Ú_apply_set_predicater\   s     r   rb   zMetadataBundle.__ge__e  ó   € ð@ ×(Ò(¨¸ÑBÔBÐBr   c                óZ   — t          | j                             ¦   «         ¦  «        |         S r!   )ÚlistrO   Úvalues)r&   Úis     r   Ú__getitem__zMetadataBundle.__getitem__‡  s$   € Ý�DÔ)×0Ò0Ñ2Ô2Ñ3Ô3°AÔ6Ð6r   c                ó.   — |                       |d¦  «        S )a1  
        True when one metadata bundle is either a subset or an identical set to
        another bundle:

        >>> #_DOCS_SHOW coreBundle = corpus.corpora.CoreCorpus().metadataBundle
        >>> coreBundle = metadata.bundles.demo_bundle('core')  #_DOCS_HIDE
        >>> #_DOCS_SHOW bachBundle = coreBundle.search('bach', 'composer')
        >>> bachBundle = metadata.bundles.demo_bundle('bach')  #_DOCS_HIDE
        >>> #_DOCS_SHOW corelliBundle = coreBundle.search('corelli', 'composer')
        >>> corelliBundle = metadata.bundles.demo_bundle('corelli')  #_DOCS_HIDE
        >>> bachBundle > bachBundle
        False
        >>> bachBundle > corelliBundle
        False
        >>> bachBundle > coreBundle
        False
        >>> corelliBundle > bachBundle
        False
        >>> corelliBundle > corelliBundle
        False
        >>> corelliBundle > coreBundle
        False
        >>> coreBundle > bachBundle
        True
        >>> coreBundle > corelliBundle
        True
        >>> coreBundle > coreBundle
        False

        Returns boolean.
        Ú__gt__rc   r\   s     r   rl   zMetadataBundle.__gt__Š  re   r   c                ó.   — |                       |d¦  «        S )a7  
        True when one metadata bundle is either a subset or an identical set to
        another bundle:

        >>> #_DOCS_SHOW coreBundle = corpus.corpora.CoreCorpus().metadataBundle
        >>> coreBundle = metadata.bundles.demo_bundle('core')  #_DOCS_HIDE
        >>> #_DOCS_SHOW bachBundle = coreBundle.search('bach', 'composer')
        >>> bachBundle = metadata.bundles.demo_bundle('bach')  #_DOCS_HIDE
        >>> #_DOCS_SHOW corelliBundle = coreBundle.search('corelli', 'composer')
        >>> corelliBundle = metadata.bundles.demo_bundle('corelli')  #_DOCS_HIDE
        >>> bachBundle <= bachBundle
        True
        >>> bachBundle <= corelliBundle
        False
        >>> bachBundle <= coreBundle
        True
        >>> corelliBundle <= bachBundle
        False
        >>> corelliBundle <= corelliBundle
        True
        >>> corelliBundle <= coreBundle
        True
        >>> coreBundle <= bachBundle
        False
        >>> coreBundle <= corelliBundle
        False
        >>> coreBundle <= coreBundle
        True

        Returns boolean.
        Ú__le__rc   r\   s     r   rn   zMetadataBundle.__le__¬  re   r   c                ó*   — t          | j        ¦  «        S r!   )ÚlenrO   r*   s    r   Ú__len__zMetadataBundle.__len__Î  s   € Ý�4Ô(Ñ)Ô)Ð)r   c                ó.   — |                       |d¦  «        S )a  
        True when one metadata bundle is a subset of another bundle:

        >>> #_DOCS_SHOW coreBundle = corpus.corpora.CoreCorpus().metadataBundle
        >>> coreBundle = metadata.bundles.demo_bundle('core')  #_DOCS_HIDE
        >>> #_DOCS_SHOW bachBundle = coreBundle.search('bach', 'composer')
        >>> bachBundle = metadata.bundles.demo_bundle('bach')  #_DOCS_HIDE
        >>> #_DOCS_SHOW corelliBundle = coreBundle.search('corelli', 'composer')
        >>> corelliBundle = metadata.bundles.demo_bundle('corelli')  #_DOCS_HIDE
        >>> bachBundle < bachBundle
        False
        >>> bachBundle < corelliBundle
        False
        >>> bachBundle < coreBundle
        True
        >>> corelliBundle < bachBundle
        False
        >>> corelliBundle < corelliBundle
        False
        >>> corelliBundle < coreBundle
        True
        >>> coreBundle < bachBundle
        False
        >>> coreBundle < corelliBundle
        False
        >>> coreBundle < coreBundle
        False

        Return boolean.
        Ú__lt__rc   r\   s     r   rs   zMetadataBundle.__lt__Ñ  s   € ð> ×(Ò(¨¸ÑBÔBÐBr   c                ó.   — |                       |d¦  «        S )aT  
        Compute the set-wise `or` of two metadata bundles:

        >>> #_DOCS_SHOW coreBundle = corpus.corpora.CoreCorpus().metadataBundle
        >>> coreBundle = metadata.bundles.demo_bundle('core')  #_DOCS_HIDE
        >>> #_DOCS_SHOW bachBundle = coreBundle.search('bach', 'composer')
        >>> bachBundle = metadata.bundles.demo_bundle('bach')  #_DOCS_HIDE
        >>> bachBundle
        <music21.metadata.bundles.MetadataBundle {363 entries}>
        >>> #_DOCS_SHOW corelliBundle = coreBundle.search('corelli', 'composer')
        >>> corelliBundle = metadata.bundles.demo_bundle('corelli')  #_DOCS_HIDE
        >>> corelliBundle
        <music21.metadata.bundles.MetadataBundle {1 entry}>
        >>> bachBundle | corelliBundle
        <music21.metadata.bundles.MetadataBundle {364 entries}>

        Returns a new metadata bundle.
        Ú__or__rZ   r\   s     r   ru   zMetadataBundle.__or__ò  s"   € ð& ×(Ò(ØØñ
ô 
ð 	
r   c                óœ   — t          | ¦  «        dk    rd}n"dt          t          | ¦  «        ¦  «        z   dz   }| j        �| j        ›d|› �}|S )Né   z	{1 entry}Ú{z	 entries}z: )rp   r   rU   )r&   Ústatuss     r   r/   zMetadataBundle._reprInternal
  sU   € Ýˆt‰9Œ9˜Š>ˆ>Ø ˆFˆFà�3�s 4™yœy™>œ>Ñ)¨KÑ7ˆFàŒ9Ð Øœ	Ð/Ð/ vÐ/Ð/ˆFØˆr   c                ó.   — |                       |d¦  «        S )aÁ  
        Compute the set-wise `subtraction` of two metadata bundles:

        >>> #_DOCS_SHOW coreBundle = corpus.corpora.CoreCorpus().metadataBundle
        >>> coreBundle = metadata.bundles.demo_bundle('core')  #_DOCS_HIDE
        >>> #_DOCS_SHOW bachBundle = coreBundle.search('bach', 'composer')
        >>> bachBundle = metadata.bundles.demo_bundle('bach')  #_DOCS_HIDE
        >>> bachBundle
        <music21.metadata.bundles.MetadataBundle {363 entries}>
        >>> #_DOCS_SHOW tripleMeterBundle = coreBundle.search('3/4')
        >>> tripleMeterBundle = metadata.bundles.demo_bundle('3/4')  #_DOCS_HIDE
        >>> tripleMeterBundle
        <music21.metadata.bundles.MetadataBundle {1875 entries}>
        >>> bachBundle - tripleMeterBundle
        <music21.metadata.bundles.MetadataBundle {323 entries}>

        Returns a new metadata bundle.

        >>> bachBundle - bachBundle
        <music21.metadata.bundles.MetadataBundle {0 entries}>
        Ú__sub__rZ   r\   s     r   r{   zMetadataBundle.__sub__  s"   € ð, ×(Ò(ØØñ
ô 
ð 	
r   c                ó.   — |                       |d¦  «        S )aa  
        Compute the set-wise `exclusive or` of two metadata bundles:

        >>> #_DOCS_SHOW coreBundle = corpus.corpora.CoreCorpus().metadataBundle
        >>> coreBundle = metadata.bundles.demo_bundle('core')  #_DOCS_HIDE
        >>> #_DOCS_SHOW bachBundle = coreBundle.search('bach', 'composer')
        >>> bachBundle = metadata.bundles.demo_bundle('bach')  #_DOCS_HIDE
        >>> bachBundle
        <music21.metadata.bundles.MetadataBundle {363 entries}>

        >>> #_DOCS_SHOW tripleMeterBundle = coreBundle.search('3/4')
        >>> tripleMeterBundle = metadata.bundles.demo_bundle('3/4')  #_DOCS_HIDE
        >>> tripleMeterBundle
        <music21.metadata.bundles.MetadataBundle {1875 entries}>
        >>> bachBundle ^ tripleMeterBundle
        <music21.metadata.bundles.MetadataBundle {2158 entries}>

        Returns a new metadata bundle.
        Ú__xor__rZ   r\   s     r   r}   zMetadataBundle.__xor__/  s"   € ð( ×(Ò(ØØñ
ô 
ð 	
r   Úoperatorr   c                óP  — t          |t          | ¦  «        ¦  «        st          d¦  «        ‚t          | j                             ¦   «         ¦  «        }t          |j                             ¦   «         ¦  «        } t          ||¦  «        |¦  «        } t          | ¦  «        ¦   «         }|D ]0}|| j        v r| j        |         }n|j        |         }||j        |<   Œ1t          |j                             ¦   «         ¦  «        }	t          t          |	d„ ¬¦  «        ¦  «        |_        |S )Nú'metadataBundle must be a MetadataBundlec                ó   — | d         j         S ©Nrw   ©r   ©Úmdes    r   ú<lambda>z5MetadataBundle._apply_set_operation.<locals>.<lambda>\  s   € È3ÈqÌ6ÔK\€ r   ©Úkey)rP   rS   r   ÚsetrO   ÚkeysÚgetattrrg   Úitemsr   Úsorted)
r&   rW   r~   ÚselfKeysÚ	otherKeysÚ
resultKeysÚresultBundlerˆ   ÚmetadataEntryÚmdbItemss
             r   r[   z#MetadataBundle._apply_set_operationJ  s)  € Ý˜.­$¨t©*¬*Ñ5Ô5ð 	UÝ)Ð*SÑTÔTÐTÝ�tÔ,×1Ò1Ñ3Ô3Ñ4Ô4ˆÝ˜Ô7×<Ò<Ñ>Ô>Ñ?Ô?ˆ	Ø ;¥¨°(Ñ ;Ô ;¸IÑ FÔ Fˆ
Ø'1¥t¨D¡z¤z¡|¤|ˆØð 	?ð 	?ˆCà�dÔ+Ð+Ð+Ø $Ô 5°cÔ :��à .Ô ?ÀÔ D�Ø1>ˆLÔ)¨#Ñ.Ð.õ 59¸Ô9V×9\Ò9\Ñ9^Ô9^Ñ4_Ô4_ˆÝ(3µF¸8Ø?\Ð?\ð5^ñ 5^ô 5^ñ )_ô )_ˆÔ%àÐr   c                ó$  — t          |t          | ¦  «        ¦  «        st          d¦  «        ‚t          | j                             ¦   «         ¦  «        }t          |j                             ¦   «         ¦  «        } t          ||¦  «        |¦  «        S )zZ
        Applies a predicate such as '__or__' to self and another metadataBundle.
        r€   )rP   rS   r   r‰   rO   rŠ   r‹   )r&   rW   Ú	predicaterŽ   r�   s        r   rd   z#MetadataBundle._apply_set_predicate_  s~   € õ ˜.­$¨t©*¬*Ñ5Ô5ð 	UÝ)Ð*SÑTÔTÐTÝ�tÔ,×1Ò1Ñ3Ô3Ñ4Ô4ˆÝ˜Ô7×<Ò<Ñ>Ô>Ñ?Ô?ˆ	Ø+�w�x Ñ+Ô+¨IÑ6Ô6Ð6r   c                óœ   — | j         �t          j        | j         ¦  «        }|�|S | j        €dS ddlm} |                     | j        ¦  «        S )a°  
        The `corpus.corpora.Corpus` object associated with the metadata
        bundle's name.

        >>> #_DOCS_SHOW coreBundle = corpus.corpora.CoreCorpus().metadataBundle
        >>> coreBundle = metadata.bundles.demo_bundle('core')  #_DOCS_HIDE
        >>> coreBundle
        <music21.metadata.bundles.MetadataBundle 'core': {151... entries}>
        >>> coreBundle.corpus
        <music21.corpus.corpora.CoreCorpus>
        Nr   )Úmanager)rT   r   ÚunwrapWeakrefrU   Úmusic21.corpusr—   ÚfromName)r&   ÚcObjr—   s      r   r4   zMetadataBundle.corpusm  s^   € ð Œ<Ð#ÝÔ'¨¬Ñ5Ô5ˆDØÐØ�àŒ9ÐØ�4à*Ð*Ð*Ð*Ð*Ð*Ø×Ò ¤	Ñ*Ô*Ð*r   c                ó8   — t          j        |¦  «        | _        d S r!   )r   ÚwrapWeakrefrT   )r&   Ú	newCorpuss     r   r4   zMetadataBundle.corpus…  s   € åÔ)¨)Ñ4Ô4ˆŒˆˆr   Úreturnúpathlib.Path | Nonec                ó†   — | j         }|€dS |j        }t          |t          j        ¦  «        st          j        |¦  «        S |S )aî  
        The filesystem name of the cached metadata bundle, if the metadata
        bundle's name is not None.

        >>> ccPath = corpus.corpora.CoreCorpus().metadataBundle.filePath
        >>> ccPath.name
        'core.p.gz'
        >>> '_metadataCache' in ccPath.parts
        True

        >>> localPath = corpus.corpora.LocalCorpus().metadataBundle.filePath
        >>> localPath.name
        'local.p.gz'

        Local corpora metadata is stored in the scratch dir, not the
        corpus directory

        >>> '_metadataCache' in localPath.parts
        False

        >>> funkCorpus = corpus.corpora.LocalCorpus('funk')
        >>> funkPath = funkCorpus.metadataBundle.filePath
        >>> funkPath.name
        'local-funk.p.gz'
        N)r4   ÚcacheFilePathrP   rE   rF   )r&   ÚcÚcfps      r   ÚfilePathzMetadataBundle.filePath‰  sE   € ð6 ŒKˆØˆ9Ø�4à”/ˆCÝ˜c¥7¤<Ñ0Ô0ð Ý”| CÑ(Ô(Ð(à�
r   c                ó   — | j         S )aM  
        The name of the metadata bundle.

        Can be 'core', 'local', '{name}' where name is the name
        of a named local corpus or None.

        The names 'core' and 'local' refer to the core and local
        corpora respectively: (virtual corpus is currently offline)

        >>> metadata.bundles.MetadataBundle().name is None
        True
        >>> corpus.corpora.CoreCorpus().metadataBundle.name
        'core'

        >>> funkCorpus = corpus.corpora.LocalCorpus('funk')
        >>> funkCorpus.metadataBundle.name
        'funk'

        Return string or None.
        )rV   r*   s    r   rU   zMetadataBundle.name®  s   € ð, ŒzÐr   FTc           	     óÈ  — ddl m} g }g }g }	| j        �8| j                             ¦   «         r| j                             ¦   «         j        }
nt          j        ¦   «         }
d|
› �}|du rt                               |¦  «         nt           	                    |¦  «         d}d}|D ]§}|  
                    |¦  «        }|| j        v r%|                     ¦   «         j        }||
k     r|dz  }ŒE|dz  }| j        }|€d}|                     d¦  «        r
|d	d…         }|j                             ||||¬
¦  «        }|                     |¦  «         Œ¨d}d|› d�}|du rt                               |¦  «         nt           	                    |¦  «         |r|j        j        j        }n|j        j        j        } ||¦  «        D ]ù}|j        j                             t+          |¦  «        |d         |d         t+          |	¦  «        ¦  «        }|du rt                               |¦  «         nt           	                    |¦  «         |dz  }|                     |d         ¦  «         |	                     |d         ¦  «         |d         D ]}|| j        |j        <   Œ|dz  dk    r|du r|                      ¦   «          Œú|                      ¦   «          |du r|                      ¦   «          |	S )a  
        Parse and store metadata from numerous files.

        If any files cannot be loaded, their file paths will be collected in a
        list that is returned.

        Returns a list of file paths with errors and stores the extracted
        metadata in `self._metadataEntries`.

        >>> metadataBundle = metadata.bundles.MetadataBundle()
        >>> p = corpus.corpora.CoreCorpus().getWorkList('bach/bwv66.6')
        >>> metadataBundle.addFromPaths(
        ...     p,
        ...     parseUsingCorpus=False,
        ...     useMultiprocessing=False,
        ...     storeOnDisk=False, #_DOCS_HIDE
        ...     )
        []
        >>> len(metadataBundle._metadataEntries)
        1

        Set Verbose to True to get updates even if debug is off.
        r   )r)   Nz"MetadataBundle Modification Time: Trw   Úcorezlocal-é   )Ú	jobNumberÚparseUsingCorpusr   zSkipped z sources already in cache.ÚremainingJobsr¥   ÚmetadataEntriesÚerrorsé2   )r5   r)   r¥   ÚexistsÚstatÚst_ctimeÚtimeÚenvironLocalÚwarnÚ
printDebugrA   rO   rU   Ú
startswithÚcachingÚMetadataCachingJobÚappendÚJobProcessorÚprocess_parallelÚprocess_serialÚ_reportrp   Úextendr.   ÚwriteÚvalidate)r&   Úpathsr«   ÚuseMultiprocessingÚstoreOnDiskÚverboser)   ÚjobsÚaccumulatedResultsÚaccumulatedErrorsÚmetadataBundleModificationTimeÚmessageÚcurrentJobNumberÚskippedJobsCountÚpathrˆ   ÚpathModificationTimer   ÚjobÚcurrentIterationÚjobProcessorÚresultr’   s                          r   ÚaddFromPathszMetadataBundle.addFromPathsÈ  sM  € ð> 	%Ð$Ð$Ð$Ð$Ð$ØˆØÐØÐØŒ=Ð$¨¬×)=Ò)=Ñ)?Ô)?Ð$Ø-1¬]×-?Ò-?Ñ-AÔ-AÔ-JÐ*Ð*å-1¬Y©[¬[Ð*àWÐ7UÐWÐWˆà�dˆ?ˆ?Ý×Ò˜gÑ&Ô&Ð&Ð&å×#Ò# GÑ,Ô,Ð,àÐØÐØð 	ð 	ˆDØ×&Ò& tÑ,Ô,ˆCØ�dÔ+Ð+Ð+Ø'+§y¢y¡{¤{Ô';Ð$Ø'Ð*HÒHÐHØ$¨Ñ)Ð$ØØ Ñ!ÐØœˆJØÐ!Ø#�
à×$Ò$ XÑ.Ô.ð ,Ø'¨¨¨œ^�
àÔ"×5Ò5ØØ*Ø!1Ø%ð	 6ñ ô ˆCð �KŠK˜ÑÔÐÐØÐØIÐ-ÐIÐIÐIˆØ�dˆ?ˆ?Ý×Ò˜gÑ&Ô&Ð&Ð&å×#Ò# GÑ,Ô,Ð,àð 	HØ#Ô+Ô8ÔIˆLˆLà#Ô+Ô8ÔGˆLØ"�l 4Ñ(Ô(ð 	ð 	ˆFØÔ&Ô3×;Ò;Ý�D‘	”	Ø�Ô'Ø�zÔ"ÝÐ%Ñ&Ô&ñ	ô ˆGð ˜$ˆˆÝ×!Ò! 'Ñ*Ô*Ð*Ð*å×'Ò'¨Ñ0Ô0Ð0à Ñ!ÐØ×%Ò% fÐ->Ô&?Ñ@Ô@Ð@Ø×$Ò$ V¨HÔ%5Ñ6Ô6Ð6Ø!'Ð(9Ô!:ð Pð P�ØBO�Ô% mÔ&>Ñ?Ð?Ø  2Ñ%¨Ò*Ð*°¸tÐ0CÐ0CØ—
’
‘”�øØ�Š‰ŒˆØ˜$ÐÐØ�JŠJ‰LŒLˆLØ Ð r   c                ó8   — | j                              ¦   «          dS )ai  
        Clear all keys in a metadata bundle:

        >>> #_DOCS_SHOW coreBundle = corpus.corpora.CoreCorpus().metadataBundle
        >>> coreBundle = metadata.bundles.demo_bundle('core')  #_DOCS_HIDE
        >>> bachBundle = coreBundle.search('bach', 'composer')
        >>> bachBundle
        <music21.metadata.bundles.MetadataBundle {363 entries}>

        >>> bachBundle.clear()
        >>> bachBundle
        <music21.metadata.bundles.MetadataBundle {0 entries}>

        Returns None.

        OMIT_FROM_DOCS

        Do not use the cached bach on this -- the .clear() manipulates the metadata bundle.
        N)rO   Úclearr*   s    r   rÕ   zMetadataBundle.clear2  s   € ð( 	Ô×#Ò#Ñ%Ô%Ð%Ð%Ð%r   r¥   r   r   r   c                ó|  — t          | t          j        ¦  «        r�	 |                      t	          j        ¦   «         dz  ¦  «        } n# t          $ r Y nw xY w| j        }|d         dk    rt          |¦  «        dk    r
|dd…         }d 	                    |¦  «        }n�d| v r|  
                    d¦  «        d         }n| }|                     t          j        ¦  «        r
|dd…         }|                     dd¦  «        }|                     t          j        d¦  «        }|                     dd¦  «        }|�|› d|› �S |S )	aB  
        Given a file path or corpus path, return the metadata key:

        >>> mb = metadata.bundles.MetadataBundle()
        >>> key = mb.corpusPathToKey('bach/bwv1007/prelude')
        >>> key.endswith('bach_bwv1007_prelude')
        True

        >>> key = mb.corpusPathToKey('corelli/opus3no1/1grave.xml')
        >>> key.endswith('corelli_opus3no1_1grave_xml')
        True

        Numbers are appended if given

        >>> key = mb.corpusPathToKey('corelli/opus3no1/1grave.xml', number=3)
        >>> key.endswith('corelli_opus3no1_1grave_xml_3')
        True
        r4   r   ú/rw   NÚ_éÿÿÿÿú.)rP   rE   rF   Úrelative_tor   ÚgetSourceFilePathÚ
ValueErrorÚpartsrp   ÚjoinÚsplitr·   ÚosÚsepÚreplace)r¥   r   rÞ   r.   s       r   rA   zMetadataBundle.corpusPathToKeyH  sR  € õ( �h¥¤Ñ-Ô-ð 	9ðØ#×/Ò/µÔ0HÑ0JÔ0JÈXÑ0UÑVÔV��øÝð ð ð Ø�ðøøøð ”NˆEØ�QŒx˜3Šˆ¥3 u¡:¤:°¢> >Ø˜a˜b˜bœ	�àŸš %™œˆJˆJà˜8Ð#Ð#à%Ÿ^š^¨HÑ5Ô5°bÔ9�
�
à%�
à×$Ò$¥R¤VÑ,Ô,ð ,Ø'¨¨¨œ^�
Ø#×+Ò+¨C°Ñ5Ô5ˆJØ#×+Ò+­B¬F°CÑ8Ô8ˆJà×'Ò'¨¨SÑ1Ô1ˆ
ð ÐØ Ð+Ð+ 6Ð+Ð+Ð+ØÐs   œ)A Á
AÁAÚNonec                ó€   — | j         �4| j                              ¦   «         r| j                              ¦   «          dS dS dS )z—
        Delete the filesystem cache of a named metadata bundle.

        Does not delete the in-memory metadata bundle.

        Return None.
        N)r¥   r°   Úunlinkr*   s    r   ÚdeletezMetadataBundle.deletez  sN   € ð Œ=Ð$ØŒ}×#Ò#Ñ%Ô%ð 'Ø”×$Ò$Ñ&Ô&Ð&Ð&Ð&ð %Ð$ð'ð 'r   c                ó.   — |                       |d¦  «        S )ag  
        Compute the set-wise difference of two metadata bundles:

        >>> #_DOCS_SHOW coreBundle = corpus.corpora.CoreCorpus().metadataBundle
        >>> coreBundle = metadata.bundles.demo_bundle('core')  #_DOCS_HIDE
        >>> #_DOCS_SHOW bachBundle = coreBundle.search('bach', 'composer')
        >>> bachBundle = metadata.bundles.demo_bundle('bach')  #_DOCS_HIDE
        >>> bachBundle
        <music21.metadata.bundles.MetadataBundle {363 entries}>

        >>> #_DOCS_SHOW tripleMeterBundle = coreBundle.search('3/4')
        >>> tripleMeterBundle = metadata.bundles.demo_bundle('3/4')  #_DOCS_HIDE
        >>> tripleMeterBundle
        <music21.metadata.bundles.MetadataBundle {1875 entries}>

        >>> bachBundle.difference(tripleMeterBundle)
        <music21.metadata.bundles.MetadataBundle {323 entries}>

        Returns a new metadata bundle.
        Ú
differencerZ   r\   s     r   ré   zMetadataBundle.difference†  s"   € ð* ×(Ò(ØØñ
ô 
ð 	
r   c                ó.   — |                       |d¦  «        S )ai  
        Compute the set-wise intersection of two metadata bundles:

        >>> #_DOCS_SHOW coreBundle = corpus.corpora.CoreCorpus().metadataBundle
        >>> coreBundle = metadata.bundles.demo_bundle('core')  #_DOCS_HIDE
        >>> #_DOCS_SHOW bachBundle = coreBundle.search('bach', 'composer')
        >>> bachBundle = metadata.bundles.demo_bundle('bach')  #_DOCS_HIDE
        >>> bachBundle
        <music21.metadata.bundles.MetadataBundle {363 entries}>

        >>> #_DOCS_SHOW tripleMeterBundle = coreBundle.search('3/4')
        >>> tripleMeterBundle = metadata.bundles.demo_bundle('3/4')  #_DOCS_HIDE
        >>> tripleMeterBundle
        <music21.metadata.bundles.MetadataBundle {1875 entries}>

        >>> bachBundle.intersection(tripleMeterBundle)
        <music21.metadata.bundles.MetadataBundle {40 entries}>

        Returns a new MetadataBundle.
        ÚintersectionrZ   r\   s     r   rë   zMetadataBundle.intersection   s"   € ð* ×(Ò(ØØñ
ô 
ð 	
r   c                ó.   — |                       |d¦  «        S )a‹  
        True if the set of keys in one metadata bundle are disjoint with
        the set of keys in another:

        >>> #_DOCS_SHOW coreBundle = corpus.corpora.CoreCorpus().metadataBundle
        >>> coreBundle = metadata.bundles.demo_bundle('core')  #_DOCS_HIDE
        >>> #_DOCS_SHOW bachBundle = coreBundle.search('bach', 'composer')
        >>> bachBundle = metadata.bundles.demo_bundle('bach')  #_DOCS_HIDE
        >>> bachBundle
        <music21.metadata.bundles.MetadataBundle {363 entries}>

        >>> #_DOCS_SHOW corelliBundle = coreBundle.search('corelli', 'composer')
        >>> corelliBundle = metadata.bundles.demo_bundle('corelli')  #_DOCS_HIDE
        >>> corelliBundle
        <music21.metadata.bundles.MetadataBundle {1 entry}>

        >>> bachBundle.isdisjoint(corelliBundle)
        True

        >>> #_DOCS_SHOW tripleMeterBundle = coreBundle.search('3/4')
        >>> tripleMeterBundle = metadata.bundles.demo_bundle('3/4')  #_DOCS_HIDE
        >>> tripleMeterBundle
        <music21.metadata.bundles.MetadataBundle {1875 entries}>

        >>> bachBundle.isdisjoint(tripleMeterBundle)
        False

        Returns boolean.
        Ú
isdisjointrc   r\   s     r   rí   zMetadataBundle.isdisjointº  s   € ð< ×(Ò(¨¸ÑFÔFÐFr   c                ó.   — |                       |d¦  «        S )a:  
        True if the set of keys in one metadata bundle are a subset of
        the keys in another:

        >>> #_DOCS_SHOW coreBundle = corpus.corpora.CoreCorpus().metadataBundle
        >>> coreBundle = metadata.bundles.demo_bundle('core')  #_DOCS_HIDE
        >>> #_DOCS_SHOW bachBundle = coreBundle.search('bach', 'composer')
        >>> bachBundle = metadata.bundles.demo_bundle('bach')  #_DOCS_HIDE
        >>> bachBundle
        <music21.metadata.bundles.MetadataBundle {363 entries}>

        >>> tripleMeterBachBundle = bachBundle.search('3/4')
        >>> tripleMeterBachBundle
        <music21.metadata.bundles.MetadataBundle {40 entries}>

        >>> tripleMeterBachBundle.issubset(bachBundle)
        True

        >>> bachBundle.issubset(tripleMeterBachBundle)
        False

        Returns boolean.
        Úissubsetrc   r\   s     r   rï   zMetadataBundle.issubsetÚ  s   € ð0 ×(Ò(¨¸ÑDÔDÐDr   c                ó.   — |                       |d¦  «        S )a@  
        True if the set of keys in one metadata bundle are a superset of
        the keys in another:

        >>> #_DOCS_SHOW coreBundle = corpus.corpora.CoreCorpus().metadataBundle
        >>> coreBundle = metadata.bundles.demo_bundle('core')  #_DOCS_HIDE
        >>> #_DOCS_SHOW bachBundle = coreBundle.search('bach', 'composer')
        >>> bachBundle = metadata.bundles.demo_bundle('bach')  #_DOCS_HIDE
        >>> bachBundle
        <music21.metadata.bundles.MetadataBundle {363 entries}>

        >>> tripleMeterBachBundle = bachBundle.search('3/4')
        >>> tripleMeterBachBundle
        <music21.metadata.bundles.MetadataBundle {40 entries}>

        >>> tripleMeterBachBundle.issuperset(bachBundle)
        False

        >>> bachBundle.issuperset(tripleMeterBachBundle)
        True

        Returns boolean.
        Ú
issupersetrc   r\   s     r   rñ   zMetadataBundle.issupersetô  s   € ð0 ×(Ò(¨¸ÑFÔFÐFr   c                 ó–   — ddl m}  ddl m} t          t	          | j        | j        z   t          |j        ¦  «        z   ¦  «        ¦  «        S )aÃ  
        List all available search field names:

        >>> for field in metadata.bundles.MetadataBundle.listSearchFields():
        ...     field
        ...
        'abstract'
        'accessRights'
        'accompanyingMaterialWriter'
        ...
        'composer'
        'composerAlias'
        'composerCorporate'
        'conceptor'
        'conductor'
        ...
        'dateCreated'
        'dateFirstPublished'
        'dateIssued'
        'dateModified'
        'dateSubmitted'
        'dateValid'
        ...
        'tempoFirst'
        'tempos'
        'textLanguage'
        'textOriginalLanguage'
        'timeSignatureFirst'
        'timeSignatures'
        'title'
        ...
        r   )Ú
properties)ÚRichMetadata)	Úmusic21.metadataró   rô   Útupler�   ÚALL_UNIQUE_NAMESÚALL_MUSIC21_WORK_IDSrg   Ú additionalRichMetadataAttributes)ró   rô   s     r   ÚlistSearchFieldszMetadataBundle.listSearchFields  sl   € ðD 	0Ð/Ð/Ð/Ð/Ð/Ø1Ð1Ð1Ð1Ð1Ð1Ý•VØÔ'ØÔ-ñ.å�<Ô@ÑAÔAñBñ
ô 
ñ ô ð 	r   c           	     ó0  — t          j        ¦   «         }|                     ¦   «          |€| j        }|€| j        €t          j        d¦  «        ‚t          |t          j	        ¦  «        st          j	        |¦  «        }| 
                    ¦   «         s-t                               d| j        ›d| j        ›d�¦  «         | S t          |¦  «        }|j        | _        t                               d| j         |¦   «         dt          | j        ¦  «        g¦  «         | S )a  
        Load cached metadata from the file path suggested by the name of this
        MetadataBundle ('core', 'local', or a name).

        If a specific filepath is given with the `filePath` keyword, attempt to
        load cached metadata from the file at that location.

        If `filePath` is None, and `self.filePath` is also None, do nothing.

        >>> #_DOCS_SHOW coreBundle = metadata.bundles.MetadataBundle('core').read()

        If a metadata is unnamed, and no file path is specified, an exception
        will be thrown:

        >>> anonymousBundle = metadata.bundles.MetadataBundle().read()
        Traceback (most recent call last):
        music21.exceptions21.MetadataException: Unnamed MetadataBundles have
            no default file path to read from.

        Nz?Unnamed MetadataBundles have no default file path to read from.zno metadata found for: z/; try building cache with corpus.cacheMetadata(ú)zMetadataBundle: loading time:z	md items:)r   ÚTimerÚstartr¥   rU   r   ÚMetadataExceptionrP   rE   rF   r°   r´   r¶   r	   rO   rp   )r&   r¥   ÚtimerÚnewMdbs       r   ÚreadzMetadataBundle.read8  s1  € õ* ”‘”ˆØ�Š‰ŒˆØÐØ”}ˆHØÐ ¤	Ð 1ÝÔ0ðñô ð õ ˜(¥G¤LÑ1Ô1ð 	.Ý”| HÑ-Ô-ˆHà�ŠÑ Ô ð 	Ý×#Ò#ðO¨$¬)ð Oð OØ@DÄ	ðOð Oð Oñô ð ð ˆKå Ñ)Ô)ˆØ &Ô 7ˆÔå×ÒØ+ØŒIØˆE‰GŒGØÝ�Ô%Ñ&Ô&ð!
ñ 	ô 	ð 	ð ˆr   r   )ÚfileExtensionsr=   ú
str | Noner  úIterable[str]c               óL  — ddl m} t          |                     |¦  «        ¦  «        }t	          ¦   «         }|€*|€(|st          d¦  «        ‚|                     ¦   «         \  }}| j                             ¦   «         D ]P\  }}	|	j	        €Œ|	j
        }
|r
|
j        |vrŒ ||j        v rŒ*|	                     ||¦  «        d         r
|	|j        |<   ŒQt          t          t          |j                             ¦   «         ¦  «        d„ ¬¦  «        ¦  «        |_        |r |j        di |¤ŽS |S )a·  
        Perform search, on all stored metadata, permit regular expression
        matching.

        >>> workList = corpus.corpora.CoreCorpus().getWorkList('ciconia')
        >>> metadataBundle = metadata.bundles.MetadataBundle()
        >>> failedPaths = metadataBundle.addFromPaths(
        ...     workList,
        ...     parseUsingCorpus=False,
        ...     useMultiprocessing=False,
        ...     storeOnDisk=False, #_DOCS_HIDE
        ...     )
        >>> failedPaths
        []

        >>> searchResult = metadataBundle.search(
        ...     'cicon',
        ...     field='composer'
        ...     )
        >>> searchResult
        <music21.metadata.bundles.MetadataBundle {1 entry}>
        >>> len(searchResult)
        1
        >>> searchResult[0]
        <music21.metadata.bundles.MetadataEntry 'ciconia_quod_jactatur_xml'>
        >>> searchResult = metadataBundle.search(
        ...     'cicon',
        ...     field='composer',
        ...     fileExtensions=('.krn',),
        ...     )
        >>> len(searchResult)  # no files in this format
        0

        >>> searchResult = metadataBundle.search(
        ...     'cicon',
        ...     field='composer',
        ...     fileExtensions=('.xml',),
        ...     )
        >>> len(searchResult)
        1

        Searches can also use keyword args:

        >>> metadataBundle.search(composer='cicon')
        <music21.metadata.bundles.MetadataBundle {1 entry}>
        r   )rR   NzQuery cannot be emptyc                ó   — | d         j         S r‚   rƒ   r„   s    r   r†   z'MetadataBundle.search.<locals>.<lambda>½  s   €  3 q¤6Ô#4€ r   r‡   r   )Úmusic21.corpus.corporarR   r‰   ÚtranslateExtensionsr   r   ÚpopitemrO   rŒ   r)   r   Úsuffixr<   r   r�   rg   )r&   r=   r>   r  r?   rR   Úacceptable_extensionsÚnewMetadataBundlerˆ   r’   Úsps              r   r<   zMetadataBundle.searchk  sv  € ðp 	2Ð1Ð1Ð1Ð1Ð1Ý*-¨f×.HÒ.HÈÑ.XÔ.XÑ*YÔ*YÐå*Ñ,Ô,ÐØˆ=˜U˜]Øð GÝ-Ð.EÑFÔFÐFØ#×+Ò+Ñ-Ô-‰LˆE�5à"&Ô"7×"=Ò"=Ñ"?Ô"?ð 	Hð 	HÑˆC�àÔ%Ð-ØØÔ)ˆBØ$ð ¨¬Ð:OÐ)OÐ)OØØÐ'Ô8Ð8Ð8Øà×#Ò# E¨5Ñ1Ô1°!Ô4ð HØ:GÐ!Ô2°3Ñ7øõ .9Ý•4Ð)Ô:×@Ò@ÑBÔBÑCÔCØ4Ð4ð6ñ 6ô 6ñ.7ô .7ÐÔ*ð ð 	8Ø+Ð$Ô+Ð7Ð7¨hÐ7Ð7Ð7à Ð r   c                ó.   — |                       |d¦  «        S )ay  
        Compute the set-wise symmetric difference of two metadata bundles:

        >>> #_DOCS_SHOW coreBundle = corpus.corpora.CoreCorpus().metadataBundle
        >>> coreBundle = metadata.bundles.demo_bundle('core')  #_DOCS_HIDE
        >>> #_DOCS_SHOW bachBundle = coreBundle.search('bach', 'composer')
        >>> bachBundle = metadata.bundles.demo_bundle('bach')  #_DOCS_HIDE
        >>> bachBundle
        <music21.metadata.bundles.MetadataBundle {363 entries}>
        >>> #_DOCS_SHOW tripleMeterBundle = coreBundle.search('3/4')
        >>> tripleMeterBundle = metadata.bundles.demo_bundle('3/4')  #_DOCS_HIDE
        >>> tripleMeterBundle
        <music21.metadata.bundles.MetadataBundle {1875 entries}>
        >>> bachBundle.symmetric_difference(tripleMeterBundle)
        <music21.metadata.bundles.MetadataBundle {2158 entries}>

        Returns a new MetadataBundle.
        Úsymmetric_differencerZ   r\   s     r   r  z#MetadataBundle.symmetric_differenceÄ  s"   € ð& ×(Ò(ØØ"ñ
ô 
ð 	
r   c                ó.   — |                       |d¦  «        S )aA  
        Compute the set-wise union of two metadata bundles:

        >>> #_DOCS_SHOW coreBundle = corpus.corpora.CoreCorpus().metadataBundle
        >>> coreBundle = metadata.bundles.demo_bundle('core')  #_DOCS_HIDE
        >>> #_DOCS_SHOW bachBundle = coreBundle.search('bach', 'composer')
        >>> bachBundle = metadata.bundles.demo_bundle('bach')  #_DOCS_HIDE
        >>> bachBundle
        <music21.metadata.bundles.MetadataBundle {363 entries}>
        >>> beethovenBundle = coreBundle.search(
        ...     'beethoven',
        ...     field='composer',
        ...     )
        >>> beethovenBundle
        <music21.metadata.bundles.MetadataBundle {23 entries}>

        >>> bachBundle.union(beethovenBundle)
        <music21.metadata.bundles.MetadataBundle {386 entries}>

        Returns a new MetadataBundle.
        ÚunionrZ   r\   s     r   r  zMetadataBundle.unionÜ  s"   € ð, ×(Ò(ØØñ
ô 
ð 	
r   c                ó*  — t          j        ¦   «         }|                     ¦   «          t                               dg¦  «         g }t          ¦   «         }| j                             ¦   «         D ]ì\  }}|j        }||v rŒt          |t          ¦  «        r0|                     d¦  «        r|                     |j        ¦  «         ŒVt          |t          ¦  «        rt          j        |¦  «        }|                     ¦   «         st          j        ¦   «         |z  }|                     ¦   «         s|                     |¦  «         |                     |j        ¦  «         Œí|D ]
}| j        |= Œd|› d�}t                               |¦  «         t'          |¦  «        S )zþ
        Validate each metadata entry in a metadata bundle.

        If the entry represents a non-virtual corpus asset, test that its
        source path is locatable on disk.  If not, remove the metadata entry
        from the metadata bundle.
        zMetadataBundle: validating...zhttp:z'MetadataBundle: finished validating in z	 seconds.)r   rý   rþ   r´   r¶   r‰   rO   rŒ   r   rP   r   r·   ÚaddrE   rF   Úis_absoluteÚgetCorpusFilePathr°   rº   rp   )r&   r   ÚinvalidatedKeysÚvalidatedPathsrˆ   r’   r   rÊ   s           r   rÁ   zMetadataBundle.validate÷  s˜  € õ ”‘”ˆØ�Š‰ŒˆÝ×ÒÐ!@Ð AÑBÔBÐBØˆÝ™œˆØ"&Ô"7×"=Ò"=Ñ"?Ô"?ð 	9ð 	9ÑˆC�ð 'Ô1ˆJØ˜^Ð+Ð+Øå˜*¥cÑ*Ô*ð 6¨z×/DÒ/DÀWÑ/MÔ/Mð 6Ø×"Ò" =Ô#;Ñ<Ô<Ð<ØÝ˜J­Ñ,Ô,ð 6Ý$œ\¨*Ñ5Ô5�
à×)Ò)Ñ+Ô+ð EÝ#Ô5Ñ7Ô7¸*ÑD�
à×$Ò$Ñ&Ô&ð ,Ø×&Ò& sÑ+Ô+Ð+à×Ò˜}Ô7Ñ8Ô8Ð8Ð8Ø"ð 	+ð 	+ˆCØÔ% cÐ*Ð*ØL¸EÐLÐLÐLˆÝ×Ò Ñ(Ô(Ð(Ý�?Ñ#Ô#Ð#r   c                óF  — |p| j         }| j         ��| j         }t                               d|g¦  «         | j        }d| _        t	          j        | d¬¦  «        }t          j        |d¦  «        5 }|                     |¦  «         ddd¦  «         n# 1 swxY w Y   || _        | S )aÇ  
        Write the metadata bundle to disk as a pickle file.

        If `filePath` is None, use `self.filePath`.

        Returns the metadata bundle.

        >>> #_DOCS_SHOW bachBundle = coreBundle.search('bach', 'composer')
        >>> bachBundle = metadata.bundles.demo_bundle('bach')  #_DOCS_HIDE
        >>> bachBundle
        <music21.metadata.bundles.MetadataBundle {363 entries}>
        >>> bachBundle.filePath is None
        True

        >>> import os
        >>> e = environment.Environment()
        >>> tempFilePath = e.getTempFile()
        >>> bachBundle.write(filePath=tempFilePath)
        <music21.metadata.bundles.MetadataBundle {363 entries}>
        >>> os.remove(tempFilePath)
        NzMetadataBundle: writing:é   )ÚprotocolÚwb)	r¥   r´   r¶   rT   ÚpickleÚdumpsÚgzipÚopenrÀ   )r&   r¥   ÚstoredCorpusClientÚuncompressedÚoutFps        r   rÀ   zMetadataBundle.write  sâ   € ð, Ð,˜tœ}ˆØŒ=Ð$Ø”}ˆHå×#Ò#Ð%?ÀÐ$JÑKÔKÐKØ!%¤ÐØˆDŒLõ "œ<¨°qÐ9Ñ9Ô9ˆLõ ”˜8 TÑ*Ô*ð *¨eØ—’˜LÑ)Ô)Ð)ð*ð *ð *ñ *ô *ð *ð *ð *ð *ð *ð *øøøð *ð *ð *ð *à-ˆDŒLàˆs   Á-BÂBÂBr!   )rL   rM   )rW   r   )rW   r   r~   r   )rŸ   r    )FTTF)r¥   r   r   r   )rŸ   rä   rH   )r=   r  r  r  ))r   r   r   rI   r'   rY   r`   rb   rj   rl   rn   rq   rs   ru   r/   r{   r}   r[   rd   rJ   r4   Úsetterr¥   rU   rÓ   rÕ   ÚstaticmethodrA   rç   ré   rë   rí   rï   rñ   rú   r  r<   r  r  rÁ   rÀ   r   r   r   r   r   ·   s"  € € € € € ðcð cðNð ð ð ð ð&
ð 
ð 
ð 
ð0ð ð ð6 Cð  Cð  Cð  CðD7ð 7ð 7ð Cð  Cð  Cð  CðD Cð  Cð  Cð  CðD*ð *ð *ðCð Cð Cð CðB
ð 
ð 
ð0ð ð ð
ð 
ð 
ð6
ð 
ð 
ð6ð ð ð ð*7ð 7ð 7ð ð+ð +ñ „Xð+ð. „]ð5ð 5ñ „]ð5ð ð"ð "ð "ñ „Xð"ðH ðð ñ „Xðð8 ØØØðh!ð h!ð h!ð h!ðT&ð &ð &ð, ð/ð /ð /ð /ñ „\ð/ðb
'ð 
'ð 
'ð 
'ð
ð 
ð 
ð4
ð 
ð 
ð4Gð Gð Gð@Eð Eð Eð4Gð Gð Gð4 ð'ð 'ñ „\ð'ðR1ð 1ð 1ð 1ðj ØðW!ð
 )+ðW!ð W!ð W!ð W!ð W!ð W!ðr
ð 
ð 
ð0
ð 
ð 
ð6%$ð %$ð %$ðN/ð /ð /ð /ð /ð /r   r   zdict[str, MetadataBundle]Ú_test_bundlesÚwhichr   c                óð  — | t           v rt           |          S | dk    r*ddlm}  |¦   «         j        t           d<   t           d         S | dk    r/t	          d¦  «                             dd¦  «        }|t           d<   |S | dk    r0t	          d¦  «                             dd¬¦  «        }|t           d<   |S | dk    r.t	          d¦  «                             d¦  «        }|t           d<   |S t          d	| ›�¦  «        ‚)
z5
    This helps with testing by reusing bundles.
    r¨   r   ©Ú
CoreCorpusÚbachÚcomposerÚcorelli©r>   z3/4zno demo bundle called )r&  r  r*  rW   Údemo_bundler<   rÝ   )r'  r*  Ú
bachBundleÚcorelliBundleÚtripleMeterBundles        r   r/  r/  Z  s  € ð •ÐÐÝ˜UÔ#Ð#Ø�‚€Ø5Ð5Ð5Ð5Ð5Ð5Ø * 
¡¤Ô ;��fÑÝ˜VÔ$Ð$Ø�‚€Ý  Ñ(Ô(×/Ò/°¸
ÑCÔCˆ
Ø *��fÑØÐØ�	ÒÐÝ# FÑ+Ô+×2Ò2°9ÀJÐ2ÑOÔOˆØ#0��iÑ ØÐØ�‚~€~Ý'¨Ñ/Ô/×6Ò6°uÑ=Ô=ÐØ0��eÑØ Ð Ý
Ð7¨eÐ7Ð7Ñ
8Ô
8Ð8r   c                  ó   — e Zd Zd„ Zd„ ZdS )ÚTestc                ó°   — ddl m}  |¦   «         }|j        }|                     d¦  «        d         }|                      t          |¦  «        d¦  «         d S )Nr   r)  zbwv66.6z;<music21.metadata.bundles.MetadataEntry 'bach_bwv66_6_mxl'>)r  r*  rW   r<   ÚassertEqualr-   )r&   r*  ÚccÚ
coreBundler’   s        r   ÚtestOneFromCorpuszTest.testOneFromCorpusx  ss   € Ø5Ð5Ð5Ð5Ð5Ð5ØˆZ‰\Œ\ˆØÔ&ˆ
Ø"×)Ò)¨)Ñ4Ô4°QÔ7ˆØ×Ò�˜mÑ,Ô,ØVñ	Xô 	Xð 	Xð 	Xð 	Xr   c                óz  — ddl m}  |¦   «         }|                     d¦  «        }t          ¦   «         }|                     |ddd¬¦  «        }|                      |¦  «         |                     dd¬¦  «        }|                      t          |¦  «        d	¦  «         |                      t          |d         ¦  «        d
¦  «         |                     ddd¬¦  «        }|                      t          |¦  «        d¦  «         |                     ddd¬¦  «        }|                      t          |¦  «        d	¦  «         d S )Nr   r)  ÚciconiaF)r«   rÃ   rÄ   Úciconr,  r.  rw   zD<music21.metadata.bundles.MetadataEntry 'ciconia_quod_jactatur_xml'>)z.krn)r>   r  )z.xml)
r  r*  ÚgetWorkListr   rÓ   ÚassertFalser<   r6  rp   r-   )r&   r*  r7  ÚworkListÚmdbÚfailedPathsÚsearchResults          r   ÚtestFileExtensionszTest.testFileExtensions€  si  € Ø5Ð5Ð5Ð5Ð5Ð5ØˆZ‰\Œ\ˆØ—>’> )Ñ,Ô,ˆÝÑÔˆØ×&Ò&ØØ"Ø$Øð	 'ñ 
ô 
ˆð 	×Ò˜Ñ%Ô%Ð%Ø—z’zØØð "ñ 
ô 
ˆð 	×Ò�˜\Ñ*Ô*¨AÑ.Ô.Ð.Ø×Ò�˜l¨1œoÑ.Ô.Ø_ñ	aô 	að 	aà—z’zØØØ$ð "ñ 
ô 
ˆð
 	×Ò�˜\Ñ*Ô*¨AÑ.Ô.Ð.Ø—z’zØØØ$ð "ñ 
ô 
ˆð
 	×Ò�˜\Ñ*Ô*¨AÑ.Ô.Ð.Ð.Ð.r   N)r   r   r   r9  rC  r   r   r   r4  r4  v  s5   € € € € € ðXð Xð Xð/ð /ð /ð /ð /r   r4  Ú__main__)r'  r   )(Ú
__future__r   Ú__all__Úcollectionsr   r  rá   rE   r  r³   ÚtypingÚtÚunittestr5   r   Úmusic21.common.fileToolsr	   r
   r   r   ÚTYPE_CHECKINGÚcollections.abcr   rõ   r   ÚEnvironmentr´   ÚMusic21Exceptionr   ÚProtoM21Objectr   r   r&  Ú__annotations__r/  ÚTestCaser4  Ú
_DOC_ORDERr   ÚmainTestr   r   r   ú<module>rU     sV  ðð #Ð "Ð "Ð "Ð "Ð "Ð "ðð ð €ð $Ð #Ð #Ð #Ð #Ð #Ø €€€Ø 	€	€	€	Ø €€€Ø €€€Ø €€€Ø Ð Ð Ð Ø €€€à Ð Ð Ð Ð Ð Ø 3Ð 3Ð 3Ð 3Ð 3Ð 3Ø Ð Ð Ð Ð Ð Ø  Ð  Ð  Ð  Ð  Ð  Ø Ð Ð Ð Ð Ð ð „?ð *Ø(Ð(Ð(Ð(Ð(Ð(Ø)Ð)Ð)Ð)Ð)Ð)ð 'ˆ{Ô&Ð'9Ñ:Ô:€ð	ð 	ð 	ð 	ð 	˜lÔ;ñ 	ô 	ð 	ð} ð } ð } ð } ð } �GÔ*ñ } ô } ð } ðFVð Vð Vð Vð V�WÔ+ñ Vô Vð VðB% ,.€Ð -Ð -Ð -Ñ -ð9ð 9ð 9ð 9ð8(/ð (/ð (/ð (/ð (/ˆ8Ôñ (/ô (/ð (/ð\ Øð€
ð ˆzÒÐØ€N€N€NØ€GÔ�TÑÔÐÐÐð Ðr   