§
    ƒØjÎ(  ã                  ó&  — d Z ddlmZ ddlZddlm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 ej        rddl
mZ  ej        d	¦  «        Zd
„ Z G d„ de¦  «        Z G d„ de	j        ¦  «        ZegZedk    rddl
Z
 e
j        e¦  «         dS dS )zn
This module defines objects for tracking the derivation of one
:class:`~music21.stream.Stream` from another.
é    )ÚannotationsN)Ú	Generator)Úcommon)ÚSlottedObjectMixin)Úenvironment)ÚbaseÚ
derivationc                óF   ‡ — t          j        ‰ ¦  «        ˆ fd„¦   «         }|S )až  
    This decorator can be used for creating a function that returns a new
    derivation.  But is currently unused, since it does not take into account `inPlace=True`.
    `Stream.cloneEmpty(derivationMethod='derivationMethod')` is preferred for
    Streams.

    >>> from copy import deepcopy
    >>> @derivation.derivationMethod
    ... def allGreen(n):
    ...     n2 = deepcopy(n)
    ...     n2.style.color = 'green'
    ...     return n2

    >>> n = note.Note('C#')
    >>> n2 = allGreen(n)
    >>> n2.style.color
    'green'

    >>> n2.name = 'D-'
    >>> n2.derivation
    <Derivation of <music21.note.Note D-> from <music21.note.Note C#> via 'allGreen'>
    c                óZ   •—  ‰| g|¢R i |¤Ž}| |j         _        ‰j        |j         _        |S ©N)r	   ÚoriginÚ__name__Úmethod)ÚselfÚ	argumentsÚkeywordsÚresultÚfunctions       €ú‡/Users/tedpeters/Documents/Projects/Claude Projects/Misc Tools/notename-sheets/.venv/lib/python3.11/site-packages/music21/derivation.pyÚwrapperz!derivationMethod.<locals>.wrapper;   s@   ø€ à�˜$Ð7 Ð7Ð7Ð7¨hÐ7Ð7ˆØ#'ˆÔÔ Ø#+Ô#4ˆÔÔ Øˆó    )Ú	functoolsÚwraps)r   r   s   ` r   ÚderivationMethodr   $   s:   ø€ õ. „_�XÑÔðð ð ð ñ Ôðð
 €Nr   c                  ó   — e Zd ZdZdZddd„Zdd„Zd„ Zd	„ Zd
