o
    ,wi                     @  s  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	m
Z
mZmZmZmZmZmZmZmZmZmZmZmZmZmZ ddlmZ ddlmZ ddlmZ ddlmZ ed	Zeed
ef ee f Zej Z ej!Z!e" Z#ej$ddZ%G dd de"Z&	dFdGddZ'	dFdHddZ(dIddZ)dFdJd"d#Z*G d$d% d%eZ+G d&d dee ej,d'Z-G d(d) d)ee e-e Z.	dKdLd.d/Z/G d0d1 d1ee e.e Z0dMd6d7Z1ed8e-d9Z2dNd<d=Z3dddddd>dOdDdEZ4dS )PzCDefines the `Config` class and associated subclasses and functions.    )annotationsN)AnyCallable
CollectionDict	FrozenSetGenericIterableMapping
NamedTupleOptionalSetTupleTypeTypeVarUnion)daglish)history)
signatures)tag_typeT.T)use_fallbackc                   @  s    e Zd ZdZdd Zdd ZdS )_Placeholderz2A Placeholder class to represent config arguments.c                 C  s
   || _ d S Nindex)selfr    r   O/home/ubuntu/sommelier/.venv/lib/python3.10/site-packages/fiddle/_src/config.py__init__7   s   
z_Placeholder.__init__c                 C  s   | j |j kS r   r   r   otherr   r   r   __eq__:      z_Placeholder.__eq__N)__name__
__module____qualname____doc__r   r"   r   r   r   r   r   4   s    r   F	buildable	Buildableinclude_defaultsboolreturn2Tuple[Tuple[Any, ...], BuildableTraverserMetadata]c                 C  sf   t | |d}t| }t| }dd | j D }dd | j D }t| j|||d}||fS )z'Implement Buildable.__flatten__ method.r*   c                 S  s   i | ]\}}|r|t |qS r   )	frozenset.0nametagsr   r   r   
<dictcomp>E   s    z&_buildable_flatten.<locals>.<dictcomp>c                 S     i | ]	\}}|t |qS r   )tupler1   r2   entriesr   r   r   r4   J   s    )	fn_or_clsargument_namesargument_tagsargument_history)	ordered_argumentsr6   keysvalues__argument_tags__items__argument_history__BuildableTraverserMetadata__fn_or_cls__)r(   r*   	argumentsr>   r?   r;   r<   metadatar   r   r   _buildable_flatten>   s    rG   Tuple[daglish.PathElement]c                 C  s   t dd t| |d D S )z-Implement Buildable.__path_elements__ method.c                 s  s.    | ]}t |trt|nt|V  qd S r   )
isinstancestrr   AttrIndexr1   r2   r   r   r   	<genexpr>[   s
    
z+_buildable_path_elements.<locals>.<genexpr>r.   )r6   r=   r>   )r(   r*   r   r   r   _buildable_path_elementsW   s   rO   clsType[Buildable]c                 C  s,   t j| tjtdd| jtjtddd dS )zERegisters defaults aware traversal routines for buildable subclasses.Tr.   
flatten_fnunflatten_fnpath_elements_fnN)"_defaults_aware_traverser_registryregister_node_traverser	functoolspartialrG   __unflatten__rO   rP   r   r   r   -_register_buildable_defaults_aware_traversersc   s   
r\   xy	check_dagc                   sz  t | tsJ t| t|urdS | j|jkrdS | jj|jjks%J dt  d fd	d
}t| jt|jB D ]<}||| }|||}| u rO| u rOJ | u sW| u rZ dS t |trnt |trnt	||ddsn dS ||kru dS q9|rt
tj| ddtd}t
tj|ddtd}tdd |D }	tdd |D }
t|	t|
krdS t|	|
D ]\}}||kr dS qdS )z=Compare if two Buildables are equal, including DAG structure.Fz`Internal invariant violated: has_var_keyword should be the same if __fn_or_cls__'s are the same.keyUnion[str, int]r(   r)   r,   r   c                   s(   |j |  }| u r|j|  }|S r   )__arguments__get__signature_info__get_default)r`   r(   valuemissingr   r   get_value_or_default   s   z0_compare_buildable.<locals>.get_value_or_defaultr_   T)memoizedmemoize_internablesregistryc                 S     g | ]}|d  qS    r   r1   eltr   r   r   
<listcomp>       z&_compare_buildable.<locals>.<listcomp>c                 S  rn   ro   r   rq   r   r   r   rs      rt   N)r`   ra   r(   r)   r,   r   )rI   r)   typerD   rd   has_var_keywordobjectsetrb   _compare_buildablelistr   iteraterV   sortedlenzip)r]   r^   r_   ri   r`   v1v2
x_elements
y_elementsx_pathsy_pathsx_pathy_pathr   rg   r   ry   o   sd   


