
    O&iH                     8   d Z ddlZddlmZ ddlmZmZ ddlmZ ddl	m
Z
 ddlmZ ddlmZ dd	lmZmZ dd
lmZ ddlmZ ddlmZmZmZmZ g dZ ej        dej                  Zd Z G d d          Z  G d de!          Z"dZ#de$fdZ% G d d          Z&dS )z
    babel.messages.catalog
    ~~~~~~~~~~~~~~~~~~~~~~

    Data structures for message catalogs.

    :copyright: (c) 2013-2022 by the Babel Team.
    :license: BSD, see LICENSE for more details.
    N)OrderedDict)datetimetime)get_close_matches)message_from_string)copy)__version__)LocaleUnknownLocaleError)format_datetime)
get_plural)distinctLOCALTZFixedOffsetTimezone_cmp)MessageCatalogTranslationErrorz
    \%
        (?:\(([\w]*)\))?
        (
            [-#0\ +]?(?:\*|[\d]+)?
            (?:\.(?:\*|[\d]+))?
            [hlL]?
        )
        ([diouxXeEfFgGcrs%])
c                    t          j        d|           }t          j        |                    d          d          }|                    d          }||d         |dd          }}|d d         |dd          }}t          |dz             }t          |          }	t          |          }
|	d	z  }||
z  }||z  }t          |          }|                    |
          }|S )Nz+^(?P<datetime>.*?)(?P<tzoffset>[+-]\d{4})?$r   z%Y-%m-%d %H:%Mtzoffsetr         1<   tzinfo)rematchr   strptimegroupintr   replace)valuer   dtr   plus_minus_sresthours_offset_smins_offset_s
plus_minushours_offsetmins_offsetnet_mins_offsets               c/home/geonatureadmin/si_en_reseau/tutos/venv/lib/python3.11/site-packages/babel/messages/catalog.py_parse_datetime_headerr.   (   s    HCUKKE		5;;z224D	E	EB {{:&&H%a[(122,d(,RaR$qrr( +,,
>**-(( '+;&:% '77 ZZxZ((I    c                       e Zd ZdZ	 	 ddZd Zd Zd Zd	 Zd
 Z	d Z
d Zd Zd Zd ZddZed             Zed             Zed             ZdS )r   z0Representation of a single message in a catalog.  Nc
                 "   || _         |s	| j        rd}|| _        t          t	          |                    | _        t          |          | _        |r"| j        r| j        	                    d           n| j        
                    d           t          t	          |                    | _        t          t	          |                    | _        t          |t                    r	|g| _        nt          |          | _        || _        |	| _        dS )a_  Create the message object.

        :param id: the message ID, or a ``(singular, plural)`` tuple for
                   pluralizable messages
        :param string: the translated message string, or a
                       ``(singular, plural)`` tuple for pluralizable messages
        :param locations: a sequence of ``(filename, lineno)`` tuples
        :param flags: a set or sequence of flags
        :param auto_comments: a sequence of automatic comments for the message
        :param user_comments: a sequence of user comments for the message
        :param previous_id: the previous message ID, or a ``(singular, plural)``
                            tuple for pluralizable messages
        :param lineno: the line number on which the msgid line was found in the
                       PO file, if any
        :param context: the message context
        )r1   r1   zpython-formatN)idpluralizablestringlistr   	locationssetflagspython_formatadddiscardauto_commentsuser_comments
isinstancestrprevious_idlinenocontext)
selfr4   r6   r8   r:   r>   r?   rB   rC   rD   s
             r-   __init__zMessage.__init__I   s    $  	 $+ 	 Fhy1122ZZ
 	0$$ 	0JNN?++++J///!(="9"9::!(="9"9::k3'' 	1 +}D#K00Dr/   c                 l    dt          |           j        d| j        dt          | j                  dS )N< z	 (flags: z)>)type__name__r4   r7   r:   rE   s    r-   __repr__zMessage.__repr__n   s;     (,T

(;(;(;TWWW(,TZ(8(8(8(8: 	:r/   c                 L    d }t           ||            ||                    S )z0Compare Messages, taking into account plural idsc                     t          | t                    r| j        r| j        d         | j        pdfS | j        | j        pdfS )Nr   r1   )r@   r   r5   r4   rD   )objs    r-   values_to_comparez*Message.__cmp__.<locals>.values_to_comparet   sJ    #w'' 4C,< 4vay#+"33363;,",,r/   )r   )rE   otherrQ   s      r-   __cmp__zMessage.__cmp__r   s;    	- 	- 	- %%d++->->u-E-EFFFr/   c                 4    |                      |          dk    S Nr   rS   rE   rR   s     r-   __gt__zMessage.__gt__z       ||E""Q&&r/   c                 4    |                      |          dk     S rU   rV   rW   s     r-   __lt__zMessage.__lt__}   rY   r/   c                 4    |                      |          dk    S rU   rV   rW   s     r-   __ge__zMessage.__ge__       ||E""a''r/   c                 4    |                      |          dk    S rU   rV   rW   s     r-   __le__zMessage.__le__   r^   r/   c                 4    |                      |          dk    S rU   rV   rW   s     r-   __eq__zMessage.__eq__   r^   r/   c                 4    |                      |          dk    S rU   rV   rW   s     r-   __ne__zMessage.__ne__   r^   r/   c                 P    t          |t                    sJ | j        |j        k    S )z[Checks whether messages are identical, taking into account all
        properties.
        )r@   r   __dict__rW   s     r-   is_identicalzMessage.is_identical   s)     %)))))}..r/   c                     t          t          t          | j        | j        | j        | j        | j        | j        | j	        | j
        | j        f	           S N)r   mapr   r4   r6   r8   r:   r>   r?   rB   rC   rD   rL   s    r-   clonezMessage.clone   sN    D47DK#':t/A#'#5t7G#';#> ? ? @ 	@r/   c                     ddl m} g }|D ];}	  |||            # t          $ r}|                    |           Y d}~4d}~ww xY w|S )a  Run various validation checks on the message.  Some validations
        are only performed if the catalog is provided.  This method returns
        a sequence of `TranslationError` objects.

        :rtype: ``iterator``
        :param catalog: A catalog instance that is passed to the checkers
        :see: `Catalog.check` for a way to perform checks for all messages
              in a catalog.
        r   )checkersN)babel.messages.checkersrm   r   append)rE   catalogrm   errorscheckeres         r-   checkzMessage.check   s     	544444 	! 	!G!&&&&# ! ! !a        !s   
