x`eVdZddlZddlZddlmZddlmZmZmZm Z ddl m Z m Z m Z mZGddZGdd ZGd d ej"ZGd d eej$Zy)a- babel.support ~~~~~~~~~~~~~ Several classes and functions that help with integrating and using Babel in applications. .. note: the code in this module is not used by Babel itself :copyright: (c) 2013-2022 by the Babel Team. :license: BSD, see LICENSE for more details. N)Locale) format_dateformat_datetime format_timeformat_timedelta)format_decimalformat_currencyformat_percentformat_scientificc^eZdZdZd dZddZddZddZ ddZdZ d d Z d Z d d Z d Z y)FormataCWrapper class providing the various date and number formatting functions bound to a specific locale and time-zone. >>> from babel.util import UTC >>> from datetime import date >>> fmt = Format('en_US', UTC) >>> fmt.date(date(2007, 4, 1)) u'Apr 1, 2007' >>> fmt.decimal(1.2345) u'1.234' NcFtj||_||_y)zInitialize the formatter. :param locale: the locale identifier or `Locale` instance :param tzinfo: the time-zone info (a `tzinfo` instance or `None`) N)rparselocaletzinfo)selfrrs //usr/lib/python3/dist-packages/babel/support.py__init__zFormat.__init__%s ll6*  c2t|||jS)zReturn a date formatted according to the given pattern. >>> from datetime import date >>> fmt = Format('en_US') >>> fmt.date(date(2007, 4, 1)) u'Apr 1, 2007' r)rr)rdateformats rrz Format.date.s4 <>> from datetime import datetime >>> from pytz import timezone >>> fmt = Format('en_US', tzinfo=timezone('America/New_York')) >>> fmt.datetime(datetime(2007, 4, 1, 15, 30)) u'Apr 1, 2007, 11:30:00 AM' rr)rrr)rdatetimers rrzFormat.datetime8s"x &*kk3 3rcHt|||j|jS)a"Return a time formatted according to the given pattern. >>> from datetime import datetime >>> from pytz import timezone >>> fmt = Format('en_US', tzinfo=timezone('America/New_York')) >>> fmt.time(datetime(2007, 4, 1, 15, 30)) u'11:30:00 AM' r)rrr)rtimers rrz Format.timeDs4 DKKPPrc8t||||||jS)zReturn a time delta according to the rules of the given locale. >>> from datetime import timedelta >>> fmt = Format('en_US') >>> fmt.timedelta(timedelta(weeks=11)) u'3 months' ) granularity thresholdr add_directionr)rr)rdeltar r!rr"s r timedeltazFormat.timedeltaOs$ ;*3'-]'+{{4 4rc0t||jS)zReturn an integer number formatted for the locale. >>> fmt = Format('en_US') >>> fmt.number(1099) u'1,099' rrrrnumbers rr(z Format.number]sfT[[99rc2t|||jS)zReturn a decimal number formatted for the locale. >>> fmt = Format('en_US') >>> fmt.decimal(1.2345) u'1.234' rr&rr(rs rdecimalzFormat.decimalfffT[[AArc2t|||jS)zHReturn a number in the given currency formatted for the locale. r)r r)rr(currencys rr.zFormat.currencyosvx DDrc2t|||jS)zReturn a number formatted as percentage for the locale. >>> fmt = Format('en_US') >>> fmt.percent(0.34) u'34%' r)r rr*s rpercentzFormat.percenttr,rc0t||jS)zLReturn a number formatted using scientific notation for the locale. r)r rr's r scientificzFormat.scientific}s! <>> def greeting(name='world'): ... return 'Hello, %s!' % name >>> lazy_greeting = LazyProxy(greeting, name='Joe') >>> print(lazy_greeting) Hello, Joe! >>> u' ' + lazy_greeting u' Hello, Joe!' >>> u'(%s)' % lazy_greeting u'(Hello, Joe!)' This can be used, for example, to implement lazy translation functions that delay the actual translation until the string is actually used. The rationale for such behavior is that the locale of the user may not always be available. In web applications, you only know the locale when processing a request. The proxy implementation attempts to be as complete as possible, so that the lazy objects should mostly work as expected, for example for sorting: >>> greetings = [ ... LazyProxy(greeting, 'world'), ... LazyProxy(greeting, 'Joe'), ... LazyProxy(greeting, 'universe'), ... ] >>> greetings.sort() >>> for greeting in greetings: ... print(greeting) Hello, Joe! Hello, universe! Hello, world! )_func_args_kwargs_value_is_cache_enabled_attribute_errorc<|jdd}tj|d|tj|d|tj|d|tj|d|tj|ddtj|ddy) N enable_cacheTr>r?r@rBrArC)popobject __setattr__)rfuncargskwargsis_cache_enableds rrzLazyProxy.__init__s!::nd;4$/4$/4F34!46FG4404!3T:rc|jL |j|ji|j}|js|St j |d||jS#t$r}t j |d|d}~wwxYw)NrCrA)rAr>r?r@AttributeErrorrGrHrB)rvalueerrors rrOzLazyProxy.values ;;  " DJJ?$,,? ))   tXu 5{{" ""4);UC s&A%% B .BB c||jvSr3rOrkeys r __contains__zLazyProxy.__contains__sdjj  rc,t|jSr3)boolrOrs r __nonzero__zLazyProxy.__nonzero__DJJrc,t|jSr3)dirrOrXs r__dir__zLazyProxy.__dir__4::rc,t|jSr3)iterrOrXs r__iter__zLazyProxy.__iter__rZrc,t|jSr3)lenrOrXs r__len__zLazyProxy.__len__r^rc,t|jSr3)strrOrXs r__str__zLazyProxy.__str__r^rc,t|jSr3)unicoderOrXs r __unicode__zLazyProxy.__unicode__stzz""rc |j|zSr3rRrothers r__add__zLazyProxy.__add__zzE!!rc ||jzSr3rRrls r__radd__zLazyProxy.__radd__tzz!!rc |j|zSr3rRrls r__mod__zLazyProxy.__mod__rorc ||jzSr3rRrls r__rmod__zLazyProxy.__rmod__rrrc |j|zSr3rRrls r__mul__zLazyProxy.__mul__rorc ||jzSr3rRrls r__rmul__zLazyProxy.__rmul__rrrc&|j|i|Sr3rR)rrJrKs r__call__zLazyProxy.__call__stzz4*6**rc |j|kSr3rRrls r__lt__zLazyProxy.__lt__rorc |j|kSr3rRrls r__le__zLazyProxy.__le__zzU""rc |j|k(Sr3rRrls r__eq__zLazyProxy.__eq__rrc |j|k7Sr3rRrls r__ne__zLazyProxy.__ne__rrc |j|kDSr3rRrls r__gt__zLazyProxy.__gt__rorc |j|k\Sr3rRrls r__ge__zLazyProxy.__ge__rrc0t|j|yr3)delattrrOrnames r __delattr__zLazyProxy.__delattr__s D!rc^|j |jt|j|Sr3)rCgetattrrOrs r __getattr__zLazyProxy.__getattr__s+  ,'' 'tzz4((rc2t|j||yr3)setattrrO)rrrOs rrHzLazyProxy.__setattr__s D%(rc|j|=yr3rRrSs r __delitem__zLazyProxy.__delitem__s JJsOrc |j|Sr3rRrSs r __getitem__zLazyProxy.__getitem__ szz#rc"||j|<yr3rR)rrTrOs r __setitem__zLazyProxy.__setitem__ s 3rctt|jg|jd|ji|jS)NrE)r=r>r?rBr@rXs r__copy__zLazyProxy.__copy__s@ JJ ZZ // ll   rcddlm}t||j|g||j|d||j |i||j |S)Nr)deepcopyrE)copyrr=r>r?rBr@)rmemors r __deepcopy__zLazyProxy.__deepcopy__s_! TZZ & djj$ ' !$"8"8$? t||T*   rN)$r7r8r9r: __slots__rpropertyrOrUrYr]rardrgrjrnrqrtrvrxrzr|r~rrrrrrrrHrrrrrr;rrr=r=s!DaI;  !  #""""""+"###"#") )   rr=ceZdZdZdfd ZdZdZdZeZdZ dZ dZ e Z d Z d Zd Zd Zd ZdZdZdZdZeZdZdZdZeZdZej:j8Zej:j>Z xZ!S)NullTranslationsNc i|_d|_t| |t t dt |ddg|_|j|_ i|_ y)aInitialize a simple translations class which is not backed by a real catalog. Behaves similar to gettext.NullTranslations but also offers Babel's on *gettext methods (e.g. 'dgettext()'). :param fp: a file-like object (ignored in this class) ct|dk7S)N)int)ns rz+NullTranslations.__init__..1sAF rfpNr) _catalogpluralsuperrlistfilterrfilesDEFAULT_DOMAINdomain_domains)rr __class__s rrzNullTranslations.__init__&sV +  B&FD(A'BCD ))  rcX|jj||j|S)zULike ``gettext()``, but look the message up in the specified domain. )rgetgettextrrmessages rdgettextzNullTranslations.dgettext7s&}}  .66w??rcddl}|jdtd|jj ||j |S)zVLike ``lgettext()``, but look the message up in the specified domain. rNz1ldgettext() is deprecated, use dgettext() instead)warningswarnDeprecationWarningrrlgettext)rrrrs r ldgettextzNullTranslations.ldgettext=s=  I(! -}}  .77@@rcX|jj||j|S)zVLike ``ugettext()``, but look the message up in the specified domain. )rrugettextrs r udgettextzNullTranslations.udgettextFs&}}  .77@@rc\|jj||j|||S)zVLike ``ngettext()``, but look the message up in the specified domain. )rrngettextrrsingularrnums r dngettextzNullTranslations.dngettextNs*}}  .77&#NNrcddl}|jdtd|jj ||j |||S)zWLike ``lngettext()``, but look the message up in the specified domain. rNz3ldngettext() is deprecated, use dngettext() insteadr)rrrrr lngettext)rrrrrrs r ldngettextzNullTranslations.ldngettextTsA  K(! -}}  .8863OOrc\|jj||j|||S)zVLike ``ungettext()`` but look the message up in the specified domain. )rr ungettextrs r udngettextzNullTranslations.udngettext]s*}}  .8863OOrz%s%sc|j||fz}t}|jj||}||ur*|jr|jj ||S|S|S)aLook up the `context` and `message` id in the catalog and return the corresponding message string, as an 8-bit string encoded with the catalog's charset encoding, if known. If there is no entry in the catalog for the `message` id and `context` , and a fallback has been set, the look up is forwarded to the fallback's ``pgettext()`` method. Otherwise, the `message` id is returned. )CONTEXT_ENCODINGrGrr _fallbackpgettext)rcontextr ctxt_msg_idmissingtmsgs rrzNullTranslations.pgettextlse++w.@@ (}}  g6 7?~~~~..w@@N rcddl}|jdtd|j||}t |ddxst j }|j|S)zEquivalent to ``pgettext()``, but the translation is returned in the preferred system encoding, if no other encoding was explicitly set with ``bind_textdomain_codeset()``. rNz1lpgettext() is deprecated, use pgettext() insteadr_output_charset)rrrrrrgetpreferredencodingencode)rrrrrencodings r lpgettextzNullTranslations.lpgettext}sW  I(! -}}Wg.4!2D9ZV=X=X=Z{{8$$rc|j||fz} |j||j|f}|S#t$r:|jr |jj ||||cYS|dk(r|cYS|cYSwxYw)a^Do a plural-forms lookup of a message id. `singular` is used as the message id for purposes of lookup in the catalog, while `num` is used to determine which plural form to use. The returned message string is an 8-bit string encoded with the catalog's charset encoding, if known. If the message id for `context` is not found in the catalog, and a fallback is specified, the request is forwarded to the fallback's ``npgettext()`` method. Otherwise, when ``num`` is 1 ``singular`` is returned, and ``plural`` is returned in all other cases. r)rrrKeyErrorr npgettext)rrrrrrrs rrzNullTranslations.npgettexts++w.AA  ==+t{{3/?!@ADK ~~~~//63OOax  s!53A8*A83A87A8cddl}|jdtd|j||fz} |j||j |f}t |ddxstj}|j|S#t$r:|jr |jj||||cYS|dk(r|cYS|cYSwxYw)zEquivalent to ``npgettext()``, but the translation is returned in the preferred system encoding, if no other encoding was explicitly set with ``bind_textdomain_codeset()``. rNz3lnpgettext() is deprecated, use npgettext() insteadrrr) rrrrrrrrrrrr lnpgettext) rrrrrrrrrs rrzNullTranslations.lnpgettexts  K(! -++w.AA  ==+t{{3/?!@ADt%6=^A\A\A^H;;x( ( ~~~~00(FCPPax  sAB3C7CCCc|j||fz}t}|jj||}||ur3|jr|jj ||St |S|S)asLook up the `context` and `message` id in the catalog and return the corresponding message string, as a Unicode string. If there is no entry in the catalog for the `message` id and `context`, and a fallback has been set, the look up is forwarded to the fallback's ``upgettext()`` method. Otherwise, the `message` id is returned. )rrGrrr upgettextrf)rrrctxt_message_idrrs rrzNullTranslations.upgettextsj//7G2DD(}}  ': 7?~~~~//AAw<  rc|j||fz} |j||j|f}|S#t$rN|jr |jj ||||cYS|dk(rt |}Y|St |}Y|SwxYw)a$Do a plural-forms lookup of a message id. `singular` is used as the message id for purposes of lookup in the catalog, while `num` is used to determine which plural form to use. The returned message string is a Unicode string. If the message id for `context` is not found in the catalog, and a fallback is specified, the request is forwarded to the fallback's ``unpgettext()`` method. Otherwise, when `num` is 1 `singular` is returned, and `plural` is returned in all other cases. r)rrrrr unpgettextrf)rrrrrrrs rrzNullTranslations.unpgettexts//7H2EE #==/4;;s3C!DED  #~~~~00(FCPPax8} 6{  #s 53B *B = B  B cZ|jj||j||S)zVLike `pgettext()`, but look the message up in the specified `domain`. )rrrrrrrs r dpgettextzNullTranslations.dpgettexts(}}  .77IIrcZ|jj||j||S)zWLike `upgettext()`, but look the message up in the specified `domain`. )rrrrs r udpgettextzNullTranslations.udpgettexts(}}  .88'JJrcZ|jj||j||S)zEquivalent to ``dpgettext()``, but the translation is returned in the preferred system encoding, if no other encoding was explicitly set with ``bind_textdomain_codeset()``. )rrrrs r ldpgettextzNullTranslations.ldpgettexts( }}  .88'JJrc^|jj||j||||S)zWLike ``npgettext``, but look the message up in the specified `domain`. )rrrrrrrrrs r dnpgettextzNullTranslations.dnpgettexts3}}  .88(9?F Frc^|jj||j||||S)zXLike ``unpgettext``, but look the message up in the specified `domain`. )rrrrs r udnpgettextzNullTranslations.udnpgettexts3}}  .99'8:@#G Grc^|jj||j||||S)zEquivalent to ``dnpgettext()``, but the translation is returned in the preferred system encoding, if no other encoding was explicitly set with ``bind_textdomain_codeset()``. )rrrrs r ldnpgettextzNullTranslations.ldnpgettexts3 }}  .99'8:@#G Grr3)"r7r8r9rrrrr dugettextrrr dungettextrrrrrrrrr dupgettextrrr dunpgettextrrrrrr __classcell__rs@rrr"sN"@ AA IO PP J"" %.* .J K JKFGKG''//H((11IrrceZdZdZdZdfd Zejj ZejjZ e d dZ dZ d dZdZxZS) Translationsz&An extended translation catalog class.messagescPt|||xs |j|_y)zInitialize the translations catalog. :param fp: the file-like object the translation should be read from :param domain: the message domain (default: 'messages') rN)rrrr)rrrrs rrzTranslations.__init__s' B3 3 3 rc,|1t|ttfs|g}|Dcgc] }t|}}|s |j}t j |||}|s tSt|d5}|||cdddScc}w#1swYyxYw)apLoad translations from the given directory. :param dirname: the directory containing the ``MO`` files :param locales: the list of locales in order of preference (items in this list can be either `Locale` objects or locale strings) :param domain: the message domain (default: 'messages') Nrb)rr) isinstancertuplerfrrfindropen)clsdirnamelocalesrrfilenamers rloadzTranslations.loads  ge}5")189vs6{9G9''F<<9#% % (D ! -R"V, - - :  - -sB1 B  Bcldt|jd|jjddS)N)typer7_inforrXs r__repr__zTranslations.__repr__4s,#Dz22#zz~~.BCE Erct|d|j}|r ||jk(r|j|S|jj |}|r||j||S|j |||j|<|S)a!Add the given translations to the catalog. If the domain of the translations is different than that of the current catalog, they are added as a catalog that is only accessible by the various ``d*gettext`` functions. :param translations: the `Translations` instance with the messages to add :param merge: whether translations for message domains that have already been added should be merged with the existing translations r)rrrmergerr add_fallback)r translationsrrexistings raddzTranslations.add8sx1D1DE Vt{{*::l+ +==$$V, X) NN< (    % %d +$0DMM& ! rct|tjrZ|jj |jt|t r%|j j|j |S)a0Merge the given translations into the catalog. Message translations in the specified catalog override any messages with the same identifier in the existing catalog. :param translations: the `Translations` instance with the messages to merge )rrGNUTranslationsrupdaterrextend)rrs rrzTranslations.mergeRsS lG$;$; < MM !6!6 7, 5 !!,"4"45 r)NN)NNN)T)r7r8r9r:rrrrrrr classmethodr rrrrrs@rrr sV0N4&&..H''00I--*E4rr)r:rr babel.corer babel.datesrrrr babel.numbersrr r r r r=rrrr;rrr!so  &&h=h=V\ \ ~h2w//h2VS#W%<%<Sr