o
    qoi%                     @   s  U d 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Zddlm	Z	m
Z
mZmZmZmZmZmZ ddlmZ e ZejddG dd dZe
g ef Zeeejjg d	aeed
f ed< defddZdefddZ e a!eed< G dd dZ"e" Z#G dd dej$Z%ejddG dd dZ&dede	de&fddZ'dede&fddZ(dedeej) de&fd d!Z*ejG d"d# d#ej+Z,e, Z-ej.d$d% Z/d&e0fd'd(Z1de0fd)d*Z2G d+d, d,e3Z4ej.d-edee fd.d/Z5dS )0a  History tracking for config objects.

In order to make it easier to understand how config objects have been
constructed, config objects keep track of the sequence of changes made to them.
This file contains the machinery to record this history and easily manipulate
it.

The history functionality has a few bits of non-trivial logic:

 1. Each history entry is associated with a monotonically increasing number.
    This allows sequencing history across multiple config objects. The
    implementation of this capability is guaranteed to be threadsafe, so users
    can mutate (different!) config objects from multiple threads without fear.
 2. The logic to determine where in the user's source code a mutation was
    generated is configurable. Simply use `custom_location` to temporarily set a
    different location provider; see the documentation on the `custom_location`
    context manager for an example.
    N)AnyCallable	FrozenSetIteratorOptionalSetTupleUnion)tag_typeT)frozenc                   @   sX   e Zd ZU dZeed< eed< ee ed< ddee fddZd	efd
dZ	dd Z
dS )Locationz,Information about where a parameter was set.filenameline_numberfunction_nameNmax_filename_partsc                 C   sx   | j }|d ur#|tjj}t||kr#tjjdg|| d  }| jd u r0| d| j S | d| j d| j S )Nz...:)	r   splitospathseplenjoinr   r   )selfr   r   filename_parts r   G/home/ubuntu/.local/lib/python3.10/site-packages/fiddle/_src/history.pyformat9   s   
zLocation.formatreturnc                 C   s   |   S N)r   r   r   r   r   __str__E   s   zLocation.__str__c                 C      ~| S r   r   r   memor   r   r   __deepcopy__H      zLocation.__deepcopy__r   )__name__
__module____qualname____doc__str__annotations__intr   r   r    r$   r   r   r   r   r   2   s   
 r   )zfiddle/_src/config.pyzfiddle/_src/copying.pyzfiddle/_src/daglish.pyzfiddle/_src/history.pyzfiddle/_src/materialize.pyzfiddle/_src/mutate_buildable.pyz'fiddle/_src/experimental/auto_config.py._exclude_locationslocationc                 C   s   t | f7 a dS )z<Adds a filename pattern to exclude from history stacktraces.N)r-   )r.   r   r   r   add_exclude_location`   s   r/   r   c                  C   sL   t  } | r"| j}| jj}|ts| jj}t|||dS | j	} | st
d)zReturns a string corresponding to the user-function that set the field.

  Raises:
    RuntimeError: if no suitable stack frame can be found.
  )r   r   r   z0Cannot find a suitable frame in the stack trace!)inspectcurrentframef_linenof_codeco_filenameendswithr-   co_namer   f_backRuntimeError)framer   r   r   r   r   r   _stacktrace_location_providerf   s   

r:   _location_providerc                   @   s   e Zd ZdZdd ZdS )_Deletedz&A marker object to indicated deletion.c                 C   s   dS )NDELETEDr   r   r   r   r   __repr__   s   z_Deleted.__repr__N)r&   r'   r(   r)   r>   r   r   r   r   r<   ~   s    r<   c                   @   s   e Zd ZdZdZdZdS )
ChangeKindzIndicates the kind of change that occurred to the parameter.

  NEW_VALUE indicates the value of the parameter changed.
  UPDATE_TAGS indicates the tag set was updated.
        N)r&   r'   r(   r)   	NEW_VALUEUPDATE_TAGSr   r   r   r   r?      s    r?   c                   @   sR   e Zd ZU dZeed< eed< eed< ee	e
ej ef ed< eed< dd Zd	S )
HistoryEntrya  An entry in the history table for a config object.

  Attributes:
    sequence_id: The global sequence number, to allow ordering of history
      sequences across config objects.
    param_name: The parameter name for the history entry.
    kind: The kind of change that occurred, which influences the interpretation
      of `value`.
    new_value: The new value of the field, the updated set of tags, or DELETED
      if the field was `del`d.
    location: The location in user code that made the modification.
  sequence_id