A?Ac                     d| j         v S )a   Whether the translation is fuzzy.

        >>> Message('foo').fuzzy
        False
        >>> msg = Message('foo', 'foo', flags=['fuzzy'])
        >>> msg.fuzzy
        True
        >>> msg
        <Message 'foo' (flags: ['fuzzy'])>

        :type:  `bool`fuzzyr:   rL   s    r-   rv   zMessage.fuzzy   s     $*$$r/   c                 D    t          | j        t          t          f          S )zWhether the message is plurizable.

        >>> Message('foo').pluralizable
        False
        >>> Message(('foo', 'bar')).pluralizable
        True

        :type:  `bool`)r@   r4   r7   tuplerL   s    r-   r5   zMessage.pluralizable   s     $'D%=111r/   c                     | j         }t          |t          t          f          s|g}t	          d |D                       S )zWhether the message contains Python-style parameters.

        >>> Message('foo %(name)s bar').python_format
        True
        >>> Message(('foo %(name)s', 'foo %(name)s')).python_format
        True

        :type:  `bool`c              3   J   K   | ]}t                               |          V  d S ri   )PYTHON_FORMATsearch).0r4   s     r-   	<genexpr>z(Message.python_format.<locals>.<genexpr>   s0      ::=''++::::::r/   )r4   r@   r7   ry   any)rE   idss     r-   r;   zMessage.python_format   sE     g#e}-- 	%C::c::::::r/   )r1   r2   r2   r2   r2   r2   NNri   )rK   
