+
    &j,                         ^ RI Ht ^ RIHt ^ RIHtHtHtHtH	t	H
t
Ht RR/R R lltRRRR/R	 R
 lltRR R lltR R ltRR ltRR ltR# )    )defaultdict)zip_longest)AnyCallableDictListOptionalTupleUnionis_leafNc          
      j    V ^8  d   QhR\         R\        R\        R\        \         ,          R\        /# )   fntreerestr   returnr   r   r	   )formats   "a/Users/jameslopez/projects/CWCArchive/cwc-podcast/.venv/lib/python3.14/site-packages/mlx/utils.py__annotate__r      s9     3 333$'32:82D33    c          
       a aaa Se   S! V4      '       d   S ! V.SO5!  # \        V\        \        34      '       dC   \        V4      pV VV3R l\	        V4       4       p\        VR4      '       d   V! V!  # V! V4      # \        V\        4      '       d@   VP                  4        UaUu/ uF!  w  opS\        S V.V3R lS 4       O5RS/ bK#  	  upp# S ! V.SO5!  # u uppi )a  Applies ``fn`` to the leaves of the Python tree ``tree`` and
returns a new collection with the results.

If ``rest`` is provided, every item is assumed to be a superset of ``tree``
and the corresponding leaves are provided as extra positional arguments to
``fn``. In that respect, :meth:`tree_map` is closer to :func:`itertools.starmap`
than to :func:`map`.

The keyword argument ``is_leaf`` decides what constitutes a leaf from
``tree`` similar to :func:`tree_flatten`.

.. code-block:: python

    import mlx.nn as nn
    from mlx.utils import tree_map

    model = nn.Linear(10, 10)
    print(model.parameters().keys())
    # dict_keys(['weight', 'bias'])

    # square the parameters
    model.update(tree_map(lambda x: x*x, model.parameters()))

Args:
    fn (callable): The function that processes the leaves of the tree.
    tree (Any): The main Python tree that will be iterated upon.
    rest (tuple[Any]): Extra trees to be iterated together with ``tree``.
    is_leaf (callable, optional): An optional callable that returns ``True``
       if the passed object is considered a leaf or ``False`` otherwise.

Returns:
    A Python tree with the new values returned by ``fn``.
c              3   `   <a"   T F"  w  op\        SV.V3R  lS 4       O5RS/ x  K$  	  R# 5i)c              3   4   <"   T F  qS,          x  K  	  R # 5iN .0ris   & r   	<genexpr>%tree_map.<locals>.<genexpr>.<genexpr>1   s     !51A$$   r   N)tree_map)r   childr    r   r   r   s   & @r   r!   tree_map.<locals>.<genexpr>0   s3      
+5 RG!5!5GwG+s   *._fieldsc              3   4   <"   T F  qS,          x  K  	  R # 5ir   r   r   r   ks   & r   r!   r&   7   s     $84aqTT4r#   r   )	
isinstancelisttupletype	enumeratehasattrdictitemsr$   )r   r   r   r   TreeTypesubtreesr*   r%   s   f&dj  ` r   r$   r$      s    H wt}}$	D4-	(	(:
%dO
 '.dI&>&>x"VHXDVV	D$		 !JJL
(5 xEJ$84$8J'JJ(
 	

 $
s   )'Cpathc                    V ^8  d   QhR\         R\        R\        R\        \         ,          R\        \        ,          R\        /# )r   r   r   r   r   r5   r   r   )r   s   "r   r   r   >   sM     5% 5%5%
5% 5% h	5%
 3-5% 	5%r   c                 a aaaa Se   S! V4      '       d   S ! W1.SO5!  # \        V\        \        34      '       d9   V'       d   V R2MRo\        V4      pV! V VVV3R l\	        V4       4       4      # \        V\
        4      '       dU   V'       d   V R2MRoVP                  4        UaUu/ uF'  w  opS\        S V.V3R lS 4       O5RSRS S 2/ bK)  	  upp# S ! W1.SO5!  # u uppi )a  Applies ``fn`` to the path and leaves of the Python tree ``tree`` and
returns a new collection with the results.

This function is the same :func:`tree_map` but the ``fn`` takes the path as
the first argument followed by the remaining tree nodes.

Args:
    fn (callable): The function that processes the leaves of the tree.
    tree (Any): The main Python tree that will be iterated upon.
    rest (tuple[Any]): Extra trees to be iterated together with ``tree``.
    is_leaf (Optional[Callable]): An optional callable that returns ``True``
       if the passed object is considered a leaf or ``False`` otherwise.
    path (Optional[Any]): Prefix will be added to the result.

Returns:
    A Python tree with the new values returned by ``fn``.

Example:
    >>> from mlx.utils import tree_map_with_path
    >>> tree = {"model": [{"w": 0, "b": 1}, {"w": 0, "b": 1}]}
    >>> new_tree = tree_map_with_path(lambda path, _: print(path), tree)
    model.0.w
    model.0.b
    model.1.w
    model.1.b
. c           	   3   l   <a"   T F(  w  op\        SV.V3R  lS 4       O5RSRS S 2/ x  K*  	  R# 5i)c              3   4   <"   T F  qS,          x  K  	  R # 5ir   r   r   s   & r   r!   /tree_map_with_path.<locals>.<genexpr>.<genexpr>f        04aqTT4r#   r   r5   N)tree_map_with_path)r   r%   r    r   r   prefixr   s   & @r   r!   %tree_map_with_path.<locals>.<genexpr>d   sQ      
 ,5 E040:AKQ(STRU ,s   04c              3   4   <"   T F  qS,          x  K  	  R # 5ir   r   r)   s   & r   r!   r@   n   r=   r#   r   r5   )r+   r,   r-   r.   r/   r1   r2   r>   )	r   r   r   r5   r   r3   r*   r%   r?   s	   f&d$j ` @r   r>   r>   >   s   B wt}}$$t$$	D4-	(	(#D6: 
 &dO	
 
 	
 
D$		#D6
 !JJL	
 )5 !E040:AKQ(STRU  )	
 	
 $$t$$
s   /-C*c                x   V ^8  d   QhR\         R\        R\        \        ,          R\        \        \
        \        \        \         3,          ,          \        \        \         3,          3,          ,          R\        \
        \        \        \         3,          ,          \        \        \         3,          3,          /# )r   r   r?   r   destinationr   )r   strr	   r   r   r   r
   r   )r   s   "r   r   r   v   s     I I
