1BABEL(1) Babel BABEL(1)
2
3
4
6 babel - Babel Documentation
7
8 Babel is an integrated collection of utilities that assist in interna‐
9 tionalizing and localizing Python applications, with an emphasis on
10 web-based applications.
11
13 The user documentation explains some core concept of the library and
14 gives some information about how it can be used.
15
16 Introduction
17 The functionality Babel provides for internationalization (I18n) and
18 localization (L10N) can be separated into two different aspects:
19
20 • tools to build and work with gettext message catalogs, and
21
22 • a Python interface to the CLDR (Common Locale Data Repository),
23 providing access to various locale display names, localized number
24 and date formatting, etc.
25
26 Message Catalogs
27 While the Python standard library includes a gettext module that en‐
28 ables applications to use message catalogs, it requires developers to
29 build these catalogs using GNU tools such as xgettext, msgmerge, and
30 msgfmt. And while xgettext does have support for extracting messages
31 from Python files, it does not know how to deal with other kinds of
32 files commonly found in Python web-applications, such as templates, nor
33 does it provide an easy extensibility mechanism to add such support.
34
35 Babel addresses this by providing a framework where various extraction
36 methods can be plugged in to a larger message extraction framework, and
37 also removes the dependency on the GNU gettext tools for common tasks,
38 as these aren’t necessarily available on all platforms. See Working
39 with Message Catalogs for details on this aspect of Babel.
40
41 Locale Data
42 Furthermore, while the Python standard library does include support for
43 basic localization with respect to the formatting of numbers and dates
44 (the locale module, among others), this support is based on the assump‐
45 tion that there will be only one specific locale used per process (at
46 least simultaneously.) Also, it doesn’t provide access to other kinds
47 of locale data, such as the localized names of countries, languages, or
48 time-zones, which are frequently needed in web-based applications.
49
50 For these requirements, Babel includes data extracted from the Common
51 Locale Data Repository (CLDR), and provides a number of convenient
52 methods for accessing and using this data. See Locale Data, Date and
53 Time, and Number Formatting for more information on this aspect of Ba‐
54 bel.
55
56 Installation
57 Babel is distributed as a standard Python package fully set up with all
58 the dependencies it needs. On Python versions where the standard li‐
59 brary zoneinfo module is not available, pytz needs to be installed for
60 timezone support. If pytz is installed, it is preferred over the stan‐
61 dard library zoneinfo module where possible.
62
63 virtualenv
64 Virtualenv is probably what you want to use during development, and if
65 you have shell access to your production machines, you’ll probably want
66 to use it there, too. Use pip to install it:
67
68 $ sudo pip install virtualenv
69
70 If you’re on Windows, run it in a command-prompt window with adminis‐
71 trator privileges, and leave out sudo.
72
73 Once you have virtualenv installed, just fire up a shell and create
74 your own environment. I usually create a project folder and a venv
75 folder within:
76
77 $ mkdir myproject
78 $ cd myproject
79 $ virtualenv venv
80 New python executable in venv/bin/python
81 Installing distribute............done.
82
83 Now, whenever you want to work on a project, you only have to activate
84 the corresponding environment. On OS X and Linux, do the following:
85
86 $ . venv/bin/activate
87
88 If you are a Windows user, the following command is for you:
89
90 $ venv\scripts\activate
91
92 Either way, you should now be using your virtualenv (notice how the
93 prompt of your shell has changed to show the active environment).
94
95 Now you can just enter the following command to get Babel installed in
96 your virtualenv:
97
98 $ pip install Babel
99
100 A few seconds later and you are good to go.
101
102 System-Wide Installation
103 This is possible as well, though I do not recommend it. Just run pip
104 with root privileges:
105
106 $ sudo pip install Babel
107
108 (On Windows systems, run it in a command-prompt window with administra‐
109 tor privileges, and leave out sudo.)
110
111 Living on the Edge
112 If you want to work with the latest version of Babel, you will need to
113 use a git checkout.
114
115 Get the git checkout in a new virtualenv and run in development mode:
116
117 $ git clone https://github.com/python-babel/babel
118 Initialized empty Git repository in ~/dev/babel/.git/
119 $ cd babel
120 $ virtualenv venv
121 New python executable in venv/bin/python
122 Installing distribute............done.
123 $ . venv/bin/activate
124 $ python setup.py import_cldr
125 $ pip install --editable .
126 ...
127 Finished processing dependencies for Babel
128
129 Make sure to not forget about the import_cldr step because otherwise
130 you will be missing the locale data. The custom setup command will
131 download the most appropriate CLDR release from the official website
132 and convert it for Babel.
133
134 This will pull also in the dependencies and activate the git head as
135 the current version inside the virtualenv. Then all you have to do is
136 run git pull origin to update to the latest version. If the CLDR data
137 changes you will have to re-run python setup.py import_cldr.
138
139 Locale Data
140 While message catalogs allow you to localize any messages in your ap‐
141 plication, there are a number of strings that are used in many applica‐
142 tions for which translations are readily available.
143
144 Imagine for example you have a list of countries that users can choose
145 from, and you’d like to display the names of those countries in the
146 language the user prefers. Instead of translating all those country
147 names yourself in your application, you can make use of the transla‐
148 tions provided by the locale data included with Babel, which is based
149 on the Common Locale Data Repository (CLDR) developed and maintained by
150 the Unicode Consortium.
151
152 The Locale Class
153 You normally access such locale data through the Locale class provided
154 by Babel:
155
156 >>> from babel import Locale
157 >>> locale = Locale('en', 'US')
158 >>> locale.territories['US']
159 u'United States'
160 >>> locale = Locale('es', 'MX')
161 >>> locale.territories['US']
162 u'Estados Unidos'
163
164 In addition to country/territory names, the locale data also provides
165 access to names of languages, scripts, variants, time zones, and more.
166 Some of the data is closely related to number and date formatting.
167
168 Most of the corresponding Locale properties return dictionaries, where
169 the key is a code such as the ISO country and language codes. Consult
170 the API documentation for references to the relevant specifications.
171
172 Likely Subtags
173 When dealing with locales you can run into the situation where a locale
174 tag is not fully descriptive. For instance people commonly refer to
175 zh_TW but that identifier does not resolve to a locale that the CLDR
176 covers. Babel’s locale identifier parser in that case will attempt to
177 resolve the most likely subtag to end up with the intended locale:
178
179 >>> from babel import Locale
180 >>> Locale.parse('zh_TW')
181 Locale('zh', territory='TW', script='Hant')
182
183 This can also be used to find the most appropriate locale for a terri‐
184 tory. In that case the territory code needs to be prefixed with und
185 (unknown language identifier):
186
187 >>> Locale.parse('und_AZ')
188 Locale('az', territory='AZ', script='Latn')
189 >>> Locale.parse('und_DE')
190 Locale('de', territory='DE')
191
192 Babel currently cannot deal with fuzzy locales (a locale not fully
193 backed by data files) so we only accept locales that are fully backed
194 by CLDR data. This will change in the future, but for the time being
195 this restriction is in place.
196
197 Locale Display Names
198 Locales itself can be used to describe the locale itself or other lo‐
199 cales. This mainly means that given a locale object you can ask it for
200 its canonical display name, the name of the language and other things.
201 Since the locales cross-reference each other you can ask for locale
202 names in any language supported by the CLDR:
203
204 >>> l = Locale.parse('de_DE')
205 >>> l.get_display_name('en_US')
206 u'German (Germany)'
207 >>> l.get_display_name('fr_FR')
208 u'allemand (Allemagne)'
209
210 Display names include all the information to uniquely identify a locale
211 (language, territory, script and variant) which is often not what you
212 want. You can also ask for the information in parts:
213
214 >>> l.get_language_name('de_DE')
215 u'Deutsch'
216 >>> l.get_language_name('it_IT')
217 u'tedesco'
218 >>> l.get_territory_name('it_IT')
219 u'Germania'
220 >>> l.get_territory_name('pt_PT')
221 u'Alemanha'
222
223 Calendar Display Names
224 The Locale class provides access to many locale display names related
225 to calendar display, such as the names of weekdays or months.
226
227 These display names are of course used for date formatting, but can
228 also be used, for example, to show a list of months to the user in
229 their preferred language:
230
231 >>> locale = Locale('es')
232 >>> month_names = locale.months['format']['wide'].items()
233 >>> for idx, name in sorted(month_names):
234 ... print name
235 enero
236 febrero
237 marzo
238 abril
239 mayo
240 junio
241 julio
242 agosto
243 septiembre
244 octubre
245 noviembre
246 diciembre
247
248 Date and Time
249 When working with date and time information in Python, you commonly use
250 the classes date, datetime and/or time from the datetime package. Ba‐
251 bel provides functions for locale-specific formatting of those objects
252 in its dates module:
253
254 >>> from datetime import date, datetime, time
255 >>> from babel.dates import format_date, format_datetime, format_time
256
257 >>> d = date(2007, 4, 1)
258 >>> format_date(d, locale='en')
259 u'Apr 1, 2007'
260 >>> format_date(d, locale='de_DE')
261 u'01.04.2007'
262
263 As this example demonstrates, Babel will automatically choose a date
264 format that is appropriate for the requested locale.
265
266 The format_*() functions also accept an optional format argument, which
267 allows you to choose between one of four format variations:
268
269 • short,
270
271 • medium (the default),
272
273 • long, and
274
275 • full.
276
277 For example:
278
279 >>> format_date(d, format='short', locale='en')
280 u'4/1/07'
281 >>> format_date(d, format='long', locale='en')
282 u'April 1, 2007'
283 >>> format_date(d, format='full', locale='en')
284 u'Sunday, April 1, 2007'
285
286 Core Time Concepts
287 Working with dates and time can be a complicated thing. Babel attempts
288 to simplify working with them by making some decisions for you.
289 Python’s datetime module has different ways to deal with times and
290 dates: naive and timezone-aware datetime objects.
291
292 Babel generally recommends you to store all your time in naive datetime
293 objects and treat them as UTC at all times. This simplifies dealing
294 with time a lot because otherwise you can get into the hairy situation
295 where you are dealing with datetime objects of different timezones.
296 That is tricky because there are situations where time can be ambigu‐
297 ous. This is usually the case when dealing with dates around timezone
298 transitions. The most common case of timezone transition is changes
299 between daylight saving time and standard time.
300
301 As such we recommend to always use UTC internally and only reformat to
302 local time when returning dates to users. At that point the timezone
303 the user has selected can usually be established and Babel can automat‐
304 ically rebase the time for you.
305
306 To get the current time use the utcnow() method of the datetime object.
307 It will return a naive datetime object in UTC.
308
309 For more information about timezones see Time-zone Support.
310
311 Pattern Syntax
312 While Babel makes it simple to use the appropriate date/time format for
313 a given locale, you can also force it to use custom patterns. Note that
314 Babel uses different patterns for specifying number and date formats
315 compared to the Python equivalents (such as time.strftime()), which
316 have mostly been inherited from C and POSIX. The patterns used in Babel
317 are based on the Locale Data Markup Language specification (LDML),
318 which defines them as follows:
319 A date/time pattern is a string of characters, where specific
320 strings of characters are replaced with date and time data from a
321 calendar when formatting or used to generate data for a calendar
322 when parsing. […]
323
324 Characters may be used multiple times. For example, if y is used for
325 the year, yy might produce “99”, whereas yyyy produces “1999”. For
326 most numerical fields, the number of characters specifies the field
327 width. For example, if h is the hour, h might produce “5”, but hh
328 produces “05”. For some characters, the count specifies whether an
329 abbreviated or full form should be used […]
330
331 Two single quotes represent a literal single quote, either inside or
332 outside single quotes. Text within single quotes is not interpreted
333 in any way (except for two adjacent single quotes).
334
335 For example:
336
337 >>> d = date(2007, 4, 1)
338 >>> format_date(d, "EEE, MMM d, ''yy", locale='en')
339 u"Sun, Apr 1, '07"
340 >>> format_date(d, "EEEE, d.M.yyyy", locale='de')
341 u'Sonntag, 1.4.2007'
342
343 >>> t = time(15, 30)
344 >>> format_time(t, "hh 'o''clock' a", locale='en')
345 u"03 o'clock PM"
346 >>> format_time(t, 'H:mm a', locale='de')
347 u'15:30 nachm.'
348
349 >>> dt = datetime(2007, 4, 1, 15, 30)
350 >>> format_datetime(dt, "yyyyy.MMMM.dd GGG hh:mm a", locale='en')
351 u'02007.April.01 AD 03:30 PM'
352
353 The syntax for custom datetime format patterns is described in detail
354 in the the Locale Data Markup Language specification. The following ta‐
355 ble is just a relatively brief overview.
356
357 Date Fields
358 ┌─────────┬─────────────────────┬─────────────────────┐
359 │Field │ Symbol │ Description │
360 ├─────────┼─────────────────────┼─────────────────────┤
361 │Era │ G │ Replaced with the │
362 │ │ │ era string for the │
363 │ │ │ current date. One │
364 │ │ │ to three letters │
365 │ │ │ for the abbreviated │
366 │ │ │ form, four letters‐ │
367 │ │ │ for the long form, │
368 │ │ │ five for the narrow │
369 │ │ │ form │
370 ├─────────┼─────────────────────┼─────────────────────┤
371 │Year │ y │ Replaced by the │
372 │ │ │ year. Normally the │
373 │ │ │ length specifies │
374 │ │ │ the padding, but │
375 │ │ │ for two letters it │
376 │ │ │ also specifies the │
377 │ │ │ maximum length. │
378 ├─────────┼─────────────────────┼─────────────────────┤
379 │Y │ Same as y but uses │ │
380 │ │ the ISO year-week │ │
381 │ │ calendar. ISO │ │
382 │ │ year-week incre‐ │ │
383 │ │ ments after com‐ │ │
384 │ │ pleting the last │ │
385 │ │ week of the year. │ │
386 │ │ Therefore it may │ │
387 │ │ change a few days │ │
388 │ │ before or after y. │ │
389 │ │ Recommend use with │ │
390 │ │ the w Symbol. │ │
391 ├─────────┼─────────────────────┼─────────────────────┤
392 │u │ ?? │ │
393 └─────────┴─────────────────────┴─────────────────────┘
394
395
396
397
398
399
400
401 │Quarter │ Q │ Use one or two for │
402 │ │ │ the numerical quar‐ │
403 │ │ │ ter, three for the │
404 │ │ │ abbreviation, or │
405 │ │ │ four for the full │
406 │ │ │ name. │
407 ├─────────┼─────────────────────┼─────────────────────┤
408 │q │ Use one or two for │ │
409 │ │ the numerical quar‐ │ │
410 │ │ ter, three for the │ │
411 │ │ abbreviation, or │ │
412 │ │ four for the full │ │
413 │ │ name. │ │
414 ├─────────┼─────────────────────┼─────────────────────┤
415 │Month │ M │ Use one or two for │
416 │ │ │ the numerical │
417 │ │ │ month, three for │
418 │ │ │ the abbreviation, │
419 │ │ │ or four for the │
420 │ │ │ full name, or five │
421 │ │ │ for the narrow │
422 │ │ │ name. │
423 ├─────────┼─────────────────────┼─────────────────────┤
424 │L │ Use one or two for │ │
425 │ │ the numerical │ │
426 │ │ month, three for │ │
427 │ │ the abbreviation, │ │
428 │ │ or four for the │ │
429 │ │ full name, or 5 for │ │
430 │ │ the narrow name. │ │
431 ├─────────┼─────────────────────┼─────────────────────┤
432 │Week │ w │ Week of year ac‐ │
433 │ │ │ cording to the ISO │
434 │ │ │ year-week calendar. │
435 │ │ │ This may have 52 or │
436 │ │ │ 53 weeks depending │
437 │ │ │ on the year. Rec‐ │
438 │ │ │ ommend use with the │
439 │ │ │ Y symbol. │
440 ├─────────┼─────────────────────┼─────────────────────┤
441 │W │ Week of month. │ │
442 ├─────────┼─────────────────────┼─────────────────────┤
443 │Day │ d │ Day of month. │
444 ├─────────┼─────────────────────┼─────────────────────┤
445 │D │ Day of year. │ │
446 ├─────────┼─────────────────────┼─────────────────────┤
447 │F │ Day of week in │ │
448 │ │ month. │ │
449 ├─────────┼─────────────────────┼─────────────────────┤
450 │g │ ?? │ │
451 ├─────────┼─────────────────────┼─────────────────────┤
452 │Week day │ E │ Day of week. Use │
453 │ │ │ one through three │
454 │ │ │ letters for the │
455 │ │ │ short day, or four │
456 │ │ │ for the full name, │
457 │ │ │ or five for the │
458 │ │ │ narrow name. │
459 └─────────┴─────────────────────┴─────────────────────┘
460
461
462
463
464
465
466
467
468 │e │ Local day of week. │ │
469 │ │ Same as E except │ │
470 │ │ adds a numeric │ │
471 │ │ value that will de‐ │ │
472 │ │ pend on the local │ │
473 │ │ starting day of the │ │
474 │ │ week, using one or │ │
475 │ │ two letters. │ │
476 ├─────────┼─────────────────────┼─────────────────────┤
477 │c │ ?? │ │
478 └─────────┴─────────────────────┴─────────────────────┘
479
480 Time Fields
481 ┌─────────┬─────────────────────┬─────────────────────┐
482 │Field │ Symbol │ Description │
483 ├─────────┼─────────────────────┼─────────────────────┤
484 │Period │ a │ AM or PM │
485 ├─────────┼─────────────────────┼─────────────────────┤
486 │Hour │ h │ Hour [1-12]. │
487 ├─────────┼─────────────────────┼─────────────────────┤
488 │H │ Hour [0-23]. │ │
489 ├─────────┼─────────────────────┼─────────────────────┤
490 │K │ Hour [0-11]. │ │
491 ├─────────┼─────────────────────┼─────────────────────┤
492 │k │ Hour [1-24]. │ │
493 ├─────────┼─────────────────────┼─────────────────────┤
494 │Minute │ m │ Use one or two for │
495 │ │ │ zero places pad‐ │
496 │ │ │ ding. │
497 ├─────────┼─────────────────────┼─────────────────────┤
498 │Second │ s │ Use one or two for │
499 │ │ │ zero places pad‐ │
500 │ │ │ ding. │
501 ├─────────┼─────────────────────┼─────────────────────┤
502 │S │ Fractional second, │ │
503 │ │ rounds to the count │ │
504 │ │ of letters. │ │
505 ├─────────┼─────────────────────┼─────────────────────┤
506 │A │ Milliseconds in │ │
507 │ │ day. │ │
508 ├─────────┼─────────────────────┼─────────────────────┤
509 │Timezone │ z │ Use one to three │
510 │ │ │ letters for the │
511 │ │ │ short timezone or │
512 │ │ │ four for the full │
513 │ │ │ name. │
514 ├─────────┼─────────────────────┼─────────────────────┤
515 │Z │ Use one to three │ │
516 │ │ letters for RFC │ │
517 │ │ 822, four letters │ │
518 │ │ for GMT format. │ │
519 ├─────────┼─────────────────────┼─────────────────────┤
520 │v │ Use one letter for │ │
521 │ │ short wall │ │
522 │ │ (generic) time, │ │
523 │ │ four for long wall │ │
524 │ │ time. │ │
525 ├─────────┼─────────────────────┼─────────────────────┤
526 │V │ Same as z, except │ │
527 │ │ that timezone ab‐ │ │
528 │ │ breviations should │ │
529 │ │ be used regardless │ │
530 │ │ of whether they are │ │
531 │ │ in common use by │ │
532 │ │ the locale. │ │
533 └─────────┴─────────────────────┴─────────────────────┘
534
535 Time Delta Formatting
536 In addition to providing functions for formatting localized dates and
537 times, the babel.dates module also provides a function to format the
538 difference between two times, called a ‘’time delta’’. These are usu‐
539 ally represented as datetime.timedelta objects in Python, and it’s also
540 what you get when you subtract one datetime object from an other.
541
542 The format_timedelta function takes a timedelta object and returns a
543 human-readable representation. This happens at the cost of precision,
544 as it chooses only the most significant unit (such as year, week, or
545 hour) of the difference, and displays that:
546
547 >>> from datetime import timedelta
548 >>> from babel.dates import format_timedelta
549 >>> delta = timedelta(days=6)
550 >>> format_timedelta(delta, locale='en_US')
551 u'1 week'
552
553 The resulting strings are based from the CLDR data, and are properly
554 pluralized depending on the plural rules of the locale and the calcu‐
555 lated number of units.
556
557 The function provides parameters for you to influence how this most
558 significant unit is chosen: with threshold you set the value after
559 which the presentation switches to the next larger unit, and with gran‐
560 ularity you can limit the smallest unit to display:
561
562 >>> delta = timedelta(days=6)
563 >>> format_timedelta(delta, threshold=1.2, locale='en_US')
564 u'6 days'
565 >>> format_timedelta(delta, granularity='month', locale='en_US')
566 u'1 month'
567
568 Time-zone Support
569 Many of the verbose time formats include the time-zone, but time-zone
570 information is not by default available for the Python datetime and
571 time objects. The standard library includes only the abstract tzinfo
572 class, which you need appropriate implementations for to actually use
573 in your application. Babel includes a tzinfo implementation for UTC
574 (Universal Time).
575
576 Babel uses either
577 `zoneinfo`_
578 or pytz for timezone support. If pytz is installed, it is preferred
579 over the standard library’s zoneinfo. You can directly interface with
580 either of these modules from within Babel:
581
582 >>> from datetime import time
583 >>> from babel.dates import get_timezone, UTC
584 >>> dt = datetime(2007, 4, 1, 15, 30, tzinfo=UTC)
585 >>> eastern = get_timezone('US/Eastern')
586 >>> format_datetime(dt, 'H:mm Z', tzinfo=eastern, locale='en_US')
587 u'11:30 -0400'
588
589 The recommended approach to deal with different time-zones in a Python
590 application is to always use UTC internally, and only convert from/to
591 the users time-zone when accepting user input and displaying date/time
592 data, respectively. You can use Babel together with zoneinfo or pytz
593 to apply a time-zone to any datetime or time object for display, leav‐
594 ing the original information unchanged:
595
596 >>> british = get_timezone('Europe/London')
597 >>> format_datetime(dt, 'H:mm zzzz', tzinfo=british, locale='en_US')
598 u'16:30 British Summer Time'
599
600 Here, the given UTC time is adjusted to the “Europe/London” time-zone,
601 and daylight savings time is taken into account. Daylight savings time
602 is also applied to format_time, but because the actual date is unknown
603 in that case, the current day is assumed to determine whether DST or
604 standard time should be used.
605
606 Babel also provides support for working with the local timezone of your
607 operating system. It’s provided through the LOCALTZ constant:
608
609 >>> from babel.dates import LOCALTZ, get_timezone_name
610 >>> LOCALTZ
611 <DstTzInfo 'Europe/Vienna' CET+1:00:00 STD>
612 >>> get_timezone_name(LOCALTZ)
613 u'Central European Time'
614
615 Localized Time-zone Names
616 While the Locale class provides access to various locale display names
617 related to time-zones, the process of building a localized name of a
618 time-zone is actually quite complicated. Babel implements it in sepa‐
619 rately usable functions in the babel.dates module, most importantly the
620 get_timezone_name function:
621
622 >>> from babel import Locale
623 >>> from babel.dates import get_timezone_name, get_timezone
624
625 >>> tz = get_timezone('Europe/Berlin')
626 >>> get_timezone_name(tz, locale=Locale.parse('pt_PT'))
627 u'Hora da Europa Central'
628
629 You can pass the function either a datetime.tzinfo object, or a date‐
630 time.date or datetime.datetime object. If you pass an actual date, the
631 function will be able to take daylight savings time into account. If
632 you pass just the time-zone, Babel does not know whether daylight sav‐
633 ings time is in effect, so it uses a generic representation, which is
634 useful for example to display a list of time-zones to the user.
635
636 >>> from datetime import datetime
637 >>> from babel.dates import _localize
638
639 >>> dt = _localize(tz, datetime(2007, 8, 15))
640 >>> get_timezone_name(dt, locale=Locale.parse('de_DE'))
641 u'Mitteleurop\xe4ische Sommerzeit'
642 >>> get_timezone_name(tz, locale=Locale.parse('de_DE'))
643 u'Mitteleurop\xe4ische Zeit'
644
645 Number Formatting
646 Support for locale-specific formatting and parsing of numbers is pro‐
647 vided by the babel.numbers module:
648
649 >>> from babel.numbers import format_number, format_decimal, format_compact_decimal, format_percent
650
651 Examples:
652
653 # Numbers with decimal places
654 >>> format_decimal(1.2345, locale='en_US')
655 u'1.234'
656 >>> format_decimal(1.2345, locale='sv_SE')
657 u'1,234'
658 # Integers with thousand grouping
659 >>> format_decimal(12345, locale='de_DE')
660 u'12.345'
661 >>> format_decimal(12345678, locale='de_DE')
662 u'12.345.678'
663
664 Pattern Syntax
665 While Babel makes it simple to use the appropriate number format for a
666 given locale, you can also force it to use custom patterns. As with
667 date/time formatting patterns, the patterns Babel supports for number
668 formatting are based on the Locale Data Markup Language specification
669 (LDML).
670
671 Examples:
672
673 >>> format_decimal(-1.2345, format='#,##0.##;-#', locale='en')
674 u'-1.23'
675 >>> format_decimal(-1.2345, format='#,##0.##;(#)', locale='en')
676 u'(1.23)'
677
678 The syntax for custom number format patterns is described in detail in
679 the the specification. The following table is just a relatively brief
680 overview.
681
682 ┌───────┬────────────────────────────┐
683 │Symbol │ Description │
684 ├───────┼────────────────────────────┤
685 │0 │ Digit │
686 ├───────┼────────────────────────────┤
687 │1-9 │ ‘1’ through ‘9’ indicate │
688 │ │ rounding. │
689 ├───────┼────────────────────────────┤
690 │@ │ Significant digit │
691 ├───────┼────────────────────────────┤
692 │# │ Digit, zero shows as ab‐ │
693 │ │ sent │
694 ├───────┼────────────────────────────┤
695 │. │ Decimal separator or mone‐ │
696 │ │ tary decimal separator │
697 ├───────┼────────────────────────────┤
698 │- │ Minus sign │
699 ├───────┼────────────────────────────┤
700 │, │ Grouping separator │
701 ├───────┼────────────────────────────┤
702 │E │ Separates mantissa and ex‐ │
703 │ │ ponent in scientific nota‐ │
704 │ │ tion │
705 ├───────┼────────────────────────────┤
706 │+ │ Prefix positive exponents │
707 │ │ with localized plus sign │
708 ├───────┼────────────────────────────┤
709 │; │ Separates positive and │
710 │ │ negative subpatterns │
711 ├───────┼────────────────────────────┤
712 │% │ Multiply by 100 and show │
713 │ │ as percentage │
714 ├───────┼────────────────────────────┤
715 │‰ │ Multiply by 1000 and show │
716 │ │ as per mille │
717 ├───────┼────────────────────────────┤
718 │¤ │ Currency sign, replaced by │
719 │ │ currency symbol. If dou‐ │
720 │ │ bled, replaced by interna‐ │
721 │ │ tional currency symbol. If │
722 │ │ tripled, uses the long │
723 │ │ form of the decimal sym‐ │
724 │ │ bol. │
725 ├───────┼────────────────────────────┤
726 │' │ Used to quote special │
727 │ │ characters in a prefix or │
728 │ │ suffix │
729 ├───────┼────────────────────────────┤
730 │* │ Pad escape, precedes pad │
731 │ │ character │
732 └───────┴────────────────────────────┘
733
734 Rounding Modes
735 Since Babel makes full use of Python’s Decimal type to perform number
736 rounding before formatting, users have the chance to control the round‐
737 ing mode and other configurable parameters through the active Context
738 instance.
739
740 By default, Python rounding mode is ROUND_HALF_EVEN which complies with
741 UTS #35 section 3.3. Yet, the caller has the opportunity to tweak the
742 current context before formatting a number or currency:
743
744 >>> from babel.numbers import decimal, format_decimal
745 >>> with decimal.localcontext(decimal.Context(rounding=decimal.ROUND_DOWN)):
746 >>> txt = format_decimal(123.99, format='#', locale='en_US')
747 >>> txt
748 u'123'
749
750 It is also possible to use decimal.setcontext or directly modifying the
751 instance returned by decimal.getcontext. However, using a context man‐
752 ager is always more convenient due to the automatic restoration and the
753 ability to nest them.
754
755 Whatever mechanism is chosen, always make use of the decimal module im‐
756 ported from babel.numbers. For efficiency reasons, Babel uses the
757 fastest decimal implementation available, such as cdecimal. These var‐
758 ious implementation offer an identical API, but their types and in‐
759 stances do not interoperate with each other.
760
761 For example, the previous example can be slightly modified to generate
762 unexpected results on Python 2.7, with the cdecimal module installed:
763
764 >>> from decimal import localcontext, Context, ROUND_DOWN
765 >>> from babel.numbers import format_decimal
766 >>> with localcontext(Context(rounding=ROUND_DOWN)):
767 >>> txt = format_decimal(123.99, format='#', locale='en_US')
768 >>> txt
769 u'124'
770
771 Changing other parameters such as the precision may also alter the re‐
772 sults of the number formatting functions. Remember to test your code
773 to make sure it behaves as desired.
774
775 Parsing Numbers
776 Babel can also parse numeric data in a locale-sensitive manner:
777
778 >>> from babel.numbers import parse_decimal, parse_number
779
780 Examples:
781
782 >>> parse_decimal('1,099.98', locale='en_US')
783 1099.98
784 >>> parse_decimal('1.099,98', locale='de')
785 1099.98
786 >>> parse_decimal('2,109,998', locale='de')
787 Traceback (most recent call last):
788 ...
789 NumberFormatError: '2,109,998' is not a valid decimal number
790
791 Note: as of version 2.8.0, the parse_number function has limited func‐
792 tionality. It can remove group symbols of certain locales from numeric
793 strings, but may behave unexpectedly until its logic handles more en‐
794 coding issues and other special cases.
795
796 Examples:
797
798 >>> parse_number('1,099', locale='en_US')
799 1099
800 >>> parse_number('1.099.024', locale='de')
801 1099024
802 >>> parse_number('123' + u'\xa0' + '4567', locale='ru')
803 1234567
804 >>> parse_number('123 4567', locale='ru')
805 ...
806 NumberFormatError: '123 4567' is not a valid number
807
808 Working with Message Catalogs
809 Introduction
810 The gettext translation system enables you to mark any strings used in
811 your application as subject to localization, by wrapping them in func‐
812 tions such as gettext(str) and ngettext(singular, plural, num). For
813 brevity, the gettext function is often aliased to _(str), so you can
814 write:
815
816 print(_("Hello"))
817
818 instead of just:
819
820 print("Hello")
821
822 to make the string “Hello” localizable.
823
824 Message catalogs are collections of translations for such localizable
825 messages used in an application. They are commonly stored in PO (Porta‐
826 ble Object) and MO (Machine Object) files, the formats of which are de‐
827 fined by the GNU gettext tools and the GNU translation project.
828
829 The general procedure for building message catalogs looks something
830 like this:
831
832 • use a tool (such as xgettext) to extract localizable strings from
833 the code base and write them to a POT (PO Template) file.
834
835 • make a copy of the POT file for a specific locale (for example,
836 “en_US”) and start translating the messages
837
838 • use a tool such as msgfmt to compile the locale PO file into a bi‐
839 nary MO file
840
841 • later, when code changes make it necessary to update the transla‐
842 tions, you regenerate the POT file and merge the changes into the
843 various locale-specific PO files, for example using msgmerge
844
845 Python provides the gettext module as part of the standard library,
846 which enables applications to work with appropriately generated MO
847 files.
848
849 As gettext provides a solid and well supported foundation for translat‐
850 ing application messages, Babel does not reinvent the wheel, but rather
851 reuses this infrastructure, and makes it easier to build message cata‐
852 logs for Python applications.
853
854 Message Extraction
855 Babel provides functionality similar to that of the xgettext program,
856 except that only extraction from Python source files is built-in, while
857 support for other file formats can be added using a simple extension
858 mechanism.
859
860 Unlike xgettext, which is usually invoked once for every file, the rou‐
861 tines for message extraction in Babel operate on directories. While the
862 per-file approach of xgettext works nicely with projects using a Make‐
863 file, Python projects rarely use make, and thus a different mechanism
864 is needed for extracting messages from the heterogeneous collection of
865 source files that many Python projects are composed of.
866
867 When message extraction is based on directories instead of individual
868 files, there needs to be a way to configure which files should be
869 treated in which manner. For example, while many projects may contain
870 .html files, some of those files may be static HTML files that don’t
871 contain localizable message, while others may be Jinja2 templates, and
872 still others may contain Genshi markup templates. Some projects may
873 even mix HTML files for different templates languages (for whatever
874 reason). Therefore the way in which messages are extracted from source
875 files can not only depend on the file extension, but needs to be con‐
876 trollable in a precise manner.
877
878 Babel accepts a configuration file to specify this mapping of files to
879 extraction methods, which is described below.
880
881 Front-Ends
882 Babel provides two different front-ends to access its functionality for
883 working with message catalogs:
884
885 • A Command-Line Interface, and
886
887 • Distutils/Setuptools Integration
888
889 Which one you choose depends on the nature of your project. For most
890 modern Python projects, the distutils/setuptools integration is proba‐
891 bly more convenient.
892
893 Extraction Method Mapping and Configuration
894 The mapping of extraction methods to files in Babel is done via a con‐
895 figuration file. This file maps extended glob patterns to the names of
896 the extraction methods, and can also set various options for each pat‐
897 tern (which options are available depends on the specific extraction
898 method).
899
900 For example, the following configuration adds extraction of messages
901 from both Genshi markup templates and text templates:
902
903 # Extraction from Python source files
904
905 [python: **.py]
906
907 # Extraction from Genshi HTML and text templates
908
909 [genshi: **/templates/**.html]
910 ignore_tags = script,style
911 include_attrs = alt title summary
912
913 [genshi: **/templates/**.txt]
914 template_class = genshi.template:TextTemplate
915 encoding = ISO-8819-15
916
917 # Extraction from JavaScript files
918
919 [javascript: **.js]
920 extract_messages = $._, jQuery._
921
922 The configuration file syntax is based on the format commonly found in
923 .INI files on Windows systems, and as supported by the ConfigParser
924 module in the Python standard library. Section names (the strings en‐
925 closed in square brackets) specify both the name of the extraction
926 method, and the extended glob pattern to specify the files that this
927 extraction method should be used for, separated by a colon. The options
928 in the sections are passed to the extraction method. Which options are
929 available is specific to the extraction method used.
930
931 The extended glob patterns used in this configuration are similar to
932 the glob patterns provided by most shells. A single asterisk (*) is a
933 wildcard for any number of characters (except for the pathname compo‐
934 nent separator “/”), while a question mark (?) only matches a single
935 character. In addition, two subsequent asterisk characters (**) can be
936 used to make the wildcard match any directory level, so the pattern
937 **.txt matches any file with the extension .txt in any directory.
938
939 Lines that start with a # or ; character are ignored and can be used
940 for comments. Empty lines are ignored, too.
941
942 NOTE:
943 if you’re performing message extraction using the command Babel pro‐
944 vides for integration into setup.py scripts, you can also provide
945 this configuration in a different way, namely as a keyword argument
946 to the setup() function. See Distutils/Setuptools Integration for
947 more information.
948
949 Default Extraction Methods
950 Babel comes with a few builtin extractors: python (which extracts mes‐
951 sages from Python source files), javascript, and ignore (which extracts
952 nothing).
953
954 The python extractor is by default mapped to the glob pattern **.py,
955 meaning it’ll be applied to all files with the .py extension in any di‐
956 rectory. If you specify your own mapping configuration, this default
957 mapping is discarded, so you need to explicitly add it to your mapping
958 (as shown in the example above.)
959
960 Referencing Extraction Methods
961 To be able to use short extraction method names such as “genshi”, you
962 need to have pkg_resources installed, and the package implementing that
963 extraction method needs to have been installed with its meta data (the
964 egg-info).
965
966 If this is not possible for some reason, you need to map the short
967 names to fully qualified function names in an extract section in the
968 mapping configuration. For example:
969
970 # Some custom extraction method
971
972 [extractors]
973 custom = mypackage.module:extract_custom
974
975 [custom: **.ctm]
976 some_option = foo
977
978 Note that the builtin extraction methods python and ignore are avail‐
979 able by default, even if pkg_resources is not installed. You should
980 never need to explicitly define them in the [extractors] section.
981
982 Writing Extraction Methods
983 Adding new methods for extracting localizable methods is easy. First,
984 you’ll need to implement a function that complies with the following
985 interface:
986
987 def extract_xxx(fileobj, keywords, comment_tags, options):
988 """Extract messages from XXX files.
989
990 :param fileobj: the file-like object the messages should be extracted
991 from
992 :param keywords: a list of keywords (i.e. function names) that should
993 be recognized as translation functions
994 :param comment_tags: a list of translator tags to search for and
995 include in the results
996 :param options: a dictionary of additional options (optional)
997 :return: an iterator over ``(lineno, funcname, message, comments)``
998 tuples
999 :rtype: ``iterator``
1000 """
1001
1002 NOTE:
1003 Any strings in the tuples produced by this function must be either
1004 unicode objects, or str objects using plain ASCII characters. That
1005 means that if sources contain strings using other encodings, it is
1006 the job of the extractor implementation to do the decoding to uni‐
1007 code objects.
1008
1009 Next, you should register that function as an entry point. This re‐
1010 quires your setup.py script to use setuptools, and your package to be
1011 installed with the necessary metadata. If that’s taken care of, add
1012 something like the following to your setup.py script:
1013
1014 def setup(...
1015
1016 entry_points = """
1017 [babel.extractors]
1018 xxx = your.package:extract_xxx
1019 """,
1020
1021 That is, add your extraction method to the entry point group babel.ex‐
1022 tractors, where the name of the entry point is the name that people
1023 will use to reference the extraction method, and the value being the
1024 module and the name of the function (separated by a colon) implementing
1025 the actual extraction.
1026
1027 NOTE:
1028 As shown in Referencing Extraction Methods, declaring an entry point
1029 is not strictly required, as users can still reference the extrac‐
1030 tion function directly. But whenever possible, the entry point
1031 should be declared to make configuration more convenient.
1032
1033 Translator Comments
1034 First of all what are comments tags. Comments tags are excerpts of text
1035 to search for in comments, only comments, right before the python get‐
1036 text calls, as shown on the following example:
1037
1038 # NOTE: This is a comment about `Foo Bar`
1039 _('Foo Bar')
1040
1041 The comments tag for the above example would be NOTE:, and the transla‐
1042 tor comment for that tag would be This is a comment about `Foo Bar`.
1043
1044 The resulting output in the catalog template would be something like:
1045
1046 #. This is a comment about `Foo Bar`
1047 #: main.py:2
1048 msgid "Foo Bar"
1049 msgstr ""
1050
1051 Now, you might ask, why would I need that?
1052
1053 Consider this simple case; you have a menu item called “manual”. You
1054 know what it means, but when the translator sees this they will wonder
1055 did you mean:
1056
1057 1. a document or help manual, or
1058
1059 2. a manual process?
1060
1061 This is the simplest case where a translation comment such as “The in‐
1062 stallation manual” helps to clarify the situation and makes a transla‐
1063 tor more productive.
1064
1065 NOTE:
1066 Whether translator comments can be extracted depends on the extrac‐
1067 tion method in use. The Python extractor provided by Babel does im‐
1068 plement this feature, but others may not.
1069
1070 Command-Line Interface
1071 Babel includes a command-line interface for working with message cata‐
1072 logs, similar to the various GNU gettext tools commonly available on
1073 Linux/Unix systems.
1074
1075 When properly installed, Babel provides a script called pybabel:
1076
1077 $ pybabel --help
1078 Usage: pybabel command [options] [args]
1079
1080 Options:
1081 --version show program's version number and exit
1082 -h, --help show this help message and exit
1083 --list-locales print all known locales and exit
1084 -v, --verbose print as much as possible
1085 -q, --quiet print as little as possible
1086
1087 commands:
1088 compile compile message catalogs to MO files
1089 extract extract messages from source files and generate a POT file
1090 init create new message catalogs from a POT file
1091 update update existing message catalogs from a POT file
1092
1093 The pybabel script provides a number of sub-commands that do the actual
1094 work. Those sub-commands are described below.
1095
1096 compile
1097 The compile sub-command can be used to compile translation catalogs
1098 into binary MO files:
1099
1100 $ pybabel compile --help
1101 Usage: pybabel compile [options]
1102
1103 compile message catalogs to MO files
1104
1105 Options:
1106 -h, --help show this help message and exit
1107 -D DOMAIN, --domain=DOMAIN
1108 domains of PO files (space separated list, default
1109 'messages')
1110 -d DIRECTORY, --directory=DIRECTORY
1111 path to base directory containing the catalogs
1112 -i INPUT_FILE, --input-file=INPUT_FILE
1113 name of the input file
1114 -o OUTPUT_FILE, --output-file=OUTPUT_FILE
1115 name of the output file (default
1116 '<output_dir>/<locale>/LC_MESSAGES/<domain>.mo')
1117 -l LOCALE, --locale=LOCALE
1118 locale of the catalog to compile
1119 -f, --use-fuzzy also include fuzzy translations
1120 --statistics print statistics about translations
1121
1122 If directory is specified, but output-file is not, the default filename
1123 of the output file will be:
1124
1125 <directory>/<locale>/LC_MESSAGES/<domain>.mo
1126
1127 If neither the input_file nor the locale option is set, this command
1128 looks for all catalog files in the base directory that match the given
1129 domain, and compiles each of them to MO files in the same directory.
1130
1131 extract
1132 The extract sub-command can be used to extract localizable messages
1133 from a collection of source files:
1134
1135 $ pybabel extract --help
1136 Usage: pybabel extract [options] <input-paths>
1137
1138 extract messages from source files and generate a POT file
1139
1140 Options:
1141 -h, --help show this help message and exit
1142 --charset=CHARSET charset to use in the output file (default "utf-8")
1143 -k KEYWORDS, --keywords=KEYWORDS, --keyword=KEYWORDS
1144 space-separated list of keywords to look for in
1145 addition to the defaults (may be repeated multiple
1146 times)
1147 --no-default-keywords
1148 do not include the default keywords
1149 -F MAPPING_FILE, --mapping-file=MAPPING_FILE, --mapping=MAPPING_FILE
1150 path to the mapping configuration file
1151 --no-location do not include location comments with filename and
1152 line number
1153 --add-location=ADD_LOCATION
1154 location lines format. If it is not given or "full",
1155 it generates the lines with both file name and line
1156 number. If it is "file", the line number part is
1157 omitted. If it is "never", it completely suppresses
1158 the lines (same as --no-location).
1159 --omit-header do not include msgid "" entry in header
1160 -o OUTPUT_FILE, --output-file=OUTPUT_FILE, --output=OUTPUT_FILE
1161 name of the output file
1162 -w WIDTH, --width=WIDTH
1163 set output line width (default 76)
1164 --no-wrap do not break long message lines, longer than the
1165 output line width, into several lines
1166 --sort-output generate sorted output (default False)
1167 --sort-by-file sort output by file location (default False)
1168 --msgid-bugs-address=MSGID_BUGS_ADDRESS
1169 set report address for msgid
1170 --copyright-holder=COPYRIGHT_HOLDER
1171 set copyright holder in output
1172 --project=PROJECT set project name in output
1173 --version=VERSION set project version in output
1174 -c ADD_COMMENTS, --add-comments=ADD_COMMENTS
1175 place comment block with TAG (or those preceding
1176 keyword lines) in output file. Separate multiple TAGs
1177 with commas(,)
1178 -s, --strip-comments, --strip-comment-tags
1179 strip the comment TAGs from the comments.
1180 --input-dirs=INPUT_DIRS
1181 alias for input-paths (does allow files as well as
1182 directories).
1183 --ignore-dirs=IGNORE_DIRS
1184 Patterns for directories to ignore when scanning for
1185 messages. Separate multiple patterns with spaces
1186 (default ".* ._")
1187 --header-comment=HEADER_COMMENT
1188 header comment for the catalog
1189
1190 init
1191 The init sub-command creates a new translations catalog based on a PO
1192 template file:
1193
1194 $ pybabel init --help
1195 Usage: pybabel init [options]
1196
1197 create new message catalogs from a POT file
1198
1199 Options:
1200 -h, --help show this help message and exit
1201 -D DOMAIN, --domain=DOMAIN
1202 domain of PO file (default 'messages')
1203 -i INPUT_FILE, --input-file=INPUT_FILE
1204 name of the input file
1205 -d OUTPUT_DIR, --output-dir=OUTPUT_DIR
1206 path to output directory
1207 -o OUTPUT_FILE, --output-file=OUTPUT_FILE
1208 name of the output file (default
1209 '<output_dir>/<locale>/LC_MESSAGES/<domain>.po')
1210 -l LOCALE, --locale=LOCALE
1211 locale for the new localized catalog
1212 -w WIDTH, --width=WIDTH
1213 set output line width (default 76)
1214 --no-wrap do not break long message lines, longer than the
1215 output line width, into several lines
1216
1217 update
1218 The update sub-command updates an existing new translations catalog
1219 based on a PO template file:
1220
1221 $ pybabel update --help
1222 Usage: pybabel update [options]
1223
1224 update existing message catalogs from a POT file
1225
1226 Options:
1227 -h, --help show this help message and exit
1228 -D DOMAIN, --domain=DOMAIN
1229 domain of PO file (default 'messages')
1230 -i INPUT_FILE, --input-file=INPUT_FILE
1231 name of the input file
1232 -d OUTPUT_DIR, --output-dir=OUTPUT_DIR
1233 path to base directory containing the catalogs
1234 -o OUTPUT_FILE, --output-file=OUTPUT_FILE
1235 name of the output file (default
1236 '<output_dir>/<locale>/LC_MESSAGES/<domain>.po')
1237 --omit-header do not include msgid entry in header
1238 -l LOCALE, --locale=LOCALE
1239 locale of the catalog to compile
1240 -w WIDTH, --width=WIDTH
1241 set output line width (default 76)
1242 --no-wrap do not break long message lines, longer than the
1243 output line width, into several lines
1244 --ignore-obsolete whether to omit obsolete messages from the output
1245 --init-missing if any output files are missing, initialize them first
1246 -N, --no-fuzzy-matching
1247 do not use fuzzy matching
1248 --update-header-comment
1249 update target header comment
1250 --previous keep previous msgids of translated messages
1251
1252 If output_dir is specified, but output-file is not, the default file‐
1253 name of the output file will be:
1254
1255 <directory>/<locale>/LC_MESSAGES/<domain>.mo
1256
1257 If neither the output_file nor the locale option is set, this command
1258 looks for all catalog files in the base directory that match the given
1259 domain, and updates each of them.
1260
1261 Distutils/Setuptools Integration
1262 Babel provides commands for integration into setup.py scripts, based on
1263 either the distutils package that is part of the Python standard li‐
1264 brary, or the third-party setuptools package.
1265
1266 These commands are available by default when Babel has been properly
1267 installed, and setup.py is using setuptools. For projects that use
1268 plain old distutils, the commands need to be registered explicitly, for
1269 example:
1270
1271 from distutils.core import setup
1272 from babel.messages import frontend as babel
1273
1274 setup(
1275 ...
1276 cmdclass = {'compile_catalog': babel.compile_catalog,
1277 'extract_messages': babel.extract_messages,
1278 'init_catalog': babel.init_catalog,
1279 'update_catalog': babel.update_catalog}
1280 )
1281
1282 compile_catalog
1283 The compile_catalog command is similar to the GNU msgfmt tool, in that
1284 it takes a message catalog from a PO file and compiles it to a binary
1285 MO file.
1286
1287 If the command has been correctly installed or registered, a project’s
1288 setup.py script should allow you to use the command:
1289
1290 $ ./setup.py compile_catalog --help
1291 Global options:
1292 --verbose (-v) run verbosely (default)
1293 --quiet (-q) run quietly (turns verbosity off)
1294 --dry-run (-n) don't actually do anything
1295 --help (-h) show detailed help message
1296
1297 Options for 'compile_catalog' command:
1298 ...
1299
1300 Running the command will produce a binary MO file:
1301
1302 $ ./setup.py compile_catalog --directory foobar/locale --locale pt_BR
1303 running compile_catalog
1304 compiling catalog to foobar/locale/pt_BR/LC_MESSAGES/messages.mo
1305
1306 Options
1307 The compile_catalog command accepts the following options:
1308
1309 ┌───────────────────┬────────────────────────────┐
1310 │Option │ Description │
1311 ├───────────────────┼────────────────────────────┤
1312 │--domain │ domain of the PO file (de‐ │
1313 │ │ faults to lower-cased │
1314 │ │ project name) │
1315 ├───────────────────┼────────────────────────────┤
1316 │--directory (-d) │ name of the base directory │
1317 ├───────────────────┼────────────────────────────┤
1318 │--input-file (-i) │ name of the input file │
1319 ├───────────────────┼────────────────────────────┤
1320 │--output-file (-o) │ name of the output file │
1321 ├───────────────────┼────────────────────────────┤
1322 │--locale (-l) │ locale for the new local‐ │
1323 │ │ ized string │
1324 ├───────────────────┼────────────────────────────┤
1325 │--use-fuzzy (-f) │ also include “fuzzy” │
1326 │ │ translations │
1327 ├───────────────────┼────────────────────────────┤
1328 │--statistics │ print statistics about │
1329 │ │ translations │
1330 └───────────────────┴────────────────────────────┘
1331
1332 If directory is specified, but output-file is not, the default filename
1333 of the output file will be:
1334
1335 <directory>/<locale>/LC_MESSAGES/<domain>.mo
1336
1337 If neither the input_file nor the locale option is set, this command
1338 looks for all catalog files in the base directory that match the given
1339 domain, and compiles each of them to MO files in the same directory.
1340
1341 These options can either be specified on the command-line, or in the
1342 setup.cfg file.
1343
1344 extract_messages
1345 The extract_messages command is comparable to the GNU xgettext program:
1346 it can extract localizable messages from a variety of difference source
1347 files, and generate a PO (portable object) template file from the col‐
1348 lected messages.
1349
1350 If the command has been correctly installed or registered, a project’s
1351 setup.py script should allow you to use the command:
1352
1353 $ ./setup.py extract_messages --help
1354 Global options:
1355 --verbose (-v) run verbosely (default)
1356 --quiet (-q) run quietly (turns verbosity off)
1357 --dry-run (-n) don't actually do anything
1358 --help (-h) show detailed help message
1359
1360 Options for 'extract_messages' command:
1361 ...
1362
1363 Running the command will produce a PO template file:
1364
1365 $ ./setup.py extract_messages --output-file foobar/locale/messages.pot
1366 running extract_messages
1367 extracting messages from foobar/__init__.py
1368 extracting messages from foobar/core.py
1369 ...
1370 writing PO template file to foobar/locale/messages.pot
1371
1372 Method Mapping
1373 The mapping of file patterns to extraction methods (and options) can be
1374 specified using a configuration file that is pointed to using the
1375 --mapping-file option shown above. Alternatively, you can configure the
1376 mapping directly in setup.py using a keyword argument to the setup()
1377 function:
1378
1379 setup(...
1380
1381 message_extractors = {
1382 'foobar': [
1383 ('**.py', 'python', None),
1384 ('**/templates/**.html', 'genshi', None),
1385 ('**/templates/**.txt', 'genshi', {
1386 'template_class': 'genshi.template:TextTemplate'
1387 })
1388 ],
1389 },
1390
1391 ...
1392 )
1393
1394 Options
1395 The extract_messages command accepts the following options:
1396
1397 ┌──────────────────────┬────────────────────────────┐
1398 │Option │ Description │
1399 ├──────────────────────┼────────────────────────────┤
1400 │--charset │ charset to use in the out‐ │
1401 │ │ put file │
1402 ├──────────────────────┼────────────────────────────┤
1403 │--keywords (-k) │ space-separated list of │
1404 │ │ keywords to look for in │
1405 │ │ addition to the defaults │
1406 ├──────────────────────┼────────────────────────────┤
1407 │--no-default-keywords │ do not include the default │
1408 │ │ keywords │
1409 ├──────────────────────┼────────────────────────────┤
1410 │--mapping-file (-F) │ path to the mapping con‐ │
1411 │ │ figuration file │
1412 └──────────────────────┴────────────────────────────┘
1413
1414
1415
1416
1417 │--no-location │ do not include location │
1418 │ │ comments with filename and │
1419 │ │ line number │
1420 ├──────────────────────┼────────────────────────────┤
1421 │--omit-header │ do not include msgid “” │
1422 │ │ entry in header │
1423 ├──────────────────────┼────────────────────────────┤
1424 │--output-file (-o) │ name of the output file │
1425 ├──────────────────────┼────────────────────────────┤
1426 │--width (-w) │ set output line width (de‐ │
1427 │ │ fault 76) │
1428 ├──────────────────────┼────────────────────────────┤
1429 │--no-wrap │ do not break long message │
1430 │ │ lines, longer than the │
1431 │ │ output line width, into │
1432 │ │ several lines │
1433 ├──────────────────────┼────────────────────────────┤
1434 │--input-dirs │ directories that should be │
1435 │ │ scanned for messages │
1436 ├──────────────────────┼────────────────────────────┤
1437 │--sort-output │ generate sorted output │
1438 │ │ (default False) │
1439 ├──────────────────────┼────────────────────────────┤
1440 │--sort-by-file │ sort output by file loca‐ │
1441 │ │ tion (default False) │
1442 ├──────────────────────┼────────────────────────────┤
1443 │--msgid-bugs-address │ set email address for mes‐ │
1444 │ │ sage bug reports │
1445 ├──────────────────────┼────────────────────────────┤
1446 │--copyright-holder │ set copyright holder in │
1447 │ │ output │
1448 ├──────────────────────┼────────────────────────────┤
1449 │--add-comments (-c) │ place comment block with │
1450 │ │ TAG (or those preceding │
1451 │ │ keyword lines) in output │
1452 │ │ file. Separate multiple │
1453 │ │ TAGs with commas(,) │
1454 └──────────────────────┴────────────────────────────┘
1455
1456 These options can either be specified on the command-line, or in the
1457 setup.cfg file. In the latter case, the options above become entries of
1458 the section [extract_messages], and the option names are changed to use
1459 underscore characters instead of dashes, for example:
1460
1461 [extract_messages]
1462 keywords = _ gettext ngettext
1463 mapping_file = mapping.cfg
1464 width = 80
1465
1466 This would be equivalent to invoking the command from the command-line
1467 as follows:
1468
1469 $ setup.py extract_messages -k _ -k gettext -k ngettext -F mapping.cfg -w 80
1470
1471 Any path names are interpreted relative to the location of the setup.py
1472 file. For boolean options, use “true” or “false” values.
1473
1474 init_catalog
1475 The init_catalog command is basically equivalent to the GNU msginit
1476 program: it creates a new translation catalog based on a PO template
1477 file (POT).
1478
1479 If the command has been correctly installed or registered, a project’s
1480 setup.py script should allow you to use the command:
1481
1482 $ ./setup.py init_catalog --help
1483 Global options:
1484 --verbose (-v) run verbosely (default)
1485 --quiet (-q) run quietly (turns verbosity off)
1486 --dry-run (-n) don't actually do anything
1487 --help (-h) show detailed help message
1488
1489 Options for 'init_catalog' command:
1490 ...
1491
1492 Running the command will produce a PO file:
1493
1494 $ ./setup.py init_catalog -l fr -i foobar/locales/messages.pot \
1495 -o foobar/locales/fr/messages.po
1496 running init_catalog
1497 creating catalog 'foobar/locales/fr/messages.po' based on 'foobar/locales/messages.pot'
1498
1499 Options
1500 The init_catalog command accepts the following options:
1501
1502 ┌───────────────────┬────────────────────────────┐
1503 │Option │ Description │
1504 ├───────────────────┼────────────────────────────┤
1505 │--domain │ domain of the PO file (de‐ │
1506 │ │ faults to lower-cased │
1507 │ │ project name) │
1508 ├───────────────────┼────────────────────────────┤
1509 │--input-file (-i) │ name of the input file │
1510 ├───────────────────┼────────────────────────────┤
1511 │--output-dir (-d) │ name of the output direc‐ │
1512 │ │ tory │
1513 ├───────────────────┼────────────────────────────┤
1514 │--output-file (-o) │ name of the output file │
1515 ├───────────────────┼────────────────────────────┤
1516 │--locale │ locale for the new local‐ │
1517 │ │ ized string │
1518 └───────────────────┴────────────────────────────┘
1519
1520 If output-dir is specified, but output-file is not, the default file‐
1521 name of the output file will be:
1522
1523 <output_dir>/<locale>/LC_MESSAGES/<domain>.po
1524
1525 These options can either be specified on the command-line, or in the
1526 setup.cfg file.
1527
1528 update_catalog
1529 The update_catalog command is basically equivalent to the GNU msgmerge
1530 program: it updates an existing translations catalog based on a PO tem‐
1531 plate file (POT).
1532
1533 If the command has been correctly installed or registered, a project’s
1534 setup.py script should allow you to use the command:
1535
1536 $ ./setup.py update_catalog --help
1537 Global options:
1538 --verbose (-v) run verbosely (default)
1539 --quiet (-q) run quietly (turns verbosity off)
1540 --dry-run (-n) don't actually do anything
1541 --help (-h) show detailed help message
1542
1543 Options for 'update_catalog' command:
1544 ...
1545
1546 Running the command will update a PO file:
1547
1548 $ ./setup.py update_catalog -l fr -i foobar/locales/messages.pot \
1549 -o foobar/locales/fr/messages.po
1550 running update_catalog
1551 updating catalog 'foobar/locales/fr/messages.po' based on 'foobar/locales/messages.pot'
1552
1553 Options
1554 The update_catalog command accepts the following options:
1555
1556 ┌─────────────────────────┬────────────────────────────┐
1557 │Option │ Description │
1558 ├─────────────────────────┼────────────────────────────┤
1559 │--domain │ domain of the PO file (de‐ │
1560 │ │ faults to lower-cased │
1561 │ │ project name) │
1562 ├─────────────────────────┼────────────────────────────┤
1563 │--input-file (-i) │ name of the input file │
1564 ├─────────────────────────┼────────────────────────────┤
1565 │--output-dir (-d) │ name of the output direc‐ │
1566 │ │ tory │
1567 ├─────────────────────────┼────────────────────────────┤
1568 │--output-file (-o) │ name of the output file │
1569 ├─────────────────────────┼────────────────────────────┤
1570 │--locale │ locale for the new local‐ │
1571 │ │ ized string │
1572 ├─────────────────────────┼────────────────────────────┤
1573 │--ignore-obsolete │ do not include obsolete │
1574 │ │ messages in the output │
1575 ├─────────────────────────┼────────────────────────────┤
1576 │--no-fuzzy-matching (-N) │ do not use fuzzy matching │
1577 ├─────────────────────────┼────────────────────────────┤
1578 │--previous │ keep previous msgids of │
1579 │ │ translated messages │
1580 └─────────────────────────┴────────────────────────────┘
1581
1582 If output-dir is specified, but output-file is not, the default file‐
1583 name of the output file will be:
1584
1585 <output_dir>/<locale>/LC_MESSAGES/<domain>.po
1586
1587 If neither the input_file nor the locale option is set, this command
1588 looks for all catalog files in the base directory that match the given
1589 domain, and updates each of them.
1590
1591 These options can either be specified on the command-line, or in the
1592 setup.cfg file.
1593
1594 Support Classes and Functions
1595 The babel.support modules contains a number of classes and functions
1596 that can help with integrating Babel, and internationalization in gen‐
1597 eral, into your application or framework. The code in this module is
1598 not used by Babel itself, but instead is provided to address common re‐
1599 quirements of applications that should handle internationalization.
1600
1601 Lazy Evaluation
1602 One such requirement is lazy evaluation of translations. Many web-based
1603 applications define some localizable message at the module level, or in
1604 general at some level where the locale of the remote user is not yet
1605 known. For such cases, web frameworks generally provide a “lazy” vari‐
1606 ant of the gettext functions, which basically translates the message
1607 not when the gettext function is invoked, but when the string is ac‐
1608 cessed in some manner.
1609
1610 Extended Translations Class
1611 Many web-based applications are composed of a variety of different com‐
1612 ponents (possibly using some kind of plugin system), and some of those
1613 components may provide their own message catalogs that need to be inte‐
1614 grated into the larger system.
1615
1616 To support this usage pattern, Babel provides a Translations class that
1617 is derived from the GNUTranslations class in the gettext module. This
1618 class adds a merge() method that takes another Translations instance,
1619 and merges the content of the latter into the main catalog:
1620
1621 translations = Translations.load('main')
1622 translations.merge(Translations.load('plugin1'))
1623
1625 The API reference lists the full public API that Babel provides.
1626
1627 API Reference
1628 This part of the documentation contains the full API reference of the
1629 public API of Babel.
1630
1631 Core Functionality
1632 The core API provides the basic core functionality. Primarily it pro‐
1633 vides the Locale object and ways to create it. This object encapsu‐
1634 lates a locale and exposes all the data it contains.
1635
1636 All the core functionality is also directly importable from the babel
1637 module for convenience.
1638
1639 Basic Interface
1640 class babel.core.Locale(language: str, territory: str | None = None,
1641 script: str | None = None, variant: str | None = None, modifier: str |
1642 None = None)
1643 Representation of a specific locale.
1644
1645 >>> locale = Locale('en', 'US')
1646 >>> repr(locale)
1647 "Locale('en', territory='US')"
1648 >>> locale.display_name
1649 u'English (United States)'
1650
1651 A Locale object can also be instantiated from a raw locale
1652 string:
1653
1654 >>> locale = Locale.parse('en-US', sep='-')
1655 >>> repr(locale)
1656 "Locale('en', territory='US')"
1657
1658 Locale objects provide access to a collection of locale data,
1659 such as territory and language names, number and date format
1660 patterns, and more:
1661
1662 >>> locale.number_symbols['decimal']
1663 u'.'
1664
1665 If a locale is requested for which no locale data is available,
1666 an UnknownLocaleError is raised:
1667
1668 >>> Locale.parse('en_XX')
1669 Traceback (most recent call last):
1670 ...
1671 UnknownLocaleError: unknown locale 'en_XX'
1672
1673 For more information see RFC 3066.
1674
1675 property character_order: str
1676 The text direction for the language.
1677
1678 >>> Locale('de', 'DE').character_order
1679 'left-to-right'
1680 >>> Locale('ar', 'SA').character_order
1681 'right-to-left'
1682
1683 property compact_currency_formats: LocaleDataDict
1684 Locale patterns for compact currency number formatting.
1685
1686 NOTE:
1687 The format of the value returned may change between
1688 Babel versions.
1689
1690 >>> Locale('en', 'US').compact_currency_formats["short"]["one"]["1000"]
1691 <NumberPattern u'¤0K'>
1692
1693 property compact_decimal_formats: LocaleDataDict
1694 Locale patterns for compact decimal number formatting.
1695
1696 NOTE:
1697 The format of the value returned may change between
1698 Babel versions.
1699
1700 >>> Locale('en', 'US').compact_decimal_formats["short"]["one"]["1000"]
1701 <NumberPattern u'0K'>
1702
1703 property currencies: LocaleDataDict
1704 Mapping of currency codes to translated currency names.
1705 This only returns the generic form of the currency name,
1706 not the count specific one. If an actual number is re‐
1707 quested use the babel.numbers.get_currency_name() func‐
1708 tion.
1709
1710 >>> Locale('en').currencies['COP']
1711 u'Colombian Peso'
1712 >>> Locale('de', 'DE').currencies['COP']
1713 u'Kolumbianischer Peso'
1714
1715 property currency_formats: LocaleDataDict
1716 Locale patterns for currency number formatting.
1717
1718 NOTE:
1719 The format of the value returned may change between
1720 Babel versions.
1721
1722 >>> Locale('en', 'US').currency_formats['standard']
1723 <NumberPattern u'\xa4#,##0.00'>
1724 >>> Locale('en', 'US').currency_formats['accounting']
1725 <NumberPattern u'\xa4#,##0.00;(\xa4#,##0.00)'>
1726
1727 property currency_symbols: LocaleDataDict
1728 Mapping of currency codes to symbols.
1729
1730 >>> Locale('en', 'US').currency_symbols['USD']
1731 u'$'
1732 >>> Locale('es', 'CO').currency_symbols['USD']
1733 u'US$'
1734
1735 property date_formats: LocaleDataDict
1736 Locale patterns for date formatting.
1737
1738 NOTE:
1739 The format of the value returned may change between
1740 Babel versions.
1741
1742 >>> Locale('en', 'US').date_formats['short']
1743 <DateTimePattern u'M/d/yy'>
1744 >>> Locale('fr', 'FR').date_formats['long']
1745 <DateTimePattern u'd MMMM y'>
1746
1747 property datetime_formats: LocaleDataDict
1748 Locale patterns for datetime formatting.
1749
1750 NOTE:
1751 The format of the value returned may change between
1752 Babel versions.
1753
1754 >>> Locale('en').datetime_formats['full']
1755 u'{1}, {0}'
1756 >>> Locale('th').datetime_formats['medium']
1757 u'{1} {0}'
1758
1759 property datetime_skeletons: LocaleDataDict
1760 Locale patterns for formatting parts of a datetime.
1761
1762 >>> Locale('en').datetime_skeletons['MEd']
1763 <DateTimePattern u'E, M/d'>
1764 >>> Locale('fr').datetime_skeletons['MEd']
1765 <DateTimePattern u'E dd/MM'>
1766 >>> Locale('fr').datetime_skeletons['H']
1767 <DateTimePattern u"HH 'h'">
1768
1769 property day_period_rules: LocaleDataDict
1770 Day period rules for the locale. Used by get_period_id.
1771
1772 property day_periods: LocaleDataDict
1773 Locale display names for various day periods (not neces‐
1774 sarily only AM/PM).
1775
1776 These are not meant to be used without the relevant
1777 day_period_rules.
1778
1779 property days: LocaleDataDict
1780 Locale display names for weekdays.
1781
1782 >>> Locale('de', 'DE').days['format']['wide'][3]
1783 u'Donnerstag'
1784
1785 property decimal_formats: LocaleDataDict
1786 Locale patterns for decimal number formatting.
1787
1788 NOTE:
1789 The format of the value returned may change between
1790 Babel versions.
1791
1792 >>> Locale('en', 'US').decimal_formats[None]
1793 <NumberPattern u'#,##0.###'>
1794
1795 classmethod default(category: str | None = None, aliases: Map‐
1796 ping[str, str] = {'ar': 'ar_SY', 'bg': 'bg_BG', 'bs': 'bs_BA',
1797 'ca': 'ca_ES', 'cs': 'cs_CZ', 'da': 'da_DK', 'de': 'de_DE',
1798 'el': 'el_GR', 'en': 'en_US', 'es': 'es_ES', 'et': 'et_EE',
1799 'fa': 'fa_IR', 'fi': 'fi_FI', 'fr': 'fr_FR', 'gl': 'gl_ES',
1800 'he': 'he_IL', 'hu': 'hu_HU', 'id': 'id_ID', 'is': 'is_IS',
1801 'it': 'it_IT', 'ja': 'ja_JP', 'km': 'km_KH', 'ko': 'ko_KR',
1802 'lt': 'lt_LT', 'lv': 'lv_LV', 'mk': 'mk_MK', 'nl': 'nl_NL',
1803 'nn': 'nn_NO', 'no': 'nb_NO', 'pl': 'pl_PL', 'pt': 'pt_PT',
1804 'ro': 'ro_RO', 'ru': 'ru_RU', 'sk': 'sk_SK', 'sl': 'sl_SI',
1805 'sv': 'sv_SE', 'th': 'th_TH', 'tr': 'tr_TR', 'uk': 'uk_UA'}) ->
1806 Locale
1807 Return the system default locale for the specified cate‐
1808 gory.
1809
1810 >>> for name in ['LANGUAGE', 'LC_ALL', 'LC_CTYPE', 'LC_MESSAGES']:
1811 ... os.environ[name] = ''
1812 >>> os.environ['LANG'] = 'fr_FR.UTF-8'
1813 >>> Locale.default('LC_MESSAGES')
1814 Locale('fr', territory='FR')
1815
1816 The following fallbacks to the variable are always con‐
1817 sidered:
1818
1819 • LANGUAGE
1820
1821 • LC_ALL
1822
1823 • LC_CTYPE
1824
1825 • LANG
1826
1827 Parameters
1828
1829 • category – one of the LC_XXX environment vari‐
1830 able names
1831
1832 • aliases – a dictionary of aliases for locale
1833 identifiers
1834
1835 property display_name: str | None
1836 The localized display name of the locale.
1837
1838 >>> Locale('en').display_name
1839 u'English'
1840 >>> Locale('en', 'US').display_name
1841 u'English (United States)'
1842 >>> Locale('sv').display_name
1843 u'svenska'
1844
1845 Type unicode
1846
1847 property english_name: str | None
1848 The english display name of the locale.
1849
1850 >>> Locale('de').english_name
1851 u'German'
1852 >>> Locale('de', 'DE').english_name
1853 u'German (Germany)'
1854
1855 Type unicode
1856
1857 property eras: LocaleDataDict
1858 Locale display names for eras.
1859
1860 NOTE:
1861 The format of the value returned may change between
1862 Babel versions.
1863
1864 >>> Locale('en', 'US').eras['wide'][1]
1865 u'Anno Domini'
1866 >>> Locale('en', 'US').eras['abbreviated'][0]
1867 u'BC'
1868
1869 property first_week_day: int
1870 The first day of a week, with 0 being Monday.
1871
1872 >>> Locale('de', 'DE').first_week_day
1873 0
1874 >>> Locale('en', 'US').first_week_day
1875 6
1876
1877 get_display_name(locale: Locale | str | None = None) -> str |
1878 None
1879 Return the display name of the locale using the given lo‐
1880 cale.
1881
1882 The display name will include the language, territory,
1883 script, and variant, if those are specified.
1884
1885 >>> Locale('zh', 'CN', script='Hans').get_display_name('en')
1886 u'Chinese (Simplified, China)'
1887
1888 Modifiers are currently passed through verbatim:
1889
1890 >>> Locale('it', 'IT', modifier='euro').get_display_name('en')
1891 u'Italian (Italy, euro)'
1892
1893 Parameters
1894 locale – the locale to use
1895
1896 get_language_name(locale: Locale | str | None = None) -> str |
1897 None
1898 Return the language of this locale in the given locale.
1899
1900 >>> Locale('zh', 'CN', script='Hans').get_language_name('de')
1901 u'Chinesisch'
1902
1903 New in version 1.0.
1904
1905
1906 Parameters
1907 locale – the locale to use
1908
1909 get_script_name(locale: Locale | str | None = None) -> str |
1910 None
1911 Return the script name in the given locale.
1912
1913 get_territory_name(locale: Locale | str | None = None) -> str |
1914 None
1915 Return the territory name in the given locale.
1916
1917 property interval_formats: LocaleDataDict
1918 Locale patterns for interval formatting.
1919
1920 NOTE:
1921 The format of the value returned may change between
1922 Babel versions.
1923
1924 How to format date intervals in Finnish when the day is
1925 the smallest changing component:
1926
1927 >>> Locale('fi_FI').interval_formats['MEd']['d']
1928 [u'E d. – ', u'E d.M.']
1929
1930 SEE ALSO:
1931 The primary API to use this data is
1932 babel.dates.format_interval().
1933
1934 Return type
1935 dict[str, dict[str, list[str]]]
1936
1937 language
1938 the language code
1939
1940 property language_name: str | None
1941 The localized language name of the locale.
1942
1943 >>> Locale('en', 'US').language_name
1944 u'English'
1945
1946 property languages: LocaleDataDict
1947 Mapping of language codes to translated language names.
1948
1949 >>> Locale('de', 'DE').languages['ja']
1950 u'Japanisch'
1951
1952 See ISO 639 for more information.
1953
1954 property list_patterns: LocaleDataDict
1955 Patterns for generating lists
1956
1957 NOTE:
1958 The format of the value returned may change between
1959 Babel versions.
1960
1961 >>> Locale('en').list_patterns['standard']['start']
1962 u'{0}, {1}'
1963 >>> Locale('en').list_patterns['standard']['end']
1964 u'{0}, and {1}'
1965 >>> Locale('en_GB').list_patterns['standard']['end']
1966 u'{0} and {1}'
1967
1968 property measurement_systems: LocaleDataDict
1969 Localized names for various measurement systems.
1970
1971 >>> Locale('fr', 'FR').measurement_systems['US']
1972 u'am\xe9ricain'
1973 >>> Locale('en', 'US').measurement_systems['US']
1974 u'US'
1975
1976 property meta_zones: LocaleDataDict
1977 Locale display names for meta time zones.
1978
1979 Meta time zones are basically groups of different Olson
1980 time zones that have the same GMT offset and daylight
1981 savings time.
1982
1983 NOTE:
1984 The format of the value returned may change between
1985 Babel versions.
1986
1987 >>> Locale('en', 'US').meta_zones['Europe_Central']['long']['daylight']
1988 u'Central European Summer Time'
1989
1990 New in version 0.9.
1991
1992
1993 property min_week_days: int
1994 The minimum number of days in a week so that the week is
1995 counted as the first week of a year or month.
1996
1997 >>> Locale('de', 'DE').min_week_days
1998 4
1999
2000 modifier
2001 the modifier
2002
2003 property months: LocaleDataDict
2004 Locale display names for months.
2005
2006 >>> Locale('de', 'DE').months['format']['wide'][10]
2007 u'Oktober'
2008
2009 classmethod negotiate(preferred: Iterable[str], available: Iter‐
2010 able[str], sep: str = '_', aliases: Mapping[str, str] = {'ar':
2011 'ar_SY', 'bg': 'bg_BG', 'bs': 'bs_BA', 'ca': 'ca_ES', 'cs':
2012 'cs_CZ', 'da': 'da_DK', 'de': 'de_DE', 'el': 'el_GR', 'en':
2013 'en_US', 'es': 'es_ES', 'et': 'et_EE', 'fa': 'fa_IR', 'fi':
2014 'fi_FI', 'fr': 'fr_FR', 'gl': 'gl_ES', 'he': 'he_IL', 'hu':
2015 'hu_HU', 'id': 'id_ID', 'is': 'is_IS', 'it': 'it_IT', 'ja':
2016 'ja_JP', 'km': 'km_KH', 'ko': 'ko_KR', 'lt': 'lt_LT', 'lv':
2017 'lv_LV', 'mk': 'mk_MK', 'nl': 'nl_NL', 'nn': 'nn_NO', 'no':
2018 'nb_NO', 'pl': 'pl_PL', 'pt': 'pt_PT', 'ro': 'ro_RO', 'ru':
2019 'ru_RU', 'sk': 'sk_SK', 'sl': 'sl_SI', 'sv': 'sv_SE', 'th':
2020 'th_TH', 'tr': 'tr_TR', 'uk': 'uk_UA'}) -> Locale | None
2021 Find the best match between available and requested lo‐
2022 cale strings.
2023
2024 >>> Locale.negotiate(['de_DE', 'en_US'], ['de_DE', 'de_AT'])
2025 Locale('de', territory='DE')
2026 >>> Locale.negotiate(['de_DE', 'en_US'], ['en', 'de'])
2027 Locale('de')
2028 >>> Locale.negotiate(['de_DE', 'de'], ['en_US'])
2029
2030 You can specify the character used in the locale identi‐
2031 fiers to separate the different components. This separa‐
2032 tor is applied to both lists. Also, case is ignored in
2033 the comparison:
2034
2035 >>> Locale.negotiate(['de-DE', 'de'], ['en-us', 'de-de'], sep='-')
2036 Locale('de', territory='DE')
2037
2038 Parameters
2039
2040 • preferred – the list of locale identifiers pre‐
2041 ferred by the user
2042
2043 • available – the list of locale identifiers
2044 available
2045
2046 • aliases – a dictionary of aliases for locale
2047 identifiers
2048
2049 property number_symbols: LocaleDataDict
2050 Symbols used in number formatting.
2051
2052 NOTE:
2053 The format of the value returned may change between
2054 Babel versions.
2055
2056 >>> Locale('fr', 'FR').number_symbols['decimal']
2057 u','
2058
2059 property ordinal_form: PluralRule
2060 Plural rules for the locale.
2061
2062 >>> Locale('en').ordinal_form(1)
2063 'one'
2064 >>> Locale('en').ordinal_form(2)
2065 'two'
2066 >>> Locale('en').ordinal_form(3)
2067 'few'
2068 >>> Locale('fr').ordinal_form(2)
2069 'other'
2070 >>> Locale('ru').ordinal_form(100)
2071 'other'
2072
2073 classmethod parse(identifier: str | Locale | None, sep: str =
2074 '_', resolve_likely_subtags: bool = True) -> Locale
2075 Create a Locale instance for the given locale identifier.
2076
2077 >>> l = Locale.parse('de-DE', sep='-')
2078 >>> l.display_name
2079 u'Deutsch (Deutschland)'
2080
2081 If the identifier parameter is not a string, but actually
2082 a Locale object, that object is returned:
2083
2084 >>> Locale.parse(l)
2085 Locale('de', territory='DE')
2086
2087 This also can perform resolving of likely subtags which
2088 it does by default. This is for instance useful to fig‐
2089 ure out the most likely locale for a territory you can
2090 use 'und' as the language tag:
2091
2092 >>> Locale.parse('und_AT')
2093 Locale('de', territory='AT')
2094
2095 Modifiers are optional, and always at the end, separated
2096 by “@”:
2097
2098 >>> Locale.parse('de_AT@euro')
2099 Locale('de', territory='AT', modifier='euro')
2100
2101 Parameters
2102
2103 • identifier – the locale identifier string
2104
2105 • sep – optional component separator
2106
2107 • resolve_likely_subtags – if this is specified
2108 then a locale will have its likely subtag re‐
2109 solved if the locale otherwise does not exist.
2110 For instance zh_TW by itself is not a locale
2111 that exists but Babel can automatically expand
2112 it to the full form of zh_hant_TW. Note that
2113 this expansion is only taking place if no locale
2114 exists otherwise. For instance there is a lo‐
2115 cale en that can exist by itself.
2116
2117 Raises
2118
2119 • ValueError – if the string does not appear to be
2120 a valid locale identifier
2121
2122 • UnknownLocaleError – if no locale data is avail‐
2123 able for the requested locale
2124
2125 • TypeError – if the identifier is not a string or
2126 a Locale
2127
2128 property percent_formats: LocaleDataDict
2129 Locale patterns for percent number formatting.
2130
2131 NOTE:
2132 The format of the value returned may change between
2133 Babel versions.
2134
2135 >>> Locale('en', 'US').percent_formats[None]
2136 <NumberPattern u'#,##0%'>
2137
2138 property periods: LocaleDataDict
2139 Locale display names for day periods (AM/PM).
2140
2141 >>> Locale('en', 'US').periods['am']
2142 u'AM'
2143
2144 property plural_form: PluralRule
2145 Plural rules for the locale.
2146
2147 >>> Locale('en').plural_form(1)
2148 'one'
2149 >>> Locale('en').plural_form(0)
2150 'other'
2151 >>> Locale('fr').plural_form(0)
2152 'one'
2153 >>> Locale('ru').plural_form(100)
2154 'many'
2155
2156 property quarters: LocaleDataDict
2157 Locale display names for quarters.
2158
2159 >>> Locale('de', 'DE').quarters['format']['wide'][1]
2160 u'1. Quartal'
2161
2162 property scientific_formats: LocaleDataDict
2163 Locale patterns for scientific number formatting.
2164
2165 NOTE:
2166 The format of the value returned may change between
2167 Babel versions.
2168
2169 >>> Locale('en', 'US').scientific_formats[None]
2170 <NumberPattern u'#E0'>
2171
2172 script the script code
2173
2174 property script_name: str | None
2175 The localized script name of the locale if available.
2176
2177 >>> Locale('sr', 'ME', script='Latn').script_name
2178 u'latinica'
2179
2180 property scripts: LocaleDataDict
2181 Mapping of script codes to translated script names.
2182
2183 >>> Locale('en', 'US').scripts['Hira']
2184 u'Hiragana'
2185
2186 See ISO 15924 for more information.
2187
2188 property territories: LocaleDataDict
2189 Mapping of script codes to translated script names.
2190
2191 >>> Locale('es', 'CO').territories['DE']
2192 u'Alemania'
2193
2194 See ISO 3166 for more information.
2195
2196 territory
2197 the territory (country or region) code
2198
2199 property territory_name: str | None
2200 The localized territory name of the locale if available.
2201
2202 >>> Locale('de', 'DE').territory_name
2203 u'Deutschland'
2204
2205 property text_direction: str
2206 The text direction for the language in CSS short-hand
2207 form.
2208
2209 >>> Locale('de', 'DE').text_direction
2210 'ltr'
2211 >>> Locale('ar', 'SA').text_direction
2212 'rtl'
2213
2214 property time_formats: LocaleDataDict
2215 Locale patterns for time formatting.
2216
2217 NOTE:
2218 The format of the value returned may change between
2219 Babel versions.
2220
2221 >>> Locale('en', 'US').time_formats['short']
2222 <DateTimePattern u'h:mm a'>
2223 >>> Locale('fr', 'FR').time_formats['long']
2224 <DateTimePattern u'HH:mm:ss z'>
2225
2226 property time_zones: LocaleDataDict
2227 Locale display names for time zones.
2228
2229 NOTE:
2230 The format of the value returned may change between
2231 Babel versions.
2232
2233 >>> Locale('en', 'US').time_zones['Europe/London']['long']['daylight']
2234 u'British Summer Time'
2235 >>> Locale('en', 'US').time_zones['America/St_Johns']['city']
2236 u'St. John’s'
2237
2238 property unit_display_names: LocaleDataDict
2239 Display names for units of measurement.
2240
2241 SEE ALSO:
2242 You may want to use babel.units.get_unit_name() in‐
2243 stead.
2244
2245 NOTE:
2246 The format of the value returned may change between
2247 Babel versions.
2248
2249 variant
2250 the variant code
2251
2252 property variants: LocaleDataDict
2253 Mapping of script codes to translated script names.
2254
2255 >>> Locale('de', 'DE').variants['1901']
2256 u'Alte deutsche Rechtschreibung'
2257
2258 property weekend_end: int
2259 The day the weekend ends, with 0 being Monday.
2260
2261 >>> Locale('de', 'DE').weekend_end
2262 6
2263
2264 property weekend_start: int
2265 The day the weekend starts, with 0 being Monday.
2266
2267 >>> Locale('de', 'DE').weekend_start
2268 5
2269
2270 property zone_formats: LocaleDataDict
2271 Patterns related to the formatting of time zones.
2272
2273 NOTE:
2274 The format of the value returned may change between
2275 Babel versions.
2276
2277 >>> Locale('en', 'US').zone_formats['fallback']
2278 u'%(1)s (%(0)s)'
2279 >>> Locale('pt', 'BR').zone_formats['region']
2280 u'Hor\xe1rio %s'
2281
2282 New in version 0.9.
2283
2284
2285 babel.core.default_locale(category: str | None = None, aliases: Map‐
2286 ping[str, str] = {'ar': 'ar_SY', 'bg': 'bg_BG', 'bs': 'bs_BA', 'ca':
2287 'ca_ES', 'cs': 'cs_CZ', 'da': 'da_DK', 'de': 'de_DE', 'el': 'el_GR',
2288 'en': 'en_US', 'es': 'es_ES', 'et': 'et_EE', 'fa': 'fa_IR', 'fi':
2289 'fi_FI', 'fr': 'fr_FR', 'gl': 'gl_ES', 'he': 'he_IL', 'hu': 'hu_HU',
2290 'id': 'id_ID', 'is': 'is_IS', 'it': 'it_IT', 'ja': 'ja_JP', 'km':
2291 'km_KH', 'ko': 'ko_KR', 'lt': 'lt_LT', 'lv': 'lv_LV', 'mk': 'mk_MK',
2292 'nl': 'nl_NL', 'nn': 'nn_NO', 'no': 'nb_NO', 'pl': 'pl_PL', 'pt':
2293 'pt_PT', 'ro': 'ro_RO', 'ru': 'ru_RU', 'sk': 'sk_SK', 'sl': 'sl_SI',
2294 'sv': 'sv_SE', 'th': 'th_TH', 'tr': 'tr_TR', 'uk': 'uk_UA'}) -> str |
2295 None
2296 Returns the system default locale for a given category, based on
2297 environment variables.
2298
2299 >>> for name in ['LANGUAGE', 'LC_ALL', 'LC_CTYPE']:
2300 ... os.environ[name] = ''
2301 >>> os.environ['LANG'] = 'fr_FR.UTF-8'
2302 >>> default_locale('LC_MESSAGES')
2303 'fr_FR'
2304
2305 The “C” or “POSIX” pseudo-locales are treated as aliases for the
2306 “en_US_POSIX” locale:
2307
2308 >>> os.environ['LC_MESSAGES'] = 'POSIX'
2309 >>> default_locale('LC_MESSAGES')
2310 'en_US_POSIX'
2311
2312 The following fallbacks to the variable are always considered:
2313
2314 • LANGUAGE
2315
2316 • LC_ALL
2317
2318 • LC_CTYPE
2319
2320 • LANG
2321
2322 Parameters
2323
2324 • category – one of the LC_XXX environment variable names
2325
2326 • aliases – a dictionary of aliases for locale identi‐
2327 fiers
2328
2329 babel.core.negotiate_locale(preferred: Iterable[str], available: Iter‐
2330 able[str], sep: str = '_', aliases: Mapping[str, str] = {'ar': 'ar_SY',
2331 'bg': 'bg_BG', 'bs': 'bs_BA', 'ca': 'ca_ES', 'cs': 'cs_CZ', 'da':
2332 'da_DK', 'de': 'de_DE', 'el': 'el_GR', 'en': 'en_US', 'es': 'es_ES',
2333 'et': 'et_EE', 'fa': 'fa_IR', 'fi': 'fi_FI', 'fr': 'fr_FR', 'gl':
2334 'gl_ES', 'he': 'he_IL', 'hu': 'hu_HU', 'id': 'id_ID', 'is': 'is_IS',
2335 'it': 'it_IT', 'ja': 'ja_JP', 'km': 'km_KH', 'ko': 'ko_KR', 'lt':
2336 'lt_LT', 'lv': 'lv_LV', 'mk': 'mk_MK', 'nl': 'nl_NL', 'nn': 'nn_NO',
2337 'no': 'nb_NO', 'pl': 'pl_PL', 'pt': 'pt_PT', 'ro': 'ro_RO', 'ru':
2338 'ru_RU', 'sk': 'sk_SK', 'sl': 'sl_SI', 'sv': 'sv_SE', 'th': 'th_TH',
2339 'tr': 'tr_TR', 'uk': 'uk_UA'}) -> str | None
2340 Find the best match between available and requested locale
2341 strings.
2342
2343 >>> negotiate_locale(['de_DE', 'en_US'], ['de_DE', 'de_AT'])
2344 'de_DE'
2345 >>> negotiate_locale(['de_DE', 'en_US'], ['en', 'de'])
2346 'de'
2347
2348 Case is ignored by the algorithm, the result uses the case of
2349 the preferred locale identifier:
2350
2351 >>> negotiate_locale(['de_DE', 'en_US'], ['de_de', 'de_at'])
2352 'de_DE'
2353
2354 >>> negotiate_locale(['de_DE', 'en_US'], ['de_de', 'de_at'])
2355 'de_DE'
2356
2357 By default, some web browsers unfortunately do not include the
2358 territory in the locale identifier for many locales, and some
2359 don’t even allow the user to easily add the territory. So while
2360 you may prefer using qualified locale identifiers in your
2361 web-application, they would not normally match the language-only
2362 locale sent by such browsers. To workaround that, this function
2363 uses a default mapping of commonly used language-only locale
2364 identifiers to identifiers including the territory:
2365
2366 >>> negotiate_locale(['ja', 'en_US'], ['ja_JP', 'en_US'])
2367 'ja_JP'
2368
2369 Some browsers even use an incorrect or outdated language code,
2370 such as “no” for Norwegian, where the correct locale identifier
2371 would actually be “nb_NO” (Bokmål) or “nn_NO” (Nynorsk). The
2372 aliases are intended to take care of such cases, too:
2373
2374 >>> negotiate_locale(['no', 'sv'], ['nb_NO', 'sv_SE'])
2375 'nb_NO'
2376
2377 You can override this default mapping by passing a different
2378 aliases dictionary to this function, or you can bypass the be‐
2379 havior althogher by setting the aliases parameter to None.
2380
2381 Parameters
2382
2383 • preferred – the list of locale strings preferred by the
2384 user
2385
2386 • available – the list of locale strings available
2387
2388 • sep – character that separates the different parts of
2389 the locale strings
2390
2391 • aliases – a dictionary of aliases for locale identi‐
2392 fiers
2393
2394 Exceptions
2395 exception babel.core.UnknownLocaleError(identifier: str)
2396 Exception thrown when a locale is requested for which no locale
2397 data is available.
2398
2399 identifier
2400 The identifier of the locale that could not be found.
2401
2402 Utility Functions
2403 babel.core.get_global(key: _GLOBAL_KEY) -> Mapping[str, Any]
2404 Return the dictionary for the given key in the global data.
2405
2406 The global data is stored in the babel/global.dat file and con‐
2407 tains information independent of individual locales.
2408
2409 >>> get_global('zone_aliases')['UTC']
2410 u'Etc/UTC'
2411 >>> get_global('zone_territories')['Europe/Berlin']
2412 u'DE'
2413
2414 The keys available are:
2415
2416 • all_currencies
2417
2418 • currency_fractions
2419
2420 • language_aliases
2421
2422 • likely_subtags
2423
2424 • parent_exceptions
2425
2426 • script_aliases
2427
2428 • territory_aliases
2429
2430 • territory_currencies
2431
2432 • territory_languages
2433
2434 • territory_zones
2435
2436 • variant_aliases
2437
2438 • windows_zone_mapping
2439
2440 • zone_aliases
2441
2442 • zone_territories
2443
2444 NOTE:
2445 The internal structure of the data may change between ver‐
2446 sions.
2447
2448 New in version 0.9.
2449
2450
2451 Parameters
2452 key – the data key
2453
2454 babel.core.parse_locale(identifier: str, sep: str = '_') -> tuple[str,
2455 str | None, str | None, str | None] | tuple[str, str | None, str |
2456 None, str | None, str | None]
2457 Parse a locale identifier into a tuple of the form (language,
2458 territory, script, variant, modifier).
2459
2460 >>> parse_locale('zh_CN')
2461 ('zh', 'CN', None, None)
2462 >>> parse_locale('zh_Hans_CN')
2463 ('zh', 'CN', 'Hans', None)
2464 >>> parse_locale('ca_es_valencia')
2465 ('ca', 'ES', None, 'VALENCIA')
2466 >>> parse_locale('en_150')
2467 ('en', '150', None, None)
2468 >>> parse_locale('en_us_posix')
2469 ('en', 'US', None, 'POSIX')
2470 >>> parse_locale('it_IT@euro')
2471 ('it', 'IT', None, None, 'euro')
2472 >>> parse_locale('it_IT@custom')
2473 ('it', 'IT', None, None, 'custom')
2474 >>> parse_locale('it_IT@')
2475 ('it', 'IT', None, None)
2476
2477 The default component separator is “_”, but a different separa‐
2478 tor can be specified using the sep parameter.
2479
2480 The optional modifier is always separated with “@” and at the
2481 end:
2482
2483 >>> parse_locale('zh-CN', sep='-')
2484 ('zh', 'CN', None, None)
2485 >>> parse_locale('zh-CN@custom', sep='-')
2486 ('zh', 'CN', None, None, 'custom')
2487
2488 If the identifier cannot be parsed into a locale, a ValueError
2489 exception is raised:
2490
2491 >>> parse_locale('not_a_LOCALE_String')
2492 Traceback (most recent call last):
2493 ...
2494 ValueError: 'not_a_LOCALE_String' is not a valid locale identifier
2495
2496 Encoding information is removed from the identifier, while modi‐
2497 fiers are kept:
2498
2499 >>> parse_locale('en_US.UTF-8')
2500 ('en', 'US', None, None)
2501 >>> parse_locale('de_DE.iso885915@euro')
2502 ('de', 'DE', None, None, 'euro')
2503
2504 See RFC 4646 for more information.
2505
2506 Parameters
2507
2508 • identifier – the locale identifier string
2509
2510 • sep – character that separates the different components
2511 of the locale identifier
2512
2513 Raises ValueError – if the string does not appear to be a valid
2514 locale identifier
2515
2516 babel.core.get_locale_identifier(tup: tuple[str] | tuple[str, str |
2517 None] | tuple[str, str | None, str | None] | tuple[str, str | None, str
2518 | None, str | None] | tuple[str, str | None, str | None, str | None,
2519 str | None], sep: str = '_') -> str
2520 The reverse of parse_locale(). It creates a locale identifier
2521 out of a (language, territory, script, variant, modifier) tuple.
2522 Items can be set to None and trailing Nones can also be left out
2523 of the tuple.
2524
2525 >>> get_locale_identifier(('de', 'DE', None, '1999', 'custom'))
2526 'de_DE_1999@custom'
2527 >>> get_locale_identifier(('fi', None, None, None, 'custom'))
2528 'fi@custom'
2529
2530 New in version 1.0.
2531
2532
2533 Parameters
2534
2535 • tup – the tuple as returned by parse_locale().
2536
2537 • sep – the separator for the identifier.
2538
2539 Date and Time
2540 The date and time functionality provided by Babel lets you format stan‐
2541 dard Python datetime, date and time objects and work with timezones.
2542
2543 Date and Time Formatting
2544 babel.dates.format_datetime(datetime=None, format='medium', tz‐
2545 info=None, locale=default_locale('LC_TIME'))
2546 Return a date formatted according to the given pattern.
2547
2548 >>> from datetime import datetime
2549 >>> dt = datetime(2007, 4, 1, 15, 30)
2550 >>> format_datetime(dt, locale='en_US')
2551 u'Apr 1, 2007, 3:30:00\u202fPM'
2552
2553 For any pattern requiring the display of the timezone:
2554
2555 >>> format_datetime(dt, 'full', tzinfo=get_timezone('Europe/Paris'),
2556 ... locale='fr_FR')
2557 'dimanche 1 avril 2007, 17:30:00 heure d’été d’Europe centrale'
2558 >>> format_datetime(dt, "yyyy.MM.dd G 'at' HH:mm:ss zzz",
2559 ... tzinfo=get_timezone('US/Eastern'), locale='en')
2560 u'2007.04.01 AD at 11:30:00 EDT'
2561
2562 Parameters
2563
2564 • datetime -- the datetime object; if None, the current
2565 date and time is used
2566
2567 • format -- one of "full", "long", "medium", or "short",
2568 or a custom date/time pattern
2569
2570 • tzinfo -- the timezone to apply to the time for display
2571
2572 • locale -- a Locale object or a locale identifier
2573
2574 babel.dates.format_date(date=None, format='medium', locale=default_lo‐
2575 cale('LC_TIME'))
2576 Return a date formatted according to the given pattern.
2577
2578 >>> from datetime import date
2579 >>> d = date(2007, 4, 1)
2580 >>> format_date(d, locale='en_US')
2581 u'Apr 1, 2007'
2582 >>> format_date(d, format='full', locale='de_DE')
2583 u'Sonntag, 1. April 2007'
2584
2585 If you don't want to use the locale default formats, you can
2586 specify a custom date pattern:
2587
2588 >>> format_date(d, "EEE, MMM d, ''yy", locale='en')
2589 u"Sun, Apr 1, '07"
2590
2591 Parameters
2592
2593 • date -- the date or datetime object; if None, the cur‐
2594 rent date is used
2595
2596 • format -- one of "full", "long", "medium", or "short",
2597 or a custom date/time pattern
2598
2599 • locale -- a Locale object or a locale identifier
2600
2601 babel.dates.format_time(time=None, format='medium', tzinfo=None, lo‐
2602 cale=default_locale('LC_TIME'))
2603 Return a time formatted according to the given pattern.
2604
2605 >>> from datetime import datetime, time
2606 >>> t = time(15, 30)
2607 >>> format_time(t, locale='en_US')
2608 u'3:30:00\u202fPM'
2609 >>> format_time(t, format='short', locale='de_DE')
2610 u'15:30'
2611
2612 If you don't want to use the locale default formats, you can
2613 specify a custom time pattern:
2614
2615 >>> format_time(t, "hh 'o''clock' a", locale='en')
2616 u"03 o'clock PM"
2617
2618 For any pattern requiring the display of the time-zone a time‐
2619 zone has to be specified explicitly:
2620
2621 >>> t = datetime(2007, 4, 1, 15, 30)
2622 >>> tzinfo = get_timezone('Europe/Paris')
2623 >>> t = _localize(tzinfo, t)
2624 >>> format_time(t, format='full', tzinfo=tzinfo, locale='fr_FR')
2625 '15:30:00 heure d’été d’Europe centrale'
2626 >>> format_time(t, "hh 'o''clock' a, zzzz", tzinfo=get_timezone('US/Eastern'),
2627 ... locale='en')
2628 u"09 o'clock AM, Eastern Daylight Time"
2629
2630 As that example shows, when this function gets passed a date‐
2631 time.datetime value, the actual time in the formatted string is
2632 adjusted to the timezone specified by the tzinfo parameter. If
2633 the datetime is "naive" (i.e. it has no associated timezone in‐
2634 formation), it is assumed to be in UTC.
2635
2636 These timezone calculations are not performed if the value is of
2637 type datetime.time, as without date information there's no way
2638 to determine what a given time would translate to in a different
2639 timezone without information about whether daylight savings time
2640 is in effect or not. This means that time values are left as-is,
2641 and the value of the tzinfo parameter is only used to display
2642 the timezone name if needed:
2643
2644 >>> t = time(15, 30)
2645 >>> format_time(t, format='full', tzinfo=get_timezone('Europe/Paris'),
2646 ... locale='fr_FR')
2647 u'15:30:00 heure normale d\u2019Europe centrale'
2648 >>> format_time(t, format='full', tzinfo=get_timezone('US/Eastern'),
2649 ... locale='en_US')
2650 u'3:30:00\u202fPM Eastern Standard Time'
2651
2652 Parameters
2653
2654 • time -- the time or datetime object; if None, the cur‐
2655 rent time in UTC is used
2656
2657 • format -- one of "full", "long", "medium", or "short",
2658 or a custom date/time pattern
2659
2660 • tzinfo -- the time-zone to apply to the time for dis‐
2661 play
2662
2663 • locale -- a Locale object or a locale identifier
2664
2665 babel.dates.format_timedelta(delta, granularity='second', thresh‐
2666 old=.85, add_direction=False, format='long', locale=default_lo‐
2667 cale('LC_TIME'))
2668 Return a time delta according to the rules of the given locale.
2669
2670 >>> from datetime import timedelta
2671 >>> format_timedelta(timedelta(weeks=12), locale='en_US')
2672 u'3 months'
2673 >>> format_timedelta(timedelta(seconds=1), locale='es')
2674 u'1 segundo'
2675
2676 The granularity parameter can be provided to alter the lowest
2677 unit presented, which defaults to a second.
2678
2679 >>> format_timedelta(timedelta(hours=3), granularity='day', locale='en_US')
2680 u'1 day'
2681
2682 The threshold parameter can be used to determine at which value
2683 the presentation switches to the next higher unit. A higher
2684 threshold factor means the presentation will switch later. For
2685 example:
2686
2687 >>> format_timedelta(timedelta(hours=23), threshold=0.9, locale='en_US')
2688 u'1 day'
2689 >>> format_timedelta(timedelta(hours=23), threshold=1.1, locale='en_US')
2690 u'23 hours'
2691
2692 In addition directional information can be provided that informs
2693 the user if the date is in the past or in the future:
2694
2695 >>> format_timedelta(timedelta(hours=1), add_direction=True, locale='en')
2696 u'in 1 hour'
2697 >>> format_timedelta(timedelta(hours=-1), add_direction=True, locale='en')
2698 u'1 hour ago'
2699
2700 The format parameter controls how compact or wide the presenta‐
2701 tion is:
2702
2703 >>> format_timedelta(timedelta(hours=3), format='short', locale='en')
2704 u'3 hr'
2705 >>> format_timedelta(timedelta(hours=3), format='narrow', locale='en')
2706 u'3h'
2707
2708 Parameters
2709
2710 • delta -- a timedelta object representing the time dif‐
2711 ference to format, or the delta in seconds as an int
2712 value
2713
2714 • granularity -- determines the smallest unit that should
2715 be displayed, the value can be one of "year", "month",
2716 "week", "day", "hour", "minute" or "second"
2717
2718 • threshold -- factor that determines at which point the
2719 presentation switches to the next higher unit
2720
2721 • add_direction -- if this flag is set to True the return
2722 value will include directional information. For in‐
2723 stance a positive timedelta will include the informa‐
2724 tion about it being in the future, a negative will be
2725 information about the value being in the past.
2726
2727 • format -- the format, can be "narrow", "short" or
2728 "long". ( "medium" is deprecated, currently converted
2729 to "long" to maintain compatibility)
2730
2731 • locale -- a Locale object or a locale identifier
2732
2733 babel.dates.format_skeleton(skeleton, datetime=None, tzinfo=None,
2734 fuzzy=True, locale=default_locale('LC_TIME'))
2735 Return a time and/or date formatted according to the given pat‐
2736 tern.
2737
2738 The skeletons are defined in the CLDR data and provide more
2739 flexibility than the simple short/long/medium formats, but are a
2740 bit harder to use. The are defined using the date/time symbols
2741 without order or punctuation and map to a suitable format for
2742 the given locale.
2743
2744 >>> from datetime import datetime
2745 >>> t = datetime(2007, 4, 1, 15, 30)
2746 >>> format_skeleton('MMMEd', t, locale='fr')
2747 u'dim. 1 avr.'
2748 >>> format_skeleton('MMMEd', t, locale='en')
2749 u'Sun, Apr 1'
2750 >>> format_skeleton('yMMd', t, locale='fi') # yMMd is not in the Finnish locale; yMd gets used
2751 u'1.4.2007'
2752 >>> format_skeleton('yMMd', t, fuzzy=False, locale='fi') # yMMd is not in the Finnish locale, an error is thrown
2753 Traceback (most recent call last):
2754 ...
2755 KeyError: yMMd
2756
2757 After the skeleton is resolved to a pattern format_datetime is
2758 called so all timezone processing etc is the same as for that.
2759
2760 Parameters
2761
2762 • skeleton -- A date time skeleton as defined in the cldr
2763 data.
2764
2765 • datetime -- the time or datetime object; if None, the
2766 current time in UTC is used
2767
2768 • tzinfo -- the time-zone to apply to the time for dis‐
2769 play
2770
2771 • fuzzy -- If the skeleton is not found, allow choosing a
2772 skeleton that's close enough to it.
2773
2774 • locale -- a Locale object or a locale identifier
2775
2776 babel.dates.format_interval(start, end, skeleton=None, tzinfo=None,
2777 fuzzy=True, locale=default_locale('LC_TIME'))
2778 Format an interval between two instants according to the lo‐
2779 cale's rules.
2780
2781 >>> from datetime import date, time
2782 >>> format_interval(date(2016, 1, 15), date(2016, 1, 17), "yMd", locale="fi")
2783 u'15.–17.1.2016'
2784
2785 >>> format_interval(time(12, 12), time(16, 16), "Hm", locale="en_GB")
2786 '12:12–16:16'
2787
2788 >>> format_interval(time(5, 12), time(16, 16), "hm", locale="en_US")
2789 '5:12 AM – 4:16 PM'
2790
2791 >>> format_interval(time(16, 18), time(16, 24), "Hm", locale="it")
2792 '16:18–16:24'
2793
2794 If the start instant equals the end instant, the interval is
2795 formatted like the instant.
2796
2797 >>> format_interval(time(16, 18), time(16, 18), "Hm", locale="it")
2798 '16:18'
2799
2800 Unknown skeletons fall back to "default" formatting.
2801
2802 >>> format_interval(date(2015, 1, 1), date(2017, 1, 1), "wzq", locale="ja")
2803 '2015/01/01~2017/01/01'
2804
2805 >>> format_interval(time(16, 18), time(16, 24), "xxx", locale="ja")
2806 '16:18:00~16:24:00'
2807
2808 >>> format_interval(date(2016, 1, 15), date(2016, 1, 17), "xxx", locale="de")
2809 '15.01.2016 – 17.01.2016'
2810
2811 Parameters
2812
2813 • start -- First instant (datetime/date/time)
2814
2815 • end -- Second instant (datetime/date/time)
2816
2817 • skeleton -- The "skeleton format" to use for format‐
2818 ting.
2819
2820 • tzinfo -- tzinfo to use (if none is already attached)
2821
2822 • fuzzy -- If the skeleton is not found, allow choosing a
2823 skeleton that's close enough to it.
2824
2825 • locale -- A locale object or identifier.
2826
2827 Returns
2828 Formatted interval
2829
2830 Timezone Functionality
2831 babel.dates.get_timezone(zone: str | tzinfo | None = None) -> tzinfo
2832 Looks up a timezone by name and returns it. The timezone object
2833 returned comes from pytz or zoneinfo, whichever is available.
2834 It corresponds to the tzinfo interface and can be used with all
2835 of the functions of Babel that operate with dates.
2836
2837 If a timezone is not known a LookupError is raised. If zone is
2838 None a local zone object is returned.
2839
2840 Parameters
2841 zone -- the name of the timezone to look up. If a time‐
2842 zone object itself is passed in, it's returned unchanged.
2843
2844 babel.dates.get_timezone_gmt(datetime: _Instant = None, width: Lit‐
2845 eral['long', 'short', 'iso8601', 'iso8601_short'] = 'long', locale:
2846 Locale | str | None = 'en_US_POSIX', return_z: bool = False) -> str
2847 Return the timezone associated with the given datetime object
2848 formatted as string indicating the offset from GMT.
2849
2850 >>> from datetime import datetime
2851 >>> dt = datetime(2007, 4, 1, 15, 30)
2852 >>> get_timezone_gmt(dt, locale='en')
2853 u'GMT+00:00'
2854 >>> get_timezone_gmt(dt, locale='en', return_z=True)
2855 'Z'
2856 >>> get_timezone_gmt(dt, locale='en', width='iso8601_short')
2857 u'+00'
2858 >>> tz = get_timezone('America/Los_Angeles')
2859 >>> dt = _localize(tz, datetime(2007, 4, 1, 15, 30))
2860 >>> get_timezone_gmt(dt, locale='en')
2861 u'GMT-07:00'
2862 >>> get_timezone_gmt(dt, 'short', locale='en')
2863 u'-0700'
2864 >>> get_timezone_gmt(dt, locale='en', width='iso8601_short')
2865 u'-07'
2866
2867 The long format depends on the locale, for example in France the
2868 acronym UTC string is used instead of GMT:
2869
2870 >>> get_timezone_gmt(dt, 'long', locale='fr_FR')
2871 u'UTC-07:00'
2872
2873 New in version 0.9.
2874
2875
2876 Parameters
2877
2878 • datetime -- the datetime object; if None, the current
2879 date and time in UTC is used
2880
2881 • width -- either "long" or "short" or "iso8601" or
2882 "iso8601_short"
2883
2884 • locale -- the Locale object, or a locale string
2885
2886 • return_z -- True or False; Function returns indicator
2887 "Z" when local time offset is 0
2888
2889 babel.dates.get_timezone_location(dt_or_tzinfo: _DtOrTzinfo = None, lo‐
2890 cale: Locale | str | None = 'en_US_POSIX', return_city: bool = False)
2891 -> str
2892 Return a representation of the given timezone using "location
2893 format".
2894
2895 The result depends on both the local display name of the country
2896 and the city associated with the time zone:
2897
2898 >>> tz = get_timezone('America/St_Johns')
2899 >>> print(get_timezone_location(tz, locale='de_DE'))
2900 Kanada (St. John’s) (Ortszeit)
2901 >>> print(get_timezone_location(tz, locale='en'))
2902 Canada (St. John’s) Time
2903 >>> print(get_timezone_location(tz, locale='en', return_city=True))
2904 St. John’s
2905 >>> tz = get_timezone('America/Mexico_City')
2906 >>> get_timezone_location(tz, locale='de_DE')
2907 u'Mexiko (Mexiko-Stadt) (Ortszeit)'
2908
2909 If the timezone is associated with a country that uses only a
2910 single timezone, just the localized country name is returned:
2911
2912 >>> tz = get_timezone('Europe/Berlin')
2913 >>> get_timezone_name(tz, locale='de_DE')
2914 u'Mitteleurop\xe4ische Zeit'
2915
2916 New in version 0.9.
2917
2918
2919 Parameters
2920
2921 • dt_or_tzinfo -- the datetime or tzinfo object that de‐
2922 termines the timezone; if None, the current date and
2923 time in UTC is assumed
2924
2925 • locale -- the Locale object, or a locale string
2926
2927 • return_city -- True or False, if True then return exem‐
2928 plar city (location) for the time zone
2929
2930 Returns
2931 the localized timezone name using location format
2932
2933 babel.dates.get_timezone_name(dt_or_tzinfo: _DtOrTzinfo = None, width:
2934 Literal['long', 'short'] = 'long', uncommon: bool = False, locale:
2935 Locale | str | None = 'en_US_POSIX', zone_variant: Literal['generic',
2936 'daylight', 'standard'] | None = None, return_zone: bool = False) ->
2937 str
2938 Return the localized display name for the given timezone. The
2939 timezone may be specified using a datetime or tzinfo object.
2940
2941 >>> from datetime import time
2942 >>> dt = time(15, 30, tzinfo=get_timezone('America/Los_Angeles'))
2943 >>> get_timezone_name(dt, locale='en_US')
2944 u'Pacific Standard Time'
2945 >>> get_timezone_name(dt, locale='en_US', return_zone=True)
2946 'America/Los_Angeles'
2947 >>> get_timezone_name(dt, width='short', locale='en_US')
2948 u'PST'
2949
2950 If this function gets passed only a tzinfo object and no con‐
2951 crete datetime, the returned display name is independent of
2952 daylight savings time. This can be used for example for select‐
2953 ing timezones, or to set the time of events that recur across
2954 DST changes:
2955
2956 >>> tz = get_timezone('America/Los_Angeles')
2957 >>> get_timezone_name(tz, locale='en_US')
2958 u'Pacific Time'
2959 >>> get_timezone_name(tz, 'short', locale='en_US')
2960 u'PT'
2961
2962 If no localized display name for the timezone is available, and
2963 the timezone is associated with a country that uses only a sin‐
2964 gle timezone, the name of that country is returned, formatted
2965 according to the locale:
2966
2967 >>> tz = get_timezone('Europe/Berlin')
2968 >>> get_timezone_name(tz, locale='de_DE')
2969 u'Mitteleurop\xe4ische Zeit'
2970 >>> get_timezone_name(tz, locale='pt_BR')
2971 u'Hor\xe1rio da Europa Central'
2972
2973 On the other hand, if the country uses multiple timezones, the
2974 city is also included in the representation:
2975
2976 >>> tz = get_timezone('America/St_Johns')
2977 >>> get_timezone_name(tz, locale='de_DE')
2978 u'Neufundland-Zeit'
2979
2980 Note that short format is currently not supported for all time‐
2981 zones and all locales. This is partially because not every
2982 timezone has a short code in every locale. In that case it cur‐
2983 rently falls back to the long format.
2984
2985 For more information see LDML Appendix J: Time Zone Display
2986 Names
2987
2988 New in version 0.9.
2989
2990
2991 Changed in version 1.0: Added zone_variant support.
2992
2993
2994 Parameters
2995
2996 • dt_or_tzinfo -- the datetime or tzinfo object that de‐
2997 termines the timezone; if a tzinfo object is used, the
2998 resulting display name will be generic, i.e. indepen‐
2999 dent of daylight savings time; if None, the current
3000 date in UTC is assumed
3001
3002 • width -- either "long" or "short"
3003
3004 • uncommon -- deprecated and ignored
3005
3006 • zone_variant -- defines the zone variation to return.
3007 By default the variation is defined from the datetime
3008 object passed in. If no datetime object is passed in,
3009 the 'generic' variation is assumed. The following val‐
3010 ues are valid: 'generic', 'daylight' and 'standard'.
3011
3012 • locale -- the Locale object, or a locale string
3013
3014 • return_zone -- True or False. If true then function re‐
3015 turns long time zone ID
3016
3017 babel.dates.UTC
3018 A timezone object for UTC.
3019
3020 babel.dates.LOCALTZ
3021 A timezone object for the computer's local timezone.
3022
3023 Data Access
3024 babel.dates.get_period_names(width: Literal['abbreviated', 'narrow',
3025 'wide'] = 'wide', context: _Context = 'stand-alone', locale: Locale |
3026 str | None = 'en_US_POSIX') -> LocaleDataDict
3027 Return the names for day periods (AM/PM) used by the locale.
3028
3029 >>> get_period_names(locale='en_US')['am']
3030 u'AM'
3031
3032 Parameters
3033
3034 • width -- the width to use, one of "abbreviated", "nar‐
3035 row", or "wide"
3036
3037 • context -- the context, either "format" or
3038 "stand-alone"
3039
3040 • locale -- the Locale object, or a locale string
3041
3042 babel.dates.get_day_names(width: Literal['abbreviated', 'narrow',
3043 'short', 'wide'] = 'wide', context: _Context = 'format', locale: Locale
3044 | str | None = 'en_US_POSIX') -> LocaleDataDict
3045 Return the day names used by the locale for the specified for‐
3046 mat.
3047
3048 >>> get_day_names('wide', locale='en_US')[1]
3049 u'Tuesday'
3050 >>> get_day_names('short', locale='en_US')[1]
3051 u'Tu'
3052 >>> get_day_names('abbreviated', locale='es')[1]
3053 u'mar'
3054 >>> get_day_names('narrow', context='stand-alone', locale='de_DE')[1]
3055 u'D'
3056
3057 Parameters
3058
3059 • width -- the width to use, one of "wide", "abbrevi‐
3060 ated", "short" or "narrow"
3061
3062 • context -- the context, either "format" or
3063 "stand-alone"
3064
3065 • locale -- the Locale object, or a locale string
3066
3067 babel.dates.get_month_names(width: Literal['abbreviated', 'narrow',
3068 'wide'] = 'wide', context: _Context = 'format', locale: Locale | str |
3069 None = 'en_US_POSIX') -> LocaleDataDict
3070 Return the month names used by the locale for the specified for‐
3071 mat.
3072
3073 >>> get_month_names('wide', locale='en_US')[1]
3074 u'January'
3075 >>> get_month_names('abbreviated', locale='es')[1]
3076 u'ene'
3077 >>> get_month_names('narrow', context='stand-alone', locale='de_DE')[1]
3078 u'J'
3079
3080 Parameters
3081
3082 • width -- the width to use, one of "wide", "abbrevi‐
3083 ated", or "narrow"
3084
3085 • context -- the context, either "format" or
3086 "stand-alone"
3087
3088 • locale -- the Locale object, or a locale string
3089
3090 babel.dates.get_quarter_names(width: Literal['abbreviated', 'narrow',
3091 'wide'] = 'wide', context: _Context = 'format', locale: Locale | str |
3092 None = 'en_US_POSIX') -> LocaleDataDict
3093 Return the quarter names used by the locale for the specified
3094 format.
3095
3096 >>> get_quarter_names('wide', locale='en_US')[1]
3097 u'1st quarter'
3098 >>> get_quarter_names('abbreviated', locale='de_DE')[1]
3099 u'Q1'
3100 >>> get_quarter_names('narrow', locale='de_DE')[1]
3101 u'1'
3102
3103 Parameters
3104
3105 • width -- the width to use, one of "wide", "abbrevi‐
3106 ated", or "narrow"
3107
3108 • context -- the context, either "format" or
3109 "stand-alone"
3110
3111 • locale -- the Locale object, or a locale string
3112
3113 babel.dates.get_era_names(width: Literal['abbreviated', 'narrow',
3114 'wide'] = 'wide', locale: Locale | str | None = 'en_US_POSIX') -> Lo‐
3115 caleDataDict
3116 Return the era names used by the locale for the specified for‐
3117 mat.
3118
3119 >>> get_era_names('wide', locale='en_US')[1]
3120 u'Anno Domini'
3121 >>> get_era_names('abbreviated', locale='de_DE')[1]
3122 u'n. Chr.'
3123
3124 Parameters
3125
3126 • width -- the width to use, either "wide", "abbrevi‐
3127 ated", or "narrow"
3128
3129 • locale -- the Locale object, or a locale string
3130
3131 babel.dates.get_date_format(format: _PredefinedTimeFormat = 'medium',
3132 locale: Locale | str | None = 'en_US_POSIX') -> DateTimePattern
3133 Return the date formatting patterns used by the locale for the
3134 specified format.
3135
3136 >>> get_date_format(locale='en_US')
3137 <DateTimePattern u'MMM d, y'>
3138 >>> get_date_format('full', locale='de_DE')
3139 <DateTimePattern u'EEEE, d. MMMM y'>
3140
3141 Parameters
3142
3143 • format -- the format to use, one of "full", "long",
3144 "medium", or "short"
3145
3146 • locale -- the Locale object, or a locale string
3147
3148 babel.dates.get_datetime_format(format: _PredefinedTimeFormat =
3149 'medium', locale: Locale | str | None = 'en_US_POSIX') -> DateTimePat‐
3150 tern
3151 Return the datetime formatting patterns used by the locale for
3152 the specified format.
3153
3154 >>> get_datetime_format(locale='en_US')
3155 u'{1}, {0}'
3156
3157 Parameters
3158
3159 • format -- the format to use, one of "full", "long",
3160 "medium", or "short"
3161
3162 • locale -- the Locale object, or a locale string
3163
3164 babel.dates.get_time_format(format: _PredefinedTimeFormat = 'medium',
3165 locale: Locale | str | None = 'en_US_POSIX') -> DateTimePattern
3166 Return the time formatting patterns used by the locale for the
3167 specified format.
3168
3169 >>> get_time_format(locale='en_US')
3170 <DateTimePattern u'h:mm:ss a'>
3171 >>> get_time_format('full', locale='de_DE')
3172 <DateTimePattern u'HH:mm:ss zzzz'>
3173
3174 Parameters
3175
3176 • format -- the format to use, one of "full", "long",
3177 "medium", or "short"
3178
3179 • locale -- the Locale object, or a locale string
3180
3181 Basic Parsing
3182 babel.dates.parse_date(string: str, locale: Locale | str | None =
3183 'en_US_POSIX', format: _PredefinedTimeFormat = 'medium') -> date‐
3184 time.date
3185 Parse a date from a string.
3186
3187 This function first tries to interpret the string as ISO-8601
3188 date format, then uses the date format for the locale as a hint
3189 to determine the order in which the date fields appear in the
3190 string.
3191
3192 >>> parse_date('4/1/04', locale='en_US')
3193 datetime.date(2004, 4, 1)
3194 >>> parse_date('01.04.2004', locale='de_DE')
3195 datetime.date(2004, 4, 1)
3196 >>> parse_date('2004-04-01', locale='en_US')
3197 datetime.date(2004, 4, 1)
3198 >>> parse_date('2004-04-01', locale='de_DE')
3199 datetime.date(2004, 4, 1)
3200
3201 Parameters
3202
3203 • string -- the string containing the date
3204
3205 • locale -- a Locale object or a locale identifier
3206
3207 • format -- the format to use (see get_date_format)
3208
3209 babel.dates.parse_time(string: str, locale: Locale | str | None =
3210 'en_US_POSIX', format: _PredefinedTimeFormat = 'medium') -> date‐
3211 time.time
3212 Parse a time from a string.
3213
3214 This function uses the time format for the locale as a hint to
3215 determine the order in which the time fields appear in the
3216 string.
3217
3218 >>> parse_time('15:30:00', locale='en_US')
3219 datetime.time(15, 30)
3220
3221 Parameters
3222
3223 • string -- the string containing the time
3224
3225 • locale -- a Locale object or a locale identifier
3226
3227 • format -- the format to use (see get_time_format)
3228
3229 Returns
3230 the parsed time
3231
3232 Return type
3233 time
3234
3235 babel.dates.parse_pattern(pattern: str | DateTimePattern) -> Date‐
3236 TimePattern
3237 Parse date, time, and datetime format patterns.
3238
3239 >>> parse_pattern("MMMMd").format
3240 u'%(MMMM)s%(d)s'
3241 >>> parse_pattern("MMM d, yyyy").format
3242 u'%(MMM)s %(d)s, %(yyyy)s'
3243
3244 Pattern can contain literal strings in single quotes:
3245
3246 >>> parse_pattern("H:mm' Uhr 'z").format
3247 u'%(H)s:%(mm)s Uhr %(z)s'
3248
3249 An actual single quote can be used by using two adjacent single
3250 quote characters:
3251
3252 >>> parse_pattern("hh' o''clock'").format
3253 u"%(hh)s o'clock"
3254
3255 Parameters
3256 pattern -- the formatting pattern to parse
3257
3258 Languages
3259 The languages module provides functionality to access data about lan‐
3260 guages that is not bound to a given locale.
3261
3262 Official Languages
3263 babel.languages.get_official_languages(territory: str, regional: bool =
3264 False, de_facto: bool = False) -> tuple[str, ...]
3265 Get the official language(s) for the given territory.
3266
3267 The language codes, if any are known, are returned in order of
3268 descending popularity.
3269
3270 If the regional flag is set, then languages which are regionally
3271 official are also returned.
3272
3273 If the de_facto flag is set, then languages which are “de facto”
3274 official are also returned.
3275
3276 WARNING:
3277 Note that the data is as up to date as the current version of
3278 the CLDR used by Babel. If you need scientifically accurate
3279 information, use another source!
3280
3281 Parameters
3282
3283 • territory (str) – Territory code
3284
3285 • regional (bool) – Whether to return regionally official
3286 languages too
3287
3288 • de_facto (bool) – Whether to return de-facto official
3289 languages too
3290
3291 Returns
3292 Tuple of language codes
3293
3294 Return type
3295 tuple[str]
3296
3297 babel.languages.get_territory_language_info(territory: str) ->
3298 dict[str, dict[str, float | str | None]]
3299 Get a dictionary of language information for a territory.
3300
3301 The dictionary is keyed by language code; the values are dicts
3302 with more information.
3303
3304 The following keys are currently known for the values:
3305
3306 •
3307
3308 population_percent: The percentage of the territory’s popula‐
3309 tion speaking the
3310 language.
3311
3312 •
3313
3314 official_status: An optional string describing the officiality
3315 status of the language.
3316 Known values are “official”, “official_regional” and
3317 “de_facto_official”.
3318
3319 WARNING:
3320 Note that the data is as up to date as the current version of
3321 the CLDR used by Babel. If you need scientifically accurate
3322 information, use another source!
3323
3324 NOTE:
3325 Note that the format of the dict returned may change between
3326 Babel versions.
3327
3328 See
3329 https://www.unicode.org/cldr/charts/latest/supplemental/territory_language_information.html
3330
3331 Parameters
3332 territory (str) – Territory code
3333
3334 Returns
3335 Language information dictionary
3336
3337 Return type
3338 dict[str, dict]
3339
3340 List Formatting
3341 This module lets you format lists of items in a locale-dependent man‐
3342 ner.
3343
3344 babel.lists.format_list(lst: Sequence[str], style: Literal['standard',
3345 'standard-short', 'or', 'or-short', 'unit', 'unit-short', 'unit-nar‐
3346 row'] = 'standard', locale: Locale | str | None = 'en_US_POSIX') -> str
3347 Format the items in lst as a list.
3348
3349 >>> format_list(['apples', 'oranges', 'pears'], locale='en')
3350 u'apples, oranges, and pears'
3351 >>> format_list(['apples', 'oranges', 'pears'], locale='zh')
3352 u'apples、oranges和pears'
3353 >>> format_list(['omena', 'peruna', 'aplari'], style='or', locale='fi')
3354 u'omena, peruna tai aplari'
3355
3356 These styles are defined, but not all are necessarily available
3357 in all locales. The following text is verbatim from the Unicode
3358 TR35-49 spec [1].
3359
3360 • standard: A typical ‘and’ list for arbitrary placeholders.
3361 eg. “January, February, and March”
3362
3363 • standard-short: A short version of a ‘and’ list, suitable for
3364 use with short or abbreviated placeholder values. eg. “Jan.,
3365 Feb., and Mar.”
3366
3367 • or: A typical ‘or’ list for arbitrary placeholders. eg. “Jan‐
3368 uary, February, or March”
3369
3370 • or-short: A short version of an ‘or’ list. eg. “Jan., Feb.,
3371 or Mar.”
3372
3373 • unit: A list suitable for wide units. eg. “3 feet, 7 inches”
3374
3375 • unit-short: A list suitable for short units eg. “3 ft, 7 in”
3376
3377 • unit-narrow: A list suitable for narrow units, where space on
3378 the screen is very limited. eg. “3′ 7″”
3379
3380 [1]:
3381 https://www.unicode.org/reports/tr35/tr35-49/tr35-general.html#ListPatterns
3382
3383 Parameters
3384
3385 • lst – a sequence of items to format in to a list
3386
3387 • style – the style to format the list with. See above
3388 for description.
3389
3390 • locale – the locale
3391
3392 Messages and Catalogs
3393 Babel provides functionality to work with message catalogs. This part
3394 of the API documentation shows those parts.
3395
3396 Messages and Catalogs
3397 This module provides a basic interface to hold catalog and message in‐
3398 formation. It’s generally used to modify a gettext catalog but it is
3399 not being used to actually use the translations.
3400
3401 Catalogs
3402 class babel.messages.catalog.Catalog(locale: str | Locale | None =
3403 None, domain: str | None = None, header_comment: str | None = '# Trans‐
3404 lations template for PROJECT.\n# Copyright (C) YEAR ORGANIZATION\n#
3405 This file is distributed under the same license as the PROJECT
3406 project.\n# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.\n#', project: str |
3407 None = None, version: str | None = None, copyright_holder: str | None =
3408 None, msgid_bugs_address: str | None = None, creation_date: datetime |
3409 str | None = None, revision_date: datetime | time | float | str | None
3410 = None, last_translator: str | None = None, language_team: str | None =
3411 None, charset: str | None = None, fuzzy: bool = True)
3412 Representation of a message catalog.
3413
3414 __iter__() -> Iterator[Message]
3415 Iterates through all the entries in the catalog, in the
3416 order they were added, yielding a Message object for ev‐
3417 ery entry.
3418
3419 Return type
3420 iterator
3421
3422 add(id: _MessageID, string: _MessageID | None = None, locations:
3423 Iterable[tuple[str, int]] = (), flags: Iterable[str] = (),
3424 auto_comments: Iterable[str] = (), user_comments: Iterable[str]
3425 = (), previous_id: _MessageID = (), lineno: int | None = None,
3426 context: str | None = None) -> Message
3427 Add or update the message with the specified ID.
3428
3429 >>> catalog = Catalog()
3430 >>> catalog.add(u'foo')
3431 <Message ...>
3432 >>> catalog[u'foo']
3433 <Message u'foo' (flags: [])>
3434
3435 This method simply constructs a Message object with the
3436 given arguments and invokes __setitem__ with that object.
3437
3438 Parameters
3439
3440 • id – the message ID, or a (singular, plural) tu‐
3441 ple for pluralizable messages
3442
3443 • string – the translated message string, or a
3444 (singular, plural) tuple for pluralizable mes‐
3445 sages
3446
3447 • locations – a sequence of (filename, lineno) tu‐
3448 ples
3449
3450 • flags – a set or sequence of flags
3451
3452 • auto_comments – a sequence of automatic comments
3453
3454 • user_comments – a sequence of user comments
3455
3456 • previous_id – the previous message ID, or a
3457 (singular, plural) tuple for pluralizable mes‐
3458 sages
3459
3460 • lineno – the line number on which the msgid line
3461 was found in the PO file, if any
3462
3463 • context – the message context
3464
3465 check() -> Iterable[tuple[babel.messages.catalog.Message, list[‐
3466 babel.messages.catalog.TranslationError]]]
3467 Run various validation checks on the translations in the
3468 catalog.
3469
3470 For every message which fails validation, this method
3471 yield a (message, errors) tuple, where message is the
3472 Message object and errors is a sequence of Translation‐
3473 Error objects.
3474
3475 Return type
3476 generator of (message, errors)
3477
3478 delete(id: _MessageID, context: str | None = None) -> None
3479 Delete the message with the specified ID and context.
3480
3481 Parameters
3482
3483 • id – the message ID
3484
3485 • context – the message context, or None for no
3486 context
3487
3488 get(id: _MessageID, context: str | None = None) -> Message |
3489 None
3490 Return the message with the specified ID and context.
3491
3492 Parameters
3493
3494 • id – the message ID
3495
3496 • context – the message context, or None for no
3497 context
3498
3499 property header_comment: str
3500 The header comment for the catalog.
3501
3502 >>> catalog = Catalog(project='Foobar', version='1.0',
3503 ... copyright_holder='Foo Company')
3504 >>> print(catalog.header_comment)
3505 # Translations template for Foobar.
3506 # Copyright (C) ... Foo Company
3507 # This file is distributed under the same license as the Foobar project.
3508 # FIRST AUTHOR <EMAIL@ADDRESS>, ....
3509 #
3510
3511 The header can also be set from a string. Any known up‐
3512 per-case variables will be replaced when the header is
3513 retrieved again:
3514
3515 >>> catalog = Catalog(project='Foobar', version='1.0',
3516 ... copyright_holder='Foo Company')
3517 >>> catalog.header_comment = '''\
3518 ... # The POT for my really cool PROJECT project.
3519 ... # Copyright (C) 1990-2003 ORGANIZATION
3520 ... # This file is distributed under the same license as the PROJECT
3521 ... # project.
3522 ... #'''
3523 >>> print(catalog.header_comment)
3524 # The POT for my really cool Foobar project.
3525 # Copyright (C) 1990-2003 Foo Company
3526 # This file is distributed under the same license as the Foobar
3527 # project.
3528 #
3529
3530 Type unicode
3531
3532 is_identical(other: Catalog) -> bool
3533 Checks if catalogs are identical, taking into account
3534 messages and headers.
3535
3536 language_team
3537 Name and email address of the language team.
3538
3539 last_translator
3540 Name and email address of the last translator.
3541
3542 property mime_headers: list[tuple[str, str]]
3543 The MIME headers of the catalog, used for the special ms‐
3544 gid "" entry.
3545
3546 The behavior of this property changes slightly depending
3547 on whether a locale is set or not, the latter indicating
3548 that the catalog is actually a template for actual trans‐
3549 lations.
3550
3551 Here’s an example of the output for such a catalog tem‐
3552 plate:
3553
3554 >>> from babel.dates import UTC
3555 >>> from datetime import datetime
3556 >>> created = datetime(1990, 4, 1, 15, 30, tzinfo=UTC)
3557 >>> catalog = Catalog(project='Foobar', version='1.0',
3558 ... creation_date=created)
3559 >>> for name, value in catalog.mime_headers:
3560 ... print('%s: %s' % (name, value))
3561 Project-Id-Version: Foobar 1.0
3562 Report-Msgid-Bugs-To: EMAIL@ADDRESS
3563 POT-Creation-Date: 1990-04-01 15:30+0000
3564 PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE
3565 Last-Translator: FULL NAME <EMAIL@ADDRESS>
3566 Language-Team: LANGUAGE <LL@li.org>
3567 MIME-Version: 1.0
3568 Content-Type: text/plain; charset=utf-8
3569 Content-Transfer-Encoding: 8bit
3570 Generated-By: Babel ...
3571
3572 And here’s an example of the output when the locale is
3573 set:
3574
3575 >>> revised = datetime(1990, 8, 3, 12, 0, tzinfo=UTC)
3576 >>> catalog = Catalog(locale='de_DE', project='Foobar', version='1.0',
3577 ... creation_date=created, revision_date=revised,
3578 ... last_translator='John Doe <jd@example.com>',
3579 ... language_team='de_DE <de@example.com>')
3580 >>> for name, value in catalog.mime_headers:
3581 ... print('%s: %s' % (name, value))
3582 Project-Id-Version: Foobar 1.0
3583 Report-Msgid-Bugs-To: EMAIL@ADDRESS
3584 POT-Creation-Date: 1990-04-01 15:30+0000
3585 PO-Revision-Date: 1990-08-03 12:00+0000
3586 Last-Translator: John Doe <jd@example.com>
3587 Language: de_DE
3588 Language-Team: de_DE <de@example.com>
3589 Plural-Forms: nplurals=2; plural=(n != 1);
3590 MIME-Version: 1.0
3591 Content-Type: text/plain; charset=utf-8
3592 Content-Transfer-Encoding: 8bit
3593 Generated-By: Babel ...
3594
3595 Type list
3596
3597 property num_plurals: int
3598 The number of plurals used by the catalog or locale.
3599
3600 >>> Catalog(locale='en').num_plurals
3601 2
3602 >>> Catalog(locale='ga').num_plurals
3603 5
3604
3605 Type int
3606
3607 property plural_expr: str
3608 The plural expression used by the catalog or locale.
3609
3610 >>> Catalog(locale='en').plural_expr
3611 '(n != 1)'
3612 >>> Catalog(locale='ga').plural_expr
3613 '(n==1 ? 0 : n==2 ? 1 : n>=3 && n<=6 ? 2 : n>=7 && n<=10 ? 3 : 4)'
3614 >>> Catalog(locale='ding').plural_expr # unknown locale
3615 '(n != 1)'
3616
3617 Type str
3618
3619 property plural_forms: str
3620 Return the plural forms declaration for the locale.
3621
3622 >>> Catalog(locale='en').plural_forms
3623 'nplurals=2; plural=(n != 1);'
3624 >>> Catalog(locale='pt_BR').plural_forms
3625 'nplurals=2; plural=(n > 1);'
3626
3627 Type str
3628
3629 update(template: Catalog, no_fuzzy_matching: bool = False, up‐
3630 date_header_comment: bool = False, keep_user_comments: bool =
3631 True) -> None
3632 Update the catalog based on the given template catalog.
3633
3634 >>> from babel.messages import Catalog
3635 >>> template = Catalog()
3636 >>> template.add('green', locations=[('main.py', 99)])
3637 <Message ...>
3638 >>> template.add('blue', locations=[('main.py', 100)])
3639 <Message ...>
3640 >>> template.add(('salad', 'salads'), locations=[('util.py', 42)])
3641 <Message ...>
3642 >>> catalog = Catalog(locale='de_DE')
3643 >>> catalog.add('blue', u'blau', locations=[('main.py', 98)])
3644 <Message ...>
3645 >>> catalog.add('head', u'Kopf', locations=[('util.py', 33)])
3646 <Message ...>
3647 >>> catalog.add(('salad', 'salads'), (u'Salat', u'Salate'),
3648 ... locations=[('util.py', 38)])
3649 <Message ...>
3650
3651 >>> catalog.update(template)
3652 >>> len(catalog)
3653 3
3654
3655 >>> msg1 = catalog['green']
3656 >>> msg1.string
3657 >>> msg1.locations
3658 [('main.py', 99)]
3659
3660 >>> msg2 = catalog['blue']
3661 >>> msg2.string
3662 u'blau'
3663 >>> msg2.locations
3664 [('main.py', 100)]
3665
3666 >>> msg3 = catalog['salad']
3667 >>> msg3.string
3668 (u'Salat', u'Salate')
3669 >>> msg3.locations
3670 [('util.py', 42)]
3671
3672 Messages that are in the catalog but not in the template
3673 are removed from the main collection, but can still be
3674 accessed via the obsolete member:
3675
3676 >>> 'head' in catalog
3677 False
3678 >>> list(catalog.obsolete.values())
3679 [<Message 'head' (flags: [])>]
3680
3681 Parameters
3682
3683 • template – the reference catalog, usually read
3684 from a POT file
3685
3686 • no_fuzzy_matching – whether to use fuzzy match‐
3687 ing of message IDs
3688
3689 Messages
3690 class babel.messages.catalog.Message(id: _MessageID, string: _MessageID
3691 | None = '', locations: Iterable[tuple[str, int]] = (), flags: Iter‐
3692 able[str] = (), auto_comments: Iterable[str] = (), user_comments: Iter‐
3693 able[str] = (), previous_id: _MessageID = (), lineno: int | None =
3694 None, context: str | None = None)
3695 Representation of a single message in a catalog.
3696
3697 check(catalog: Catalog | None = None) -> list[‐
3698 babel.messages.catalog.TranslationError]
3699 Run various validation checks on the message. Some vali‐
3700 dations are only performed if the catalog is provided.
3701 This method returns a sequence of TranslationError ob‐
3702 jects.
3703
3704 Return type
3705 iterator
3706
3707 Parameters
3708 catalog – A catalog instance that is passed to the
3709 checkers
3710
3711 See Catalog.check for a way to perform checks for all
3712 messages in a catalog.
3713
3714 property fuzzy: bool
3715 Whether the translation is fuzzy.
3716
3717 >>> Message('foo').fuzzy
3718 False
3719 >>> msg = Message('foo', 'foo', flags=['fuzzy'])
3720 >>> msg.fuzzy
3721 True
3722 >>> msg
3723 <Message 'foo' (flags: ['fuzzy'])>
3724
3725 Type bool
3726
3727 is_identical(other: Message) -> bool
3728 Checks whether messages are identical, taking into ac‐
3729 count all properties.
3730
3731 property pluralizable: bool
3732 Whether the message is plurizable.
3733
3734 >>> Message('foo').pluralizable
3735 False
3736 >>> Message(('foo', 'bar')).pluralizable
3737 True
3738
3739 Type bool
3740
3741 property python_format: bool
3742 Whether the message contains Python-style parameters.
3743
3744 >>> Message('foo %(name)s bar').python_format
3745 True
3746 >>> Message(('foo %(name)s', 'foo %(name)s')).python_format
3747 True
3748
3749 Type bool
3750
3751 Exceptions
3752 exception babel.messages.catalog.TranslationError
3753 Exception thrown by translation checkers when invalid message
3754 translations are encountered.
3755
3756 Low-Level Extraction Interface
3757 The low level extraction interface can be used to extract from directo‐
3758 ries or files directly. Normally this is not needed as the command
3759 line tools can do that for you.
3760
3761 Extraction Functions
3762 The extraction functions are what the command line tools use internally
3763 to extract strings.
3764
3765 babel.messages.extract.extract_from_dir(dirname: str | os.PathLike[str]
3766 | None = None, method_map: Iterable[tuple[str, str]] = [('**.py',
3767 'python')], options_map: SupportsItems[str, dict[str, Any]] | None =
3768 None, keywords: Mapping[str, _Keyword] = {'N_': None, '_': None, 'dget‐
3769 text': (2,), 'dngettext': (2, 3), 'gettext': None, 'ngettext': (1, 2),
3770 'npgettext': ((1, 'c'), 2, 3), 'pgettext': ((1, 'c'), 2), 'ugettext':
3771 None, 'ungettext': (1, 2)}, comment_tags: Collection[str] = (), call‐
3772 back: Callable[[str, str, dict[str, Any]], object] | None = None,
3773 strip_comment_tags: bool = False, directory_filter: Callable[[str],
3774 bool] | None = None) -> Generator[_FileExtractionResult, None, None]
3775 Extract messages from any source files found in the given direc‐
3776 tory.
3777
3778 This function generates tuples of the form (filename, lineno,
3779 message, comments, context).
3780
3781 Which extraction method is used per file is determined by the
3782 method_map parameter, which maps extended glob patterns to ex‐
3783 traction method names. For example, the following is the de‐
3784 fault mapping:
3785
3786 >>> method_map = [
3787 ... ('**.py', 'python')
3788 ... ]
3789
3790 This basically says that files with the filename extension “.py”
3791 at any level inside the directory should be processed by the
3792 “python” extraction method. Files that don’t match any of the
3793 mapping patterns are ignored. See the documentation of the path‐
3794 match function for details on the pattern syntax.
3795
3796 The following extended mapping would also use the “genshi” ex‐
3797 traction method on any file in “templates” subdirectory:
3798
3799 >>> method_map = [
3800 ... ('**/templates/**.*', 'genshi'),
3801 ... ('**.py', 'python')
3802 ... ]
3803
3804 The dictionary provided by the optional options_map parameter
3805 augments these mappings. It uses extended glob patterns as keys,
3806 and the values are dictionaries mapping options names to option
3807 values (both strings).
3808
3809 The glob patterns of the options_map do not necessarily need to
3810 be the same as those used in the method mapping. For example,
3811 while all files in the templates folders in an application may
3812 be Genshi applications, the options for those files may differ
3813 based on extension:
3814
3815 >>> options_map = {
3816 ... '**/templates/**.txt': {
3817 ... 'template_class': 'genshi.template:TextTemplate',
3818 ... 'encoding': 'latin-1'
3819 ... },
3820 ... '**/templates/**.html': {
3821 ... 'include_attrs': ''
3822 ... }
3823 ... }
3824
3825 Parameters
3826
3827 • dirname – the path to the directory to extract messages
3828 from. If not given the current working directory is
3829 used.
3830
3831 • method_map – a list of (pattern, method) tuples that
3832 maps of extraction method names to extended glob pat‐
3833 terns
3834
3835 • options_map – a dictionary of additional options (op‐
3836 tional)
3837
3838 • keywords – a dictionary mapping keywords (i.e. names of
3839 functions that should be recognized as translation
3840 functions) to tuples that specify which of their argu‐
3841 ments contain localizable strings
3842
3843 • comment_tags – a list of tags of translator comments to
3844 search for and include in the results
3845
3846 • callback – a function that is called for every file
3847 that message are extracted from, just before the ex‐
3848 traction itself is performed; the function is passed
3849 the filename, the name of the extraction method and and
3850 the options dictionary as positional arguments, in that
3851 order
3852
3853 • strip_comment_tags – a flag that if set to True causes
3854 all comment tags to be removed from the collected com‐
3855 ments.
3856
3857 • directory_filter – a callback to determine whether a
3858 directory should be recursed into. Receives the full
3859 directory path; should return True if the directory is
3860 valid.
3861
3862 See pathmatch
3863
3864 babel.messages.extract.extract_from_file(method: _ExtractionMethod,
3865 filename: str | os.PathLike[str], keywords: Mapping[str, _Keyword] =
3866 {'N_': None, '_': None, 'dgettext': (2,), 'dngettext': (2, 3), 'get‐
3867 text': None, 'ngettext': (1, 2), 'npgettext': ((1, 'c'), 2, 3), 'pget‐
3868 text': ((1, 'c'), 2), 'ugettext': None, 'ungettext': (1, 2)}, com‐
3869 ment_tags: Collection[str] = (), options: Mapping[str, Any] | None =
3870 None, strip_comment_tags: bool = False) -> list[_ExtractionResult]
3871 Extract messages from a specific file.
3872
3873 This function returns a list of tuples of the form (lineno, mes‐
3874 sage, comments, context).
3875
3876 Parameters
3877
3878 • filename – the path to the file to extract messages
3879 from
3880
3881 • method – a string specifying the extraction method
3882 (.e.g. “python”)
3883
3884 • keywords – a dictionary mapping keywords (i.e. names of
3885 functions that should be recognized as translation
3886 functions) to tuples that specify which of their argu‐
3887 ments contain localizable strings
3888
3889 • comment_tags – a list of translator tags to search for
3890 and include in the results
3891
3892 • strip_comment_tags – a flag that if set to True causes
3893 all comment tags to be removed from the collected com‐
3894 ments.
3895
3896 • options – a dictionary of additional options (optional)
3897
3898 Returns
3899 list of tuples of the form (lineno, message, comments,
3900 context)
3901
3902 Return type
3903 list[tuple[int, str|tuple[str], list[str], str|None]
3904
3905 babel.messages.extract.extract(method: _ExtractionMethod, fileobj:
3906 _FileObj, keywords: Mapping[str, _Keyword] = {'N_': None, '_': None,
3907 'dgettext': (2,), 'dngettext': (2, 3), 'gettext': None, 'ngettext': (1,
3908 2), 'npgettext': ((1, 'c'), 2, 3), 'pgettext': ((1, 'c'), 2), 'uget‐
3909 text': None, 'ungettext': (1, 2)}, comment_tags: Collection[str] = (),
3910 options: Mapping[str, Any] | None = None, strip_comment_tags: bool =
3911 False) -> Generator[_ExtractionResult, None, None]
3912 Extract messages from the given file-like object using the spec‐
3913 ified extraction method.
3914
3915 This function returns tuples of the form (lineno, message, com‐
3916 ments, context).
3917
3918 The implementation dispatches the actual extraction to plugins,
3919 based on the value of the method parameter.
3920
3921 >>> source = b'''# foo module
3922 ... def run(argv):
3923 ... print(_('Hello, world!'))
3924 ... '''
3925
3926 >>> from io import BytesIO
3927 >>> for message in extract('python', BytesIO(source)):
3928 ... print(message)
3929 (3, u'Hello, world!', [], None)
3930
3931 Parameters
3932
3933 • method – an extraction method (a callable), or a string
3934 specifying the extraction method (.e.g. “python”); if
3935 this is a simple name, the extraction function will be
3936 looked up by entry point; if it is an explicit refer‐
3937 ence to a function (of the form package.module:funcname
3938 or package.module.funcname), the corresponding function
3939 will be imported and used
3940
3941 • fileobj – the file-like object the messages should be
3942 extracted from
3943
3944 • keywords – a dictionary mapping keywords (i.e. names of
3945 functions that should be recognized as translation
3946 functions) to tuples that specify which of their argu‐
3947 ments contain localizable strings
3948
3949 • comment_tags – a list of translator tags to search for
3950 and include in the results
3951
3952 • options – a dictionary of additional options (optional)
3953
3954 • strip_comment_tags – a flag that if set to True causes
3955 all comment tags to be removed from the collected com‐
3956 ments.
3957
3958 Raises ValueError – if the extraction method is not registered
3959
3960 Returns
3961 iterable of tuples of the form (lineno, message, com‐
3962 ments, context)
3963
3964 Return type
3965 Iterable[tuple[int, str|tuple[str], list[str], str|None]
3966
3967 Language Parsing
3968 The language parsing functions are used to extract strings out of
3969 source files. These are automatically being used by the extraction
3970 functions but sometimes it can be useful to register wrapper functions,
3971 then these low level functions can be invoked.
3972
3973 New functions can be registered through the setuptools entrypoint sys‐
3974 tem.
3975
3976 babel.messages.extract.extract_python(fileobj: IO[bytes], keywords:
3977 Mapping[str, _Keyword], comment_tags: Collection[str], options: _PyOp‐
3978 tions) -> Generator[_ExtractionResult, None, None]
3979 Extract messages from Python source code.
3980
3981 It returns an iterator yielding tuples in the following form
3982 (lineno, funcname, message, comments).
3983
3984 Parameters
3985
3986 • fileobj – the seekable, file-like object the messages
3987 should be extracted from
3988
3989 • keywords – a list of keywords (i.e. function names)
3990 that should be recognized as translation functions
3991
3992 • comment_tags – a list of translator tags to search for
3993 and include in the results
3994
3995 • options – a dictionary of additional options (optional)
3996
3997 Return type
3998 iterator
3999
4000 babel.messages.extract.extract_javascript(fileobj: _FileObj, keywords:
4001 Mapping[str, _Keyword], comment_tags: Collection[str], options: _JSOp‐
4002 tions, lineno: int = 1) -> Generator[_ExtractionResult, None, None]
4003 Extract messages from JavaScript source code.
4004
4005 Parameters
4006
4007 • fileobj – the seekable, file-like object the messages
4008 should be extracted from
4009
4010 • keywords – a list of keywords (i.e. function names)
4011 that should be recognized as translation functions
4012
4013 • comment_tags – a list of translator tags to search for
4014 and include in the results
4015
4016 • options –
4017
4018 a dictionary of additional options (optional) Supported
4019 options are: * jsx – set to false to disable JSX/E4X
4020 support. * template_string – if True, supports get‐
4021 text(key) * parse_template_string – if True will parse
4022 the
4023 contents of javascript template strings.
4024
4025
4026 • lineno – line number offset (for parsing embedded frag‐
4027 ments)
4028
4029 babel.messages.extract.extract_nothing(fileobj: _FileObj, keywords:
4030 Mapping[str, _Keyword], comment_tags: Collection[str], options: Map‐
4031 ping[str, Any]) -> list[_ExtractionResult]
4032 Pseudo extractor that does not actually extract anything, but
4033 simply returns an empty list.
4034
4035 MO File Support
4036 The MO file support can read and write MO files. It reads them into
4037 Catalog objects and also writes catalogs out.
4038
4039 babel.messages.mofile.read_mo(fileobj: SupportsRead[bytes]) -> Catalog
4040 Read a binary MO file from the given file-like object and return
4041 a corresponding Catalog object.
4042
4043 Parameters
4044 fileobj – the file-like object to read the MO file from
4045
4046 Note The implementation of this function is heavily based on
4047 the GNUTranslations._parse method of the gettext module
4048 in the standard library.
4049
4050 babel.messages.mofile.write_mo(fileobj: SupportsWrite[bytes], catalog:
4051 Catalog, use_fuzzy: bool = False) -> None
4052 Write a catalog to the specified file-like object using the GNU
4053 MO file format.
4054
4055 >>> import sys
4056 >>> from babel.messages import Catalog
4057 >>> from gettext import GNUTranslations
4058 >>> from io import BytesIO
4059
4060 >>> catalog = Catalog(locale='en_US')
4061 >>> catalog.add('foo', 'Voh')
4062 <Message ...>
4063 >>> catalog.add((u'bar', u'baz'), (u'Bahr', u'Batz'))
4064 <Message ...>
4065 >>> catalog.add('fuz', 'Futz', flags=['fuzzy'])
4066 <Message ...>
4067 >>> catalog.add('Fizz', '')
4068 <Message ...>
4069 >>> catalog.add(('Fuzz', 'Fuzzes'), ('', ''))
4070 <Message ...>
4071 >>> buf = BytesIO()
4072
4073 >>> write_mo(buf, catalog)
4074 >>> x = buf.seek(0)
4075 >>> translations = GNUTranslations(fp=buf)
4076 >>> if sys.version_info[0] >= 3:
4077 ... translations.ugettext = translations.gettext
4078 ... translations.ungettext = translations.ngettext
4079 >>> translations.ugettext('foo')
4080 u'Voh'
4081 >>> translations.ungettext('bar', 'baz', 1)
4082 u'Bahr'
4083 >>> translations.ungettext('bar', 'baz', 2)
4084 u'Batz'
4085 >>> translations.ugettext('fuz')
4086 u'fuz'
4087 >>> translations.ugettext('Fizz')
4088 u'Fizz'
4089 >>> translations.ugettext('Fuzz')
4090 u'Fuzz'
4091 >>> translations.ugettext('Fuzzes')
4092 u'Fuzzes'
4093
4094 Parameters
4095
4096 • fileobj – the file-like object to write to
4097
4098 • catalog – the Catalog instance
4099
4100 • use_fuzzy – whether translations marked as “fuzzy”
4101 should be included in the output
4102
4103 PO File Support
4104 The PO file support can read and write PO and POT files. It reads them
4105 into Catalog objects and also writes catalogs out.
4106
4107 babel.messages.pofile.read_po(fileobj: IO[AnyStr], locale: str | Locale
4108 | None = None, domain: str | None = None, ignore_obsolete: bool =
4109 False, charset: str | None = None, abort_invalid: bool = False) ->
4110 Catalog
4111 Read messages from a gettext PO (portable object) file from the
4112 given file-like object and return a Catalog.
4113
4114 >>> from datetime import datetime
4115 >>> from io import StringIO
4116 >>> buf = StringIO('''
4117 ... #: main.py:1
4118 ... #, fuzzy, python-format
4119 ... msgid "foo %(name)s"
4120 ... msgstr "quux %(name)s"
4121 ...
4122 ... # A user comment
4123 ... #. An auto comment
4124 ... #: main.py:3
4125 ... msgid "bar"
4126 ... msgid_plural "baz"
4127 ... msgstr[0] "bar"
4128 ... msgstr[1] "baaz"
4129 ... ''')
4130 >>> catalog = read_po(buf)
4131 >>> catalog.revision_date = datetime(2007, 4, 1)
4132
4133 >>> for message in catalog:
4134 ... if message.id:
4135 ... print((message.id, message.string))
4136 ... print(' ', (message.locations, sorted(list(message.flags))))
4137 ... print(' ', (message.user_comments, message.auto_comments))
4138 (u'foo %(name)s', u'quux %(name)s')
4139 ([(u'main.py', 1)], [u'fuzzy', u'python-format'])
4140 ([], [])
4141 ((u'bar', u'baz'), (u'bar', u'baaz'))
4142 ([(u'main.py', 3)], [])
4143 ([u'A user comment'], [u'An auto comment'])
4144
4145 New in version 1.0: Added support for explicit charset argument.
4146
4147
4148 Parameters
4149
4150 • fileobj – the file-like object to read the PO file from
4151
4152 • locale – the locale identifier or Locale object, or
4153 None if the catalog is not bound to a locale (which ba‐
4154 sically means it’s a template)
4155
4156 • domain – the message domain
4157
4158 • ignore_obsolete – whether to ignore obsolete messages
4159 in the input
4160
4161 • charset – the character set of the catalog.
4162
4163 • abort_invalid – abort read if po file is invalid
4164
4165 babel.messages.pofile.write_po(fileobj: SupportsWrite[bytes], catalog:
4166 Catalog, width: int = 76, no_location: bool = False, omit_header: bool
4167 = False, sort_output: bool = False, sort_by_file: bool = False, ig‐
4168 nore_obsolete: bool = False, include_previous: bool = False, in‐
4169 clude_lineno: bool = True) -> None
4170 Write a gettext PO (portable object) template file for a given
4171 message catalog to the provided file-like object.
4172
4173 >>> catalog = Catalog()
4174 >>> catalog.add(u'foo %(name)s', locations=[('main.py', 1)],
4175 ... flags=('fuzzy',))
4176 <Message...>
4177 >>> catalog.add((u'bar', u'baz'), locations=[('main.py', 3)])
4178 <Message...>
4179 >>> from io import BytesIO
4180 >>> buf = BytesIO()
4181 >>> write_po(buf, catalog, omit_header=True)
4182 >>> print(buf.getvalue().decode("utf8"))
4183 #: main.py:1
4184 #, fuzzy, python-format
4185 msgid "foo %(name)s"
4186 msgstr ""
4187
4188 #: main.py:3
4189 msgid "bar"
4190 msgid_plural "baz"
4191 msgstr[0] ""
4192 msgstr[1] ""
4193
4194
4195
4196 Parameters
4197
4198 • fileobj – the file-like object to write to
4199
4200 • catalog – the Catalog instance
4201
4202 • width – the maximum line width for the generated out‐
4203 put; use None, 0, or a negative number to completely
4204 disable line wrapping
4205
4206 • no_location – do not emit a location comment for every
4207 message
4208
4209 • omit_header – do not include the msgid "" entry at the
4210 top of the output
4211
4212 • sort_output – whether to sort the messages in the out‐
4213 put by msgid
4214
4215 • sort_by_file – whether to sort the messages in the out‐
4216 put by their locations
4217
4218 • ignore_obsolete – whether to ignore obsolete messages
4219 and not include them in the output; by default they are
4220 included as comments
4221
4222 • include_previous – include the old msgid as a comment
4223 when updating the catalog
4224
4225 • include_lineno – include line number in the location
4226 comment
4227
4228 Numbers and Currencies
4229 The number module provides functionality to format numbers for differ‐
4230 ent locales. This includes arbitrary numbers as well as currency.
4231
4232 Number Formatting
4233 babel.numbers.format_number(number: float | Decimal | str, locale:
4234 Locale | str | None = 'en_US_POSIX') -> str
4235 Return the given number formatted for a specific locale.
4236
4237 >>> format_number(1099, locale='en_US')
4238 u'1,099'
4239 >>> format_number(1099, locale='de_DE')
4240 u'1.099'
4241
4242 Deprecated since version 2.6.0: Use babel.numbers.format_deci‐
4243 mal() instead.
4244
4245
4246 Parameters
4247
4248 • number – the number to format
4249
4250 • locale – the Locale object or locale identifier
4251
4252 babel.numbers.format_decimal(number: float | Decimal | str, format: str
4253 | NumberPattern | None = None, locale: Locale | str | None =
4254 'en_US_POSIX', decimal_quantization: bool = True, group_separator: bool
4255 = True) -> str
4256 Return the given decimal number formatted for a specific locale.
4257
4258 >>> format_decimal(1.2345, locale='en_US')
4259 u'1.234'
4260 >>> format_decimal(1.2346, locale='en_US')
4261 u'1.235'
4262 >>> format_decimal(-1.2346, locale='en_US')
4263 u'-1.235'
4264 >>> format_decimal(1.2345, locale='sv_SE')
4265 u'1,234'
4266 >>> format_decimal(1.2345, locale='de')
4267 u'1,234'
4268
4269 The appropriate thousands grouping and the decimal separator are
4270 used for each locale:
4271
4272 >>> format_decimal(12345.5, locale='en_US')
4273 u'12,345.5'
4274
4275 By default the locale is allowed to truncate and round a
4276 high-precision number by forcing its format pattern onto the
4277 decimal part. You can bypass this behavior with the deci‐
4278 mal_quantization parameter:
4279
4280 >>> format_decimal(1.2346, locale='en_US')
4281 u'1.235'
4282 >>> format_decimal(1.2346, locale='en_US', decimal_quantization=False)
4283 u'1.2346'
4284 >>> format_decimal(12345.67, locale='fr_CA', group_separator=False)
4285 u'12345,67'
4286 >>> format_decimal(12345.67, locale='en_US', group_separator=True)
4287 u'12,345.67'
4288
4289 Parameters
4290
4291 • number – the number to format
4292
4293 • format –
4294
4295 • locale – the Locale object or locale identifier
4296
4297 • decimal_quantization – Truncate and round high-preci‐
4298 sion numbers to the format pattern. Defaults to True.
4299
4300 • group_separator – Boolean to switch group separator
4301 on/off in a locale’s number format.
4302
4303 babel.numbers.format_compact_decimal(number: float | decimal.Decimal |
4304 str, *, format_type: Literal['short', 'long'] = 'short', locale: Locale
4305 | str | None = 'en_US_POSIX', fraction_digits: int = 0) -> str
4306 Return the given decimal number formatted for a specific locale
4307 in compact form.
4308
4309 >>> format_compact_decimal(12345, format_type="short", locale='en_US')
4310 u'12K'
4311 >>> format_compact_decimal(12345, format_type="long", locale='en_US')
4312 u'12 thousand'
4313 >>> format_compact_decimal(12345, format_type="short", locale='en_US', fraction_digits=2)
4314 u'12.34K'
4315 >>> format_compact_decimal(1234567, format_type="short", locale="ja_JP")
4316 u'123万'
4317 >>> format_compact_decimal(2345678, format_type="long", locale="mk")
4318 u'2 милиони'
4319 >>> format_compact_decimal(21000000, format_type="long", locale="mk")
4320 u'21 милион'
4321
4322 Parameters
4323
4324 • number – the number to format
4325
4326 • format_type – Compact format to use (“short” or “long”)
4327
4328 • locale – the Locale object or locale identifier
4329
4330 • fraction_digits – Number of digits after the decimal
4331 point to use. Defaults to 0.
4332
4333 babel.numbers.format_currency(number: float | decimal.Decimal | str,
4334 currency: str, format: str | NumberPattern | None = None, locale:
4335 Locale | str | None = 'en_US_POSIX', currency_digits: bool = True, for‐
4336 mat_type: Literal['name', 'standard', 'accounting'] = 'standard', deci‐
4337 mal_quantization: bool = True, group_separator: bool = True) -> str
4338 Return formatted currency value.
4339
4340 >>> format_currency(1099.98, 'USD', locale='en_US')
4341 '$1,099.98'
4342 >>> format_currency(1099.98, 'USD', locale='es_CO')
4343 u'US$1.099,98'
4344 >>> format_currency(1099.98, 'EUR', locale='de_DE')
4345 u'1.099,98\xa0\u20ac'
4346
4347 The format can also be specified explicitly. The currency is
4348 placed with the ‘¤’ sign. As the sign gets repeated the format
4349 expands (¤ being the symbol, ¤¤ is the currency abbreviation and
4350 ¤¤¤ is the full name of the currency):
4351
4352 >>> format_currency(1099.98, 'EUR', u'¤¤ #,##0.00', locale='en_US')
4353 u'EUR 1,099.98'
4354 >>> format_currency(1099.98, 'EUR', u'#,##0.00 ¤¤¤', locale='en_US')
4355 u'1,099.98 euros'
4356
4357 Currencies usually have a specific number of decimal digits.
4358 This function favours that information over the given format:
4359
4360 >>> format_currency(1099.98, 'JPY', locale='en_US')
4361 u'\xa51,100'
4362 >>> format_currency(1099.98, 'COP', u'#,##0.00', locale='es_ES')
4363 u'1.099,98'
4364
4365 However, the number of decimal digits can be overridden from the
4366 currency information, by setting the last parameter to False:
4367
4368 >>> format_currency(1099.98, 'JPY', locale='en_US', currency_digits=False)
4369 u'\xa51,099.98'
4370 >>> format_currency(1099.98, 'COP', u'#,##0.00', locale='es_ES', currency_digits=False)
4371 u'1.099,98'
4372
4373 If a format is not specified the type of currency format to use
4374 from the locale can be specified:
4375
4376 >>> format_currency(1099.98, 'EUR', locale='en_US', format_type='standard')
4377 u'\u20ac1,099.98'
4378
4379 When the given currency format type is not available, an excep‐
4380 tion is raised:
4381
4382 >>> format_currency('1099.98', 'EUR', locale='root', format_type='unknown')
4383 Traceback (most recent call last):
4384 ...
4385 UnknownCurrencyFormatError: "'unknown' is not a known currency format type"
4386
4387 >>> format_currency(101299.98, 'USD', locale='en_US', group_separator=False)
4388 u'$101299.98'
4389
4390 >>> format_currency(101299.98, 'USD', locale='en_US', group_separator=True)
4391 u'$101,299.98'
4392
4393 You can also pass format_type=’name’ to use long display names.
4394 The order of the number and currency name, along with the cor‐
4395 rect localized plural form of the currency name, is chosen ac‐
4396 cording to locale:
4397
4398 >>> format_currency(1, 'USD', locale='en_US', format_type='name')
4399 u'1.00 US dollar'
4400 >>> format_currency(1099.98, 'USD', locale='en_US', format_type='name')
4401 u'1,099.98 US dollars'
4402 >>> format_currency(1099.98, 'USD', locale='ee', format_type='name')
4403 u'us ga dollar 1,099.98'
4404
4405 By default the locale is allowed to truncate and round a
4406 high-precision number by forcing its format pattern onto the
4407 decimal part. You can bypass this behavior with the deci‐
4408 mal_quantization parameter:
4409
4410 >>> format_currency(1099.9876, 'USD', locale='en_US')
4411 u'$1,099.99'
4412 >>> format_currency(1099.9876, 'USD', locale='en_US', decimal_quantization=False)
4413 u'$1,099.9876'
4414
4415 Parameters
4416
4417 • number – the number to format
4418
4419 • currency – the currency code
4420
4421 • format – the format string to use
4422
4423 • locale – the Locale object or locale identifier
4424
4425 • currency_digits – use the currency’s natural number of
4426 decimal digits
4427
4428 • format_type – the currency format type to use
4429
4430 • decimal_quantization – Truncate and round high-preci‐
4431 sion numbers to the format pattern. Defaults to True.
4432
4433 • group_separator – Boolean to switch group separator
4434 on/off in a locale’s number format.
4435
4436 babel.numbers.format_compact_currency(number: float | decimal.Decimal |
4437 str, currency: str, *, format_type: Literal['short'] = 'short', locale:
4438 Locale | str | None = 'en_US_POSIX', fraction_digits: int = 0) -> str
4439 Format a number as a currency value in compact form.
4440
4441 >>> format_compact_currency(12345, 'USD', locale='en_US')
4442 u'$12K'
4443 >>> format_compact_currency(123456789, 'USD', locale='en_US', fraction_digits=2)
4444 u'$123.46M'
4445 >>> format_compact_currency(123456789, 'EUR', locale='de_DE', fraction_digits=1)
4446 '123,5 Mio. €'
4447
4448 Parameters
4449
4450 • number – the number to format
4451
4452 • currency – the currency code
4453
4454 • format_type – the compact format type to use. Defaults
4455 to “short”.
4456
4457 • locale – the Locale object or locale identifier
4458
4459 • fraction_digits – Number of digits after the decimal
4460 point to use. Defaults to 0.
4461
4462 babel.numbers.format_percent(number: float | Decimal | str, format: str
4463 | NumberPattern | None = None, locale: Locale | str | None =
4464 'en_US_POSIX', decimal_quantization: bool = True, group_separator: bool
4465 = True) -> str
4466 Return formatted percent value for a specific locale.
4467
4468 >>> format_percent(0.34, locale='en_US')
4469 u'34%'
4470 >>> format_percent(25.1234, locale='en_US')
4471 u'2,512%'
4472 >>> format_percent(25.1234, locale='sv_SE')
4473 u'2\xa0512\xa0%'
4474
4475 The format pattern can also be specified explicitly:
4476
4477 >>> format_percent(25.1234, u'#,##0‰', locale='en_US')
4478 u'25,123‰'
4479
4480 By default the locale is allowed to truncate and round a
4481 high-precision number by forcing its format pattern onto the
4482 decimal part. You can bypass this behavior with the deci‐
4483 mal_quantization parameter:
4484
4485 >>> format_percent(23.9876, locale='en_US')
4486 u'2,399%'
4487 >>> format_percent(23.9876, locale='en_US', decimal_quantization=False)
4488 u'2,398.76%'
4489
4490 >>> format_percent(229291.1234, locale='pt_BR', group_separator=False)
4491 u'22929112%'
4492
4493 >>> format_percent(229291.1234, locale='pt_BR', group_separator=True)
4494 u'22.929.112%'
4495
4496 Parameters
4497
4498 • number – the percent number to format
4499
4500 • format –
4501
4502 • locale – the Locale object or locale identifier
4503
4504 • decimal_quantization – Truncate and round high-preci‐
4505 sion numbers to the format pattern. Defaults to True.
4506
4507 • group_separator – Boolean to switch group separator
4508 on/off in a locale’s number format.
4509
4510 babel.numbers.format_scientific(number: float | Decimal | str, format:
4511 str | NumberPattern | None = None, locale: Locale | str | None =
4512 'en_US_POSIX', decimal_quantization: bool = True) -> str
4513 Return value formatted in scientific notation for a specific lo‐
4514 cale.
4515
4516 >>> format_scientific(10000, locale='en_US')
4517 u'1E4'
4518
4519 The format pattern can also be specified explicitly:
4520
4521 >>> format_scientific(1234567, u'##0.##E00', locale='en_US')
4522 u'1.23E06'
4523
4524 By default the locale is allowed to truncate and round a
4525 high-precision number by forcing its format pattern onto the
4526 decimal part. You can bypass this behavior with the deci‐
4527 mal_quantization parameter:
4528
4529 >>> format_scientific(1234.9876, u'#.##E0', locale='en_US')
4530 u'1.23E3'
4531 >>> format_scientific(1234.9876, u'#.##E0', locale='en_US', decimal_quantization=False)
4532 u'1.2349876E3'
4533
4534 Parameters
4535
4536 • number – the number to format
4537
4538 • format –
4539
4540 • locale – the Locale object or locale identifier
4541
4542 • decimal_quantization – Truncate and round high-preci‐
4543 sion numbers to the format pattern. Defaults to True.
4544
4545 Number Parsing
4546 babel.numbers.parse_number(string: str, locale: Locale | str | None =
4547 'en_US_POSIX') -> int
4548 Parse localized number string into an integer.
4549
4550 >>> parse_number('1,099', locale='en_US')
4551 1099
4552 >>> parse_number('1.099', locale='de_DE')
4553 1099
4554
4555 When the given string cannot be parsed, an exception is raised:
4556
4557 >>> parse_number('1.099,98', locale='de')
4558 Traceback (most recent call last):
4559 ...
4560 NumberFormatError: '1.099,98' is not a valid number
4561
4562 Parameters
4563
4564 • string – the string to parse
4565
4566 • locale – the Locale object or locale identifier
4567
4568 Returns
4569 the parsed number
4570
4571 Raises NumberFormatError – if the string can not be converted to
4572 a number
4573
4574 babel.numbers.parse_decimal(string: str, locale: Locale | str | None =
4575 'en_US_POSIX', strict: bool = False) -> Decimal
4576 Parse localized decimal string into a decimal.
4577
4578 >>> parse_decimal('1,099.98', locale='en_US')
4579 Decimal('1099.98')
4580 >>> parse_decimal('1.099,98', locale='de')
4581 Decimal('1099.98')
4582 >>> parse_decimal('12 345,123', locale='ru')
4583 Decimal('12345.123')
4584
4585 When the given string cannot be parsed, an exception is raised:
4586
4587 >>> parse_decimal('2,109,998', locale='de')
4588 Traceback (most recent call last):
4589 ...
4590 NumberFormatError: '2,109,998' is not a valid decimal number
4591
4592 If strict is set to True and the given string contains a number
4593 formatted in an irregular way, an exception is raised:
4594
4595 >>> parse_decimal('30.00', locale='de', strict=True)
4596 Traceback (most recent call last):
4597 ...
4598 NumberFormatError: '30.00' is not a properly formatted decimal number. Did you mean '3.000'? Or maybe '30,00'?
4599
4600 >>> parse_decimal('0.00', locale='de', strict=True)
4601 Traceback (most recent call last):
4602 ...
4603 NumberFormatError: '0.00' is not a properly formatted decimal number. Did you mean '0'?
4604
4605 Parameters
4606
4607 • string – the string to parse
4608
4609 • locale – the Locale object or locale identifier
4610
4611 • strict – controls whether numbers formatted in a weird
4612 way are accepted or rejected
4613
4614 Raises NumberFormatError – if the string can not be converted to
4615 a decimal number
4616
4617 Exceptions
4618 exception babel.numbers.NumberFormatError(message: str, suggestions:
4619 list[str] | None = None)
4620 Exception raised when a string cannot be parsed into a number.
4621
4622 suggestions
4623 a list of properly formatted numbers derived from the in‐
4624 valid input
4625
4626 Data Access
4627 babel.numbers.get_currency_name(currency: str, count: float | Decimal |
4628 None = None, locale: Locale | str | None = 'en_US_POSIX') -> str
4629 Return the name used by the locale for the specified currency.
4630
4631 >>> get_currency_name('USD', locale='en_US')
4632 u'US Dollar'
4633
4634 New in version 0.9.4.
4635
4636
4637 Parameters
4638
4639 • currency – the currency code.
4640
4641 • count – the optional count. If provided the currency
4642 name will be pluralized to that number if possible.
4643
4644 • locale – the Locale object or locale identifier.
4645
4646 babel.numbers.get_currency_symbol(currency: str, locale: Locale | str |
4647 None = 'en_US_POSIX') -> str
4648 Return the symbol used by the locale for the specified currency.
4649
4650 >>> get_currency_symbol('USD', locale='en_US')
4651 u'$'
4652
4653 Parameters
4654
4655 • currency – the currency code.
4656
4657 • locale – the Locale object or locale identifier.
4658
4659 babel.numbers.get_currency_unit_pattern(currency: str, count: float |
4660 Decimal | None = None, locale: Locale | str | None = 'en_US_POSIX') ->
4661 str
4662 Return the unit pattern used for long display of a currency
4663 value for a given locale. This is a string containing {0} where
4664 the numeric part should be substituted and {1} where the cur‐
4665 rency long display name should be substituted.
4666
4667 >>> get_currency_unit_pattern('USD', locale='en_US', count=10)
4668 u'{0} {1}'
4669
4670 New in version 2.7.0.
4671
4672
4673 Parameters
4674
4675 • currency – the currency code.
4676
4677 • count – the optional count. If provided the unit pat‐
4678 tern for that number will be returned.
4679
4680 • locale – the Locale object or locale identifier.
4681
4682 babel.numbers.get_decimal_symbol(locale: Locale | str | None =
4683 'en_US_POSIX') -> str
4684 Return the symbol used by the locale to separate decimal frac‐
4685 tions.
4686
4687 >>> get_decimal_symbol('en_US')
4688 u'.'
4689
4690 Parameters
4691 locale – the Locale object or locale identifier
4692
4693 babel.numbers.get_plus_sign_symbol(locale: Locale | str | None =
4694 'en_US_POSIX') -> str
4695 Return the plus sign symbol used by the current locale.
4696
4697 >>> get_plus_sign_symbol('en_US')
4698 u'+'
4699
4700 Parameters
4701 locale – the Locale object or locale identifier
4702
4703 babel.numbers.get_minus_sign_symbol(locale: Locale | str | None =
4704 'en_US_POSIX') -> str
4705 Return the plus sign symbol used by the current locale.
4706
4707 >>> get_minus_sign_symbol('en_US')
4708 u'-'
4709
4710 Parameters
4711 locale – the Locale object or locale identifier
4712
4713 babel.numbers.get_territory_currencies(territory: str, start_date: date
4714 | None = None, end_date: date | None = None, tender: bool = True,
4715 non_tender: bool = False, include_details: Literal[False] = False) ->
4716 list[str]
4717
4718 babel.numbers.get_territory_currencies(territory: str, start_date: date
4719 | None = None, end_date: date | None = None, tender: bool = True,
4720 non_tender: bool = False, include_details: Literal[True] = False) ->
4721 list[dict[str, Any]]
4722 Returns the list of currencies for the given territory that are
4723 valid for the given date range. In addition to that the cur‐
4724 rency database distinguishes between tender and non-tender cur‐
4725 rencies. By default only tender currencies are returned.
4726
4727 The return value is a list of all currencies roughly ordered by
4728 the time of when the currency became active. The longer the
4729 currency is being in use the more to the left of the list it
4730 will be.
4731
4732 The start date defaults to today. If no end date is given it
4733 will be the same as the start date. Otherwise a range can be
4734 defined. For instance this can be used to find the currencies
4735 in use in Austria between 1995 and 2011:
4736
4737 >>> from datetime import date
4738 >>> get_territory_currencies('AT', date(1995, 1, 1), date(2011, 1, 1))
4739 ['ATS', 'EUR']
4740
4741 Likewise it’s also possible to find all the currencies in use on
4742 a single date:
4743
4744 >>> get_territory_currencies('AT', date(1995, 1, 1))
4745 ['ATS']
4746 >>> get_territory_currencies('AT', date(2011, 1, 1))
4747 ['EUR']
4748
4749 By default the return value only includes tender currencies.
4750 This however can be changed:
4751
4752 >>> get_territory_currencies('US')
4753 ['USD']
4754 >>> get_territory_currencies('US', tender=False, non_tender=True,
4755 ... start_date=date(2014, 1, 1))
4756 ['USN', 'USS']
4757
4758 New in version 2.0.
4759
4760
4761 Parameters
4762
4763 • territory – the name of the territory to find the cur‐
4764 rency for.
4765
4766 • start_date – the start date. If not given today is as‐
4767 sumed.
4768
4769 • end_date – the end date. If not given the start date
4770 is assumed.
4771
4772 • tender – controls whether tender currencies should be
4773 included.
4774
4775 • non_tender – controls whether non-tender currencies
4776 should be included.
4777
4778 • include_details – if set to True, instead of returning
4779 currency codes the return value will be dictionaries
4780 with detail information. In that case each dictionary
4781 will have the keys 'currency', 'from', 'to', and 'ten‐
4782 der'.
4783
4784 Pluralization Support
4785 The pluralization support provides functionality around the CLDR plu‐
4786 ralization rules. It can parse and evaluate pluralization rules, as
4787 well as convert them to other formats such as gettext.
4788
4789 Basic Interface
4790 class babel.plural.PluralRule(rules: Mapping[str, str] | Iterable[tu‐
4791 ple[str, str]])
4792 Represents a set of language pluralization rules. The construc‐
4793 tor accepts a list of (tag, expr) tuples or a dict of CLDR
4794 rules. The resulting object is callable and accepts one parame‐
4795 ter with a positive or negative number (both integer and float)
4796 for the number that indicates the plural form for a string and
4797 returns the tag for the format:
4798
4799 >>> rule = PluralRule({'one': 'n is 1'})
4800 >>> rule(1)
4801 'one'
4802 >>> rule(2)
4803 'other'
4804
4805 Currently the CLDR defines these tags: zero, one, two, few, many
4806 and other where other is an implicit default. Rules should be
4807 mutually exclusive; for a given numeric value, only one rule
4808 should apply (i.e. the condition should only be true for one of
4809 the plural rule elements.
4810
4811 classmethod parse(rules: Mapping[str, str] | Iterable[tuple[str,
4812 str]] | PluralRule) -> PluralRule
4813 Create a PluralRule instance for the given rules. If the
4814 rules are a PluralRule object, that object is returned.
4815
4816 Parameters
4817 rules – the rules as list or dict, or a PluralRule
4818 object
4819
4820 Raises RuleError – if the expression is malformed
4821
4822 property rules: Mapping[str, str]
4823 The PluralRule as a dict of unicode plural rules.
4824
4825 >>> rule = PluralRule({'one': 'n is 1'})
4826 >>> rule.rules
4827 {'one': 'n is 1'}
4828
4829 property tags: frozenset[str]
4830 A set of explicitly defined tags in this rule. The im‐
4831 plicit default 'other' rules is not part of this set un‐
4832 less there is an explicit rule for it.
4833
4834 Conversion Functionality
4835 babel.plural.to_javascript(rule: Mapping[str, str] | Iterable[tu‐
4836 ple[str, str]] | PluralRule) -> str
4837 Convert a list/dict of rules or a PluralRule object into a Java‐
4838 Script function. This function depends on no external library:
4839
4840 >>> to_javascript({'one': 'n is 1'})
4841 "(function(n) { return (n == 1) ? 'one' : 'other'; })"
4842
4843 Implementation detail: The function generated will probably
4844 evaluate expressions involved into range operations multiple
4845 times. This has the advantage that external helper functions
4846 are not required and is not a big performance hit for these sim‐
4847 ple calculations.
4848
4849 Parameters
4850 rule – the rules as list or dict, or a PluralRule object
4851
4852 Raises RuleError – if the expression is malformed
4853
4854 babel.plural.to_python(rule: Mapping[str, str] | Iterable[tuple[str,
4855 str]] | PluralRule) -> Callable[[float | Decimal], str]
4856 Convert a list/dict of rules or a PluralRule object into a regu‐
4857 lar Python function. This is useful in situations where you
4858 need a real function and don’t are about the actual rule object:
4859
4860 >>> func = to_python({'one': 'n is 1', 'few': 'n in 2..4'})
4861 >>> func(1)
4862 'one'
4863 >>> func(3)
4864 'few'
4865 >>> func = to_python({'one': 'n in 1,11', 'few': 'n in 3..10,13..19'})
4866 >>> func(11)
4867 'one'
4868 >>> func(15)
4869 'few'
4870
4871 Parameters
4872 rule – the rules as list or dict, or a PluralRule object
4873
4874 Raises RuleError – if the expression is malformed
4875
4876 babel.plural.to_gettext(rule: Mapping[str, str] | Iterable[tuple[str,
4877 str]] | PluralRule) -> str
4878 The plural rule as gettext expression. The gettext expression
4879 is technically limited to integers and returns indices rather
4880 than tags.
4881
4882 >>> to_gettext({'one': 'n is 1', 'two': 'n is 2'})
4883 'nplurals=3; plural=((n == 1) ? 0 : (n == 2) ? 1 : 2);'
4884
4885 Parameters
4886 rule – the rules as list or dict, or a PluralRule object
4887
4888 Raises RuleError – if the expression is malformed
4889
4890 General Support Functionality
4891 Babel ships a few general helpers that are not being used by Babel it‐
4892 self but are useful in combination with functionality provided by it.
4893
4894 Convenience Helpers
4895 class babel.support.Format(locale: Locale | str, tzinfo: datetime.tz‐
4896 info | None = None)
4897 Wrapper class providing the various date and number formatting
4898 functions bound to a specific locale and time-zone.
4899
4900 >>> from babel.util import UTC
4901 >>> from datetime import date
4902 >>> fmt = Format('en_US', UTC)
4903 >>> fmt.date(date(2007, 4, 1))
4904 u'Apr 1, 2007'
4905 >>> fmt.decimal(1.2345)
4906 u'1.234'
4907
4908 compact_currency(number: float | decimal.Decimal | str, cur‐
4909 rency: str, format_type: Literal['short'] = 'short', frac‐
4910 tion_digits: int = 0) -> str
4911 Return a number in the given currency formatted for the
4912 locale using the compact number format.
4913
4914 >>> Format('en_US').compact_currency(1234567, "USD", format_type='short', fraction_digits=2)
4915 '$1.23M'
4916
4917 compact_decimal(number: float | decimal.Decimal | str, for‐
4918 mat_type: Literal['short', 'long'] = 'short', fraction_digits:
4919 int = 0) -> str
4920 Return a number formatted in compact form for the locale.
4921
4922 >>> fmt = Format('en_US')
4923 >>> fmt.compact_decimal(123456789)
4924 u'123M'
4925 >>> fmt.compact_decimal(1234567, format_type='long', fraction_digits=2)
4926 '1.23 million'
4927
4928 currency(number: float | Decimal | str, currency: str) -> str
4929 Return a number in the given currency formatted for the
4930 locale.
4931
4932 date(date: datetime.date | None = None, format: _PredefinedTime‐
4933 Format | str = 'medium') -> str
4934 Return a date formatted according to the given pattern.
4935
4936 >>> from datetime import date
4937 >>> fmt = Format('en_US')
4938 >>> fmt.date(date(2007, 4, 1))
4939 u'Apr 1, 2007'
4940
4941 datetime(datetime: datetime.date | None = None, format: _Prede‐
4942 finedTimeFormat | str = 'medium') -> str
4943 Return a date and time formatted according to the given
4944 pattern.
4945
4946 >>> from datetime import datetime
4947 >>> from babel.dates import get_timezone
4948 >>> fmt = Format('en_US', tzinfo=get_timezone('US/Eastern'))
4949 >>> fmt.datetime(datetime(2007, 4, 1, 15, 30))
4950 u'Apr 1, 2007, 11:30:00 AM'
4951
4952 decimal(number: float | Decimal | str, format: str | None =
4953 None) -> str
4954 Return a decimal number formatted for the locale.
4955
4956 >>> fmt = Format('en_US')
4957 >>> fmt.decimal(1.2345)
4958 u'1.234'
4959
4960 number(number: float | Decimal | str) -> str
4961 Return an integer number formatted for the locale.
4962
4963 >>> fmt = Format('en_US')
4964 >>> fmt.number(1099)
4965 u'1,099'
4966
4967 percent(number: float | Decimal | str, format: str | None =
4968 None) -> str
4969 Return a number formatted as percentage for the locale.
4970
4971 >>> fmt = Format('en_US')
4972 >>> fmt.percent(0.34)
4973 u'34%'
4974
4975 scientific(number: float | Decimal | str) -> str
4976 Return a number formatted using scientific notation for
4977 the locale.
4978
4979 time(time: datetime.time | datetime.datetime | None = None, for‐
4980 mat: _PredefinedTimeFormat | str = 'medium') -> str
4981 Return a time formatted according to the given pattern.
4982
4983 >>> from datetime import datetime
4984 >>> from babel.dates import get_timezone
4985 >>> fmt = Format('en_US', tzinfo=get_timezone('US/Eastern'))
4986 >>> fmt.time(datetime(2007, 4, 1, 15, 30))
4987 u'11:30:00 AM'
4988
4989 timedelta(delta: datetime.timedelta | int, granularity: Lit‐
4990 eral['year', 'month', 'week', 'day', 'hour', 'minute', 'second']
4991 = 'second', threshold: float = 0.85, format: Literal['narrow',
4992 'short', 'medium', 'long'] = 'long', add_direction: bool =
4993 False) -> str
4994 Return a time delta according to the rules of the given
4995 locale.
4996
4997 >>> from datetime import timedelta
4998 >>> fmt = Format('en_US')
4999 >>> fmt.timedelta(timedelta(weeks=11))
5000 u'3 months'
5001
5002 class babel.support.LazyProxy(func: Callable[[...], Any], *args: Any,
5003 enable_cache: bool = True, **kwargs: Any)
5004 Class for proxy objects that delegate to a specified function to
5005 evaluate the actual object.
5006
5007 >>> def greeting(name='world'):
5008 ... return 'Hello, %s!' % name
5009 >>> lazy_greeting = LazyProxy(greeting, name='Joe')
5010 >>> print(lazy_greeting)
5011 Hello, Joe!
5012 >>> u' ' + lazy_greeting
5013 u' Hello, Joe!'
5014 >>> u'(%s)' % lazy_greeting
5015 u'(Hello, Joe!)'
5016
5017 This can be used, for example, to implement lazy translation
5018 functions that delay the actual translation until the string is
5019 actually used. The rationale for such behavior is that the lo‐
5020 cale of the user may not always be available. In web applica‐
5021 tions, you only know the locale when processing a request.
5022
5023 The proxy implementation attempts to be as complete as possible,
5024 so that the lazy objects should mostly work as expected, for ex‐
5025 ample for sorting:
5026
5027 >>> greetings = [
5028 ... LazyProxy(greeting, 'world'),
5029 ... LazyProxy(greeting, 'Joe'),
5030 ... LazyProxy(greeting, 'universe'),
5031 ... ]
5032 >>> greetings.sort()
5033 >>> for greeting in greetings:
5034 ... print(greeting)
5035 Hello, Joe!
5036 Hello, universe!
5037 Hello, world!
5038
5039 Gettext Support
5040 class babel.support.Translations(fp: gettext._TranslationsReader | None
5041 = None, domain: str | None = None)
5042 An extended translation catalog class.
5043
5044 add(translations: Translations, merge: bool = True)
5045 Add the given translations to the catalog.
5046
5047 If the domain of the translations is different than that
5048 of the current catalog, they are added as a catalog that
5049 is only accessible by the various d*gettext functions.
5050
5051 Parameters
5052
5053 • translations – the Translations instance with
5054 the messages to add
5055
5056 • merge – whether translations for message domains
5057 that have already been added should be merged
5058 with the existing translations
5059
5060 classmethod load(dirname: str | PathLike[str] | None = None, lo‐
5061 cales: list[str] | tuple[str, ...] | str | None = None, domain:
5062 str | None = None) -> NullTranslations
5063 Load translations from the given directory.
5064
5065 Parameters
5066
5067 • dirname – the directory containing the MO files
5068
5069 • locales – the list of locales in order of pref‐
5070 erence (items in this list can be either Locale
5071 objects or locale strings)
5072
5073 • domain – the message domain (default: ‘mes‐
5074 sages’)
5075
5076 merge(translations: Translations)
5077 Merge the given translations into the catalog.
5078
5079 Message translations in the specified catalog override
5080 any messages with the same identifier in the existing
5081 catalog.
5082
5083 Parameters
5084 translations – the Translations instance with the
5085 messages to merge
5086
5087 Units
5088 The unit module provides functionality to format measurement units for
5089 different locales.
5090
5091 babel.units.format_unit(value: float | decimal.Decimal, measure‐
5092 ment_unit: str, length: Literal['short', 'long', 'narrow'] = 'long',
5093 format: str | None = None, locale: Locale | str | None = 'en_US_POSIX')
5094 -> str
5095 Format a value of a given unit.
5096
5097 Values are formatted according to the locale’s usual pluraliza‐
5098 tion rules and number formats.
5099
5100 >>> format_unit(12, 'length-meter', locale='ro_RO')
5101 u'12 metri'
5102 >>> format_unit(15.5, 'length-mile', locale='fi_FI')
5103 u'15,5 mailia'
5104 >>> format_unit(1200, 'pressure-millimeter-ofhg', locale='nb')
5105 u'1\xa0200 millimeter kvikks\xf8lv'
5106 >>> format_unit(270, 'ton', locale='en')
5107 u'270 tons'
5108
5109 Number formats may be overridden with the format parameter.
5110
5111 >>> import decimal
5112 >>> format_unit(decimal.Decimal("-42.774"), 'temperature-celsius', 'short', format='#.0', locale='fr')
5113 u'-42,8\u202f\xb0C'
5114
5115 The locale’s usual pluralization rules are respected.
5116
5117 >>> format_unit(1, 'length-meter', locale='ro_RO')
5118 u'1 metru'
5119 >>> format_unit(0, 'length-mile', locale='cy')
5120 u'0 mi'
5121 >>> format_unit(1, 'length-mile', locale='cy')
5122 u'1 filltir'
5123 >>> format_unit(3, 'length-mile', locale='cy')
5124 u'3 milltir'
5125
5126 >>> format_unit(15, 'length-horse', locale='fi')
5127 Traceback (most recent call last):
5128 ...
5129 UnknownUnitError: length-horse is not a known unit in fi
5130
5131 New in version 2.2.0.
5132
5133
5134 Parameters
5135
5136 • value – the value to format. If this is a string, no
5137 number formatting will be attempted.
5138
5139 • measurement_unit – the code of a measurement unit.
5140 Known units can be found in the CLDR Unit Validity XML
5141 file:
5142 https://unicode.org/repos/cldr/tags/latest/common/validity/unit.xml
5143
5144 • length – “short”, “long” or “narrow”
5145
5146 • format – An optional format, as accepted by format_dec‐
5147 imal.
5148
5149 • locale – the Locale object or locale identifier
5150
5151 babel.units.format_compound_unit(numerator_value: float | decimal.Deci‐
5152 mal, numerator_unit: str | None = None, denominator_value: float | dec‐
5153 imal.Decimal = 1, denominator_unit: str | None = None, length: Lit‐
5154 eral['short', 'long', 'narrow'] = 'long', format: str | None = None,
5155 locale: Locale | str | None = 'en_US_POSIX') -> str | None
5156 Format a compound number value, i.e. “kilometers per hour” or
5157 similar.
5158
5159 Both unit specifiers are optional to allow for formatting of ar‐
5160 bitrary values still according to the locale’s general “per”
5161 formatting specifier.
5162
5163 >>> format_compound_unit(7, denominator_value=11, length="short", locale="pt")
5164 '7/11'
5165
5166 >>> format_compound_unit(150, "kilometer", denominator_unit="hour", locale="sv")
5167 '150 kilometer per timme'
5168
5169 >>> format_compound_unit(150, "kilowatt", denominator_unit="year", locale="fi")
5170 '150 kilowattia / vuosi'
5171
5172 >>> format_compound_unit(32.5, "ton", 15, denominator_unit="hour", locale="en")
5173 '32.5 tons per 15 hours'
5174
5175 >>> format_compound_unit(160, denominator_unit="square-meter", locale="fr")
5176 '160 par m\xe8tre carr\xe9'
5177
5178 >>> format_compound_unit(4, "meter", "ratakisko", length="short", locale="fi")
5179 '4 m/ratakisko'
5180
5181 >>> format_compound_unit(35, "minute", denominator_unit="fathom", locale="sv")
5182 '35 minuter per famn'
5183
5184 >>> from babel.numbers import format_currency
5185 >>> format_compound_unit(format_currency(35, "JPY", locale="de"), denominator_unit="liter", locale="de")
5186 '35\xa0\xa5 pro Liter'
5187
5188 See
5189 https://www.unicode.org/reports/tr35/tr35-general.html#perUnitPatterns
5190
5191 Parameters
5192
5193 • numerator_value – The numerator value. This may be a
5194 string, in which case it is considered preformatted and
5195 the unit is ignored.
5196
5197 • numerator_unit – The numerator unit. See format_unit.
5198
5199 • denominator_value – The denominator value. This may be
5200 a string, in which case it is considered preformatted
5201 and the unit is ignored.
5202
5203 • denominator_unit – The denominator unit. See for‐
5204 mat_unit.
5205
5206 • length – The formatting length. “short”, “long” or
5207 “narrow”
5208
5209 • format – An optional format, as accepted by format_dec‐
5210 imal.
5211
5212 • locale – the Locale object or locale identifier
5213
5214 Returns
5215 A formatted compound value.
5216
5217 babel.units.get_unit_name(measurement_unit: str, length: Lit‐
5218 eral['short', 'long', 'narrow'] = 'long', locale: Locale | str | None =
5219 'en_US_POSIX') -> str | None
5220 Get the display name for a measurement unit in the given locale.
5221
5222 >>> get_unit_name("radian", locale="en")
5223 'radians'
5224
5225 Unknown units will raise exceptions:
5226
5227 >>> get_unit_name("battery", locale="fi")
5228 Traceback (most recent call last):
5229 ...
5230 UnknownUnitError: battery/long is not a known unit/length in fi
5231
5232 Parameters
5233
5234 • measurement_unit – the code of a measurement unit.
5235 Known units can be found in the CLDR Unit Validity XML
5236 file:
5237 https://unicode.org/repos/cldr/tags/latest/common/validity/unit.xml
5238
5239 • length – “short”, “long” or “narrow”
5240
5241 • locale – the Locale object or locale identifier
5242
5243 Returns
5244 The unit display name, or None.
5245
5247 Babel Development
5248 Babel as a library has a long history that goes back to the Trac
5249 project. Since then it has evolved into an independently developed
5250 project that implements data access for the CLDR project.
5251
5252 This document tries to explain as best as possible the general rules of
5253 the project in case you want to help out developing.
5254
5255 Tracking the CLDR
5256 Generally the goal of the project is to work as closely as possible
5257 with the CLDR data. This has in the past caused some frustrating prob‐
5258 lems because the data is entirely out of our hand. To minimize the
5259 frustration we generally deal with CLDR updates the following way:
5260
5261 • bump the CLDR data only with a major release of Babel.
5262
5263 • never perform custom bugfixes on the CLDR data.
5264
5265 • never work around CLDR bugs within Babel. If you find a problem in
5266 the data, report it upstream.
5267
5268 • adjust the parsing of the data as soon as possible, otherwise this
5269 will spiral out of control later. This is especially the case for
5270 bigger updates that change pluralization and more.
5271
5272 • try not to test against specific CLDR data that is likely to change.
5273
5274 Python Versions
5275 At the moment the following Python versions should be supported:
5276
5277 • Python 3.7 and up
5278
5279 • PyPy 3.7 and up
5280
5281 Unicode
5282 Unicode is a big deal in Babel. Here is how the rules are set up:
5283
5284 • internally everything is unicode that makes sense to have as unicode.
5285
5286 • Encode / decode at boundaries explicitly. Never assume an encoding
5287 in a way it cannot be overridden. utf-8 should be generally consid‐
5288 ered the default encoding.
5289
5290 Dates and Timezones
5291 Babel’s timezone support relies on either pytz or zoneinfo; if pytz is
5292 installed, it is preferred over zoneinfo. Babel should assume that any
5293 timezone objects can be from either of these modules.
5294
5295 Assumptions to make:
5296
5297 • use UTC where possible.
5298
5299 • be super careful with local time. Do not use local time without
5300 knowing the exact timezone.
5301
5302 • time without date is a very useless construct. Do not try to support
5303 timezones for it. If you do, assume that the current local date is
5304 assumed and not utc date.
5305
5306 Babel Changelog
5307 Version 2.12.1
5308 Fixes
5309 • Version 2.12.0 was missing the py.typed marker file. Thanks to Alex
5310 Waygood for the fix! #975
5311
5312 • The copyright year in all files was bumped to 2023.
5313
5314 Version 2.12.0
5315 Deprecations & breaking changes
5316 • Python 3.6 is no longer supported (#919) - Aarni Koskela
5317
5318 • The get_next_timezone_transition function is no more (#958) - Aarni
5319 Koskela
5320
5321 New features
5322 • CLDR: Babel now uses CLDR 42 (#951) - Aarni Koskela
5323
5324 • Dates: pytz is now optional; Babel will prefer it but will use zone‐
5325 info when available. (#940) - @ds-cbo
5326
5327 • General: Babel now ships type annotations, thanks to Jonah Lawrence’s
5328 work in multiple PRs.
5329
5330 • Locales: @modifiers are now retained when parsing locales (#947) -
5331 martin f. krafft
5332
5333 • Messages: JavaScript template string expression extraction is now
5334 smarter. (#939) - Johannes Wilm
5335
5336 • Numbers: NaN and Infinity are now better supported (#955) - Jonah
5337 Lawrence
5338
5339 • Numbers: Short compact currency formats are now supported (#926) -
5340 Jonah Lawrence
5341
5342 • Numbers: There’s now a Format.compact_decimal utility function. (‐
5343 #921) - Jonah Lawrence
5344
5345 Bugfixes
5346 • Dates: The cache for parsed datetime patterns is now bounded (#967) -
5347 Aarni Koskela
5348
5349 • Messages: Fuzzy candidate matching accuracy is improved (#970) - Jean
5350 Abou Samra
5351
5352 • Numbers: Compact singular formats and patterns with no numbers work
5353 correctly (#930, #932) - Jonah Lawrence, Jun Omae
5354
5355 Improvements & cleanup
5356 • Dates: babel.dates.UTC is now an alias for datetime.timezone.utc (‐
5357 #957) - Aarni Koskela
5358
5359 • Dates: babel.localtime was slightly cleaned up. (#952) - Aarni
5360 Koskela
5361
5362 • Documentation: Documentation was improved by Maciej Olko, Jonah
5363 Lawrence, lilinjie, and Aarni Koskela.
5364
5365 • Infrastructure: Babel is now being linted with pre-commit and ruff. -
5366 Aarni Koskela
5367
5368 Version 2.11.0
5369 Upcoming deprecation
5370 • This version, Babel 2.11, is the last version of Babel to support
5371 Python 3.6. Babel 2.12 will require Python 3.7 or newer.
5372
5373 Improvements
5374 • Support for hex escapes in JavaScript string literals #877 - Przemys‐
5375 law Wegrzyn
5376
5377 • Add support for formatting decimals in compact form #909 - Jonah
5378 Lawrence
5379
5380 • Adapt parse_date to handle ISO dates in ASCII format #842 - Eric L.
5381
5382 •
5383
5384 Use ast instead of eval for Python string extraction #915 - Aarni
5385 Koskela
5386
5387 • This also enables extraction from static f-strings.
5388 F-strings with expressions are silently ignored (but won’t
5389 raise an error as they used to).
5390
5391 Infrastructure
5392 • Tests: Use regular asserts and pytest.raises() #875 – Aarni Koskela
5393
5394 • Wheels are now built in GitHub Actions #888 – Aarni Koskela
5395
5396 • Small improvements to the CLDR downloader script #894 – Aarni Koskela
5397
5398 • Remove antiquated __nonzero__ methods #896 - Nikita Sobolev
5399
5400 • Remove superfluous __unicode__ declarations #905 - Lukas Juhrich
5401
5402 • Mark package compatible with Python 3.11 #913 - Aarni Koskela
5403
5404 • Quiesce pytest warnings #916 - Aarni Koskela
5405
5406 Bugfixes
5407 • Use email.Message for pofile header parsing instead of the deprecated
5408 cgi.parse_header function. #876 – Aarni Koskela
5409
5410 • Remove determining time zone via systemsetup on macOS #914 - Aarni
5411 Koskela
5412
5413 Documentation
5414 • Update Python versions in documentation #898 - Raphael Nestler
5415
5416 • Align BSD-3 license with OSI template #912 - Lukas Kahwe Smith
5417
5418 Version 2.10.3
5419 This is a bugfix release for Babel 2.10.2, which was mistakenly pack‐
5420 aged with outdated locale data.
5421
5422 Thanks to Michał Górny for pointing this out and Jun Omae for verify‐
5423 ing.
5424
5425 This and future Babel PyPI packages will be built by a more automated
5426 process, which should make problems like this less likely to occur.
5427
5428 Version 2.10.2
5429 This is a bugfix release for Babel 2.10.1.
5430
5431 • Fallback count=”other” format in format_currency() (#872) - Jun Omae
5432
5433 • Fix get_period_id() with dayPeriodRule across 0:00 (#871) - Jun Omae
5434
5435 • Add support for b and B period symbols in time format (#869) - Jun
5436 Omae
5437
5438 • chore(docs/typo): Fixes a minor typo in a function comment (#864) -
5439 Frank Harrison
5440
5441 Version 2.10.1
5442 This is a bugfix release for Babel 2.10.0.
5443
5444 • Messages: Fix distutils import. Regressed in #843. (#852) - Nehal J
5445 Wani
5446
5447 • The wheel file is no longer marked as universal, since Babel only
5448 supports Python 3.
5449
5450 Version 2.10.0
5451 Upcoming deprecation
5452 • The get_next_timezone_transition() function is marked deprecated in
5453 this version and will be removed likely as soon as Babel 2.11. No
5454 replacement for this function is planned; based on discussion in
5455 #716, it’s likely the function is not used in any real code. (#852) -
5456 Aarni Koskela, Paul Ganssle
5457
5458 Improvements
5459 • CLDR: Upgrade to CLDR 41.0. (#853) - Aarni Koskela
5460
5461 • The c and e plural form operands introduced in CLDR 40 are
5462 parsed, but otherwise unsupported. (#826)
5463
5464 • Non-nominative forms of units are currently ignored.
5465
5466 • Messages: Implement --init-missing option for pybabel update (#785) -
5467 ruro
5468
5469 • Messages: For extract, you can now replace the built-in .* / _* ig‐
5470 nored directory patterns with ones of your own. (#832) - Aarni
5471 Koskela, Kinshuk Dua
5472
5473 • Messages: Add --check to verify if catalogs are up-to-date (#831) -
5474 Krzysztof Jagiełło
5475
5476 • Messages: Add --header-comment to override default header comment (‐
5477 #720) - Mohamed Hafez Morsy, Aarni Koskela
5478
5479 • Dates: parse_time now supports 12-hour clock, and is better at pars‐
5480 ing partial times. (#834) - Aarni Koskela, David Bauer, Arthur Jo‐
5481 vart
5482
5483 • Dates: parse_date and parse_time now raise ParseError, a subclass of
5484 ValueError, in certain cases. (#834) - Aarni Koskela
5485
5486 • Dates: parse_date and parse_time now accept the format parameter. (‐
5487 #834) - Juliette Monsel, Aarni Koskela
5488
5489 Infrastructure
5490 • The internal babel/_compat.py module is no more (#808) - Hugo van Ke‐
5491 menade
5492
5493 • Python 3.10 is officially supported (#809) - Hugo van Kemenade
5494
5495 • There’s now a friendly GitHub issue template. (#800) – Álvaro
5496 Mondéjar Rubio
5497
5498 • Don’t use the deprecated format_number function internally or in
5499 tests - Aarni Koskela
5500
5501 • Add GitHub URL for PyPi (#846) - Andrii Oriekhov
5502
5503 • Python 3.12 compatibility: Prefer setuptools imports to distutils im‐
5504 ports (#843) - Aarni Koskela
5505
5506 • Python 3.11 compatibility: Add deprecations to l*gettext variants (‐
5507 #835) - Aarni Koskela
5508
5509 • CI: Babel is now tested with PyPy 3.7. (#851) - Aarni Koskela
5510
5511 Bugfixes
5512 • Date formatting: Allow using other as fallback form (#827) - Aarni
5513 Koskela
5514
5515 • Locales: Locale.parse() normalizes variant tags to upper case (#829)
5516 - Aarni Koskela
5517
5518 • A typo in the plural format for Maltese is fixed. (#796) - Lukas Win‐
5519 kler
5520
5521 • Messages: Catalog date parsing is now timezone independent. (#701) -
5522 rachele-collin
5523
5524 • Messages: Fix duplicate locations when writing without lineno (#837)
5525 - Sigurd Ljødal
5526
5527 • Messages: Fix missing trailing semicolon in plural form headers (‐
5528 #848) - farhan5900
5529
5530 • CLI: Fix output of --list-locales to not be a bytes repr (#845) -
5531 Morgan Wahl
5532
5533 Documentation
5534 • Documentation is now correctly built again, and up to date (#830) -
5535 Aarni Koskela
5536
5537 Version 2.9.1
5538 Bugfixes
5539 • The internal locale-data loading functions now validate the name of
5540 the locale file to be loaded and only allow files within Babel’s data
5541 directory. Thank you to Chris Lyne of Tenable, Inc. for discovering
5542 the issue!
5543
5544 Version 2.9.0
5545 Upcoming version support changes
5546 • This version, Babel 2.9, is the last version of Babel to support
5547 Python 2.7, Python 3.4, and Python 3.5.
5548
5549 Improvements
5550 • CLDR: Use CLDR 37 – Aarni Koskela (#734)
5551
5552 • Dates: Handle ZoneInfo objects in get_timezone_location, get_time‐
5553 zone_name - Alessio Bogon (#741)
5554
5555 • Numbers: Add group_separator feature in number formatting - Abdullah
5556 Javed Nesar (#726)
5557
5558 Bugfixes
5559 • Dates: Correct default Format().timedelta format to ‘long’ to mute
5560 deprecation warnings – Aarni Koskela
5561
5562 • Import: Simplify iteration code in “import_cldr.py” – Felix Schwarz
5563
5564 • Import: Stop using deprecated ElementTree methods “getchildren()” and
5565 “getiterator()” – Felix Schwarz
5566
5567 • Messages: Fix unicode printing error on Python 2 without TTY. –
5568 Niklas Hambüchen
5569
5570 • Messages: Introduce invariant that _invalid_pofile() takes unicode
5571 line. – Niklas Hambüchen
5572
5573 • Tests: fix tests when using Python 3.9 – Felix Schwarz
5574
5575 • Tests: Remove deprecated ‘sudo: false’ from Travis configuration –
5576 Jon Dufresne
5577
5578 • Tests: Support Py.test 6.x – Aarni Koskela
5579
5580 • Utilities: LazyProxy: Handle AttributeError in specified func – Niki‐
5581 forov Konstantin (#724)
5582
5583 • Utilities: Replace usage of parser.suite with ast.parse – Miro
5584 Hrončok
5585
5586 Documentation
5587 • Update parse_number comments – Brad Martin (#708)
5588
5589 • Add __iter__ to Catalog documentation – @CyanNani123
5590
5591 Version 2.8.1
5592 This is solely a patch release to make running tests on Py.test 6+ pos‐
5593 sible.
5594
5595 Bugfixes
5596 • Support Py.test 6 - Aarni Koskela (#747, #750, #752)
5597
5598 Version 2.8.0
5599 Improvements
5600 • CLDR: Upgrade to CLDR 36.0 - Aarni Koskela (#679)
5601
5602 • Messages: Don’t even open files with the “ignore” extraction method -
5603 @sebleblanc (#678)
5604
5605 Bugfixes
5606 • Numbers: Fix formatting very small decimals when quantization is dis‐
5607 abled - Lev Lybin, @miluChen (#662)
5608
5609 • Messages: Attempt to sort all messages – Mario Frasca (#651, #606)
5610
5611 Docs
5612 • Add years to changelog - Romuald Brunet
5613
5614 • Note that installation requires pytz - Steve (Gadget) Barnes
5615
5616 Version 2.7.0
5617 Possibly incompatible changes
5618 These may be backward incompatible in some cases, as some more-or-less
5619 internal APIs have changed. Please feel free to file issues if you bump
5620 into anything strange and we’ll try to help!
5621
5622 • General: Internal uses of babel.util.odict have been replaced with
5623 collections.OrderedDict from The Python standard library.
5624
5625 Improvements
5626 • CLDR: Upgrade to CLDR 35.1 - Alberto Mardegan, Aarni Koskela (#626,
5627 #643)
5628
5629 • General: allow anchoring path patterns to the start of a string -
5630 Brian Cappello (#600)
5631
5632 • General: Bumped version requirement on pytz - @chrisbrake (#592)
5633
5634 • Messages: pybabel compile: exit with code 1 if errors were encoun‐
5635 tered - Aarni Koskela (#647)
5636
5637 • Messages: Add omit-header to update_catalog - Cédric Krier (#633)
5638
5639 • Messages: Catalog update: keep user comments from destination by de‐
5640 fault - Aarni Koskela (#648)
5641
5642 • Messages: Skip empty message when writing mo file - Cédric Krier (‐
5643 #564)
5644
5645 • Messages: Small fixes to avoid crashes on badly formatted .po files -
5646 Bryn Truscott (#597)
5647
5648 • Numbers: parse_decimal() strict argument and suggestions - Charly C
5649 (#590)
5650
5651 • Numbers: don’t repeat suggestions in parse_decimal strict - Serban
5652 Constantin (#599)
5653
5654 • Numbers: implement currency formatting with long display names - Luke
5655 Plant (#585)
5656
5657 • Numbers: parse_decimal(): assume spaces are equivalent to non-break‐
5658 ing spaces when not in strict mode - Aarni Koskela (#649)
5659
5660 • Performance: Cache locale_identifiers() - Aarni Koskela (#644)
5661
5662 Bugfixes
5663 • CLDR: Skip alt=… for week data (minDays, firstDay, weekendStart,
5664 weekendEnd) - Aarni Koskela (#634)
5665
5666 • Dates: Fix wrong weeknumber for 31.12.2018 - BT-sschmid (#621)
5667
5668 • Locale: Avoid KeyError trying to get data on WindowsXP - mondeja (‐
5669 #604)
5670
5671 • Locale: get_display_name(): Don’t attempt to concatenate variant in‐
5672 formation to None - Aarni Koskela (#645)
5673
5674 • Messages: pofile: Add comparison operators to _NormalizedString -
5675 Aarni Koskela (#646)
5676
5677 • Messages: pofile: don’t crash when message.locations can’t be sorted
5678 - Aarni Koskela (#646)
5679
5680 Tooling & docs
5681 • Docs: Remove all references to deprecated easy_install - Jon Dufresne
5682 (#610)
5683
5684 • Docs: Switch print statement in docs to print function - NotAFile
5685
5686 • Docs: Update all pypi.python.org URLs to pypi.org - Jon Dufresne (‐
5687 #587)
5688
5689 • Docs: Use https URLs throughout project where available - Jon
5690 Dufresne (#588)
5691
5692 • Support: Add testing and document support for Python 3.7 - Jon
5693 Dufresne (#611)
5694
5695 • Support: Test on Python 3.8-dev - Aarni Koskela (#642)
5696
5697 • Support: Using ABCs from collections instead of collections.abc is
5698 deprecated. - Julien Palard (#609)
5699
5700 • Tests: Fix conftest.py compatibility with pytest 4.3 - Miro Hrončok
5701 (#635)
5702
5703 • Tests: Update pytest and pytest-cov - Miro Hrončok (#635)
5704
5705 Version 2.6.0
5706 Possibly incompatible changes
5707 These may be backward incompatible in some cases, as some more-or-less
5708 internal APIs have changed. Please feel free to file issues if you
5709 bump into anything strange and we’ll try to help!
5710
5711 • Numbers: Refactor decimal handling code and allow bypass of decimal
5712 quantization. (@kdeldycke) (PR #538)
5713
5714 • Messages: allow processing files that are in locales unknown to Babel
5715 (@akx) (PR #557)
5716
5717 • General: Drop support for EOL Python 2.6 and 3.3 (@hugovk) (PR #546)
5718
5719 Other changes
5720 • CLDR: Use CLDR 33 (@akx) (PR #581)
5721
5722 • Lists: Add support for various list styles other than the default
5723 (@akx) (#552)
5724
5725 • Messages: Add new PoFileError exception (@Bedrock02) (PR #532)
5726
5727 • Times: Simplify Linux distro specific explicit timezone setting
5728 search (@scop) (PR #528)
5729
5730 Bugfixes
5731 • CLDR: avoid importing alt=narrow currency symbols (@akx) (PR #558)
5732
5733 • CLDR: ignore non-Latin numbering systems (@akx) (PR #579)
5734
5735 • Docs: Fix improper example for date formatting (@PTrottier) (PR #574)
5736
5737 • Tooling: Fix some deprecation warnings (@akx) (PR #580)
5738
5739 Tooling & docs
5740 • Add explicit signatures to some date autofunctions (@xmo-odoo) (PR
5741 #554)
5742
5743 • Include license file in the generated wheel package (@jdufresne) (PR
5744 #539)
5745
5746 • Python 3.6 invalid escape sequence deprecation fixes (@scop) (PR
5747 #528)
5748
5749 • Test and document all supported Python versions (@jdufresne) (PR
5750 #540)
5751
5752 • Update copyright header years and authors file (@akx) (PR #559)
5753
5754 Version 2.5.3
5755 This is a maintenance release that reverts undesired API-breaking
5756 changes that slipped into 2.5.2 (see #550).
5757
5758 It is based on v2.5.1 (f29eccd) with commits 7cedb84, 29da2d2 and
5759 edfb518 cherry-picked on top.
5760
5761 Version 2.5.2
5762 Bugfixes
5763 • Revert the unnecessary PyInstaller fixes from 2.5.0 and 2.5.1 (#533)
5764 (@yagebu)
5765
5766 Version 2.5.1
5767 Minor Improvements and bugfixes
5768 • Use a fixed datetime to avoid test failures (#520) (@narendravardi)
5769
5770 • Parse multi-line __future__ imports better (#519) (@akx)
5771
5772 • Fix validate_currency docstring (#522)
5773
5774 • Allow normalize_locale and exists to handle various unexpected inputs
5775 (#523) (@suhojm)
5776
5777 • Make PyInstaller support more robust (#525, #526) (@thijstriemstra,
5778 @akx)
5779
5780 Version 2.5.0
5781 New Features
5782 • Numbers: Add currency utilities and helpers (#491) (@kdeldycke)
5783
5784 • Support PyInstaller (#500, #505) (@wodo)
5785
5786 Minor Improvements and bugfixes
5787 • Dates: Add __str__ to DateTimePattern (#515) (@sfermigier)
5788
5789 • Dates: Fix an invalid string to bytes comparison when parsing TZ
5790 files on Py3 (#498) (@rowillia)
5791
5792 • Dates: Formatting zero-padded components of dates is faster (#517)
5793 (@akx)
5794
5795 • Documentation: Fix “Good Commits” link in CONTRIBUTING.md (#511)
5796 (@naryanacharya6)
5797
5798 • Documentation: Fix link to Python gettext module (#512) (@Linkid)
5799
5800 • Messages: Allow both dash and underscore separated locale identifiers
5801 in pofiles (#489, #490) (@akx)
5802
5803 • Messages: Extract Python messages in nested gettext calls (#488)
5804 (@sublee)
5805
5806 • Messages: Fix in-place editing of dir list while iterating (#476,
5807 #492) (@MarcDufresne)
5808
5809 • Messages: Stabilize sort order (#482) (@xavfernandez)
5810
5811 • Time zones: Honor the no-inherit marker for metazone names (#405)
5812 (@akx)
5813
5814 Version 2.4.0
5815 New Features
5816 Some of these changes might break your current code and/or tests.
5817
5818 • CLDR: CLDR 29 is now used instead of CLDR 28 (#405) (@akx)
5819
5820 • Messages: Add option ‘add_location’ for location line formatting (‐
5821 #438, #459) (@rrader, @alxpy)
5822
5823 • Numbers: Allow full control of decimal behavior (#410) (@etanol)
5824
5825 Minor Improvements and bugfixes
5826 • Documentation: Improve Date Fields descriptions (#450) (@ldwoolley)
5827
5828 • Documentation: Typo fixes and documentation improvements (#406, #412,
5829 #403, #440, #449, #463) (@zyegfryed, @adamchainz, @jwilk, @akx, @ro‐
5830 ramirez, @abhishekcs10)
5831
5832 • Messages: Default to UTF-8 source encoding instead of ISO-8859-1 (‐
5833 #399) (@asottile)
5834
5835 • Messages: Ensure messages are extracted in the order they were passed
5836 in (#424) (@ngrilly)
5837
5838 • Messages: Message extraction for JSX files is improved (#392, #396,
5839 #425) (@karloskar, @georgschoelly)
5840
5841 • Messages: PO file reading supports multi-line obsolete units (#429)
5842 (@mbirtwell)
5843
5844 • Messages: Python message extractor respects unicode_literals in __fu‐
5845 ture__ (#427) (@sublee)
5846
5847 • Messages: Roundtrip Language headers (#420) (@kruton)
5848
5849 • Messages: units before obsolete units are no longer erroneously
5850 marked obsolete (#452) (@mbirtwell)
5851
5852 • Numbers: parse_pattern now preserves the full original pattern (#414)
5853 (@jtwang)
5854
5855 • Numbers: Fix float conversion in extract_operands (#435) (@akx)
5856
5857 • Plurals: Fix plural forms for Czech and Slovak locales (#373) (@yk‐
5858 shatroff)
5859
5860 • Plurals: More plural form fixes based on Mozilla and CLDR references
5861 (#431) (@mshenfield)
5862
5863 Internal improvements
5864 • Local times are constructed correctly in tests (#411) (@etanol)
5865
5866 • Miscellaneous small improvements (#437) (@scop)
5867
5868 • Regex flags are extracted from the regex strings (#462) (@singing‐
5869 wolfboy)
5870
5871 • The PO file reader is now a class and has seen some refactoring (‐
5872 #429, #452) (@mbirtwell)
5873
5874 Version 2.3.4
5875 (Bugfix release, released on April 22th 2016)
5876
5877 Bugfixes
5878 • CLDR: The lxml library is no longer used for CLDR importing, so it
5879 should not cause strange failures either. Thanks to @aronbierbaum for
5880 the bug report and @jtwang for the fix. (‐
5881 https://github.com/python-babel/babel/pull/393)
5882
5883 • CLI: Every last single CLI usage regression should now be gone, and
5884 both distutils and stand-alone CLIs should work as they have in the
5885 past. Thanks to @paxswill and @ajaeger for bug reports. (‐
5886 https://github.com/python-babel/babel/pull/389)
5887
5888 Version 2.3.3
5889 (Bugfix release, released on April 12th 2016)
5890
5891 Bugfixes
5892 • CLI: Usage regressions that had snuck in between 2.2 and 2.3 should
5893 be no more. (https://github.com/python-babel/babel/pull/386) Thanks
5894 to @ajaeger, @sebdiem and @jcristovao for bug reports and patches.
5895
5896 Version 2.3.2
5897 (Bugfix release, released on April 9th 2016)
5898
5899 Bugfixes
5900 • Dates: Period (am/pm) formatting was broken in certain locales
5901 (namely zh_TW). Thanks to @jun66j5 for the bug report. (#378, #379)
5902
5903 Version 2.3.1
5904 (Bugfix release because of deployment problems, released on April 8th
5905 2016)
5906
5907 Version 2.3
5908 (Feature release, released on April 8th 2016)
5909
5910 Internal improvements
5911 • The CLI frontend and Distutils commands use a shared implementation
5912 (https://github.com/python-babel/babel/pull/311)
5913
5914 • PyPy3 is supported (https://github.com/python-babel/babel/pull/343)
5915
5916 Features
5917 • CLDR: Add an API for territory language data (‐
5918 https://github.com/python-babel/babel/pull/315)
5919
5920 • Core: Character order and measurement system data is imported and ex‐
5921 posed (https://github.com/python-babel/babel/pull/368)
5922
5923 • Dates: Add an API for time interval formatting (‐
5924 https://github.com/python-babel/babel/pull/316)
5925
5926 • Dates: More pattern formats and lengths are supported (‐
5927 https://github.com/python-babel/babel/pull/347)
5928
5929 • Dates: Period IDs are imported and exposed (‐
5930 https://github.com/python-babel/babel/pull/349)
5931
5932 • Dates: Support for date-time skeleton formats has been added (‐
5933 https://github.com/python-babel/babel/pull/265)
5934
5935 • Dates: Timezone formatting has been improved (‐
5936 https://github.com/python-babel/babel/pull/338)
5937
5938 • Messages: JavaScript extraction now supports dotted names, ES6 tem‐
5939 plate strings and JSX tags (‐
5940 https://github.com/python-babel/babel/pull/332)
5941
5942 • Messages: npgettext is recognized by default (‐
5943 https://github.com/python-babel/babel/pull/341)
5944
5945 • Messages: The CLI learned to accept multiple domains (‐
5946 https://github.com/python-babel/babel/pull/335)
5947
5948 • Messages: The extraction commands now accept filenames in addition to
5949 directories (https://github.com/python-babel/babel/pull/324)
5950
5951 • Units: A new API for unit formatting is implemented (‐
5952 https://github.com/python-babel/babel/pull/369)
5953
5954 Bugfixes
5955 • Core: Mixed-case locale IDs work more reliably (‐
5956 https://github.com/python-babel/babel/pull/361)
5957
5958 • Dates: S…S formats work correctly now (‐
5959 https://github.com/python-babel/babel/pull/360)
5960
5961 • Messages: All messages are now sorted correctly if sorting has been
5962 specified (https://github.com/python-babel/babel/pull/300)
5963
5964 • Messages: Fix the unexpected behavior caused by catalog header updat‐
5965 ing (e0e7ef1) (https://github.com/python-babel/babel/pull/320)
5966
5967 • Messages: Gettext operands are now generated correctly (‐
5968 https://github.com/python-babel/babel/pull/295)
5969
5970 • Messages: Message extraction has been taught to detect encodings bet‐
5971 ter (https://github.com/python-babel/babel/pull/274)
5972
5973 Version 2.2
5974 (Feature release, released on January 2nd 2016)
5975
5976 Bugfixes
5977 • General: Add __hash__ to Locale. (#303) (2aa8074)
5978
5979 • General: Allow files with BOM if they’re UTF-8 (#189) (da87edd)
5980
5981 • General: localedata directory is now locale-data (#109) (2d1882e)
5982
5983 • General: odict: Fix pop method (0a9e97e)
5984
5985 • General: Removed uses of datetime.date class from .dat files (#174)
5986 (94f6830)
5987
5988 • Messages: Fix plural selection for Chinese (531f666)
5989
5990 • Messages: Fix typo and add semicolon in plural_forms (5784501)
5991
5992 • Messages: Flatten NullTranslations.files into a list (ad11101)
5993
5994 • Times: FixedOffsetTimezone: fix display of negative offsets (d816803)
5995
5996 Features
5997 • CLDR: Update to CLDR 28 (#292) (9f7f4d0)
5998
5999 • General: Add __copy__ and __deepcopy__ to LazyProxy. (a1cc3f1)
6000
6001 • General: Add official support for Python 3.4 and 3.5
6002
6003 • General: Improve odict performance by making key search O(1)
6004 (6822b7f)
6005
6006 • Locale: Add an ordinal_form property to Locale (#270) (b3f3430)
6007
6008 • Locale: Add support for list formatting (37ce4fa, be6e23d)
6009
6010 • Locale: Check inheritance exceptions first (3ef0d6d)
6011
6012 • Messages: Allow file locations without line numbers (#279) (79bc781)
6013
6014 • Messages: Allow passing a callable to extract() (#289) (3f58516)
6015
6016 • Messages: Support ‘Language’ header field of PO files (#76) (3ce842b)
6017
6018 • Messages: Update catalog headers from templates (e0e7ef1)
6019
6020 • Numbers: Properly load and expose currency format types (#201)
6021 (df676ab)
6022
6023 • Numbers: Use cdecimal by default when available (b6169be)
6024
6025 • Numbers: Use the CLDR’s suggested number of decimals for format_cur‐
6026 rency (#139) (201ed50)
6027
6028 • Times: Add format_timedelta(format=’narrow’) support (edc5eb5)
6029
6030 Version 2.1
6031 (Bugfix/minor feature release, released on September 25th 2015)
6032
6033 • Parse and honour the locale inheritance exceptions (#97)
6034
6035 • Fix Locale.parse using global.dat incompatible types (#174)
6036
6037 • Fix display of negative offsets in FixedOffsetTimezone (#214)
6038
6039 • Improved odict performance which is used during localization file
6040 build, should improve compilation time for large projects
6041
6042 • Add support for “narrow” format for format_timedelta
6043
6044 • Add universal wheel support
6045
6046 • Support ‘Language’ header field in .PO files (fixes #76)
6047
6048 • Test suite enhancements (coverage, broken tests fixed, etc)
6049
6050 • Documentation updated
6051
6052 Version 2.0
6053 (Released on July 27th 2015, codename Second Coming)
6054
6055 • Added support for looking up currencies that belong to a territory
6056 through the babel.numbers.get_territory_currencies() function.
6057
6058 • Improved Python 3 support.
6059
6060 • Fixed some broken tests for timezone behavior.
6061
6062 • Improved various smaller things for dealing with dates.
6063
6064 Version 1.4
6065 (bugfix release, release date to be decided)
6066
6067 • Fixed a bug that caused deprecated territory codes not being con‐
6068 verted properly by the subtag resolving. This for instance showed up
6069 when trying to use und_UK as a language code which now properly re‐
6070 solves to en_GB.
6071
6072 • Fixed a bug that made it impossible to import the CLDR data from
6073 scratch on windows systems.
6074
6075 Version 1.3
6076 (bugfix release, released on July 29th 2013)
6077
6078 • Fixed a bug in likely-subtag resolving for some common locales. This
6079 primarily makes zh_CN work again which was broken due to how it was
6080 defined in the likely subtags combined with our broken resolving.
6081 This fixes #37.
6082
6083 • Fixed a bug that caused pybabel to break when writing to stdout on
6084 Python 3.
6085
6086 • Removed a stray print that was causing issues when writing to stdout
6087 for message catalogs.
6088
6089 Version 1.2
6090 (bugfix release, released on July 27th 2013)
6091
6092 • Included all tests in the tarball. Previously the include skipped
6093 past recursive folders.
6094
6095 • Changed how tests are invoked and added separate standalone test com‐
6096 mand. This simplifies testing of the package for linux distributors.
6097
6098 Version 1.1
6099 (bugfix release, released on July 27th 2013)
6100
6101 • added dummy version requirements for pytz so that it installs on pip
6102 1.4.
6103
6104 • Included tests in the tarball.
6105
6106 Version 1.0
6107 (Released on July 26th 2013, codename Revival)
6108
6109 • support python 2.6, 2.7, 3.3+ and pypy - drop all other versions
6110
6111 • use tox for testing on different pythons
6112
6113 • Added support for the locale plural rules defined by the CLDR.
6114
6115 • Added format_timedelta function to support localized formatting of
6116 relative times with strings such as “2 days” or “1 month” (ticket
6117 #126).
6118
6119 • Fixed negative offset handling of Catalog._set_mime_headers (ticket
6120 #165).
6121
6122 • Fixed the case where messages containing square brackets would break
6123 with an unpack error.
6124
6125 • updated to CLDR 23
6126
6127 • Make the CLDR import script work with Python 2.7.
6128
6129 • Fix various typos.
6130
6131 • Sort output of list-locales.
6132
6133 • Make the POT-Creation-Date of the catalog being updated equal to
6134 POT-Creation-Date of the template used to update (ticket #148).
6135
6136 • Use a more explicit error message if no option or argument (command)
6137 is passed to pybabel (ticket #81).
6138
6139 • Keep the PO-Revision-Date if it is not the default value (ticket
6140 #148).
6141
6142 • Make –no-wrap work by reworking –width’s default and mimic xgettext’s
6143 behaviour of always wrapping comments (ticket #145).
6144
6145 • Add –project and –version options for commandline (ticket #173).
6146
6147 • Add a __ne__() method to the Local class.
6148
6149 • Explicitly sort instead of using sorted() and don’t assume ordering
6150 (Jython compatibility).
6151
6152 • Removed ValueError raising for string formatting message checkers if
6153 the string does not contain any string formatting (ticket #150).
6154
6155 • Fix Serbian plural forms (ticket #213).
6156
6157 • Small speed improvement in format_date() (ticket #216).
6158
6159 • Fix so frontend.CommandLineInterface.run does not accumulate logging
6160 handlers (ticket #227, reported with initial patch by dfraser)
6161
6162 • Fix exception if environment contains an invalid locale setting (‐
6163 ticket #200)
6164
6165 • use cPickle instead of pickle for better performance (ticket #225)
6166
6167 • Only use bankers round algorithm as a tie breaker if there are two
6168 nearest numbers, round as usual if there is only one nearest number
6169 (ticket #267, patch by Martin)
6170
6171 • Allow disabling cache behaviour in LazyProxy (ticket #208, initial
6172 patch from Pedro Algarvio)
6173
6174 • Support for context-aware methods during message extraction (ticket
6175 #229, patch from David Rios)
6176
6177 • “init” and “update” commands support “–no-wrap” option (ticket #289)
6178
6179 • fix formatting of fraction in format_decimal() if the input value is
6180 a float with more than 7 significant digits (ticket #183)
6181
6182 • fix format_date() with datetime parameter (ticket #282, patch from
6183 Xavier Morel)
6184
6185 • fix format_decimal() with small Decimal values (ticket #214, patch
6186 from George Lund)
6187
6188 • fix handling of messages containing ‘\n’ (ticket #198)
6189
6190 • handle irregular multi-line msgstr (no “” as first line) gracefully
6191 (ticket #171)
6192
6193 • parse_decimal() now returns Decimals not floats, API change (ticket
6194 #178)
6195
6196 • no warnings when running setup.py without installed setuptools (‐
6197 ticket #262)
6198
6199 • modified Locale.__eq__ method so Locales are only equal if all of
6200 their attributes (language, territory, script, variant) are equal
6201
6202 • resort to hard-coded message extractors/checkers if pkg_resources is
6203 installed but no egg-info was found (ticket #230)
6204
6205 • format_time() and format_datetime() now accept also floats (ticket
6206 #242)
6207
6208 • add babel.support.NullTranslations class similar to gettext.Null‐
6209 Translations but with all of Babel’s new gettext methods (ticket
6210 #277)
6211
6212 • “init” and “update” commands support “–width” option (ticket #284)
6213
6214 • fix ‘input_dirs’ option for setuptools integration (ticket #232, ini‐
6215 tial patch by Étienne Bersac)
6216
6217 • ensure .mo file header contains the same information as the source
6218 .po file (ticket #199)
6219
6220 • added support for get_language_name() on the locale objects.
6221
6222 • added support for get_territory_name() on the locale objects.
6223
6224 • added support for get_script_name() on the locale objects.
6225
6226 • added pluralization support for currency names and added a ‘¤¤¤’ pat‐
6227 tern for currencies that includes the full name.
6228
6229 • depend on pytz now and wrap it nicer. This gives us improved support
6230 for things like timezone transitions and an overall nicer API.
6231
6232 • Added support for explicit charset to PO file reading.
6233
6234 • Added experimental Python 3 support.
6235
6236 • Added better support for returning timezone names.
6237
6238 • Don’t throw away a Catalog’s obsolete messages when updating it.
6239
6240 • Added basic likelySubtag resolving when doing locale parsing and no
6241 match can be found.
6242
6243 Version 0.9.6
6244 (released on March 17th 2011)
6245
6246 • Backport r493-494: documentation typo fixes.
6247
6248 • Make the CLDR import script work with Python 2.7.
6249
6250 • Fix various typos.
6251
6252 • Fixed Python 2.3 compatibility (ticket #146, ticket #233).
6253
6254 • Sort output of list-locales.
6255
6256 • Make the POT-Creation-Date of the catalog being updated equal to
6257 POT-Creation-Date of the template used to update (ticket #148).
6258
6259 • Use a more explicit error message if no option or argument (command)
6260 is passed to pybabel (ticket #81).
6261
6262 • Keep the PO-Revision-Date if it is not the default value (ticket
6263 #148).
6264
6265 • Make –no-wrap work by reworking –width’s default and mimic xgettext’s
6266 behaviour of always wrapping comments (ticket #145).
6267
6268 • Fixed negative offset handling of Catalog._set_mime_headers (ticket
6269 #165).
6270
6271 • Add –project and –version options for commandline (ticket #173).
6272
6273 • Add a __ne__() method to the Local class.
6274
6275 • Explicitly sort instead of using sorted() and don’t assume ordering
6276 (Python 2.3 and Jython compatibility).
6277
6278 • Removed ValueError raising for string formatting message checkers if
6279 the string does not contain any string formatting (ticket #150).
6280
6281 • Fix Serbian plural forms (ticket #213).
6282
6283 • Small speed improvement in format_date() (ticket #216).
6284
6285 • Fix number formatting for locales where CLDR specifies alt or draft
6286 items (ticket #217)
6287
6288 • Fix bad check in format_time (ticket #257, reported with patch and
6289 tests by jomae)
6290
6291 • Fix so frontend.CommandLineInterface.run does not accumulate logging
6292 handlers (ticket #227, reported with initial patch by dfraser)
6293
6294 • Fix exception if environment contains an invalid locale setting (‐
6295 ticket #200)
6296
6297 Version 0.9.5
6298 (released on April 6th 2010)
6299
6300 • Fixed the case where messages containing square brackets would break
6301 with an unpack error.
6302
6303 • Backport of r467: Fuzzy matching regarding plurals should NOT be
6304 checked against len(message.id) because this is always 2, instead,
6305 it’s should be checked against catalog.num_plurals (ticket #212).
6306
6307 Version 0.9.4
6308 (released on August 25th 2008)
6309
6310 • Currency symbol definitions that is defined with choice patterns in
6311 the CLDR data are no longer imported, so the symbol code will be used
6312 instead.
6313
6314 • Fixed quarter support in date formatting.
6315
6316 • Fixed a serious memory leak that was introduces by the support for
6317 CLDR aliases in 0.9.3 (ticket #128).
6318
6319 • Locale modifiers such as “@euro” are now stripped from locale identi‐
6320 fiers when parsing (ticket #136).
6321
6322 • The system locales “C” and “POSIX” are now treated as aliases for
6323 “en_US_POSIX”, for which the CLDR provides the appropriate data.
6324 Thanks to Manlio Perillo for the suggestion.
6325
6326 • Fixed JavaScript extraction for regular expression literals (ticket
6327 #138) and concatenated strings.
6328
6329 • The Translation class in babel.support can now manage catalogs with
6330 different message domains, and exposes the family of d*gettext func‐
6331 tions (ticket #137).
6332
6333 Version 0.9.3
6334 (released on July 9th 2008)
6335
6336 • Fixed invalid message extraction methods causing an UnboundLocalEr‐
6337 ror.
6338
6339 • Extraction method specification can now use a dot instead of the
6340 colon to separate module and function name (ticket #105).
6341
6342 • Fixed message catalog compilation for locales with more than two plu‐
6343 ral forms (ticket #95).
6344
6345 • Fixed compilation of message catalogs for locales with more than two
6346 plural forms where the translations were empty (ticket #97).
6347
6348 • The stripping of the comment tags in comments is optional now and is
6349 done for each line in a comment.
6350
6351 • Added a JavaScript message extractor.
6352
6353 • Updated to CLDR 1.6.
6354
6355 • Fixed timezone calculations when formatting datetime and time values.
6356
6357 • Added a get_plural function into the plurals module that returns the
6358 correct plural forms for a locale as tuple.
6359
6360 • Added support for alias definitions in the CLDR data files, meaning
6361 that the chance for items missing in certain locales should be
6362 greatly reduced (ticket #68).
6363
6364 Version 0.9.2
6365 (released on February 4th 2008)
6366
6367 • Fixed catalogs’ charset values not being recognized (ticket #66).
6368
6369 • Numerous improvements to the default plural forms.
6370
6371 • Fixed fuzzy matching when updating message catalogs (ticket #82).
6372
6373 • Fixed bug in catalog updating, that in some cases pulled in transla‐
6374 tions from different catalogs based on the same template.
6375
6376 • Location lines in PO files do no longer get wrapped at hyphens in
6377 file names (ticket #79).
6378
6379 • Fixed division by zero error in catalog compilation on empty catalogs
6380 (ticket #60).
6381
6382 Version 0.9.1
6383 (released on September 7th 2007)
6384
6385 • Fixed catalog updating when a message is merged that was previously
6386 simple but now has a plural form, for example by moving from gettext
6387 to ngettext, or vice versa.
6388
6389 • Fixed time formatting for 12 am and 12 pm.
6390
6391 • Fixed output encoding of the pybabel –list-locales command.
6392
6393 • MO files are now written in binary mode on windows (ticket #61).
6394
6395 Version 0.9
6396 (released on August 20th 2007)
6397
6398 • The new_catalog distutils command has been renamed to init_catalog
6399 for consistency with the command-line frontend.
6400
6401 • Added compilation of message catalogs to MO files (ticket #21).
6402
6403 • Added updating of message catalogs from POT files (ticket #22).
6404
6405 • Support for significant digits in number formatting.
6406
6407 • Apply proper “banker’s rounding” in number formatting in a
6408 cross-platform manner.
6409
6410 • The number formatting functions now also work with numbers repre‐
6411 sented by Python Decimal objects (ticket #53).
6412
6413 • Added extensible infrastructure for validating translation catalogs.
6414
6415 • Fixed the extractor not filtering out messages that didn’t validate
6416 against the keyword’s specification (ticket #39).
6417
6418 • Fixed the extractor raising an exception when encountering an empty
6419 string msgid. It now emits a warning to stderr.
6420
6421 • Numerous Python message extractor fixes: it now handles nested func‐
6422 tion calls within a gettext function call correctly, uses the correct
6423 line number for multi-line function calls, and other small fixes
6424 (tickets ticket #38 and ticket #39).
6425
6426 • Improved support for detecting Python string formatting fields in
6427 message strings (ticket #57).
6428
6429 • CLDR upgraded to the 1.5 release.
6430
6431 • Improved timezone formatting.
6432
6433 • Implemented scientific number formatting.
6434
6435 • Added mechanism to lookup locales by alias, for cases where browsers
6436 insist on including only the language code in the Accept-Language
6437 header, and sometimes even the incorrect language code.
6438
6439 Version 0.8.1
6440 (released on July 2nd 2007)
6441
6442 • default_locale() would fail when the value of the LANGUAGE environ‐
6443 ment variable contained multiple language codes separated by colon,
6444 as is explicitly allowed by the GNU gettext tools. As the default_lo‐
6445 cale() function is called at the module level in some modules, this
6446 bug would completely break importing these modules on systems where
6447 LANGUAGE is set that way.
6448
6449 • The character set specified in PO template files is now respected
6450 when creating new catalog files based on that template. This allows
6451 the use of characters outside the ASCII range in POT files (ticket
6452 #17).
6453
6454 • The default ordering of messages in generated POT files, which is
6455 based on the order those messages are found when walking the source
6456 tree, is no longer subject to differences between platforms; direc‐
6457 tory and file names are now always sorted alphabetically.
6458
6459 • The Python message extractor now respects the special encoding com‐
6460 ment to be able to handle files containing non-ASCII characters (‐
6461 ticket #23).
6462
6463 • Added N_ (gettext noop) to the extractor’s default keywords.
6464
6465 • Made locale string parsing more robust, and also take the script part
6466 into account (ticket #27).
6467
6468 • Added a function to list all locales for which locale data is avail‐
6469 able.
6470
6471 • Added a command-line option to the pybabel command which prints out
6472 all available locales (ticket #24).
6473
6474 • The name of the command-line script has been changed from just babel
6475 to pybabel to avoid a conflict with the OpenBabel project (ticket
6476 #34).
6477
6478 Version 0.8
6479 (released on June 20th 2007)
6480
6481 • First public release
6482
6483 License
6484 Babel is licensed under a three clause BSD License. It basically
6485 means: do whatever you want with it as long as the copyright in Babel
6486 sticks around, the conditions are not modified and the disclaimer is
6487 present. Furthermore you must not use the names of the authors to pro‐
6488 mote derivatives of the software without written consent.
6489
6490 The full license text can be found below (Babel License).
6491
6492 Authors
6493 Babel is written and maintained by the Babel team and various contribu‐
6494 tors:
6495
6496 • Aarni Koskela
6497
6498 • Christopher Lenz
6499
6500 • Armin Ronacher
6501
6502 • Alex Morega
6503
6504 • Lasse Schuirmann
6505
6506 • Felix Schwarz
6507
6508 • Pedro Algarvio
6509
6510 • Jeroen Ruigrok van der Werven
6511
6512 • Philip Jenvey
6513
6514 • benselme
6515
6516 • Isaac Jurado
6517
6518 • Tobias Bieniek
6519
6520 • Erick Wilder
6521
6522 • Jonah Lawrence
6523
6524 • Michael Birtwell
6525
6526 • Jonas Borgström
6527
6528 • Kevin Deldycke
6529
6530 • Jon Dufresne
6531
6532 • Ville Skyttä
6533
6534 • Jun Omae
6535
6536 • Hugo
6537
6538 • Heungsub Lee
6539
6540 • Jakob Schnitzer
6541
6542 • Sachin Paliwal
6543
6544 • Alex Willmer
6545
6546 • Daniel Neuhäuser
6547
6548 • Hugo van Kemenade
6549
6550 • Miro Hrončok
6551
6552 • Cédric Krier
6553
6554 • Luke Plant
6555
6556 • Jennifer Wang
6557
6558 • Lukas Balaga
6559
6560 • sudheesh001
6561
6562 • Jean Abou Samra
6563
6564 • Niklas Hambüchen
6565
6566 • Changaco
6567
6568 • Xavier Fernandez
6569
6570 • KO. Mattsson
6571
6572 • Sébastien Diemer
6573
6574 • alexbodn@gmail.com
6575
6576 • saurabhiiit
6577
6578 • srisankethu
6579
6580 • Erik Romijn
6581
6582 • Lukas B
6583
6584 • Ryan J Ollos
6585
6586 • Arturas Moskvinas
6587
6588 • Leonardo Pistone
6589
6590 • Hyunjun Kim
6591
6592 • Alex Waygood
6593
6594 • Maciej Olko
6595
6596 • martin f. krafft
6597
6598 • DS/Charlie
6599
6600 • lilinjie
6601
6602 • Johannes Wilm
6603
6604 • Eric L
6605
6606 • Przemyslaw Wegrzyn
6607
6608 • Lukas Kahwe Smith
6609
6610 • Lukas Juhrich
6611
6612 • Nikita Sobolev
6613
6614 • Raphael Nestler
6615
6616 • Frank Harrison
6617
6618 • Nehal J Wani
6619
6620 • Mohamed Morsy
6621
6622 • Krzysztof Jagiełło
6623
6624 • Morgan Wahl
6625
6626 • farhan5900
6627
6628 • Sigurd Ljødal
6629
6630 • Andrii Oriekhov
6631
6632 • rachele-collin
6633
6634 • Lukas Winkler
6635
6636 • Juliette Monsel
6637
6638 • Álvaro Mondéjar Rubio
6639
6640 • ruro
6641
6642 • Alessio Bogon
6643
6644 • Nikiforov Konstantin
6645
6646 • Abdullah Javed Nesar
6647
6648 • Brad Martin
6649
6650 • Tyler Kennedy
6651
6652 • CyanNani123
6653
6654 • sebleblanc
6655
6656 • He Chen
6657
6658 • Steve (Gadget) Barnes
6659
6660 • Romuald Brunet
6661
6662 • Mario Frasca
6663
6664 • BT-sschmid
6665
6666 • Alberto Mardegan
6667
6668 • mondeja
6669
6670 • NotAFile
6671
6672 • Julien Palard
6673
6674 • Brian Cappello
6675
6676 • Serban Constantin
6677
6678 • Bryn Truscott
6679
6680 • Chris
6681
6682 • Charly C
6683
6684 • PTrottier
6685
6686 • xmo-odoo
6687
6688 • StevenJ
6689
6690 • Jungmo Ku
6691
6692 • Simeon Visser
6693
6694 • Narendra Vardi
6695
6696 • Stefane Fermigier
6697
6698 • Narayan Acharya
6699
6700 • François Magimel
6701
6702 • Wolfgang Doll
6703
6704 • Roy Williams
6705
6706 • Marc-André Dufresne
6707
6708 • Abhishek Tiwari
6709
6710 • David Baumgold
6711
6712 • Alex Kuzmenko
6713
6714 • Georg Schölly
6715
6716 • ldwoolley
6717
6718 • Rodrigo Ramírez Norambuena
6719
6720 • Jakub Wilk
6721
6722 • Roman Rader
6723
6724 • Max Shenfield
6725
6726 • Nicolas Grilly
6727
6728 • Kenny Root
6729
6730 • Adam Chainz
6731
6732 • Sébastien Fievet
6733
6734 • Anthony Sottile
6735
6736 • Yuriy Shatrov
6737
6738 • iamshubh22
6739
6740 • Sven Anderson
6741
6742 • Eoin Nugent
6743
6744 • Roman Imankulov
6745
6746 • David Stanek
6747
6748 • Roy Wellington Ⅳ
6749
6750 • Florian Schulze
6751
6752 • Todd M. Guerra
6753
6754 • Joseph Breihan
6755
6756 • Craig Loftus
6757
6758 • The Gitter Badger
6759
6760 • Régis Behmo
6761
6762 • Julen Ruiz Aizpuru
6763
6764 • astaric
6765
6766 • Felix Yan
6767
6768 • Philip_Tzou
6769
6770 • Jesús Espino
6771
6772 • Jeremy Weinstein
6773
6774 • James Page
6775
6776 • masklinn
6777
6778 • Sjoerd Langkemper
6779
6780 • Matt Iversen
6781
6782 • Alexander A. Dyshev
6783
6784 • Dirkjan Ochtman
6785
6786 • Nick Retallack
6787
6788 • Thomas Waldmann
6789
6790 • xen
6791
6792 Babel was previously developed under the Copyright of Edgewall Soft‐
6793 ware. The following copyright notice holds true for releases before
6794 2013: “Copyright (c) 2007 - 2011 by Edgewall Software”
6795
6796 In addition to the regular contributions Babel includes a fork of
6797 Lennart Regebro’s tzlocal that originally was licensed under the CC0
6798 license. The original copyright of that project is “Copyright 2013 by
6799 Lennart Regebro”.
6800
6801 General License Definitions
6802 The following section contains the full license texts for Babel and the
6803 documentation.
6804
6805 • “AUTHORS” hereby refers to all the authors listed in the Authors sec‐
6806 tion.
6807
6808 • The “Babel License” applies to all the sourcecode shipped as part of
6809 Babel (Babel itself as well as the examples and the unit tests) as
6810 well as documentation.
6811
6812 Babel License
6813 Copyright (c) 2013-2023 by the Babel Team, see AUTHORS for more infor‐
6814 mation.
6815
6816 Redistribution and use in source and binary forms, with or without mod‐
6817 ification, are permitted provided that the following conditions are
6818 met:
6819
6820 1. Redistributions of source code must retain the above copyright
6821 notice, this list of conditions and the following disclaimer.
6822
6823 2. Redistributions in binary form must reproduce the above copyright
6824 notice, this list of conditions and the following disclaimer in
6825 the documentation and/or other materials provided with the dis‐
6826 tribution.
6827
6828 3. Neither the name of the copyright holder nor the names of its
6829 contributors may be used to endorse or promote products derived
6830 from this software without specific prior written permission.
6831
6832 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS
6833 IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
6834 TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTIC‐
6835 ULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
6836 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
6837 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
6838 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
6839 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
6840 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
6841 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
6842 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
6843
6845 The Babel Team
6846
6848 2023, The Babel Team
6849
6850
6851
6852
68532.12 Jul 19, 2023 BABEL(1)