__module____qualname____doc__rF   rM   rS   rX   r[   r]   r`   rb   rd   rg   rk   rt   propertyrv   r5   r;   r2   r/   r-   r   r   F   s6       ::MOHL# # # #J: : :G G G' ' '' ' '( ( (( ( (( ( (( ( (/ / /@ @ @   & % % X% 	2 	2 X	2 ; ; X; ; ;r/   r   c                       e Zd ZdZdS )r   z_Exception thrown by translation checkers when invalid message
    translations are encountered.N)rK   r   r   r   r2   r/   r-   r   r      s        % % % %r/   r   z# Translations template for PROJECT.
# Copyright (C) YEAR ORGANIZATION
# This file is distributed under the same license as the PROJECT project.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#r#   c                 n    ddl m}  |            }| |d<   t          |                                          S )Nr   )r   content-type)email.messager   dict
get_params)r#   r   ms      r-   parse_separated_headerr      s?    %%%%%%		AAnr/   c                   p   e Zd ZdZddeddddddddddfdZd Zd Zd Z e	ee          Z
 e	e          Zd Zd	 Z e	eed
          Zd Zd%dZd Z e	eed          Ze	d             Ze	d             Ze	d             Zd Zd Zd Zd Zd Zd Zd Z	 	 d&dZd Zd'dZd'd Z d(d"Z!d'd#Z"d$ Z#dS ))r   z$Representation of a message catalog.NTc                 b   || _         || _        || _        t                      | _        |pd| _        |pd| _        |pd| _        |pd| _        |
pd| _	        	 |pd| _
        	 |pd| _        |t          j        t                    }n7t          |t                    r"|j        s|                    t          	          }|| _        |	d
}	n7t          |	t                    r"|	j        s|	                    t          	          }	|	| _        || _        t                      | _        d| _        d| _        dS )aD  Initialize the catalog object.

        :param locale: the locale identifier or `Locale` object, or `None`
                       if the catalog is not bound to a locale (which basically
                       means it's a template)
        :param domain: the message domain
        :param header_comment: the header comment as string, or `None` for the
                               default header
        :param project: the project's name
        :param version: the project's version
        :param copyright_holder: the copyright holder of the catalog
        :param msgid_bugs_address: the email address or URL to submit bug
                                   reports to
        :param creation_date: the date the catalog was created
        :param revision_date: the date the catalog was revised
        :param last_translator: the name and email of the last translator
        :param language_team: the name and email of the language team
        :param charset: the encoding to use in the output (defaults to utf-8)
        :param fuzzy: the fuzzy bit on the catalog header
        PROJECTVERSIONORGANIZATIONzEMAIL@ADDRESSzFULL NAME <EMAIL@ADDRESS>zLANGUAGE <LL@li.org>utf-8Nr   zYEAR-MO-DA HO:MI+ZONE)domainlocale_header_commentr   	_messagesprojectversioncopyright_holdermsgid_bugs_addresslast_translatorlanguage_teamcharsetr   nowr   r@   r   r"   creation_daterevision_daterv   obsolete_num_plurals_plural_expr)rE   r   r   header_commentr   r   r   r   r   r   r   r   r   rv   s                 r-   rF   zCatalog.__init__   sI   2 -$+)+) 0 BN"4"G.M2M<*D.D:)' $L11MMx00 	B9M 	B)111AAM* 3MMx00 	B9M 	B)111AAM*
#  r/   c                 h   |d | _         d | _        d S t          |t                    rt	          |          | _         || _        d S t          |t                    rHt	          |          | _         	 t          j        |          | _        n# t          $ r
 d | _        Y nw xY wd S t          d|z            )NzF`locale` must be a Locale, a locale identifier string, or None; got %r)_locale_identifier_localer@   r
   rA   parser   	TypeErrorrE   r   s     r-   _set_localezCatalog._set_locale(  s    >&*D#DLFff%% 	&)&kkD#!DLFfc"" 	&)&kkD#$%|F33% $ $ $#$F`ciijjjs   /B	 	BBc                     | j         S ri   )r   rL   s    r-   _get_localezCatalog._get_locale=  s
    |r/   c                     | j         S ri   )r   rL   s    r-   _get_locale_identifierzCatalog._get_locale_identifier@  s    &&r/   c                    | j         }t          j        t                                        d          }t          | j        d          r| j                            d          }|                    d| j                                      d| j	                                      d|                              d| j
                  }| j        r| j        j        n| j        }|r|                    dd|z            }|S )	Nz%Ystrftimer   r   YEARr   zTranslations templatez%s translations)r   r   r   r   r   hasattrr   r"   r   r   r   r   english_namelocale_identifier)rE   commentyearlocale_names       r-   _get_header_commentzCatalog._get_header_commentF  s    &|G$$--d334%z22 	5%..t44D//)T\::!')T\::!'&$//!'.$2GHH 	 48;Zt{//DDZ 	`oo&=?PS^?^__Gr/   c                     || _         d S ri   )r   )rE   r6   s     r-   _set_header_commentzCatalog._set_header_commentT  s    %r/   a      The header comment for the catalog.

    >>> catalog = Catalog(project='Foobar', version='1.0',
    ...                   copyright_holder='Foo Company')
    >>> print(catalog.header_comment) #doctest: +ELLIPSIS
    # Translations template for Foobar.
    # Copyright (C) ... Foo Company
    # This file is distributed under the same license as the Foobar project.
    # FIRST AUTHOR <EMAIL@ADDRESS>, ....
    #

    The header can also be set from a string. Any known upper-case variables
    will be replaced when the header is retrieved again:

    >>> catalog = Catalog(project='Foobar', version='1.0',
    ...                   copyright_holder='Foo Company')
    >>> catalog.header_comment = '''\
    ... # The POT for my really cool PROJECT project.
    ... # Copyright (C) 1990-2003 ORGANIZATION
    ... # This file is distributed under the same license as the PROJECT
    ... # project.
    ... #'''
    >>> print(catalog.header_comment)
    # The POT for my really cool Foobar project.
    # Copyright (C) 1990-2003 Foo Company
    # This file is distributed under the same license as the Foobar
    # project.
    #

    :type: `unicode`
    )docc           	      ^   g }|                     d| j        d| j        f           |                     d| j        f           |                     dt	          | j        dd          f           t          | j        t          t          t          t          f          r-|                     dt	          | j        dd          f           n|                     d| j        f           |                     d	| j        f           | j        r)|                     d
