o
    V\(~                     @   s0  d Z ddlZddl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 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 ddlmZmZmZm Z m!Z!m"Z" g dZ#e$dej%Z&dd Z'G dd de(Z)G dd de*Z+dZ,erdd Z-neZ-G dd de(Z.dS )z
    babel.messages.catalog
    ~~~~~~~~~~~~~~~~~~~~~~

    Data structures for message catalogs.

    :copyright: (c) 2013-2019 by the Babel Team.
    :license: BSD, see LICENSE for more details.
    N)parse_header)OrderedDict)datetimetime)get_close_matches)message_from_string)copy)__version__)LocaleUnknownLocaleError)format_datetime)
get_plural)distinctLOCALTZFixedOffsetTimezone)string_typesnumber_typesPY2cmp	text_type
force_text)MessageCatalogTranslationErrorz
    \%
        (?:\(([\w]*)\))?
        (
            [-#0\ +]?(?:\*|[\d]+)?
            (?:\.(?:\*|[\d]+))?
            [hlL]?
        )
        ([diouxXeEfFgGcrs%])
c                 C   s   t d| }t|dd}t|}t|}|d}|d ur^|d |dd  }}|d d |dd  }}	t|d }
t|}t|	}|d	 }||7 }||
9 }t	|}|j
|d
}|S )Nz+^(?P<datetime>.*?)(?P<tzoffset>[+-]\d{4})?$r   z%Y-%m-%d %H:%Mtzoffsetr         1<   tzinfo)rematchr   strptimegroupmktimer   fromtimestampintr   replace)valuer"   tttsdtr   plus_minus_sresthours_offset_smins_offset_s
plus_minushours_offsetmins_offsetnet_mins_offset r5   8/usr/lib/python3/dist-packages/babel/messages/catalog.py_parse_datetime_header,   s"   


r7   c                   @   s   e Zd ZdZ		d!ddZdd Zd	d
 Zdd Zdd Zdd Z	dd Z
dd Zdd Zdd Zd"ddZedd Zedd Zedd  ZdS )#r   z0Representation of a single message in a catalog. r5   Nc
           
      C   s   || _ |s
| jr
d}|| _tt|| _t|| _|r%| jr%| j	d n| j
d tt|| _tt|| _t|trC|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
        )r8   r8   zpython-formatN)idpluralizablestringlistr   	locationssetflagspython_formatadddiscardauto_commentsuser_comments
isinstancer   previous_idlinenocontext)
selfr9   r;   r=   r?   rC   rD   rF   rG   rH   r5   r5   r6   __init__O   s    






zMessage.__init__c                 C   s   dt | j| jt| jf S )Nz<%s %r (flags: %r)>)type__name__r9   r<   r?   rI   r5   r5   r6   __repr__t   s   zMessage.__repr__c                 C   s   dd }t || ||S )z0Compare Messages, taking into account plural idsc                 S   s4   t | tr| jr| jd | jpdfS | j| jpdfS )Nr   r8   )rE   r   r:   r9   rH   )objr5   r5   r6   values_to_comparez   s   z*Message.__cmp__.<locals>.values_to_compare)r   )rI   otherrP   r5   r5   r6   __cmp__x   s   zMessage.__cmp__c                 C   s   |  |dkS Nr   rR   rI   rQ   r5   r5   r6   __gt__      zMessage.__gt__c                 C   s   |  |dk S rS   rT   rU   r5   r5   r6   __lt__   rW   zMessage.__lt__c                 C   s   |  |dkS rS   rT   rU   r5   r5   r6   __ge__   rW   zMessage.__ge__c                 C   s   |  |dkS rS   rT   rU   r5   r5   r6   __le__   rW   zMessage.__le__c                 C   s   |  |dkS rS   rT   rU   r5   r5   r6   __eq__   rW   zMessage.__eq__c                 C   s   |  |dkS rS   rT   rU   r5   r5   r6   __ne__   rW   zMessage.__ne__c                 C   s2   t tt| j| j| j| j| j| j| j	| j
| jf	 S N)r   mapr   r9   r;   r=   r?   rC   rD   rF   rG   rH   rM   r5   r5   r6   clone   s
   zMessage.clonec                 C   sZ   ddl m} g }|D ] }z|||  W q
 ty* } z|| W Y d}~q
d}~w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.checkersr`   r   append)rI   catalogr`   errorscheckerer5   r5   r6   check   s   
zMessage.checkc                 C   s
   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?   rM   r5   r5   r6   rh      s   
zMessage.fuzzyc                 C   s   t | jttfS )zWhether the message is plurizable.

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

        :type:  `bool`)rE   r9   r<   tuplerM   r5   r5   r6   r:         