„ Z	e
dd„¦   «         Zej        dd„¦   «         Zdd„Ze
dd„¦   «         Zej        dd„¦   «         Ze
dd„¦   «         Zej        d d„¦   «         Ze
d!d„¦   «         Ze
dd„¦   «         ZdS )"Ú
Derivationa‚  
    A Derivation object keeps track of which Streams (or perhaps other Music21Objects)
    a Stream or other music21 object has come from and how.

    Derivation is automatically updated by many methods:

    >>> import copy
    >>> sOrig = stream.Stream(id='orig')
    >>> sNew = copy.deepcopy(sOrig)
    >>> sNew.id = 'copy'
    >>> sNew.derivation
    <Derivation of <music21.stream.Stream copy>
        from <music21.stream.Stream orig> via '__deepcopy__'>

    >>> sNew.derivation.client
    <music21.stream.Stream copy>
    >>> sNew.derivation.client is sNew
    True
    >>> sNew.derivation.origin
    <music21.stream.Stream orig>
    >>> sNew.derivation.method
    '__deepcopy__'

    >>> s1 = stream.Stream()
    >>> s1.id = 'DerivedStream'
    >>> d1 = derivation.Derivation(s1)

    >>> s2 = stream.Stream()
    >>> s2.id = 'OriginalStream'

    >>> d1.method = 'manual'
    >>> d1.origin = s2
    >>> d1
    <Derivation of <music21.stream.Stream DerivedStream> from
        <music21.stream.Stream OriginalStream> via 'manual'>
    >>> d1.origin is s2
    True

    >>> d1.client is s1
    True

    >>> import copy
    >>> d2 = copy.deepcopy(d1)
    >>> d2.origin is s2
    True

    >>> d1.method = 'measure'
    >>> d1.method
    'measure'

    Deleting the origin stream does not change the Derivation, since origin is held by strong ref:

    >>> import gc  # Garbage collection
    >>> del s2
    >>> unused = gc.collect()  # ensure Garbage collection is run
    >>> d1
    <Derivation of <music21.stream.Stream DerivedStream>
        from <music21.stream.Stream OriginalStream> via 'measure'>

    But deleting the client stream changes the Derivation, since client is held by weak ref,
    and will also delete the origin (so long as client was ever set)

    >>> del s1
    >>> unused = gc.collect()  # ensure Garbage collection is run
    >>> d1
    <Derivation of None from None via 'measure'>
    )Ú_clientÚ	_clientIdÚ_methodÚ_originÚ	_originIdNÚclientúbase.Music21Object | Nonec                óZ   — d | _         d | _        d | _        d | _        d | _        || _        d S r   )r   r   r   r    r!   r"   ©r   r"   s     r   Ú__init__zDerivation.__init__•   s2   € à37ˆŒØ#'ˆŒØ!%ˆŒà04ˆŒØ#'ˆŒð ˆŒˆˆr   c                ód   —  t          | ¦  «        ¦   «         }| j        |_        | j        |_        |S )z—
        Manage deepcopying by creating a new reference to the same object. If
        the origin no longer exists, than origin is set to None
        )Útyper"   r   )r   ÚmemoÚnews      r   Ú__deepcopy__zDerivation.__deepcopy__£   s,   € ð
 �d�4‰jŒj‰lŒlˆØ”[ˆŒ
Ø”[ˆŒ
Øˆ
r   c                óp   — | j         j        }| j        r
d| j        ›�nd}d|› d| j        › d| j        › |› d�S )z2
        representation of the Derivation
        z via Ú ú<z of z from ú>)Ú	__class__r   r   r"   r   )r   ÚklassÚvias      r   Ú__repr__zDerivation.__repr__­   sT   € ð ”Ô'ˆØ)-¬Ð<Ð%�d”kÐ%Ð%Ð%¸"ˆØD�5ÐDÐD˜dœkÐDÐD°´ÐD¸cÐDÐDÐDÐDr   c                óf   — t          j        | j        ¦  «        | _        t          j        | ¦  «        S r   )r   ÚunwrapWeakrefr   r   Ú__getstate__©r   s    r   r6   zDerivation.__getstate__µ   s'   € åÔ+¨D¬LÑ9Ô9ˆŒÝ!Ô.¨tÑ4Ô4Ð4r   c                ól   — t          j        | |¦  «         t          j        | j        ¦  «        | _        d S r   )r   Ú__setstate__r   ÚwrapWeakrefr   )r   Ústates     r   r9   zDerivation.__setstate__º   s-   € ÝÔ'¨¨eÑ4Ô4Ð4ÝÔ)¨$¬,Ñ7Ô7ˆŒˆˆr   Úreturnc                ó‚   — t          j        | j        ¦  «        }|€#| j        �d | _        d | _        d | _        d | _        |S r   )r   r5   r   r   r    r!   )r   Úcs     r   r"   zDerivation.clientÂ   sA   € åÔ  ¤Ñ.Ô.ˆØˆ9˜œÐ3Ø!ˆDŒNØˆDŒLØˆDŒLØ!ˆDŒNØˆr   c                ó„   — |€d | _         d | _        d S t          |¦  «        | _         t          j        |¦  «        | _        d S r   )r   r   Úidr   r:   r%   s     r   r"   zDerivation.clientÌ   s>   € ð ˆ>Ø!ˆDŒNØˆDŒLˆLˆLå ™ZœZˆDŒNÝ!Ô-¨fÑ5Ô5ˆDŒLˆLˆLr   ú)Generator[base.Music21Object, None, None]c              #  óD   K  — | j         }|�|V — |j        j         }|­dS dS )aR  
        Iterator/Generator

        Yields the Streams which this Derivation's client Stream was derived
        from. This provides a way to obtain all Streams that the client passed
        through, such as those created by
        :meth:`~music21.stream.Stream.getElementsByClass` or
        :meth:`~music21.stream.Stream.flatten`.

        >>> s1 = stream.Stream()
        >>> s1.id = 's1'
        >>> s1.repeatAppend(note.Note(), 10)
        >>> s1.repeatAppend(note.Rest(), 10)
        >>> s2 = s1.notesAndRests.stream()
        >>> s2.id = 's2'
        >>> s3 = s2.getElementsByClass(note.Note).stream()
        >>> s3.id = 's3'
        >>> for y in s3.derivation.chain():
        ...     print(y)
        <music21.stream.Stream s2>
        <music21.stream.Stream s1>

        >>> list(s3.derivation.chain()) == [s2, s1]
        True
        N)r   r	   )r   Úorigs     r   ÚchainzDerivation.chainÖ   s<   è è € ð4 +/¬+ˆØÐØˆJˆJˆJØ”?Ô)ˆDð ÐÐÐÐÐr   ú
