
    Vii2                     V   S r SSKJr  SSKrSSKJr   \  / SQr	\R                  " S5      rS rS rS	 rS
rSr\" \ V s/ s H  o \4PM     sn \ V s/ s H  o \4PM     sn -   5      r\\S'   S rSS jr " S S\5      r\" 5       r " S S\5      rg! \ a    \r Nf = fs  sn f s  sn f )aF  `PEP 3101`_ introduced the :meth:`str.format` method, and what
would later be called "new-style" string formatting. For the sake of
explicit correctness, it is probably best to refer to Python's dual
string formatting capabilities as *bracket-style* and
*percent-style*. There is overlap, but one does not replace the
other.

  * Bracket-style is more pluggable, slower, and uses a method.
  * Percent-style is simpler, faster, and uses an operator.

Bracket-style formatting brought with it a much more powerful toolbox,
but it was far from a full one. :meth:`str.format` uses `more powerful
syntax`_, but `the tools and idioms`_ for working with
that syntax are not well-developed nor well-advertised.

``formatutils`` adds several functions for working with bracket-style
format strings:

  * :class:`DeferredValue`: Defer fetching or calculating a value
    until format time.
  * :func:`get_format_args`: Parse the positional and keyword
    arguments out of a format string.
  * :func:`tokenize_format_str`: Tokenize a format string into
    literals and :class:`BaseFormatField` objects.
  * :func:`construct_format_field_str`: Assists in progammatic
    construction of format strings.
  * :func:`infer_positional_format_args`: Converts anonymous
    references in 2.7+ format strings to explicit positional arguments
    suitable for usage with Python 2.6.

.. _more powerful syntax: https://docs.python.org/2/library/string.html#format-string-syntax
.. _the tools and idioms: https://docs.python.org/2/library/string.html#string-formatting
.. _PEP 3101: https://www.python.org/dev/peps/pep-3101/
    )print_functionN)	Formatter)DeferredValueget_format_argstokenize_format_strconstruct_format_field_strinfer_positional_format_argsBaseFormatFieldz({{)|(}})|({[:!.\[}])c                 ^    U c  gSU -   nU(       a  USU-   -  nU(       a  USU-   -  nUS-  nU$ )z
Constructs a format field string from the field name, spec, and
conversion character (``fname``, ``fspec``, ``conv``). See Python
String Formatting for more info.
 {!:} )fnamefspecconvrets       f/home/james-whalen/.local/share/pipx/venvs/semgrep/lib/python3.13/site-packages/boltons/formatutils.pyr   r   Z   sE     }
+CsTzsU{3JCJ    c                     / n[        5       R                  U 5       H<  u  p#pEUc  UR                  US45        M  [        X4U5      nUR                  X&45        M>     U$ )zDoes very basic splitting of a format string, returns a list of
strings. For full tokenization, see :func:`tokenize_format_str`.

N)r   parseappendr   )fstrr   litr   r   r   	field_strs          r   split_format_strr   k   s_    
 C#,;#4#4T#:E=JJT{#.uTB	

C#$ $; Jr   c                 "   Su  pSu  p4n[         R                  U 5       He  nUR                  5       UR                  5       UR	                  5       ptnXS:  a  XXS -  nUnUS:X  d  US:X  a  X-  nMQ  USU< USS < 3-  nUS-  nMg     XUS -  nU$ )zTakes format strings with anonymous positional arguments, (e.g.,
"{}" and {:d}), and converts them into numbered ones for explicitness and
compatibility with 2.6.

Returns a string with the inferred positional arguments.
)r   r   )r   r   r   z{{z}}r      N)_pos_farg_refinditerstartendgroup)r   r   max_anonr#   r$   prev_endmatchr%   s           r   r	   r	   {   s     MC"E&&t,!KKM599;E''CD=ETMLC(E!"I..A - 	?CJr   bcdoxXnzeEfFgGn%sc                   ^^^ [        5       n/ / [        5       smmmS	UUU4S jjnUR                  U 5       H  u  p4pVUc  M  USS n[        R                  " SU5      n[        U5      S:  a  [        SU-  5      e US   n	U	(       d   e U" XG5        UR                  U5       H  u  p  nUc  M  U" U5        M     M     TT4$ ! [        [        4 a    [        S5      ef = f)
a  
Turn a format string into two lists of arguments referenced by the
format string. One is positional arguments, and the other is named
arguments. Each element of the list includes the name and the
nominal type of the field.