param_namekind	new_valuer.   c                 C   r!   r   r   r"   r   r   r   r$      r%   zHistoryEntry.__deepcopy__N)r&   r'   r(   r)   r,   r+   r*   r?   r	   r   r   r
   TagTyper<   r   r$   r   r   r   r   rD      s   
 rD   rF   valuec                 C   s   t tt| tj|t dS )a  Returns a newly constructed history entry.

  Args:
    param_name: The name of the config parameter the entry is associated with.
    value: The new value, or DELETED to indicate a deletion of the param.

  Returns:
    The newly constructed HistoryEntry.
  rE   rF   rG   rH   r.   )rD   next_set_counterr?   rB   r;   )rF   rJ   r   r   r   rH      s   
rH   c                 C   s   t tt| tjtt dS )zReturns a newly constructed history entry.

  Args:
    param_name: The name of the config parameter the entry is associated with.

  Returns:
    The newly constructed HistoryEntry.
  rK   )rD   rL   rM   r?   rB   r=   r;   )rF   r   r   r   deleted_value   s   	rN   updated_tagsc                 C   s   t tt| tjt|t dS )zReturns a newly constructed history entry.

  Args:
    param_name: The name of the config parameter the entry is associated with.
    updated_tags: The new set of tags associated with `param_name`.

  Returns:
    The newly constructed HistoryEntry.
  rK   )rD   rL   rM   r?   rC   	frozensetr;   )rF   rO   r   r   r   update_tags   s   rQ   c                   @   s   e Zd ZU dZeed< dS )_TrackingStateTenabledN)r&   r'   r(   rS   boolr+   r   r   r   r   rR      s   
 rR   c               	   c   s6    t  } tdd zdV  W t| d dS t| d w )a  A context manager for temporarily suspending history tracking.

  This can be useful in certain cases for performance reasons, or for specific
  operations that want to avoid associated history modifications.

  Example:

      with history.suspend_tracking():
        ...  # Modifications made here won't affect Buildable history.

  Yields:
    There is no associated yield value.
  FrS   N)tracking_enabledset_tracking)previous_enabledr   r   r   suspend_tracking   s   
rY   rS   c                 C   s
   | t _dS )a  Sets whether Fiddle performs history tracking.

  For performance reasons, it can be valuable to disable history tracking. This
  function enables callers to imperatively control whether Fiddle tracks
  mutations to Buildable objects. To disable history tracking::

    history.set_tracking(enabled=False)

  Note: where possible, prefer the context manager ``suspend_tracking`` instead.

  Args:
    enabled: Whether history tracking should be enabled.
  N_tracking_staterS   rU   r   r   r   rW     s   
rW   c                   C   s   t jS )z6Returns whether history tracking is currently enabled.rZ   r   r   r   r   rV     s   rV   c                   @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )Historyz+Utility class to manage argument histories.c                 C   s   |  |g S r   )
setdefault)r   keyr   r   r   __missing__  s   zHistory.__missing__c                 C   "   t  r| | t|| dS dS )z>Adds a history entry for a new value, created via `new_value`.N)rV   appendrH   )r   rF   rJ   r   r   r   add_new_value     zHistory.add_new_valuec                 C   s    t  r| | t| dS dS )zEAdds a history entry for a deleted value, created via `delete_value`.N)rV   ra   rN   )r   rF   r   r   r   add_deleted_value"  s   zHistory.add_deleted_valuec                 C   r`   )zAAdds a history entry for updated tags, created via `update_tags`.N)rV   ra   rQ   )r   rF   rO   r   r   r   add_updated_tags'  rc   zHistory.add_updated_tagsN)r&   r'   r(   r)   r_   rb   rd   re   r   r   r   r   r\     s    r\   temporary_providerc                 c   s"    t }| a z| V  W |a dS |a w )az  Temporarily sets a custom LocationProvider.

  Example usage:
  ```py
  my_config =  # ...
  with custom_location(lambda: Location('my_loc', 123, None)):
    my_config.x = 123  # the location of my_config.x will be 'my_loc:123'.
  ```

  Args:
    temporary_provider: A location provider to use for the duration of the with
      block.

  Yields:
    The temporary provider.
  N)r;   )rf   original_location_providerr   r   r   custom_location-  s   rh   )6r)   
contextlibdataclassesenumr0   	itertoolsr   	threadingtypingr   r   r   r   r   r   r   r	   fiddle._srcr
   countrM   	dataclassr   LocationProvidertuplemapr   normpathr-   r*   r+   r/   r:   r;   r<   r=   Enumr?   rD   rH   rN   rI   rQ   localrR   r[   contextmanagerrY   rT   rW   rV   dictr\   rh   r   r   r   r   <module>   sb   (




