o
    qoi                  
   @   sv  d 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 ddlmZ ddlmZ ddlmZ ddlmZ e
dZG d	d
 d
ejZe Zejdd ZdedefddZdejdejde	e deeef def
ddZdejdeeeef ef dejdefddZedej e dedef fddZ!edej"e defddZ!ededefddZ!dd Z!dS ) z%Implements Fiddle's build() function.    N)AnyCallableDictSequenceTypeVarUnionoverload)config)daglish)partial)reraised_exceptionTc                       s   e Zd Z fddZ  ZS )_BuildGuardStatec                    s   t    d| _d S )NF)super__init__in_build)self	__class__ H/home/ubuntu/.local/lib/python3.10/site-packages/fiddle/_src/building.pyr   "   s   

z_BuildGuardState.__init__)__name__
__module____qualname__r   __classcell__r   r   r   r   r       s    r   c                   c   s2    t jrtddt _z	dV  W dt _dS dt _w )z@A context manager to ensure fdl.build is not called recursively.zDIt is forbidden to call `fdl.build` inside another `fdl.build` call.TNF)_stater   
ValueErrorr   r   r   r   	_in_build*   s   r   argreturnc                 C   s.   zt | W S  ty   dt|  d Y S w )z?Returns repr(arg), returning a constant string if repr() fails.z<ERROR FORMATTING z
 ARGUMENT>)repr	Exceptiontype)r   r   r   r   _format_arg7   s
   
r#   current_path	buildableargskwargsc                 C   s$  dt |  }t|}z|j}W n ty   t|}Y nw ddd |D }ddd | D }d}	|j	j
j|i |}
|
  g }|j	jD ](}||
jv rSqK|j|d}|rsdtd	d |D }|d
| d|  qK|rd|}d| }	d| d| d| d| d|	 dS )z>Returns Fiddle-related debugging information for an exception.z<root>z, c                 s   s    | ]}t | V  qd S Nr#   ).0valuer   r   r   	<genexpr>L   s    z _make_message.<locals>.<genexpr>c                 s   s&    | ]\}}| d t | V  qdS )=Nr)   )r*   namer+   r   r   r   r,   M   s    
 N c                 s   s    | ]}t |V  qd S r(   )str)r*   tagr   r   r   r,   \   s    z - z: 
z
Tags for unset arguments:
z.

Fiddle context: failed to construct or call z at z with positional arguments: (z), keyword arguments: ().)r
   path_str
config_libget_callabler   AttributeErrorr1   joinitems__signature_info__	signaturebind_partialapply_defaults
parameters	arguments__argument_tags__getsortedappend)r$   r%   r&   r'   r6   	fn_or_clsfn_or_cls_nameargs_str
kwargs_strtag_information
bound_argsunset_arg_tagsparamtagstag_strtag_detailsr   r   r   _make_message?   sT   





rQ   rA   c                C   s`   | j |\}}tt|| ||}t| | j|i |W  d   S 1 s)w   Y  dS )z>Prepare positional arguments and actually build the buildable.N)r<   transform_to_args_kwargs	functoolsr   rQ   r   try_with_lazy_message	__build__)r%   rA   r$   r&   r'   make_messager   r   r   call_buildablej   s   
$rW   .c                 C      d S r(   r   r%   r   r   r   build|      rZ   c                 C   rX   r(   r   rY   r   r   r   rZ      r[   c                 C   rX   r(   r   rY   r   r   r   rZ      r[   c                    sr   d dt dtjdt f fdd}t  tj|| }W d   n1 s%w   Y   s7tdt| t	|  |S )	a  Builds ``buildable``, recursively building nested ``Buildable`` instances.

  This is the core function for turning a ``Buildable`` into a usable object. It
  recursively walks through ``buildable``'s parameters, building any nested
  ``Config`` instances. Depending on the specific ``Buildable`` type passed
  (``Config`` or ``Partial``), the result is either the result of calling
  ``config.__fn_or_cls__`` with the configured parameters, or a partial function
  or class with those parameters bound.

  If the same ``Buildable`` instance is seen multiple times during traversal of
  the configuration tree, ``build`` is called only once (for the first instance
  encountered), and the result is reused for subsequent copies of the instance.
  This is achieved via the ``memo`` dictionary (similar to ``deepcopy``). This
  has the effect that for configured class instances, each separate config
  instance is in one-to-one correspondence with an actual instance of the
  configured class after calling ``build`` (shared config instances <=> shared
  class instances).

  Args:
    buildable: A ``Buildable`` instance to build, or a nested structure of
      ``Buildable`` objects.

  Returns:
    The built version of ``buildable``.
  Fr+   stater   c                    sF   t | tjr|| }|j}||j}d t| ||jdS |	| S )z)Inner method / implementation of build().T)r$   )

isinstancer7   	Buildableflattened_map_childrenmetadatarA   valuesrW   r$   map_children)r+   r\   sub_traversalr`   rA   is_builtr   r   _build   s   

zbuild.<locals>._buildNzFNo Buildables found in value passed to `fdl.build()`: %s with type %s.)
r   r
   Stater   MemoizedTraversalrunloggingwarningr1   r"   )r%   rf   resultr   rd   r   rZ      s   )#__doc__
contextlibrS   rj   	threadingtypingr   r   r   r   r   r   r   fiddle._srcr	   r7   r
   r   r   r   localr   r   contextmanagerr   r1   r#   Pathr^   rQ   intrW   PartialrZ   Configr   r   r   r   <module>   sV   $


+
"