# >>> get_format_args("{noun} is {1:d} years old{punct}")
# ([(1, <type 'int'>)], [('noun', <type 'str'>), ('punct', <type 'str'>)])

# XXX: Py3k
>>> get_format_args("{noun} is {1:d} years old{punct}") ==         ([(1, int)], [('noun', str), ('punct', str)])
True
c                    > U T;  aI  TR                  U 5        [        R                  U[        5      n TR	                  [        U 5      U45        g g ! [         a    TR	                  X45         g f = fN)add	_TYPE_MAPgetstrr   int
ValueError)argname	type_charargtype_dedupfargsfkwargss      r   _add_arg!get_format_args.<locals>._add_arg   sf    & JJwmmIs3G3c'lG45	 !
  3123s   A A10A1N[.[]r    z#encountered compound format arg: %rr   z)encountered anonymous positional argument)r*   )	r   setr   resplitlenr3   
IndexErrorAssertionError)r   	formatterr:   r   r   r   r   r5   
fname_list
base_fnamesublitsubfname_r7   r8   r9   s                @@@r   r   r      s      ISUE7F3 3 $-??4#8Ebc
I&%0J:" !F!NOON']
!!z U&*3//%*@&!Q'X& +A $9  '> / N !LMMNs   =CC!c                     / nU(       a  [        U 5      n [        5       nUR                  U 5       H>  u  pEpgU(       a  UR                  U5        Uc  M#  UR                  [	        XVU5      5        M@     U$ )a  Takes a format string, turns it into a list of alternating string
literals and :class:`BaseFormatField` tokens. By default, also
infers anonymous positional references into explicit, numbered
positional references. To disable this behavior set *resolve_pos*
to ``False``.
)r	   r   r   r   r
   )r   resolve_posr   rD   r   r   r   r   s           r   r   r      se     C+D1I#,??4#8EJJsO=

?567 $9 Jr   c                   P    \ rS rSrSrSS jrS rS rS r\	S 5       r
S	 rS
 rSrg)r
      a|  A class representing a reference to an argument inside of a
bracket-style format string. For instance, in ``"{greeting},
world!"``, there is a field named "greeting".

These fields can have many options applied to them. See the
Python docs on `Format String Syntax`_ for the full details.

.. _Format String Syntax: https://docs.python.org/2/library/string.html#string-formatting
Nc                 j    U R                  U5        U R                  U5        U R                  U5        g r-   )	set_fname	set_fspecset_conv)selfr   r   r   s       r   __init__BaseFormatField.__init__   s&    uudr   c                     [         R                  " SU5      nUS   U l        Xl        USS U l        U R                  (       + =(       d    U R                  R                  5       U l        g)zSet the field name.r=   r   r    N)r?   r@   	base_namer   subpathisdigitis_positional)rR   r   	path_lists      r   rO   BaseFormatField.set_fname   sR     HHVU+	"1
 }!%/K4>>3I3I3Kr   c                    U=(       d    Sn/ n[        5       R                  U5       H  u  p4  nUc  M  UR                  U5        M     X l        Xl        USS U l        [        R                  U R
                  [        5      U l	        g)zSet the field spec.r   Nr<   )
r   r   r   	subfieldsr   r5   r/   r0   r1   	type_func)rR   r   r]   rG   rH   rI   s         r   rP   BaseFormatField.set_fspec   sq    	&/k&7&7&>"Fa#  * '? #
rs"t~~s;r   c                     Xl         SU l        g)zmThere are only two built-in converters: ``s`` and ``r``. They are
somewhat rare and appearlike ``"{ref!r}"``.N)r   	conv_func)rR   r   s     r   rQ   BaseFormatField.set_conv  s     	r   c                 X    [        U R                  U R                  U R                  5      $ )z0The current state of the field in string format.)r   r   r   r   rR   s    r   r   BaseFormatField.fstr  s     *$**djj$))LLr   c                 |   U R                   R                  nU R                  /nU R                  b(  UR	                  U R
                  U R                  /5        O+U R
                  S:w  a  UR                  U R
                  5        SR                  U Vs/ s H  n[        U5      PM     sn5      nU< SU< S3$ s  snf )Nr   z, ())		__class____name__r   r   extendr   r   joinrepr)rR   cnargsa	args_reprs        r   __repr__BaseFormatField.__repr__  s    ^^$$