II hI %U38_ 5tCH~ EFG	I
 4c3h $sCx.01Ir   c                .   Vf   . p\        V\        4      '       d   VP                  pM.\        V\        4      '       d   VP                  pM\        R4      hVe#   V! V 4      '       d   V! VR,          V 3.4       V# \        V \        \        34      '       d(   \        V 4       F  w  rV\        Wa RV 2W#4       K  	  V# \        V \        4      '       d-   V P                  4        F  w  rx\        W RV 2W#4       K  	  V# V! VR,          V 3.4       V# )a  Flattens a Python tree to a list of key, value tuples.

The keys are using the dot notation to define trees of arbitrary depth and
complexity.

.. code-block:: python

    from mlx.utils import tree_flatten

    print(tree_flatten([[[0]]]))
    # [("0.0.0", 0)]

    print(tree_flatten([[[0]]], prefix=".hello"))
    # [("hello.0.0.0", 0)]

    tree_flatten({"a": {"b": 1}}, destination={})
    {"a.b": 1}

.. note::
   Dictionaries should have keys that are valid Python identifiers.

Args:
    tree (Any): The Python tree to be flattened.
    prefix (str): A prefix to use for the keys. The first character is
        always discarded.
    is_leaf (callable): An optional callable that returns True if the
        passed object is considered a leaf or False otherwise.
    destination (list or dict, optional): A list or dictionary to store the
        flattened tree. If None an empty list will be used. Default: ``None``.

Returns:
    Union[List[Tuple[str, Any]], Dict[str, Any]]: The flat representation of
        the Python tree.
z;Destination should be either a list or a dictionary or None:   NNr8   )
r+   r,   extendr1   update
ValueErrorr-   r/   tree_flattenr2   )	r   r?   r   rC   _add_to_destinationr    itemkeyvalues	   &&&&     r   rJ   rJ   v   s   P 
 +t$$)00	K	&	&)00VWW wt}}fRj$/01 $u&& GA1#E ' $**,JC(!C5 17H ' &*d+,-r   c                    V ^8  d   QhR\         \        \        \        \        3,          ,          \
        \        \        3,          3,          R\        /# )r   r   r   )r   r   r
   rD   r   r   )r   s   "r   r   r      s=     /C /CtE#s(O4d38nDE /C# /Cr   c           	        \        V \        4      '       d   V P                  4       MT p\        V4      ^8X  d    \	        \        V4      4      w  r#VR8X  d   V# \        \        4      pV FD  w  r#VP                  R^R7      vrVV'       g   RMV^ ,          pWE,          P                  Wc34       KF  	   \        R VP                  4        4       4      p. pV F_  w  rTP                  \        V	\        V4      ,
          4       Uu. uF  p/ NK  	  up4       VP                  \        WJ,          4      4       Ka  	  V# u upi   \         d9    TP                  4        U
Uu/ uF  w  rT
\        T4      bK  	  Mu upp
i upp
u # i ; i)a  Recreate a Python tree from its flat representation.