zMessage.pluralizablec                 C   s,   | j }t|ttfs|g}td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                 s   s    | ]}t |V  qd S r]   )PYTHON_FORMATsearch).0r9   r5   r5   r6   	<genexpr>   s    z(Message.python_format.<locals>.<genexpr>)r9   rE   r<   rj   any)rI   idsr5   r5   r6   r@      s   
zMessage.python_format)r8   r5   r5   r5   r5   r5   NNr]   )rL   
__module____qualname____doc__rJ   rN   rR   rV   rX   rY   rZ   r[   r\   r_   rg   propertyrh   r:   r@   r5   r5   r5   r6   r   L   s*    
%


r   c                   @   s   e Zd ZdZdS )r   z_Exception thrown by translation checkers when invalid message
    translations are encountered.N)rL   rr   rs   rt   r5   r5   r5   r6   r      s    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.
#c                 C   sD   t | d}i }| D ]\}}|d}|d}|||< q|S )Nutf8)r   encodeitemsdecode)header_stringheadersdecoded_headersnamer)   r5   r5   r6   _parse_header   s   


r~   c                   @   s4  e Zd ZdZddeddddddddddfddZdd Zdd	 Zd
d Ze	eeZ
e	eZdd Zdd Ze	eeddZdd Zdd Ze	eeddZe	dd Ze	dd Ze	dd Zdd Zdd  Zd!d" Zd#d$ Zd%d& Zd'd( Zd)d* Z	+	d9d,d-Zd.d/ Zd:d0d1Zd:d2d3Zd;d5d6Z d:d7d8Z!dS )<r   z$Representation of a message catalog.NTc                 C   s   || _ || _|| _t | _|pd| _|pd| _|pd| _|pd| _|
p$d| _		 |p*d| _
	 |p0d| _|du r<tt}nt|trJ|jsJ|jtd	}|| _|	du rTd
}	nt|	trb|	jsb|	jtd	}	|	| _|| _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>z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   rE   r    r(   creation_daterevision_daterh   obsolete_num_plurals_plural_expr)rI   r   r   header_commentr   r   r   r   r   r   r   r   r   rh   r5   r5   r6   rJ      s6   







zCatalog.__init__c                 C   s   |d u rd | _ d | _d S t|trt|| _ || _d S t|tr<t|| _ z	t|| _W d S  ty;   d | _Y d S w td| )NzF`locale` must be a Locale, a locale identifier string, or None; got %r)	_locale_identifier_localerE   r
   r   r   parser   	TypeErrorrI   r   r5   r5   r6   _set_locale/  s$   



zCatalog._set_localec                 C      | j S r]   )r   rM   r5   r5   r6   _get_localeD     zCatalog._get_localec                 C   r   r]   )r   rM   r5   r5   r6   _get_locale_identifierG  r   zCatalog._get_locale_identifierc                 C   s   | j }ttd}t| jdr| jd}|d| jd| j	d|d| j
}| jr3| jjn| j}|r@|dd| }|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)rI   commentyearlocale_namer5   r5   r6   _get_header_commentM  s   

zCatalog._get_header_commentc                 C   s
   || _ d S r]   )r   )rI   r;   r5   r5   r6   _set_header_comment[  s   
zCatalog._set_header_commenta      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                 C   sJ  g }| dd| j| jf f | d| jf | dt| jdddf t| jtt	ft
 r<| dt| jdddf n| d| jf | d	| jf | jrY| d
t| jf | jrqd| jv rq| d| jdt| jf n| d| jf | jd ur| d| jf | d | dd| j f | d | ddt f |S )NzProject-Id-Versionz%s %sz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
)rb   r   r   r   r   r   rE   r   r   time_r   r   r   strr   r(   r   plural_formsr   r   )rI   r{   r5   r5   r6   _get_mime_headers  sH   


zCatalog._get_mime_headersc                 C   sH  |D ]\}}t | | jd}t || jd}|dkr/|d}d|d d | _|d | _q|dkr7|| _q|dkr?|| _q|dkrO|	dd	}| 
| q|d
krW|| _q|dkrmt|\}}d|v rl|d  | _q|dkrtd| \}}t|dd| _|dd| _q|dkrt|| _q|dkrd|vrt|| _qd S )N)encodingzproject-id-version zreport-msgid-bugs-tozlast-translatorlanguage-_zlanguage-teamzcontent-typer   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   r7   r   r   )rI   r{   r}   r)   partsmimetypeparamsr   r5   r5   r6   _set_mime_headers  s@   

zCatalog._set_mime_headersa      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                 C   .   | j du r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   )rI   numr5   r5   r6   num_plurals  s   

