U
    \ShK                     @  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	 dddhdd	hd
dddhgZ
ddddddZddddddZddddddZd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-2025 by the Babel Team.
    :license: BSD, see LICENSE for more details.
    )annotations)Callable)PYTHON_FORMATCatalogMessageTranslationErroriduxXfFgGzCatalog | Noner   None)catalogmessagereturnc                 C  sd   |j st|jtstddS | dkr*dS |j}t|ttfsD|f}t|| jkr`td| j dS )z0Verify the number of plurals in the translation.z/Found plural forms for non-pluralizable messageNz*Wrong number of plural forms (expected %d))	Zpluralizable
isinstancestringstrr   listtuplelennum_plurals)r   r   msgstrs r   J/root/rtd-docs/venv/lib/python3.8/site-packages/babel/messages/checkers.pyr      s    r   c                 C  sh   d|j krdS |j}t|ttfs(|f}|j}t|ttfsB|f}t||D ]\}}|rLt|| qLdS )z9Verify the format string placeholders in the translation.zpython-formatN)flagsidr   r   r   r   zip_validate_format)r   r   Zmsgidsr   msgidZmsgstrr   r   r   python_format.   s    
r$   r   )formatalternativer   c              	   C  sH  ddddd}dddddd	}ddd
dd}t || |f\}}|sLdS t |||f\}}|rt|st|sttdn||krtd|rt|t|krtdtt||D ]4\}	\\}
}\}
}|||std|	d ||f qn^t|}|D ]P\}}||krtd|q|||| std|d|d|| dqd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   zlist[tuple[str, str]])r   r   c                 S  sJ   g }t | D ]6}| \}}}|dkr2|d kr2q||t|f q|S )N%)r   finditergroupsappendr   )r   resultmatchnamer%   typecharr   r   r   _parse[   s    z _validate_format.<locals>._parsebool)abr   c                 S  s0   | |krdS t D ]}| |kr||kr dS qdS )NTF)_string_format_compatibilities)r1   r2   setr   r   r   _compatibled   s    z%_validate_format.<locals>._compatible)resultsr   c                 S  s@   d }| D ].\}}|d kr"|d k}q|d k|krt dqt|S )Nz5format string mixes positional and named placeholders)r   r0   )r6   
positionalr-   _charr   r   r   _check_positionall   s    

z+_validate_format.<locals>._check_positionalNz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)mapr   r   	enumerater!   dict)r%   r&   r/   r5   r9   r1   r2   Za_positionalZb_positionalidx_firstsecondZtype_mapr-   r.   r   r   r   r"   >   s6    	
"


r"   z1list[Callable[[Catalog | None, Message], object]])r   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   ).0r-   loadr   r   r   	<genexpr>   s     z!_find_checkers.<locals>.<genexpr>zbabel.checkers)Zbabel.messages._compatrB   extendr   r   r$   )rB   checkersr   r   r   _find_checkers   s    rH   rG   N)__doc__
__future__r   collections.abcr   Zbabel.messages.catalogr   r   r   r   r3   r   r$   r"   rH   rG   __annotations__r   r   r   r   <module>   s   
_