
    1yiA                        U d Z ddlmZ ddlmZ ddlmZmZmZm	Z	 h dddhh dgZ
dd	Zdd
ZddZddZ e       Zded<   y)z
babel.messages.checkers
~~~~~~~~~~~~~~~~~~~~~~~

Various routines that help with validation of translations.

:since: version 0.9

:copyright: (c) 2013-2026 by the Babel Team.
:license: BSD, see LICENSE for more details.
    )annotations)Callable)PYTHON_FORMATCatalogMessageTranslationError>   diuxX>   FGfgc                   |j                   s&t        |j                  t              st	        d      y| y|j                  }t        |t
        t        f      s|f}t        |      | j                  k7  rt	        d| j                   d      y)z0Verify the number of plurals in the translation.z/Found plural forms for non-pluralizable messageNz'Wrong number of plural forms (expected ))	pluralizable
isinstancestringstrr   listtuplelennum_plurals)catalogmessagemsgstrss      Y/var/www/html/content_weaver/venv/lib/python3.12/site-packages/babel/messages/checkers.pyr   r      s    '..#."#TUU 
nnGge}-*
7|w***5g6I6I5J!L
 	
 +    c                6   d|j                   vry|j                  }t        |t        t        f      s|f}|j
                  }t        |t        t        f      s|f}|d   rt        |d   |d          |j                  r|dd D ]  }|st        |d   |        yy)z9Verify the format string placeholders in the translation.zpython-formatNr      )flagsidr   r   r   r   _validate_formatr   )r   r   msgidsr   msgstrs        r   python_formatr(   /   s    gmm+ZZFftUm,nnGge}-*qzGAJ/abk 	4F F3	4 r    c           
        dd}dd}dd} ||       } ||      }|sy ||      } ||      }|r|s|st        d      ||k7  rt        d      |rkt        |      t        |      k7  rt        d      t        t        ||            D ]0  \  }	\  \  }
}\  }
} |||      rt        d|	d	z   d
d|d|d       yt	        |      }|D ];  \  }}||vrt        d|       ||||         r%t        d|d|d||   d       y)a(  Test format string `alternative` against `format`.  `format` can be the
    msgid of a message and `alternative` one of the `msgstr`\s.  The two
    arguments are not interchangeable as `alternative` may contain less
    placeholders if `format` uses named placeholders.

    If the string formatting of `alternative` is compatible to `format` the
    function returns `None`, otherwise a `TranslationError` is raised.

    Examples for compatible format strings:

    >>> _validate_format('Hello %s!', 'Hallo %s!')
    >>> _validate_format('Hello %i!', 'Hallo %d!')

    Example for an incompatible format strings:

    >>> _validate_format('Hello %(name)s!', 'Hallo %s!')
    Traceback (most recent call last):
      ...
    TranslationError: the format strings are of different kinds

    This function is used by the `python_format` checker.

    :param format: The original format string
    :param alternative: The alternative format string that should be checked
                        against format
    :raises TranslationError: on formatting errors
    c                    g }t        j                  |       D ]:  }|j                         \  }}}|dk(  r||j                  |t	        |      f       < |S )N%)r   finditergroupsappendr   )r   resultmatchnameformattypechars         r   _parsez _validate_format.<locals>._parse_   s]    (*"++F3 	1E%*\\^"D&(34<MM4X/0		1
 r    c                <    | |k(  ryt         D ]  }| |v s||v s y y)NTF)_string_format_compatibilities)absets      r   _compatiblez%_validate_format.<locals>._compatibleh   s0    61 	CCxAH	 r    c                b    d }| D ]  \  }}||d u }|d u |k7  st        d       t        |      S )Nz5format string mixes positional and named placeholders)r   bool)results
positionalr1   _chars       r   _check_positionalz+_validate_format.<locals>._check_positionalp   sR    
" 	KD%!!T\
DLZ/*O 	 Jr    Nzplaceholders are incompatiblez)the format strings are of different kindsz-positional format placeholders are unbalancedz$incompatible format for placeholder r"   r	   z: z and z are not compatiblezunknown named placeholder )r   r   returnlist[tuple[str, str]])r7   r   r8   r   rA   r<   )r=   rB   rA   r<   )r   r   	enumeratezipdict)r2   alternativer4   r:   r@   r7   r8   a_positionalb_positionalidx_firstsecondtype_mapr1   r3   s                   r   r%   r%   B   sf   :
  	vA{A %Q'L$Q'LL>??		%JKK q6SV"#RSS.7Aq	.B 	*C**1ekq&uf-&:371+RiuVJ.AC 	 7 	ND(8#&)CD8'LMM 8D>:&:4("l%'99LN 		r    1list[Callable[[Catalog | None, Message], object]]c                     ddl m}  g }|j                  d  | d      D               t        |      dk(  rt        t
        gS |S )Nr   )find_entrypointsc              3  0   K   | ]  \  }} |         y w)N ).0r1   loads      r   	<genexpr>z!_find_checkers.<locals>.<genexpr>   s     R|dDFRs   zbabel.checkers)babel.messages._compatrP   extendr   r   r(   )rP   checkerss     r   _find_checkersrY      sA    7BDHOOR/?@P/QRR
8} ]++Or    rX   N)r   zCatalog | Noner   r   rA   None)r2   r   rF   r   rA   rZ   )rA   rN   )__doc__
__future__r   collections.abcr   babel.messages.catalogr   r   r   r   r6   r   r(   r%   rY   rX   __annotations__rR   r    r   <module>r`      sV   
 # $ T T #J" 
(4&_D	 ?M>N
; Nr    