|99 KKTYY/0ZZ2KK

#II51tAw56	y)) 6s   B9c                     U R                   $ r-   )r   rd   s    r   __str__BaseFormatField.__str__  s    yyr   )
rV   r   ra   r   r   rY   r]   rW   r5   r^   )r   N)rj   
__module____qualname____firstlineno____doc__rS   rO   rP   rQ   propertyr   rr   ru   __static_attributes__r   r   r   r
   r
      s<    
L
< M M*r   r
   c                   L    \ rS rSrSrSS jrS rS rS rS r	S r
S	 rS
 rSrg)r   i!  ai  :class:`DeferredValue` is a wrapper type, used to defer computing
values which would otherwise be expensive to stringify and
format. This is most valuable in areas like logging, where one
would not want to waste time formatting a value for a log message
which will subsequently be filtered because the message's log
level was DEBUG and the logger was set to only emit CRITICAL
messages.

The :class:``DeferredValue`` is initialized with a callable that
takes no arguments and returns the value, which can be of any
type. By default DeferredValue only calls that callable once, and
future references will get a cached value. This behavior can be
disabled by setting *cache_value* to ``False``.

Args:

    func (function): A callable that takes no arguments and
        computes the value being represented.
    cache_value (bool): Whether subsequent usages will call *func*
        again. Defaults to ``True``.

>>> import sys
>>> dv = DeferredValue(lambda: len(sys._current_frames()))
>>> output = "works great in all {0} threads!".format(dv)

PROTIP: To keep lines shorter, use: ``from formatutils import
DeferredValue as DV``
c                 2    Xl         X l        [        U l        g r-   )funccache_value_UNSET_value)rR   r   r   s      r   rS   DeferredValue.__init__>  s    	&r   c                     U R                   [        La  U R                  (       a  U R                   nU$ U R                  5       nU R                  (       a  Xl         U$ )zComputes, optionally caches, and returns the value of the
*func*. If ``get_value()`` has been called before, a cached
value may be returned depending on the *cache_value* option
passed to the constructor.
)r   r   r   r   )rR   values     r   	get_valueDeferredValue.get_valueC  sH     ;;f$)9)9KKE
  IIKE#r   c                 4    [        U R                  5       5      $ r-   )r2   r   rd   s    r   __int__DeferredValue.__int__Q      4>>#$$r   c                 4    [        U R                  5       5      $ r-   )floatr   rd   s    r   	__float__DeferredValue.__float__T  s    T^^%&&r   c                 4    [        U R                  5       5      $ r-   )r1   r   rd   s    r   ru   DeferredValue.__str__W  r   r   c                 4    [        U R                  5       5      $ r-   )unicoder   rd   s    r   __unicode__DeferredValue.__unicode__Z  s    t~~'((r   c                 4    [        U R                  5       5      $ r-   )rm   r   rd   s    r   rr   DeferredValue.__repr__]  s    DNN$%%r   c                     U R                  5       nUSS  n[        R                  U[        5      n UR	                  U5      $ ! [
        [        4 a    U" U5      R	                  U5      s $ f = f)Nr<   )r   r/   r0   r1   
__format__r3   	TypeError)rR   fmtr   pt	type_convs        r   r   DeferredValue.__format__`  si     XMM"c*		4##C((I& 	4U#..s33	4s   A 'A,+A,)r   r   r   NT)rj   rw   rx   ry   rz   rS   r   r   r   ru   r   rr   r   r|   r   r   r   r   r   !  s/    8
%'%)&
4r   r   r   )rz   
__future__r   r?   stringr   r   	NameErrorr1   __all__compiler!   r   r   r	   	_INTCHARS_FLOATCHARSdictr2   r   r/   r   r   objectr
   r   r   )xs   0r   <module>r      s   B!J & 	 
 zz ) *
" 4 	I.Iqc(I.&12ke*k23 4		#,^(<f <~ 
I4F I4i  GT /2s   B B!B&
BB