zCatalog.num_pluralsc                 C   r   )a`  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: `string_types`Nr   r   )r   r   r   )rI   exprr5   r5   r6   plural_expr  s   
zCatalog.plural_exprc                 C   s   d| j | jf 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=%s; plural=%s)r   r   rM   r5   r5   r6   r     rk   zCatalog.plural_formsc                 C   s   |  || jv S )z?Return whether the catalog has a message with the specified ID._key_forr   rI   r9   r5   r5   r6   __contains__"  s   zCatalog.__contains__c                 C   s
   t | jS )zeThe number of messages in the catalog.

        This does not include the special ``msgid ""`` entry.)lenr   rM   r5   r5   r6   __len__&  s   
zCatalog.__len__c                 c   sp    g }| j D ]\}}|d||f  qt }| jr|dhO }tdd||dV  | jD ]}| j| V  q-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%s: %srh   r8   
ri   N)mime_headersrb   r>   rh   r   r   r   )rI   bufr}   r)   r?   keyr5   r5   r6   __iter__,  s   

zCatalog.__iter__c                 C   s*   d}| j r
d| j  }dt| j| j|f S )Nr8   z %sz	<%s %r%s>)r   rK   rL   r   r   r5   r5   r6   rN   ;  s   
zCatalog.__repr__c                 C   s   |  | dS )z)Delete the message with the specified ID.N)deleter   r5   r5   r6   __delitem__A  s   zCatalog.__delitem__c                 C   s
   |  |S )zUReturn the message with the specified ID.

        :param id: the message ID
        )r   r   r5   r5   r6   __getitem__E  s   
zCatalog.__getitem__c                 C   s   t |ts	J d| ||j}| j|}|rS|jr&|js&|j|_|j|_t	t
|j|j |_t	t
|j|j |_t	t
|j|j |_| j|jO  _|}dS |dkrqt|j | _ddd |jD | _|j| _dS t |t	tfrt |jt	tfsJ dt|j || 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 objectr8   r   c                 S   s   g | ]}d |   qS )z# %s)rstrip)rn   cr5   r5   r6   
<listcomp>u  s    z'Catalog.__setitem__.<locals>.<listcomp>zExpected sequence but got %sN)rE   r   r   rH   r   r   r:   r9   r;   r<   r   r=   rC   rD   r?   r~   rx   r   r   r   rh   rj   rK   )rI   r9   messager   currentr5   r5   r6   __setitem__L  s:   




zCatalog.__setitem__r5   c
                 C   s*   t ||t|||||||	d	}
|
| |< |
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
        )rG   rH   )r   r<   )rI   r9   r;   r=   r?   rC   rD   rF   rG   rH   r   r5   r5   r6   rA   ~  s   zCatalog.addc                 c   s0    | j  D ]}|j| d}|r||fV  q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``
        )rc   N)r   valuesrg   )rI   r   rd   r5   r5   r6   rg     s   	
zCatalog.checkc                 C   s   | 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   )rI   r9   rH   r5   r5   r6   r     s   zCatalog.getc                 C   s&   |  ||}|| 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   rI   r9   rH   r   r5   r5   r6   r     s   
zCatalog.deleteFc                    s6  j  t _ g }|stfddD }t   fdd}|D ]R}|jr||j|j}|v rB|||| q*|du rwt|t	rP|d }	n|}	t
|	  | d}
|
rw|
d }|| }|durp||f}|||| q*||j< q*D ]}|s| vr| j|< q|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                    s.   g | ]}|r | j r| | jfqS r5   )r;   r   rH   )rn   msgid)messagesrI   r5   r6   r     s    z"Catalog.update.<locals>.<listcomp>c                    sD  |   } d}||kr)d} | |}t|jtr"|jg| _nt|j| _n|d }|j	| _	r=tt
|j| _t| jttfryt| j	ttfsad}t| j	gdgt| jd   | _	n(t| j	jkrxd}t| j	d t|j	 | _	nt| j	ttfrd}| j	d | _	|  j|jO  _|r|  jdhO  _| | j< d S )NFTr8   r   r   rh   )r_   rA   r   rE   r9   r   rF   r<   popr;   r   rD   rj   r   r   r?   )r   oldkeynewkeyrh   oldmsgfuzzy_matcheskeep_user_commentsr   	remainingrI   r5   r6   _merge  s<   

zCatalog.update.<locals>._mergeFr   r   N)r   r   r   dictr>   r9   r   rH   rE   rj   r   r   stripkeysr   r   r   )rI   templateno_fuzzy_matchingupdate_header_commentr   fuzzy_candidatesr   r   r   matchkeymatchesr   newctxtr   r5   r   r6   update  sL   5#


zCatalog.updatec                 C   s.   |}t |ttfr|d }|dur||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   N)rE   r<   rj   r   r5   r5   r6   r   I  s   zCatalog._key_for)Nr5   r5   r5   r5   r5   NNr]   )FFT)"rL   rr   rs   rt   DEFAULT_HEADERrJ   r   r   r   ru   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rN   r   r   r   rA   rg   r   r   r   r   r5   r5   r5   r6   r      sR    
:
!  3


2
!



 r   )/rt   r!   r   cgir   collectionsr   r   r   difflibr   emailr   r   babelr	   r   
babel.corer
   r   babel.datesr   babel.messages.pluralsr   
babel.utilr   r   r   babel._compatr   r   r   r   r   r   __all__compileVERBOSErl   r7   objectr   	Exceptionr   r   r~   r   r5   r5   r5   r6   <module>   s8   
 	  
