
    XhK                        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-2025 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                  z        y)z0Verify the number of plurals in the translation.z/Found plural forms for non-pluralizable messageNz*Wrong number of plural forms (expected %d))	pluralizable
isinstancestringstrr   listtuplelennum_plurals)catalogmessagemsgstrss      K/var/www/html/myenv/lib/python3.12/site-packages/babel/messages/checkers.pyr   r      s    '..#." $- . . 
nnGge}-*
7|w***K&22 3 4 	4 +    c                    d|j                   vry|j                  }t        |t        t        f      s|f}|j
                  }t        |t        t        f      s|f}t        ||      D ]  \  }}|s	t        ||        y)z9Verify the format string placeholders in the translation.zpython-formatN)flagsidr   r   r   r   zip_validate_format)r   r   msgidsr   msgidmsgstrs         r   python_formatr(   .   st    gmm+ZZFftUm,nnGge}-*VW- ,vUF+,r   c           
        dd}dd}dd}t        || |f      \  }}|syt        |||f      \  }}|r|s|st        d      ||k7  rt        d      |rft        |      t        |      k7  rt        d      t        t	        ||            D ]+  \  }	\  \  }
}\  }
} |||      rt        d|	d	z   ||fz         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>._compatibled   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_positionall   sY    
" 	EKD%!!T\
DLZ/* ,D E E	E Jr   Nzplaceholders are incompatiblez)the format strings are of different kindsz-positional format placeholders are unbalancedzDincompatible format for placeholder %d: %r and %r are not compatible   zunknown named placeholder z$incompatible format for placeholder z: z and z are not compatible)r   r   returnlist[tuple[str, str]])r7   r   r8   r   rB   r<   )r=   rC   rB   r<   )mapr   r   	enumerater#   dict)r2   alternativer4   r:   r@   r7   r8   a_positionalb_positionalidx_firstsecondtype_mapr1   r3   s                   r   r$   r$   >   sk   :	  v,-DAq "%%6A!?L,L>??		%JKK q6SV" $0 1 1.7Aq	.B 	A*C**1ekq&uf-& (J(+a'?(@ A A	A 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._compatrQ   extendr   r   r(   )rQ   checkerss     r   _find_checkersrZ      sA    7BDHOOR/?@P/QRR
8} ]++Or   rY   N)r   zCatalog | Noner   r   rB   None)r2   r   rG   r   rB   r[   )rB   rO   )__doc__
__future__r   collections.abcr   babel.messages.catalogr   r   r   r   r6   r   r(   r$   rZ   rY   __annotations__rS   r   r   <module>ra      sV   
 # $ T T #J" 4(, \~ ?M>N
; Nr   