t          | j                  f           | j        rLd| j        v rC|                     d| j                            dt          | j                            f           n|                     d| j        f           | j        |                     d| j        f           |                     d           |                     dd| j        z  f           |                     d           |                     ddt(          z  f           |S )NzProject-Id-VersionrI   zReport-Msgid-Bugs-TozPOT-Creation-Datezyyyy-MM-dd HH:mmZen)r   zPO-Revision-DatezLast-TranslatorLanguageLANGUAGEzLanguage-TeamzPlural-Forms)zMIME-Versionz1.0zContent-Typeztext/plain; charset=%s)zContent-Transfer-Encoding8bitzGenerated-Byz	Babel %s
)ro   r   r   r   r   r   r@   r   r   time_r!   floatr   r   rA   r   r"   r   plural_formsr   r   )rE   headerss     r-   _get_mime_headerszCatalog._get_mime_headersx  sw   ,#'<<<>@ 	A 	A 	A.0GHIII+'(:<O/35 5 56 	7 	7 	7 d(8UC*GHH 	ENN.+D,>,?N N NO P P P P NN.0BCDDD)4+?@AAA! 	FNNJD,B(C(CDEEE! 	BzT5G'G'GNNO .66z7:4;Q7R7RT TU V V V V NNOT-?@AAA;"NNND,=>???.///04<?A 	B 	B 	B<===w(>?@@@r/   r   strictc                     t          |t                    r|S t          |t                    r|                    ||          S t          |          S ri   )r@   rA   bytesdecode)rE   sencodingrq   s       r-   _force_textzCatalog._force_text  sJ    a 	Ha 	.88Hf---1vvr/   c                    |D ]\  }}|                      |                                | j                  }|                      || j                  }|dk    rE|                    d          }d                    |d d                   | _        |d         | _        |dk    r|| _        |dk    r|| _        |dk    r,|	                    dd	          }| 
                    |           |d
k    r|| _        |dk    r4t          |          }d|v r|d                                         | _        1|dk    rWt          d|z             }t          |                    dd                    | _        |                    dd          | _        |dk    rt#          |          | _        |dk    rd|vrt#          |          | _        d S )N)r   zproject-id-versionrI   zreport-msgid-bugs-tozlast-translatorlanguage-_zlanguage-teamr   r   zplural-formsz ;npluralsr   plural(n != 1)zpot-creation-datezpo-revision-dater   )r   lowerr   splitjoinr   r   r   r   r"   r   r   r   r!   getr   r   r.   r   r   )rE   r   namer#   partsparamss         r-   _set_mime_headerszCatalog._set_mime_headers  s   " 	G 	GKD%##DJJLL4<#HHD$$UT\$BBE+++C((#yyss44$Ry///*/''***',$$##c3//  ''''((%*""''/66&&#))#4#:#:#<#<DL''/u==$'

