o
    qoiX                  	   @   s   d Z ddlmZmZmZmZ ddlmZ ddlm	Z	 edZ
eede
f ee
 f ZdZdejd	ejfd
dZ	ddejdededdfddZdejfddZdS )z)Library for mutating Buildable instances.    )CallableTypeTypeVarUnion)config)
signaturesT.)__fn_or_cls____arguments____argument_tags____argument_history____signature_info__sourcedestinationc                 C   sP   t | t |urtdt |  dt | dtD ]}t||t| | qdS )aR  Changes the internals of `destination` to be equivalent to `source`.

  Currently, this results in aliasing behavior, but this should not be relied
  upon. All the internals of `source` are aliased into `destination`.

  Args:
    source: The source configuration to pull internals from.
    destination: One of the buildables to swap.
  ztypes must match exactly: z vs .N)type	TypeError_buildable_internals_keysobject__setattr__getattr)r   r   attr r   P/home/ubuntu/.local/lib/python3.10/site-packages/fiddle/_src/mutate_buildable.pymove_buildable_internals%   s   
r   F	buildablenew_callabledrop_invalid_argsreturnNc                    s   | j  D ]}t|trtdqt| tj d}t	| d  t	| d| |j
sW fdd| j  D }|rW|rH|D ]}t| | q?ntd| d| j d	| d
t	| d| | jd| dS )a   Updates ``config`` to build ``new_callable`` instead.

  When extending a base configuration, it can often be useful to swap one class
  for another. For example, an experiment may want to swap in a subclass that
  has augmented functionality.

  ``update_callable`` updates ``config`` in-place (preserving argument history).

  Args:
    buildable: A ``Buildable`` (e.g. a ``fdl.Config``) to mutate.
    new_callable: The new callable ``config`` should call when built.
    drop_invalid_args: If True, arguments that don't exist in the new callable
      will be removed from buildable. If False, raise an exception for such
      arguments.

  Raises:
    TypeError: if ``new_callable`` has varargs, or if there are arguments set on
      ``config`` that are invalid to pass to ``new_callable``.
  zKUpdate callable for configs with positional arguments is not supported yet.)	signature__signature__r   c                    s$   g | ]}| j vrt|tr|qS r   )
parameters
isinstancestr).0argnew_signaturer   r   
<listcomp>g   s
    z#update_callable.<locals>.<listcomp>zCannot switch to z (from z5) because the Buildable would have invalid arguments r   r	   N)r
   keysr"   intNotImplementedErrorr   get_signatureSignatureInfor   r   has_var_keyworddelattrr   r	   r   add_new_value)r   r   r   keynew_signature_infoinvalid_argsr%   r   r&   r   update_callable<   s8   



r4   c                 K   s"   |  D ]
\}}t| || qdS )ar  Assigns multiple arguments to ``buildable``.

  Although this function does not enable a caller to do something they can't
  already do with other syntax, this helper function can be useful when
  manipulating deeply nested configs. Example::

    cfg = # ...
    fdl.assign(cfg.my.deeply.nested.child.object, arg_a=1, arg_b='b')

  The above code snippet is equivalent to::

    cfg = # ...
    cfg.my.deeply.nested.child.object.arg_a = 1
    cfg.my.deeply.nested.child.object.arg_b = 'b'

  Args:
    buildable: A ``Buildable`` (e.g. a ``fdl.Config``) to set values upon.
    **kwargs: The arguments and values to assign.
  N)itemssetattr)r   kwargsnamevaluer   r   r   assignz   s   r:   )F)__doc__typingr   r   r   r   fiddle._srcr   
config_libr   r   TypeOrCallableProducingTr   	Buildabler   boolr4   r:   r   r   r   r   <module>   s.   	

>