ry   c                   @  sd   e Zd ZU dZded< ded< ded< ei Zded	< dddZdddZ	dddZ
dddZdS )rC   zOMetadata for a Buildable.

  This separate class is used for DAG traversals.
  zCallable[..., Any]r9   zTuple[Union[str, int], ...]r:   z&Dict[str, FrozenSet[tag_type.TagType]]r;   z.Mapping[str, Tuple[history.HistoryEntry, ...]]r<   r,   c                 C  s   | j i dS )N)r<   )_replacer   r   r   r   without_history   r#   z*BuildableTraverserMetadata.without_historyr?   Iterable[Any]Dict[str, Any]c                 C  s   t t| j|S )zGReturns a dictionary combining ``self.argument_names`` with ``values``.)dictr~   r:   )r   r?   r   r   r   rE      s   z$BuildableTraverserMetadata.arguments Dict[str, set[tag_type.TagType]]c                 C  s   t tdd | j D S )Nc                 S  r5   r   )rx   r0   r   r   r   r4          z3BuildableTraverserMetadata.tags.<locals>.<dictcomp>)collectionsdefaultdictrx   r;   rA   r   r   r   r   r3      s   zBuildableTraverserMetadata.tagshistory.Historyc                 C  s   t dd | j D S )Nc                 S  r5   r   )rz   r7   r   r   r   r4      r   z6BuildableTraverserMetadata.history.<locals>.<dictcomp>)r   Historyr<   rA   r   r   r   r   r      s   z"BuildableTraverserMetadata.historyN)r,   rC   )r?   r   r,   r   )r,   r   )r,   r   )r$   r%   r&   r'   __annotations__typesMappingProxyTyper<   r   rE   r3   r   r   r   r   r   rC      s   
 



rC   c                      s6  e Zd ZU dZded< ded< ded< ded	< d
ed< dR fddZdS fddZdd Zej	dd Z
dTddZedUdd ZdVd"d#ZdWd&d'ZdXd,d-ZdYd.d/ZdZd0d1Zd2d3 Zd[d4d5Zd[d6d7Zd\d9d:Zd]d=d>Zd^d?d@Zd_dBdCZdDdE ZdFdG Zd`dJdKZdLdM ZdNdO Zda fdPdQZ  Z S )br)   a  Base class for buildable types (``Config`` and ``Partial``).

  Buildable types implement a ``__build__`` method that is called during
  ``fdl.build()`` with arguments set on the ``Buildable`` to get output for the
  corresponding instance.

  Arguments are stored in the `__arguments__` dict with the following
  "canonical storage format":
  Positional-only and variadic-positional arguments use the position index of
  the argument as a key (of type int); all other arguments use the name of the
  argument as a key (of type str).
  TypeOrCallableProducingT[T]rD   zDict[Union[str, int], Any]rb   r   rB   z,Dict[Union[str, int], Set[tag_type.TagType]]r@   signatures.SignatureInford   r9   2Union['Buildable[T]', TypeOrCallableProducingT[T]]c           
        s   |  | t }|d| t d| t dtt t	j
j|g|R i |}| D ]\}}t|ttfrC| || q1td|t| D ]\}}	| j| |	 | j|| j|  qQdS )aw  Initialize for ``fn_or_cls``, optionally specifying parameters.

    Args:
      fn_or_cls: A callable to configure. The signature of this callable will
        determine the parameters this ``Buidlable`` can be used to configure.
      *args: Any positional arguments to configure for ``fn_or_cls``.
      **kwargs: Any keyword arguments to configure for ``fn_or_cls``.
    rD   rB   r@   z0Unexpected type received for the argument name: N)__init_callable__r   r   add_new_valuesuper__setattr__r   r   rx   r   SignatureInfosignature_bindingrA   rI   rJ   int_arguments_set_value