:q(A(A$B$B!$*JJx$D$D!!,,,%;E%B%B""+++&&)?)F)FD&;	G 	Gr/   a      The MIME headers of the catalog, used for the special ``msgid ""`` entry.

    The behavior of this property changes slightly depending on whether a locale
    is set or not, the latter indicating that the catalog is actually a template
    for actual translations.

    Here's an example of the output for such a catalog template:

    >>> from babel.dates import UTC
    >>> created = datetime(1990, 4, 1, 15, 30, tzinfo=UTC)
    >>> catalog = Catalog(project='Foobar', version='1.0',
    ...                   creation_date=created)
    >>> for name, value in catalog.mime_headers:
    ...     print('%s: %s' % (name, value))
    Project-Id-Version: Foobar 1.0
    Report-Msgid-Bugs-To: EMAIL@ADDRESS
    POT-Creation-Date: 1990-04-01 15:30+0000
    PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE
    Last-Translator: FULL NAME <EMAIL@ADDRESS>
    Language-Team: LANGUAGE <LL@li.org>
    MIME-Version: 1.0
    Content-Type: text/plain; charset=utf-8
    Content-Transfer-Encoding: 8bit
    Generated-By: Babel ...

    And here's an example of the output when the locale is set:

    >>> revised = datetime(1990, 8, 3, 12, 0, tzinfo=UTC)
    >>> catalog = Catalog(locale='de_DE', project='Foobar', version='1.0',
    ...                   creation_date=created, revision_date=revised,
    ...                   last_translator='John Doe <jd@example.com>',
    ...                   language_team='de_DE <de@example.com>')
    >>> for name, value in catalog.mime_headers:
    ...     print('%s: %s' % (name, value))
    Project-Id-Version: Foobar 1.0
    Report-Msgid-Bugs-To: EMAIL@ADDRESS
    POT-Creation-Date: 1990-04-01 15:30+0000
    PO-Revision-Date: 1990-08-03 12:00+0000
    Last-Translator: John Doe <jd@example.com>
    Language: de_DE
    Language-Team: de_DE <de@example.com>
    Plural-Forms: nplurals=2; plural=(n != 1);
    MIME-Version: 1.0
    Content-Type: text/plain; charset=utf-8
    Content-Transfer-Encoding: 8bit
    Generated-By: Babel ...

    :type: `list`
    c                 r    | j         *d}| j        rt          | j                  d         }|| _         | j         S )zThe number of plurals used by the catalog or locale.

        >>> Catalog(locale='en').num_plurals
        2
        >>> Catalog(locale='ga').num_plurals
        5

        :type: `int`Nr   r   )r   r   r   )rE   nums     r-   num_pluralszCatalog.num_plurals  sA     $C{ 1 --a0 #D  r/   c                 r    | j         *d}| j        rt          | j                  d         }|| _         | j         S )aW  The plural expression used by the catalog or locale.

        >>> Catalog(locale='en').plural_expr
        '(n != 1)'
        >>> Catalog(locale='ga').plural_expr
        '(n==1 ? 0 : n==2 ? 1 : n>=3 && n<=6 ? 2 : n>=7 && n<=10 ? 3 : 4)'
        >>> Catalog(locale='ding').plural_expr  # unknown locale
        '(n != 1)'

        :type: `str`Nr   r   )r   r   r   )rE   exprs     r-   plural_exprzCatalog.plural_expr  sA     $D{ 2!$+..q1 $D  r/   c                 (    d| j         d| j        dS )zReturn the plural forms declaration for the locale.

        >>> Catalog(locale='en').plural_forms
        'nplurals=2; plural=(n != 1);'
        >>> Catalog(locale='pt_BR').plural_forms
        'nplurals=2; plural=(n > 1);'

        :type: `str`z	nplurals=z	; plural=;)r   r   rL   s    r-   r   zCatalog.plural_forms  s#      -1,<,<,<d>N>N>NOOr/   c                 :    |                      |          | j        v S )z?Return whether the catalog has a message with the specified ID._key_forr   rE   r4   s     r-   __contains__zCatalog.__contains__"  s    }}R  DN22r/   c                 *    t          | j                  S )zeThe number of messages in the catalog.

        This does not include the special ``msgid ""`` entry.)lenr   rL   s    r-   __len__zCatalog.__len__&  s     4>"""r/   c              #     K   g }| j         D ]\  }}|                    |d|            t                      }| j        r|dhz  }t	          dd                    |          |          V  | j        D ]}| j        |         V  dS )zIterates through all the entries in the catalog, in the order they
        were added, yielding a `Message` object for every entry.

        :rtype: ``iterator``z: rv   r1   
rw   N)mime_headersro   r9   rv   r   r   r   )rE   bufr   r#   r:   keys         r-   __iter__zCatalog.__iter__,  s      
 , 	1 	1KD%JJ444/0000: 	gYEc499S>>777777> 	& 	&C.%%%%%	& 	&r/   c                 l    d}| j         r
d| j         z  }dt          |           j        d| j        |dS )Nr1   z %srH   rI   >)r   rJ   rK   r   r   s     r-   rM   zCatalog.__repr__;  sB    ; 	)T[(F"4jj1114;;GGr/   c                 0    |                      |           dS )z)Delete the message with the specified ID.N)deleter   s     r-   __delitem__zCatalog.__delitem__A  s    Br/   c                 ,    |                      |          S )zUReturn the message with the specified ID.

        :param id: the message ID
        )r   r   s     r-   __getitem__zCatalog.__getitem__E  s    
 xx||r/   c                    t          |t                    s
J d            |                     ||j                  }| j                            |          }|r|j        r|j        s|j        |_        |j        |_        t          t          |j        |j        z                       |_        t          t          |j        |j        z                       |_        t          t          |j        |j        z                       |_        |xj        |j        z  c_        |}dS |dk    rbt          |j                                                  | _        d                    d |j        D                       | _        |j        | _        dS t          |t          t*          f          r@t          |j        t          t*          f          sJ dt-          |j                  z              || j        |<   dS )a  Add or update the message with the specified ID.

        >>> catalog = Catalog()
        >>> catalog[u'foo'] = Message(u'foo')
        >>> catalog[u'foo']
        <Message u'foo' (flags: [])>

        If a message with that ID is already in the catalog, it is updated
        to include the locations and flags of the new message.

        >>> catalog = Catalog()
        >>> catalog[u'foo'] = Message(u'foo', locations=[('main.py', 1)])
        >>> catalog[u'foo'].locations
        [('main.py', 1)]
        >>> catalog[u'foo'] = Message(u'foo', locations=[('utils.py', 5)])
        >>> catalog[u'foo'].locations
        [('main.py', 1), ('utils.py', 5)]

        :param id: the message ID
        :param message: the `Message` object
        zexpected a Message objectr1   r   c                 <    g | ]}d |z                                   S )z# %s)rstrip)r~   cs     r-   
<listcomp>z'Catalog.__setitem__.<locals>.<listcomp>u  s:     -G -G -Gqfqj-@-@-B-B -G -G -Gr/   zExpected sequence but got %sN)r@   r   r   rD   r   r   r5   r4   r6   r7   r   r8   r>   r?   r:   r   itemsr   r   r   rv   ry   rJ   )rE   r4   messager   currents        r-   __setitem__zCatalog.__setitem__L  s   , '7++HH-HHHHmmB00.$$S)) 	*# 0G,@ 0$Z
!( $Xg.?.5.?/@ &A &A !B !BG$('2G292G3H *I *I %J %JG!$('2G292G3H *I *I %J %JG!MMW]*MMGGG2XX 3GN C C I I K KD"&)) -G -G070E-G -G -G #H #HD DJJJ"tUm,, J!'.4-@@ J J2T'.5I5IIJ J J")DN3r/   r2   c
                 Z    t          ||t          |          ||||||		  	        }
|
| |<   |
S )at  Add or update the message with the specified ID.

        >>> catalog = Catalog()
        >>> catalog.add(u'foo')
        <Message ...>
        >>> catalog[u'foo']
        <Message u'foo' (flags: [])>

        This method simply constructs a `Message` object with the given
        arguments and invokes `__setitem__` with that object.

        :param id: the message ID, or a ``(singular, plural)`` tuple for
                   pluralizable messages
        :param string: the translated message string, or a
                       ``(singular, plural)`` tuple for pluralizable messages
        :param locations: a sequence of ``(filename, lineno)`` tuples
        :param flags: a set or sequence of flags
        :param auto_comments: a sequence of automatic comments
        :param user_comments: a sequence of user comments
        :param previous_id: the previous message ID, or a ``(singular, plural)``
                            tuple for pluralizable messages
        :param lineno: the line number on which the msgid line was found in the
                       PO file, if any
        :param context: the message context
        )rC   rD   )r   r7   )rE   r4   r6   r8   r:   r>   r?   rB   rC   rD   r  s              r-   r<   zCatalog.add~  sB    6 "fd9ooum'V")+ + + Rr/   c              #   ~   K   | j                                         D ] }|                    |           }|r||fV  !dS )aB  Run various validation checks on the translations in the catalog.

        For every message which fails validation, this method yield a
        ``(message, errors)`` tuple, where ``message`` is the `Message` object
        and ``errors`` is a sequence of `TranslationError` objects.

        :rtype: ``iterator``
        )rp   N)r   valuesrt   )rE   r  rq   s      r-   rt   zCatalog.check  s[       ~,,.. 	& 	&G]]4]00F &vo%%%	& 	&r/   c                 ^    | j                             |                     ||                    S )zReturn the message with the specified ID and context.

        :param id: the message ID
        :param context: the message context, or ``None`` for no context
        )r   r   r   )rE   r4   rD   s      r-   r   zCatalog.get  s(     ~!!$--G"<"<===r/   c                 X    |                      ||          }|| j        v r
| j        |= dS dS )zDelete the message with the specified ID and context.

        :param id: the message ID
        :param context: the message context, or ``None`` for no context
        Nr   rE   r4   rD   r   s       r-   r   zCatalog.delete  s<     mmB(($.  s### ! r/   Fc                      j                                         t                       _         g }|s fdD             }t                       fd}|D ]}|j        rˉ                     |j        |j                  }|v r ||||           ;|st          |t                    r	|d         }	n|}	t          |	
                                                                |                                d          }
|
r$|
d         }||         }|||f} ||||           | |j        <   ՉD ]}|s|vr|          j        |<   |r|j         _        |j         _        dS )a  Update the catalog based on the given template catalog.

        >>> from babel.messages import Catalog
        >>> template = Catalog()
        >>> template.add('green', locations=[('main.py', 99)])
        <Message ...>
        >>> template.add('blue', locations=[('main.py', 100)])
        <Message ...>
        >>> template.add(('salad', 'salads'), locations=[('util.py', 42)])
        <Message ...>
        >>> catalog = Catalog(locale='de_DE')
        >>> catalog.add('blue', u'blau', locations=[('main.py', 98)])
        <Message ...>
        >>> catalog.add('head', u'Kopf', locations=[('util.py', 33)])
        <Message ...>
        >>> catalog.add(('salad', 'salads'), (u'Salat', u'Salate'),
        ...             locations=[('util.py', 38)])
        <Message ...>

        >>> catalog.update(template)
        >>> len(catalog)
        3

        >>> msg1 = catalog['green']
        >>> msg1.string
        >>> msg1.locations
        [('main.py', 99)]

        >>> msg2 = catalog['blue']
        >>> msg2.string
        u'blau'
        >>> msg2.locations
        [('main.py', 100)]

        >>> msg3 = catalog['salad']
        >>> msg3.string
        (u'Salat', u'Salate')
        >>> msg3.locations
        [('util.py', 42)]

        Messages that are in the catalog but not in the template are removed
        from the main collection, but can still be accessed via the `obsolete`
        member:

        >>> 'head' in catalog
        False
        >>> list(catalog.obsolete.values())
        [<Message 'head' (flags: [])>]

        :param template: the reference catalog, usually read from a POT file
        :param no_fuzzy_matching: whether to use fuzzy matching of message IDs
        c                 p    i | ]2}||         j                             |          |         j        3S r2   )r6   r   rD   )r~   msgidmessagesrE   s     r-   
<dictcomp>z"Catalog.update.<locals>.<dictcomp>  sR           3;E?3I e$$huo&=     r/   c                    |                                  } d}||k    rnd}                    |                               |          }t          |j        t
                    r|j        g| _        n0t          |j                  | _        n                    |d           }|j	        | _	        r&t          t          |j                            | _        t          | j        t          t          f          rt          | j	        t          t          f          s9d}t          | j	        gdgt          | j                  dz
  z  z             | _	        nt          | j	                  	j        k    r5d}t          | j	        d t          |j	                                     | _	        n5t          | j	        t          t          f          rd}| j	        d         | _	        | xj        |j        z  c_        |r| xj        dhz  c_        | 	| j        <   d S )NFTr1   r   r   rv   )rk   r<   r   r@   r4   rA   rB   r7   popr6   r   r?   ry   r   r   r:   )
r  oldkeynewkeyrv   oldmsgfuzzy_matcheskeep_user_commentsr  	remainingrE   s
        r-   _mergezCatalog.update.<locals>._merge  s   mmooGE!!&)))!f--fi-- :+19+G''*.vy//G''"vt44#]GN! M(,Xf6J-K-K(L(L%'*tUm44 3!'.4-@@ P E%* (SES__q5H,IJ& &GNN ((D,<<< E%*7>:M3v};M;M:M+N%O%OGNGNT5M:: 3!(!2MMV\)MM ,(+&Dr/   r   r   N)r   r   r   r9   r4   r   rD   r@   ry   r   r   stripkeysr   r   r   )rE   templateno_fuzzy_matchingupdate_header_commentr  fuzzy_candidatesr  r  r   matchkeymatchesr  newctxtr  r  r  r  s   `   `         @@@r-   updatezCatalog.update  s   j >MMOO	$   	         %      !	' !	' !	' !	' !	' !	' !	' !	' !	'F   	/ 	/Gz /mmGJ@@(??F7C----, %%c511 +'*1vHH'*H"3HNN4D4D4J4J4L4L4D4I4I4K4KQ#P #P" %%,QZF&6v&>G&2)/"F7FC888$'.D$ 	8 	8E  8E$>$>'0'7e$  	: #+"9D &3r/   c                 ^    |}t          |t          t          f          r|d         }|||f}|S )zThe key for a message is just the singular ID even for pluralizable
        messages, but is a ``(msgid, msgctxt)`` tuple for context-specific
        messages.
        r   )r@   r7   ry   r
  s       r-   r   zCatalog._key_forI  s<    
 cD%=)) 	Q%C.C
r/   c                 |   t          |t                    sJ | j                                        |j                                        z  D ]H}|                     |          }|                    |          }|||                    |          s dS It          | j                  t          |j                  k    S )z\Checks if catalogs are identical, taking into account messages and
        headers.
        NF)r@   r   r   r  r   rg   r   r   )rE   rR   r   	message_1	message_2s        r-   rg   zCatalog.is_identicalU  s     %)))))>&&((5?+?+?+A+AA 	 	CI		#I!$ --i88 % uu % D%&&$u/A*B*BBBr/   )r   r   )Nr2   r2   r2   r2   r2   NNri   )FFT)$rK   r   r   r   DEFAULT_HEADERrF   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rM   r   r   r  r<   rt   r   r   r"  r   rg   r2   r/   r-   r   r      s       .."4td$(#TT	8! 8! 8! 8!tk k k*  ' ' ' Xk;//F !788  & & & X13F M 	 	 	NB  @   G G G@ 8-/@ 1G 1	 1	 1	Lf ! ! X!  ! ! X!$ 	P 	P X	P3 3 3# # #& & &H H H    0* 0* 0*d JLCG   B& & &> > > >$ $ $ $H4 H4 H4 H4T
 
 
 
C C C C Cr/   r   )'r   r   collectionsr   r   r   r   difflibr   emailr   r   babelr	   r   
babel.corer
   r   babel.datesr   babel.messages.pluralsr   
babel.utilr   r   r   r   __all__compileVERBOSEr|   r.   r   	Exceptionr   r'  rA   r   r   r2   r/   r-   <module>r4     s    
			 # # # # # # , , , , , , , , % % % % % % % % % % % %       ( ( ( ( ( ( 1 1 1 1 1 1 1 1 ' ' ' ' ' ' - - - - - - C C C C C C C C C C C C
4
4
4 
 	 Z	 	  <N; N; N; N; N; N; N; N;b% % % % %y % % %
 #        x	C x	C x	C x	C x	C x	C x	C x	C x	C x	Cr/   