.. code-block:: python

    from mlx.utils import tree_unflatten

    d = tree_unflatten([("hello.world", 42)])
    print(d)
    # {"hello": {"world": 42}}

    d = tree_unflatten({"hello.world": 42})
    print(d)
    # {"hello": {"world": 42}}

Args:
    tree (list[tuple[str, Any]] or dict[str, Any]): The flat representation of a Python tree.
       For instance as returned by :meth:`tree_flatten`.

Returns:
    A Python tree.
r9   r8   )maxsplitc              3   <   "   T F  p\        V4      V3x  K  	  R # 5ir   )int)r   idxs   & r   r!   !tree_unflatten.<locals>.<genexpr>   s     A#s3xos   )r+   r1   r2   lennextiterr   r,   splitappendsortedkeysrG   rangetree_unflattenrI   )r   r2   rM   rN   childrencurrent_idxnext_idxr\   lr    r*   _vs   &            r   r^   r^      sG   , 'tT22DJJLE 5zQ$u+&
"9L 4 H
!$3!;%28A;$$h%67 	CAAADAHH%CF
"34"3Qb"345HH^HK01   5  C191AB1A>!$$1ABBCs1   2AE  D;
,E  ;E   FE65FFc                >   Ve   V! V4      '       d   Vf   V# V ! W!4      # Tp\        V\        \        34      '       d   V F  p\        WWC4      pK  	  V# \        V\        4      '       d&   VP                  4        F  p\        WWC4      pK  	  V# Vf   V# V ! WA4      # )a  Applies a reduction to the leaves of a Python tree.

This function reduces Python trees into an accumulated result by applying
the provided function ``fn`` to the leaves of the tree.

Example:
    >>> from mlx.utils import tree_reduce
    >>> tree = {"a": [1, 2, 3], "b": [4, 5]}
    >>> tree_reduce(lambda acc, x: acc + x, tree, 0)
    15

Args:
    fn (callable): The reducer function that takes two arguments (accumulator,
        current value) and returns the updated accumulator.
    tree (Any): The Python tree to reduce. It can be any nested combination of
        lists, tuples, or dictionaries.
    initializer (Any, optional): The initial value to start the reduction. If
        not provided, the first leaf value is used.
    is_leaf (callable, optional): A function to determine if an object is a
        leaf, returning ``True`` for leaf nodes and ``False`` otherwise.

Returns:
    Any: The accumulated value.
)r+   r,   r-   tree_reducer1   values)r   r   initializerr   accumulatorrL   s   &&&&  r   rf   rf      s    2 wt}}"*tE;0EEK$u&&D%bEK   
D$		KKMD%bEK "
  #*tE;0EEr   c                *  a \        V \        \        \        34      '       d   \	        V 4      ^ 8X  d   Rp \        V\        \        \        34      '       d   \	        V4      ^ 8X  d   RpV f   Ve   V# V e   Vf   V # \        V \        \        34      '       dC   \        V\        \        34      '       d'   \        V 4      pV! V3R l\        W4       4       4      # \        V \        4      '       d   \        V\        4      '       dt   \        V P                  4       4      \        VP                  4       4      ,           Uu/ uF1  pV\        V P                  VR4      VP                  VR4      S4      bK3  	  up# Sf   \        R4      hS! W4      # u upi )ad  Merge two Python trees in one containing the values of both. It can be
thought of as a deep dict.update method.

Args:
    tree_a (Any): The first Python tree.
    tree_b (Any): The second Python tree.
    merge_fn (callable, optional): A function to merge leaves.

Returns:
    The Python tree containing the values of both ``tree_a`` and
    ``tree_b``.
Nc              3   @   <"   T F  w  r\        WS4      x  K  	  R # 5ir   )
tree_merge)r   abmerge_fns   &  r   r!   tree_merge.<locals>.<genexpr>6  s!      
3N41JqX&&3Ns   zOTrees contain elements at the same locations but no merge function was provided)r+   r1   r,   r-   rV   r.   r   setr\   rl   getrI   )tree_atree_bro   r3   r*   s   &&f  r   rl   rl     s\    &4u-..3v;!3C&4u-..3v;!3C~&,fn&4-((Zu-N-N< 
3>v3N
 
 	
 
FD	!	!j&>&> '#fkkm*<<
< z&**Q-vzz!T/BHMM<
 	

 ,  ''
s   ?7F)r9   NN)NNr   )collectionsr   	itertoolsr   typingr   r   r   r   r	   r
   r   r$   r>   rJ   r^   rf   rl   r   r   r   <module>rx      sW    $ ! D D D3GK3l5% #'	5%
 5%pIX/Cd'T((r   