a
    ij+                     @  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 ddddZejG d	d
 d
ZG dd dZe dddddZdddddZdddddZddddddZdS )zText utils.    )annotationsN)AnyIterableIteratorUnion)())[]){})r   r	   r   c                   @  s*   e Zd ZU dZded< ded< ded< dS )_Linez
Line item.strcontentint
indent_lvlindent_sizeN)__name__
__module____qualname____doc____annotations__ r   r   R/home/ghrups/robot-bench/.venv/lib/python3.9/site-packages/etils/epy/text_utils.pyr   "   s   
r   c                
   @  s   e Zd ZdZddddddZddd	d
dZdddddZdd d	ddZej	ddddZ
dddddddZed(ddd d!dd"d#dddd$d%d&Zd'S ))Linesan  Util to build multi-line text.

  Useful for pretty-print tools and human readable `__repr__`.

  Example:

  ```python
  d = {'a': 1, 'b': 2}

  lines = epy.Lines()
  lines += 'dict('
  with lines.indent():
    for k, v in d.items():
      lines += f'{k}={v},'
  lines += ')'
  text = lines.join()
  ```

  Output:

  ```
  dict(
      a=1,
      b=2,
  )
  ```

     )indentr   c                C  s   g | _ || _d| _d S )Nr   )_lines_indent_size_indent_lvl)selfr   r   r   r   __init__I   s    zLines.__init__r   None)linereturnc                 C  s6   t |tstd|| jt|| j| jd dS )Append a new line `str`.z&Lines should be added with `str`. Got )r   r   r   N)
isinstancer   	TypeErrorr   appendr   r   r   r    r#   r   r   r   r(   N   s    
zLines.appendzIterable[str])iterabler$   c                 C  s   |D ]}|  | qdS )z0Append all the new line `str` from the iterable.Nr(   )r    r*   r#   r   r   r   extend[   s    zLines.extendc                 C  s   |  | | S )r%   r+   r)   r   r   r   __iadd__`   s    
zLines.__iadd__zIterator[None])r$   c              	   c  s<   |  j d7  _ zd V  W |  j d8  _ n|  j d8  _ 0 d S )N   )r   )r    r   r   r   r   e   s    zLines.indentFcollapsebool)r0   r$   c                C  sX   g }| j D ]4}|j}|s4d|j |j }t||}|| q
|rJd}nd}||S )zReturns the lines.

    Args:
      collapse: If `True`, all lines are merged together in a single line.

    Returns:
      text: All lines merged together
      
)r   r   r   r   textwrapr   r(   join)r    r0   linesr#   r   indentationtokenr   r   r   r6   m   s    	
z
Lines.joinr3   r   r   =   )bracesequallimitz2str | dict[str, Any] | list[Any] | tuple[Any, ...]zUnion[str, tuple[str, str]])headerr   r<   r=   r>   r$   c                  s<  t |trt| }|\}}t |tr*|g}t |trL fdd| D }n0t |ttfrjdd |D }ntdt| t	|dk}	t
dd |D rd}	ntd	d |D |krd
}	|  }
|
| | 7 }
|
 < |	r|
d|7 }
n|D ]}|
| d7 }
qW d   n1 s0    Y  |
| 7 }
|
j|	dS )a  Util function to create a code block.

    Example:

    ```python
    epy.Lines.make_block('A', {}) == 'A()'
    epy.Lines.make_block('A', {'x': '1'}) == 'A(x=1)'
    epy.Lines.make_block('A', {'x': '1', 'y': '2'}) == '''A(
        x=1,
        y=2,
    )'''
    ```

    Pattern is as:

    ```
    {header}{braces[0]}
        {k}={v},
        ...
    {braces[1]}
    ```

    Args:
      header: Prefix before the brace
      content: Dict of key to values. One line will be displayed per item if
        `len(content) > 1`. Otherwise the code is collapsed
      braces: Brace type (`(`, `[`, `{`), can be tuple for custom open/close.
      equal: The separator (`=`, `: `)
      limit: Strings smaller than this will be collapsed

    Returns:
      The block string
    c                   s$   g | ]\}}|   t | qS r   pretty_repr.0kvr=   r   r   
<listcomp>       z$Lines.make_block.<locals>.<listcomp>c                 S  s   g | ]}t | qS r   r@   )rC   rE   r   r   r   rG      rH   zInvalid fields r.   c                 s  s   | ]}d |v V  qdS )r4   Nr   rC   pr   r   r   	<genexpr>   rH   z#Lines.make_block.<locals>.<genexpr>Fc                 s  s   | ]}t |V  qd S )N)lenrI   r   r   r   rK      rH   Tz, ,Nr/   )r&   r   _BRACE_TO_BRACESdictitemslisttupler'   typerL   anysumr   r6   )clsr?   r   r<   r=   r>   Zbrace_startZ	brace_endpartsr0   r7   rJ   r   rF   r   
make_block   s0    +



0
zLines.make_blockN)r3   r   )r   r   r   r   r!   r(   r,   r-   
contextlibcontextmanagerr   r6   classmethodrX   r   r   r   r   r   +   s      r   r   r   )objr$   c                   s   t  trt S t ttfv r>tj t  tr6dnddS t tu rhtjdd  	 D dddS t  tst
 rȈ jjrtt st jtu rt
 }tj jj fd	d|D d
S t S dS )z9Pretty `repr(obj)` for nested list, dict, dataclasses,...r	   r   )r   r<   c                 S  s   i | ]\}}t ||qS r   )reprrB   r   r   r   
<dictcomp>   rH   zpretty_repr.<locals>.<dictcomp>r   z: )r   r<   r=   c                   s"   i | ]}|j r|jt |jqS r   )r]   namegetattr)rC   fieldr\   r   r   r^      s   )r?   r   N)r&   r   r]   rS   rQ   rR   r   rX   rO   rP   dataclassesis_dataclass__dataclass_params__has_default_repr__repr__rA   fields	__class__r   )r\   Z
all_fieldsr   rb   r   rA      s>    



	rA   r1   )rV   r$   c                 C  s   t | j}|jdkS )z<Returns `True` if the dataclass do not overwrite `__repr__`.z__create_fn__.<locals>.__repr__)inspectunwraprg   r   )rV   Zrepr_fnr   r   r   rf      s    rf   )textr$   c                 C  s   t |  S )al  Wrapper around `textwrap.dedent` which also `strip()` the content.

  Before:

  ```python
  text = textwrap.dedent(
      \"\"\"\\
      A(
         x=1,
      )\"\"\"
  )
  ```

  After:

  ```python
  text = epy.dedent(
      \"\"\"
      A(
         x=1,
      )
      \"\"\"
  )
  ```

  Args:
    text: The text to dedent

  Returns:
    The dedented text
  )r5   dedentstrip)rl   r   r   r   rm      s     rm   zstr | object)abr$   c                 C  sF   t | tst| d} t |ts0t|d}t| |}d|S )zPretty diff between 2 objects.

  Args:
    a: Object/str to compare
    b: Object/str to compare

  Returns:
    The diff string
  r4   )r&   r   rA   splitdifflibZndiffr6   )ro   rp   diffr   r   r   diff_str   s    


rt   )r   
__future__r   rY   rc   rr   rj   reprlibr5   typingr   r   r   r   rN   	dataclassr   r   recursive_reprrA   rf   rm   rt   r   r   r   r   <module>   s*    ($#