ValueErrorr   find_tags_from_annotationsr@   updaterB   add_updated_tags)
r   r9   argskwargsarg_historyrE   r`   rf   r2   r3   	__class__r   r   r      s0   

zBuildable.__init__r,   Nonec                   sR   t |tr	tdt d| t di  t|}t dtj|d dS )z3Save information on `fn_or_cls` to the `Buildable`.zUsing the Buildable constructor to convert a buildable to a new type or to override arguments is forbidden; please use either `fdl.cast(new_type, buildable)` (for casting) or `fdl.copy_with(buildable, **kwargs)` (for overriding arguments).rD   rb   rd   	signatureN)rI   r)   r   r   r   r   get_signaturer   )r   r9   r   r   r   r   r     s   


zBuildable.__init_callable__c                 C  s(   t j| dd | jdd d t|  d S )Nc                 S     |   S r   )__flatten__r]   r   r   r   <lambda>,      z-Buildable.__init_subclass__.<locals>.<lambda>c                 S  r   r   )__path_elements__r   r   r   r   r   .  r   rR   )r   rW   rZ   r\   r[   r   r   r   __init_subclass__)  s   zBuildable.__init_subclass__c                 O  s   t  )z<Builds output for this instance; see subclasses for details.)NotImplementedErrorr   r   r   r   r   r   	__build__2  s   zBuildable.__build__r-   c                 C     t | ddS NFr.   )rG   r   r   r   r   r   7  r#   zBuildable.__flatten__r?   r   rF   rC   c                 C  sR   |  | }||j t|d|  t|d|  t|d|| |S )Nr@   rB   rb   )__new__r   r9   rw   r   r3   r   rE   )rP   r?   rF   rebuiltr   r   r   rZ   :  s   
zBuildable.__unflatten__rH   c                 C  r   r   )rO   r   r   r   r   r   E  r#   zBuildable.__path_elements__r2   rJ   c                 C  s   | j |t}| jj|}|dur&|j|j|jfv r&td| d| d|tur,|S t	
| jrHt| j|rHtd| jj d| d d |durU|j|jurU|jS d	| d
| d}t| j|rx|d| jj d| jj d| jj d7 }t|)z"Get parameter with given ``name``.Nz?Cannot access positional-only or variadic positional arguments z on z using attributes.z,Can't get default value for dataclass field . z since it uses a default_factory.No parameter '' has been set on z Note: zP has an attribute/method with this name, so this could be caused by using a fdl.zd in place of the actual function or class being configured. Did you forget to call `fdl.build(...)`?)rb   rc   _UNSET_SENTINELrd   
parameterskindPOSITIONAL_ONLYVAR_POSITIONALAttributeErrordataclassesis_dataclassrD   _field_uses_default_factoryr   r&   defaultemptyhasattrr%   r   )r   r2   rf   parammsgr   r   r   __getattr__H  sJ   
zBuildable.__getattr__r`   Union[int, str]rf   r   c                 C  sv   t |tr-|jdd}|r | j| | | j|| j|  d|jv r+|jd }ndS || j|< | j|| dS )z)Set `self.__arguments__` values directly.rf   r   N)	rI   TaggedValueClsr@   rc   r   rB   r   rb   r   )r   r`   rf   r3   r   r   r   r   o  s   



zBuildable._arguments_set_valuec                 C  s   | j |= | j| dS )z,Delete `self.__arguments__` values directly.N)rb   rB   add_deleted_value)r   r`   r   r   r   _arguments_del_value  s   zBuildable._arguments_del_valuec                 C  s    | j || j | || dS )z%Sets parameter ``name`` to ``value``.N)rd   validate_param_namerD   r   )r   r2   rf   r   r   r   r     s   zBuildable.__setattr__c                 C  s:   z|  | W dS  ty   td| d| }|dw )zUnsets parameter ``name``.r   r   N)r   KeyErrorr   )r   r2   errr   r   r   __delattr__  s   zBuildable.__delattr__c                 C  s   | j |}| j j| jddd\}}t| j j }t|D ]\}}|tu r;|t	|k r;|| }|j
|jur;|j
||< q|| S )z"Get positional arguments by index.Tinclude_pos_or_kw_in_argsinclude_no_value)rd   replace_varargs_handletransform_to_args_kwargsrb   rz   r   r?   	enumerateNO_VALUEr}   r   r   )r   r`   all_positional_args_paramsr   rf   r   r   r   r   __getitem__  s   