str | Nonec                ó   — | j         S )a®  
        Returns or sets the string of the method that was used to generate this
        Stream.

        >>> s = stream.Stream()
        >>> s.derivation.method is None
        True

        >>> sNotes = s.notes.stream()
        >>> sNotes.derivation.method
        'notes'

        Some examples are 'getElementsByClass' etc.

        >>> s = stream.Stream()
        >>> s.id = 'lonelyStream'
        >>> s.append(clef.TrebleClef())
        >>> s.append(note.Note())
        >>> sNotes = s.notes.stream()
        >>> sNotes.derivation
        <Derivation of <music21.stream.Stream lonelyStream>
            from <music21.stream.Stream lonelyStream> via 'notes'>

        >>> derived = sNotes.derivation
        >>> derived.method
        'notes'

        >>> derived.method = 'blah'
        >>> derived.method
        'blah'

        >>> derived is sNotes.derivation
        True
        >>> sNotes.derivation.method
        'blah'
        ©r   r7   s    r   r   zDerivation.methodõ   s   € ðL Œ|Ðr   r   c                ó   — || _         d S r   rG   )r   r   s     r   r   zDerivation.method  s   € àˆŒˆˆr   c                ó   — | j         S r   )r    r7   s    r   r   zDerivation.origin!  s
   € àŒ|Ðr   r   c                ó`   — |€d | _         d | _        d S t          |¦  «        | _         || _        d S r   )r!   r    r@   )r   r   s     r   r   zDerivation.origin%  s3   € ð ˆ>Ø!ˆDŒNØˆDŒLˆLˆLå ™ZœZˆDŒNØ!ˆDŒLˆLˆLr   ú
int | Nonec                ó   — | j         S )z˜
        Return the Python id (=memory location) of the origin.
        (Same as id(derivation.origin).  Not the same as derivation.origin.ind)
        )r!   r7   s    r   ÚoriginIdzDerivation.originId0  s   € ð Œ~Ðr   c                ó\   — t          |                      ¦   «         ¦  «        }|r|d         S dS )aó  
        Return a reference to the oldest source of this Stream; that is, chain
        calls to :attr:`~music21.stream.Stream.derivesFrom` until we get to a
        Stream that cannot be further derived.

        >>> s1 = stream.Stream()
        >>> s1.repeatAppend(note.Note(), 10)
        >>> s1.repeatAppend(note.Rest(), 10)
        >>> s2 = s1.notesAndRests.stream()
        >>> s3 = s2.getElementsByClass(note.Note).stream()
        >>> s3.derivation.rootDerivation is s1
        True
        éÿÿÿÿN)ÚlistrD   )r   ÚderivationChains     r   ÚrootDerivationzDerivation.rootDerivation8  s1   € õ ˜tŸzšz™|œ|Ñ,Ô,ˆØð 	Ø" 2Ô&Ð&à�4r   r   )r"   r#   )r<   r#   )r<   rA   )r<   rE   )r   rE   )r   r#   )r<   rK   )r   Ú
__module__Ú__qualname__Ú__doc__Ú	__slots__r&   r+   r3   r6   r9   Úpropertyr"   ÚsetterrD   r   r   rM   rR   © r   r   r   r   D   s   € € € € € ðBð BðL€Ið
ð 
ð 
ð 
ð 
ðð ð ð ðEð Eð Eð5ð 5ð 5ð
8ð 8ð 8ð ðð ð ñ „Xðð „]ð6ð 6ð 6ñ „]ð6ð*ð *ð *ð *ð> ð%ð %ð %ñ „Xð%ðN „]ðð ð ñ „]ðð ðð ð ñ „Xðð „]ð"ð "ð "ñ „]ð"ð ðð ð ñ „Xðð ðð ð ñ „Xðð ð r   r   c                  ó   — e Zd ZdS )ÚTestN)r   rS   rT   rY   r   r   r[   r[   P  s   € € € € € Ø€Dr   r[   Ú__main__)rU   Ú
__future__r   ÚweakrefÚcollections.abcr   r   ÚtypingÚtÚunittestÚmusic21r   Úmusic21.common.objectsr   r   ÚTYPE_CHECKINGr   ÚEnvironmentÚenvironLocalr   r   ÚTestCaser[   Ú
_DOC_ORDERr   ÚmainTestrY   r   r   ú<module>rk      sv  ððð ð #Ð "Ð "Ð "Ð "Ð "à €€€Ø %Ð %Ð %Ð %Ð %Ð %Ø Ð Ð Ð Ø Ð Ð Ð Ø €€€à Ð Ð Ð Ð Ð Ø 5Ð 5Ð 5Ð 5Ð 5Ð 5Ø Ð Ð Ð Ð Ð ð „?ð ØÐÐÐÐÐð 'ˆ{Ô& |Ñ4Ô4€ðð ð ð@Gð Gð Gð Gð GÐ#ñ Gô Gð GðX	ð 	ð 	ð 	ð 	ˆ8Ôñ 	ô 	ð 	ð ˆ\€
àˆzÒÐà€N€N€NØ€GÔ�TÑÔÐÐÐð Ðr   