o
    NiA                     @  s   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dZdddZdddZdddZe Zded< dS ) 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gcatalogCatalog | Nonemessager   returnNonec                 C  sh   |j st|jtstddS | du rdS |j}t|ttfs"|f}t|| jkr2td| j ddS )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)r   r   msgstrs r    K/home/ubuntu/.local/lib/python3.10/site-packages/babel/messages/checkers.pyr      s   r   c                 C  s   d|j vrdS |j}t|ttfs|f}|j}t|ttfs!|f}|d r.t|d |d  |jrC|dd D ]}|rBt|d | q7dS dS )z9Verify the format string placeholders in the translation.zpython-formatNr      )flagsidr   r   r   r   _validate_formatr   )r   r   msgidsr   msgstrr    r    r!   python_format/   s"   
r(   formatr   alternativec              	   C  s8  ddd}dd
d}ddd}|| }||}|sdS ||}||}|r-|s-|s-t d||kr5t d|rmt|t|krCt dtt||D ] \}	\\}
}\}
}|||sjt d|	d dd|d|dqJdS t|}|D ]&\}}||vrt d||||| st d|d|d|| dqsdS )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
    r   r   r   list[tuple[str, str]]c                 S  sJ   g }t | D ]}| \}}}|dkr|d u rq||t|f q|S )N%)r   finditergroupsappendr   )r   resultmatchnamer)   typecharr    r    r!   _parse_   s   z _validate_format.<locals>._parseabboolc                 S  s0   | |krdS t D ]}| |v r||v r dS qdS )NTF)_string_format_compatibilities)r5   r6   setr    r    r!   _compatibleh   s   z%_validate_format.<locals>._compatibleresultsc                 S  s@   d }| D ]\}}|d u r|d u }q|d u |krt dqt|S )Nz5format string mixes positional and named placeholders)r   r7   )r;   
positionalr2   _charr    r    r!   _check_positionalp   s   
z+_validate_format.<locals>._check_positionalNz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   r   r+   )r5   r   r6   r   r   r7   )r;   r+   r   r7   )r   r   	enumeratezipdict)r)   r*   r4   r:   r>   r5   r6   a_positionalb_positionalidx_firstsecondtype_mapr2   r3   r    r    r!   r%   B   sR   

	
"

r%   1list[Callable[[Catalog | None, Message], object]]c                  C  s@   ddl m}  g }|dd | dD  t|dkrttgS |S )Nr   )find_entrypointsc                 s  s    | ]\}}| V  qd S )Nr    ).0r2   loadr    r    r!   	<genexpr>   s    z!_find_checkers.<locals>.<genexpr>zbabel.checkers)babel.messages._compatrJ   extendr   r   r(   )rJ   checkersr    r    r!   _find_checkers   s   rQ   rP   N)r   r   r   r   r   r   )r)   r   r*   r   r   r   )r   rI   )__doc__
__future__r   collections.abcr   babel.messages.catalogr   r   r   r   r8   r   r(   r%   rQ   rP   __annotations__r    r    r    r!   <module>   s    



b