zBuildable.__getitem__c                 C  s.  | j |}| j j| jddd\}}| j j}t|tr)|t|}t	t
| }n|dk r3|t|7 }|g}dd t
t|D }| }|ddd D ]}||k re| j || j}	|	| jv rd| |	 qL||= qLt
|t|D ]$}|t|k r|| || kr| j|| j }
| ||
 qp| | qpdS )z%Delete positional arguments by index.Tr   r   c                 S     g | ]}t |qS r   r   r1   r   r   r   r   rs         z)Buildable.__delitem__.<locals>.<listcomp>N)rd   r   r   rb   var_positional_startrI   sliceindicesr}   rz   rangecopyindex_to_keyr   r   r   )r   r`   r   r   r   r   old_placeholdersnew_placeholdersr   k	new_valuer   r   r   __delitem__  s@   




zBuildable.__delitem__r   c                 C  sx   | j || j}| j j}|du rt| j j}| j jr|d8 }t|tr4||kr4|| jvr4t	d| d| 
|| dS )"Set positional arguments by index.Nrp   z*Cannot set positional argument with index z (index out of range).)rd   r   rb   r   r}   r   var_keyword_namerI   r   
IndexErrorr   )r   r`   rf   positional_numr   r   r   _set_item_by_index  s   

zBuildable._set_item_by_index	slice_keyr   c                 C  s^  | j j| jddd\}}| j j}|t|}|du s!|d |k rCt| }t|t|kr1tdt||D ]
\}}	| 	||	 q6dS dd tt|D }
|

 }|||< t|t|
D ]*}|t|k r|| }t|tr{||
| kruq]| j|j }| || q]| | q]t|
}t|}t||D ]}|| }t|tr| j|j }| || qdS )z"Set positional arguments by slice.Tr   Nr   a  Cannot modify the total length of full positional arguments list with __setitem__ when the slice key spans over non-variadic positional arguments. To remove values, use `del config[key]`. To append values to variadic positional arguments, you can use  config[fdl.VARARGS:] = value.c                 S  r   r   r   r   r   r   r   rs     r   z0Buildable._set_item_by_slice.<locals>.<listcomp>)rd   r   rb   r   r   r}   r   r   r~   r   r   rI   r   r   r   r   )r   r   rf   r   r   r   index_ranger   r   vr   r   r   len_oldlen_newr   r   r   _set_item_by_slice  sL   



