§
    ƒØj`'  ã                  ó    — d Z ddlmZ ddlZddlZ G d„ d¦  «        Z[ G d„ dej        ¦  «        Ze	dk    rddl
Z
 e
j        e¦  «         dS dS )	zÜ
Classes for pseudo-m21 objects to inherit from.  The most import attributes that nearly
everything in music21 -- not just things that live in streams --
should inherit from are given below.

Concept borrowed from m21j.
é    )ÚannotationsNc                  ó”   — e Zd ZU dZddgZi Zded<   i Zded<   i Zded	<   d
Z	ded<   e
dd„¦   «         Ze
dd„¦   «         Zdd„Zdd„ZdS )ÚProtoM21Objectam  
    A class for pseudo-m21 objects to inherit from.  Any object can inherit from
    ProtoM21Object, and it makes sense for anything a user is likely to encounter
    to inherit from it.  Certain translators, etc. can choose to skip it.

    >>> class PitchCounter(prebase.ProtoM21Object):
    ...     def _reprInternal(self):
    ...         return 'no pitches'

    >>> pc = PitchCounter()
    >>> pc.classes
    ('PitchCounter', 'ProtoM21Object', 'object')
    >>> PitchCounter in pc.classSet
    True
    >>> 'Note' in pc.classSet
    False

    For a True/False intersection check against an iterable, use `classSet.isdisjoint`:

    >>> classList = ('music21.note.Note', 'music21.note.Rest')
    >>> pc.classSet.isdisjoint(classList)
    True
    >>> repr(pc)
    '<...PitchCounter no pitches>'

    ProtoM21Objects, like other Python primitives, cannot be put into streams --
    this is what base.Music21Object does.

    A ProtoM21Object defines several methods relating to unified representation
    and keeping track of the classes of the object.  It has no instance attributes
    or properties, and thus adds a very small creation time impact: recent
    tests show that an empty object with an empty `__init__()` method can
    be created in about 175ns while an empty object that subclasses ProtoM21Object
    with the same empty `__init__()` takes only 180ns, or a 5ns impact.  On
    real objects, the creation time percentage hit is usually much smaller.

    ProtoM21Objects have no __init__() defined, so do not call super().__init__() on
    objects that only inherit from ProtoM21Object unless you like wasting 200ns.
    ÚclassesÚclassSetzdict[str, str]Ú	_DOC_ATTRzdict[type, tuple[str, ...]]Ú_classTupleCacheDictz!dict[type, frozenset[str | type]]Ú_classSetCacheDict© útuple[str, ...]Ú	__slots__Úreturnc                óÊ   — 	 | j         | j                 S # t          $ rD t          d„ | j                             ¦   «         D ¦   «         ¦  «        }|| j         | j        <   |cY S w xY w)a[  
        Returns a tuple containing the names (strings, not objects) of classes that this
        object belongs to -- starting with the object's class name and going up the mro()
        for the object.

        Notes are Music21Objects:

        >>> n = note.Note('C#')
        >>> n.classes
        ('Note', 'NotRest', 'GeneralNote', 'Music21Object', 'ProtoM21Object', 'object')

        Durations are not, but they inherit from ProtoM21Object

        >>> d = duration.Duration('half')
        >>> d.classes
        ('Duration', 'ProtoM21Object', 'SlottedObjectMixin', 'object')

        Having quick access to these things as strings makes it easier to do comparisons:

        Example: find GClefs that are not Treble clefs (or treble 8vb, etc.):

        >>> s = stream.Stream()
        >>> s.insert(10, clef.GClef())
        >>> s.insert(20, clef.TrebleClef())
        >>> s.insert(30, clef.FrenchViolinClef())
        >>> s.insert(40, clef.Treble8vbClef())
        >>> s.insert(50, clef.BassClef())
        >>> s2 = stream.Stream()
        >>> for thing in s:
        ...    if isinstance(thing, clef.GClef) and not isinstance(thing, clef.TrebleClef):
        ...        s2.insert(thing)
        >>> s2.show('text')
        {10.0} <music21.clef.GClef>
        {30.0} <music21.clef.FrenchViolinClef>

        * Changed in v2: returns a tuple, not a list.
        c              3  ó$   K  — | ]}|j         V — Œd S )N)Ú__name__©Ú.0Úxs     ú„/Users/tedpeters/Documents/Projects/Claude Projects/Misc Tools/notename-sheets/.venv/lib/python3.11/site-packages/music21/prebase.pyú	<genexpr>z)ProtoM21Object.classes.<locals>.<genexpr>z   s$   è è € ÐHÐH¨a˜qœzÐHÐHÐHÐHÐHÐHó    )r	   Ú	__class__ÚKeyErrorÚtupleÚmro)ÚselfÚ
classTuples     r   r   zProtoM21Object.classesP   sx   € ðN	ØÔ,¨T¬^Ô<Ð<øÝð 	ð 	ð 	ÝÐHÐH°4´>×3EÒ3EÑ3GÔ3GÐHÑHÔHÑHÔHˆJØ8BˆDÔ% d¤nÑ5ØÐÐÐð	øøøs   ‚ ”AA"Á!A"úfrozenset[str | type]c                óº  — 	 | j         | j                 S # t          $ r¼ t          | j        ¦  «        }|                     | j                             ¦   «         ¦  «         d„ | j                             ¦   «         D ¦   «         }|                     |¦  «         d„ |D ¦   «         }|                     |¦  «         t          |¦  «        }|| j         | j        <   |cY S w xY w)aÒ  
        Returns a set (that is, unordered, but indexed) of all classes that
        this class belongs to, including
        string names, fullyQualified string names, and objects themselves.

        It's cached on a per-class basis, so makes for a really fast way of checking to
        see if something belongs
        to a particular class when you don't know if the user has given a string,
        a fully qualified string name, or an object.

        Did I mention it's fast?  It's not as fast as x in n.classes or isinstance(n, x)
        if you know whether it's a string or class, but this is good and safe to take
        in either a string or a class.

        >>> n = note.Note()
        >>> 'Note' in n.classSet
        True
        >>> 'music21.note.Note' in n.classSet
        True
        >>> note.Note in n.classSet
        True

        >>> 'Rest' in n.classSet
        False
        >>> note.Rest in n.classSet
        False

        For checking if an object is part of any number of objects use `not`
        with `isdisjoint`.  A little unwiedly but works super fast:

        >>> checkClasses = (spanner.Slur, note.NotRest)
        >>> not n.classSet.isdisjoint(checkClasses)
        True

        >>> object in n.classSet
        True

        >>> sorted([s for s in n.classSet if isinstance(s, str)])
        ['GeneralNote',
         'Music21Object',
         'NotRest',
         'Note',
         'ProtoM21Object',
         'base.Music21Object',
         'builtins.object',
         'music21.base.Music21Object',
         'music21.note.GeneralNote',
         'music21.note.NotRest',
         'music21.note.Note',
         'music21.prebase.ProtoM21Object',
         'note.GeneralNote',
         'note.NotRest',
         'note.Note',
         'object',
         'prebase.ProtoM21Object']

        >>> sorted([s for s in n.classSet if not isinstance(s, str)], key=lambda x: x.__name__)
        [<class 'music21.note.GeneralNote'>,
         <class 'music21.base.Music21Object'>,
         <class 'music21.note.NotRest'>,
         <class 'music21.note.Note'>,
         <class 'music21.prebase.ProtoM21Object'>,
         <class 'object'>]

        * Changed in v8: partially qualified objects such as 'note.Note' have been added.
        c                ó2   — g | ]}|j         d z   |j        z   ‘ŒS )ú.)Ú
__module__r   r   s     r   ú
<listcomp>z+ProtoM21Object.classSet.<locals>.<listcomp>Ç   s&   € Ð$cÐ$cÐ$cÈ Q¤\°CÑ%7¸!¼*Ñ%DÐ$cÐ$cÐ$cr   c                ó:   — g | ]}|                      d d¦  «        ‘ŒS )zmusic21.Ú )Úreplacer   s     r   r#   z+ProtoM21Object.classSet.<locals>.<listcomp>É   s&   € Ð(bÐ(bÐ(bÀq¨¯ª°:¸rÑ)BÔ)BÐ(bÐ(bÐ(br   )r
   r   r   Úlistr   Úextendr   Ú	frozenset)r   Ú	classListÚfullyQualifiedStringsÚpartiallyQualifiedStringsr   s        r   r   zProtoM21Object.classSet~   sê   € ðH	ØÔ*¨4¬>Ô:Ð:øÝð 		ð 		ð 		Ý(,¨T¬\Ñ(:Ô(:ˆIØ×Ò˜Tœ^×/Ò/Ñ1Ô1Ñ2Ô2Ð2Ø$cÐ$cÈdÌn×N`ÒN`ÑNbÔNbÐ$cÑ$cÔ$cÐ!Ø×ÒÐ2Ñ3Ô3Ð3Ø(bÐ(bÐLaÐ(bÑ(bÔ(bÐ%Ø×ÒÐ6Ñ7Ô7Ð7Ý  Ñ+Ô+ˆHØ6>ˆDÔ# D¤NÑ3ØˆOˆOˆOð		øøøs   ‚ ”CCÃCÚstrc                ó,  — d}| j         dk    r|| j         dz   z  }|| j        j        z  }d|v rd|vr|                     dd¦  «        }|                      ¦   «         }|r|                     d¦  «        s|d	z  }|r||                     ¦   «         z  }|d
z   S )a^  
        Defines the default representation for a ProtoM21Object
        which includes the module name, the class name, and additional
        information, such as the memory location:

        >>> p = prebase.ProtoM21Object()
        >>> repr(p)
        '<music21.prebase.ProtoM21Object object at 0x112590380>'

        The additional information is defined in the `_reprInternal` method,
        so objects inheriting from ProtoM21Object (such as Music21Object)
        should change `_reprInternal` and not `__repr__`.

        Except for music21.base itself, any object in a file called base.py
        has the base part removed.

        >>> from music21.midi.base import MidiEvent
        >>> me = MidiEvent()
        >>> repr(me)
        '<music21.midi.MidiEvent UNKNOWN, track=None>'
        >>> me._reprInternal()
        'UNKNOWN, track=None'
        ú<Ú__main__r!   z.base.zmusic21.basez.baser%   ú:ú ú>)r"   r   Ú__qualname__r&   Ú_reprInternalÚ
startswithÚstrip)r   ÚreprHeadÚstrReprs      r   Ú__repr__zProtoM21Object.__repr__Ï   s»   € ð0 ˆØŒ?˜jÒ(Ð(Ø˜œ¨#Ñ-Ñ-ˆHØ�D”NÔ/Ñ/ˆØ�xÐÐ N¸(Ð$BÐ$BØ×'Ò'¨°Ñ4Ô4ˆHØ×$Ò$Ñ&Ô&ˆØð 	˜7×-Ò-¨cÑ2Ô2ð 	Ø˜‰OˆHàð 	(Ø˜Ÿš™œÑ'ˆHØ˜#‰~Ðr   c                ó@   — dt          t          | ¦  «        ¦  «        › �S )av  
        Defines the insides of the representation.

        Overload this method for most objects.

        A default representation:

        >>> p = prebase.ProtoM21Object()
        >>> p._reprInternal()
        'object at 0x112590380'

        A more complex `_reprInternal` that handles the case of objects
        with `.id` defined is found in Music21Object.
        z
object at )ÚhexÚid)r   s    r   r5   zProtoM21Object._reprInternalõ   s   € ð ,�C¥ 4¡¤™MœMÐ+Ð+Ð+r   N)r   r   )r   r   )r   r-   )r   r"   r4   Ú__doc__Ú
_DOC_ORDERr   Ú__annotations__r	   r
   r   Úpropertyr   r   r:   r5   r   r   r   r   r      sç   € € € € € € ð&ð &ðT 	Øð€Jð !#€IÐ"Ð"Ð"Ñ"ð
 9;ÐÐ:Ð:Ð:Ñ:Ø:<ÐÐ<Ð<Ð<Ñ<à!#€IÐ#Ð#Ð#Ñ#àð+ð +ð +ñ „Xð+ðZ ðNð Nð Nñ „XðNð`$ð $ð $ð $ðL,ð ,ð ,ð ,ð ,ð ,r   r   c                  ó   — e Zd Zd„ Zd„ ZdS )ÚTestc                óB   — ddl m}  || t          ¦   «         ¦  «         d S )Nr   )ÚtestCopyAll)Úmusic21.test.commonTestrE   Úglobals)r   rE   s     r   ÚtestCopyAndDeepcopyzTest.testCopyAndDeepcopy  s0   € Ø7Ð7Ð7Ð7Ð7Ð7Øˆ�D�'™)œ)Ñ$Ô$Ð$Ð$Ð$r   c                ó~   — ddl m}  |¦   «         }d|_        t          |¦  «        }|                      |d¦  «         d S )Nr   )ÚMusic21ObjectÚhelloz%<music21.base.Music21Object id=hello>)Úmusic21.baserJ   r=   ÚreprÚassertEqual)r   rJ   ÚbÚrs       r   Útest_reprInternalzTest.test_reprInternal  sN   € Ø.Ð.Ð.Ð.Ð.Ð.ØˆM‰OŒOˆØˆŒÝ�‰GŒGˆØ×Ò˜ÐCÑDÔDÐDÐDÐDr   N)r   r"   r4   rH   rQ   r   r   r   rC   rC   
  s7   € € € € € ð%ð %ð %ðEð Eð Eð Eð Er   rC   r0   )r>   Ú
__future__r   ÚtypingÚtÚunittestr   ÚTestCaserC   r   Úmusic21ÚmainTestr   r   r   ú<module>rY      sÚ   ððð ð #Ð "Ð "Ð "Ð "Ð "à Ð Ð Ð Ø €€€ðn,ð n,ð n,ð n,ð n,ñ n,ô n,ð n,ðb ð
Eð 
Eð 
Eð 
Eð 
Eˆ8Ôñ 
Eô 
Eð 
Eð ˆzÒÐØ€N€N€NØ€GÔ�TÑÔÐÐÐð Ðr   