zBuildable._set_item_by_slicec                 C  sD   | j |}t|tr| || dS t|tr | || dS dS )r   N)rd   r   rI   r   r   r   r   )r   r`   rf   r   r   r   __setitem__  s   

zBuildable.__setitem__Collection[str]c                 C  s$   | j  }t| jj}||}|S )a  Provide a useful list of attribute names, optimized for Jupyter/Colab.

    ``__dir__`` is often implicitly called by tooling such as Jupyter/Colab to
    provide autocomplete suggestions. This implementation of ``__dir__`` makes
    it easy to see what are valid attributes to get, set, or delete.

    Returns:
      A list of useful attribute names corresponding to set or unset parameters.
    )rb   r>   rx   rd   valid_param_namesunion)r   set_argument_namesr   	all_namesr   r   r   __dir__  s   


zBuildable.__dir__c           	        s4  t jdrjj}ntj}g }tjjfddjD  }|D ]>}j	|d}j	|t
}|s:|t
urbt|}|rR|ddtdd |D  d	7 }|t
ur]|d
|7 }|| q$tj}d|}t|t| t| dkrdd  d fdd|D }n|}d| d| d| dS )Nr&   c                   s   g | ]
}| j jvr|qS r   )rd   r   rM   r   r   r   rs   1  s
    z&Buildable.__repr__.<locals>.<listcomp>r   [z, c                 s  s    | ]}t |V  qd S r   )rJ   )r1   tagr   r   r   rN   =  s    z%Buildable.__repr__.<locals>.<genexpr>]=P   c                 S  s   d dd | dD S )N
c                 S  s   g | ]}d | qS )z  r   r1   r]   r   r   r   rs   N  rt   z6Buildable.__repr__.<locals>.indent.<locals>.<listcomp>)joinsplit)sr   r   r   indentM  s   z"Buildable.__repr__.<locals>.indent,c                   s   g | ]}d  | qS )r	  r   r
  )r  r   r   rs   P  s    <(z)]>)r   rD   r&   rJ   rz   rd   r   rb   r@   rc   r   r  r|   appendru   r$   r}   )	r   formatted_fn_or_clsformatted_paramsparam_namesr2   r3   rf   	param_strformatted_params_no_linebreakr   )r  r   r   __repr__)  s>   

$


zBuildable.__repr__c                 C  s   | j |   S )ak  Shallowly copies this ``Buildable`` instance.

    This copy implementation ensures that setting parameters on a copy of a
    ``Buildable`` won't affect the original instance. However, the copy is
    shallow, so parameter values will still refer to the same instances of
    objects after the copy.

    Returns:
      A shallow copy of this ``Buildable``.
    )rZ   r   r   r   r   r   __copy__V  s   zBuildable.__copy__memoDict[int, Any]c                 C  s<   | j j|t| j j< tt| }|jt	| j| |S )zFDeepcopies this Buildable, skipping copying of ``__signature_info__``.)
rd   r   idrw   r   ru   __dict__r   r   deepcopy)r   r  resultr   r   r   __deepcopy__d  s
   zBuildable.__deepcopy__c                 C  s   t | |ddS )a9  Returns true iff self and other contain the same argument values.

    This compares the specific types of ``self`` and ``other``, the function or
    class being configured, and then checks for equality in the configured
    arguments.

    Default argument values are considered in this comparison: If one
    ``Buildable`` has an argument explicitly set to its default value while
    another does not, the two will still be considered equal (motivated by the
    fact that calls to the function or class being configured will be the same).

    Argument history is not compared (i.e., it doesn't matter how the
    ``Buildable``'s being compared reached their current state).

    Args:
      other: The other value to compare ``self`` to.

    Returns:
      ``True`` if ``self`` equals ``other``, ``False`` if not.
    Trj   )ry   r    r   r   r   r"   o  s   zBuildable.__eq__c                 C  s   t | j}d|d< |S )a  Gets pickle serialization state, removing some fields.

    For now, we discard the ``__signature_info__.signature`` (which can be
    recalculated), because these tend to contain values which cannot be
    serialized.

    Returns:
      Dict of serialized state.
    Nrd   )r   r  )r   r  r   r   r   __getstate__  s   

zBuildable.__getstate__c                   s@   | j | | jdu rt| j}t dtj|d dS dS )zLoads pickle serialization state.

    This re-derives the signature if not present.

    Args:
      state: State dictionary, from ``__getstate__``.
    Nrd   r   )	r  r   rd   r   r   rD   r   r   r   )r   stater   r   r   r   __setstate__  s   

zBuildable.__setstate__)r9   r   )r9   r   r,   r   )r,   r-   )r?   r   rF   rC   )r,   rH   )r2   rJ   )r`   r   rf   r   )r`   r   )r2   rJ   rf   r   )r`   r   )r`   r   rf   r   )r   r   rf   r   )r`   r   rf   r   )r,   r   )r  r  )r,   r   )!r$   r%   r&   r'   r   r   r   r   abcabstractmethodr   r   classmethodrZ   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r   r"   r!  r#  __classcell__r   r   r   r   r)      sB   
 %	





'




'

1
-
)	metaclassc                   @  s*   e Zd ZU dZded< ded< dd ZdS )	Configa  A mutable representation of a function or class's parameters.

  This class represents the configuration for a given function or class,
  exposing configured parameters as mutable attributes. For example, given a
  class::

      class SampleClass:
        '''Example class for demonstration purposes.'''

        def __init__(self, arg, kwarg=None):
          self.arg = arg
          self.kwarg = kwarg

  a configuration may (for instance) be accomplished via::

      class_config = Config(SampleClass, 1, kwarg='kwarg')

  or via::

      class_config = Config(SampleClass)
      class_config.arg = 1
      class_config.kwarg = 'kwarg'

  A function can be configured in the same ways::

      def test_function(arg, kwarg=None):
        return arg, kwarg

      fn_config = Config(test_function, 1)
      fn_config.kwarg = 'kwarg'

  If the class/function has positional arguments, they can be accessed through
  the `[]` syntax::

      def test_function(a, b, /, c, *args):
        return locals()

      fn_config = Config(test_function, 1, 2, 3, 4, 5)

      # Read
      assert fn_config[0] == 1
      assert fn_config[:] == [1, 2, 3, 4, 5]

      # Modify
      fn_config[0] = 'a'
      fn_config.c = 'c'

      # `fdl.VARARGS` represents the start of variadic positional args (*args)
      fn_config[fdl.VARARGS:] = ['x', 'y']
      assert fn_config[:] == [1, 2, 3, 'x', 'y']

      # Delete
      del fn_config[0]
      del fn_config[fdl.VARARGS:]
      assert fn_config[:] == [fdl.NO_VALUE, 2, 3]

  NOTE: Directly calling `list` methods like `append` and `extend` is not
  supported, and will not mutate the config. Like with Python lists, slice
  operations on Configs effectively create a copy of the underlying sequence.

  NOTE: If using `slice` as key for modifying the config, and the `slice` spans
  over positional-only or positional-or-keyword arguments, the provided value
  must have the same length as that of the slice range.

  fn_config[2:4] = ['a', 'b'] # OK
  fn_config[2:4] = ['m']      # Not OK. Will raise an error!

  A ``Config`` instance may be transformed into instances and function outputs
  by passing it to the ``build`` function. The ``build`` function invokes each
  function or class in the configuration tree (appropriately propagating the
  built outputs from nested ``Config``'s). For example, using the
  ``SampleClass`` config from above::

      instance = build(class_config)
      assert instance.arg == 1
      assert instance.kwarg == 'kwarg'

  If the same ``Config`` instance is used in multiple places within the
  configuration tree, its function or class is invoked only once during
  ``build``, and the result shared across all occurrences of the ``Config``
  instance. (See ``build`` documentation for further details.) To create a new
  instance of a ``Config`` with the same parameter settings that will yield a
  separate instance during ``build``, ``copy.copy()`` or ``copy.deepcopy()``
  may be used.
  r   rD   r   rd   c                 O  s   | j |i |S )a  Builds this ``Config`` for the given ``args`` and ``kwargs``.

    This method is called during `build` to get the output for this `Config`.

    Args:
      *args: Positional arguments to pass to ``self.__fn_or_cls__``.
      **kwargs: Keyword arguments to pass to ``self.__fn_or_cls__`.

    Returns:
      The result of calling ``self.__fn_or_cls__`` with the given ``args`` and
      ``kwargs``.
    rD   r   r   r   r   r     s   zConfig.__build__N)r$   r%   r&   r'   r   r   r   r   r   r   r)    s
   
 Wr)  rf   Union[T, NoValue]r3   Optional[Set[tag_type.TagType]]c                 C  s.   | t u rd}|r|dt| 7 }t|| S )a  Identity function to return value if set, and raise an error if not.

  Args:
    value: The value to return.
    tags: The tags associated with the value. (Used in generating error messages
      if `value` is not set.)

  Returns:
    The value `value` passed to it.
  z[Expected all `TaggedValue`s to be replaced via fdl.set_tagged() calls, but one was not set.z Unset tags: )r   rJ   r   TaggedValueNotFilledError)rf   r3   r   r   r   r   tagged_value_fn  s   
r.  c                   @  s8   e Zd ZU dZded< ded< edd ZdddZdS )r   a,  Placeholder class for TaggedValue instances.

  Instances of this class are generally transitory; when passed as an argument
  of a Fiddle Buildable, will be expanded into that argument's values and tags.
  However, they may survive as stand-alone objects within tuples, lists, and
  dictionaries.
  r   rD   r   rd   c                 C  s
   | j d S )Nrf   )r@   r   r   r   r   r3   7  s   
zTaggedValueCls.tagsr   r   r   r,   r   c                 O  s0   | j turtd| j  | j |d| ji|S )Nz2Unexpected __fn_or_cls__ in TaggedValueCls; found:r3   )rD   r.  RuntimeErrorr3   r   r   r   r   r   ;  s   
zTaggedValueCls.__build__N)r   r   r   r   r,   r   )r$   r%   r&   r'   r   propertyr3   r   r   r   r   r   r   *  s   
 	
r   dataclass_type	Type[Any]
field_namerJ   c                 C  s.   t | D ]}|j|kr|jt jk  S qdS )zEReturns true if <dataclass_type>.<field_name> uses a default_factory.F)r   fieldsr2   default_factoryMISSING)r1  r3  fieldr   r   r   r   D  s
   
r   
BuildableT)boundBuildable[T] Union[Callable[..., T], Type[T]]c                 C  s   | j S )z$Returns the callable of a Buildable.r*  )r(   r   r   r   get_callableO  s   r<  )include_var_keywordr*   include_unsetinclude_positionalinclude_equal_to_defaultr=  r>  r?  r@  Dict[Union[int, str], Any]c                C  sv  |s|rt di }t }t| jj D ]w\}\}	}
|
j|
j|
jfvrq|}|	| j	v s6|| j	v rG|
j|
j
krG|	| j	v rA| j	|	 }n| j	| }n|
j|
jurS|rR|
j}n|rWt}||urq|sb||
jkrq|
j|
j
krm|||< n|||	< |
j|
jkr|| j	v r| j	| ||< |d7 }|| j	v s|q|r| j	 D ]\}	}| jj|	}
|
du s|
j|
jkr|||	< q|sdd | D }|S )aY  Returns arguments of a Buildable, ordered by the signature.

  Args:
    buildable: The buildable whose arguments should be returned.
    include_var_keyword: If True, then include arguments that will be consumed
      by the buildable's callable's `VAR_KEYWORD` parameter (e.g. `**kwargs`).
    include_defaults: If True, then include arguments that have not been
      explicitly set, but that have a default value.  Can not be combined with
      `include_equal_to_default=False`.
    include_unset: If True, then include arguments that have not been explicitly
      set, that don't have a default value.  The value for these parameters will
      be `fdl.NO_VALUE`.
    include_positional: If False, positional-only and variadic positional
      arguments will be excluded from the output.
    include_equal_to_default: If False, then exclude arguments that are equal to
      their default value (using `==`).  Can not be combined with
      `include_defaults=True`.

  Returns:
    A dictionary mapping argument keys to values or `fdl.NO_VALUE`. Argument
    keys are either positional indices or names.
  zEExclude_equal_to_default and include_defaults are mutually exclusive.rp   Nc                 S  s    i | ]\}}t |tr||qS r   )rI   rJ   )r1   r   r   r   r   r   r4     s     z%ordered_arguments.<locals>.<dictcomp>)r   rw   r   rd   r   rA   r   r   VAR_KEYWORDrb   r   r   r   r   rc   )r(   r=  r*   r>  r?  r@  r  unsetr   r2   r   rf   r   r   r   r=   T  sV   






r=   )F)r(   r)   r*   r+   r,   r-   )r(   r)   r*   r+   r,   rH   )rP   rQ   )r]   r)   r^   r)   r_   r+   r   )rf   r+  r3   r,  r,   r   )r1  r2  r3  rJ   )r(   r:  r,   r;  )r(   r)   r=  r+   r*   r+   r>  r+   r?  r+   r@  r+   r,   rA  )5r'   
__future__r   r$  r   r   r   rX   r   typingr   r   r   r   r   r   r	   r
   r   r   r   r   r   r   r   fiddle._srcr   r   r   r   r   TypeOrCallableProducingTNoValuer   rw   r   NodeTraverserRegistryrV   r   rG   rO   r\   ry   rC   ABCMetar)   r)  r.  r   r   r8  r<  r=   r   r   r   r   <module>   s\   D
F   Vl

