0
# Internationalization
1
2
Activate and manage localization for 25+ supported languages with locale-specific number formatting, date formatting, and text translations throughout the humanize library.
3
4
## Capabilities
5
6
### Locale Activation
7
8
Activate internationalization for a specific locale, loading the appropriate translation files and configuring locale-specific formatting.
9
10
```python { .api }
11
def activate(
12
locale: str | None,
13
path: str | os.PathLike[str] | None = None
14
) -> gettext.NullTranslations:
15
"""
16
Activate internationalization for a specific locale.
17
18
Args:
19
locale: Language code (e.g., 'en_GB', 'fr_FR', 'de_DE') or None for default
20
path: Custom path to search for locale files (optional)
21
22
Returns:
23
Translation object for the activated locale
24
25
Raises:
26
Exception: If locale folder cannot be found and path not provided
27
28
Examples:
29
>>> activate('fr_FR') # Activate French
30
>>> activate('de_DE') # Activate German
31
>>> activate(None) # Deactivate (same as deactivate())
32
"""
33
```
34
35
### Locale Deactivation
36
37
Deactivate internationalization, returning to the default English behavior.
38
39
```python { .api }
40
def deactivate() -> None:
41
"""
42
Deactivate internationalization, returning to default English.
43
44
Example:
45
>>> activate('fr_FR')
46
>>> intword(1000000) # Returns French text
47
>>> deactivate()
48
>>> intword(1000000) # Returns '1.0 million'
49
"""
50
```
51
52
### Number Formatting Separators
53
54
Get locale-specific thousands and decimal separators for number formatting.
55
56
```python { .api }
57
def thousands_separator() -> str:
58
"""
59
Return the thousands separator for current locale.
60
61
Returns:
62
Thousands separator character (default: ',')
63
64
Examples:
65
>>> activate('en_US')
66
>>> thousands_separator()
67
','
68
>>> activate('fr_FR')
69
>>> thousands_separator()
70
' '
71
>>> activate('de_DE')
72
>>> thousands_separator()
73
'.'
74
"""
75
76
def decimal_separator() -> str:
77
"""
78
Return the decimal separator for current locale.
79
80
Returns:
81
Decimal separator character (default: '.')
82
83
Examples:
84
>>> activate('en_US')
85
>>> decimal_separator()
86
'.'
87
>>> activate('de_DE')
88
>>> decimal_separator()
89
','
90
>>> activate('fr_FR')
91
>>> decimal_separator()
92
'.'
93
"""
94
```
95
96
## Supported Languages
97
98
The humanize library includes translations for over 25 languages:
99
100
- **Arabic** (ar)
101
- **Basque** (eu)
102
- **Bengali** (bn)
103
- **Brazilian Portuguese** (pt_BR)
104
- **Catalan** (ca)
105
- **Danish** (da)
106
- **Dutch** (nl)
107
- **Esperanto** (eo)
108
- **European Portuguese** (pt)
109
- **Finnish** (fi)
110
- **French** (fr_FR)
111
- **German** (de_DE)
112
- **Greek** (el)
113
- **Hebrew** (he)
114
- **Indonesian** (id)
115
- **Italian** (it_IT)
116
- **Japanese** (ja)
117
- **Klingon** (tlh)
118
- **Korean** (ko)
119
- **Norwegian** (no)
120
- **Persian** (fa)
121
- **Polish** (pl)
122
- **Russian** (ru)
123
- **Simplified Chinese** (zh_CN)
124
- **Slovak** (sk)
125
- **Slovenian** (sl)
126
- **Spanish** (es)
127
- **Swedish** (sv)
128
- **Turkish** (tr)
129
- **Ukrainian** (uk)
130
- **Vietnamese** (vi)
131
132
## Usage Examples
133
134
### Basic Localization
135
136
```python
137
import humanize
138
139
# Default English behavior
140
print(humanize.intword(1000000)) # "1.0 million"
141
print(humanize.naturaltime(3600, future=True)) # "an hour from now"
142
143
# Activate French
144
humanize.activate('fr_FR')
145
print(humanize.intword(1000000)) # "1.0 million" (French translation)
146
print(humanize.naturaltime(3600, future=True)) # French equivalent
147
148
# Return to English
149
humanize.deactivate()
150
print(humanize.intword(1000000)) # "1.0 million"
151
```
152
153
### Number Formatting with Locales
154
155
```python
156
import humanize
157
158
# German locale - uses period for thousands, comma for decimal
159
humanize.activate('de_DE')
160
print(humanize.intcomma(1234567.89)) # Uses German separators
161
print(humanize.thousands_separator()) # '.'
162
print(humanize.decimal_separator()) # ','
163
164
# French locale - uses space for thousands
165
humanize.activate('fr_FR')
166
print(humanize.intcomma(1234567.89)) # Uses French separators
167
print(humanize.thousands_separator()) # ' '
168
print(humanize.decimal_separator()) # '.'
169
```
170
171
### Context Manager Pattern
172
173
For temporary locale changes, you can create a simple context manager:
174
175
```python
176
import humanize
177
from contextlib import contextmanager
178
179
@contextmanager
180
def temporary_locale(locale):
181
"""Temporarily activate a locale."""
182
original = humanize.get_translation() # Would need to be implemented
183
try:
184
humanize.activate(locale)
185
yield
186
finally:
187
humanize.deactivate()
188
189
# Usage
190
with temporary_locale('de_DE'):
191
print(humanize.intcomma(1234567)) # German formatting
192
print(humanize.intcomma(1234567)) # Back to default
193
```
194
195
### Ordinal Gender Support
196
197
Some languages support gendered ordinals:
198
199
```python
200
import humanize
201
202
# English (no gender distinction)
203
print(humanize.ordinal(1)) # "1st"
204
205
# Languages with gender support (theoretical example)
206
humanize.activate('some_locale')
207
print(humanize.ordinal(1, gender='male')) # Masculine form
208
print(humanize.ordinal(1, gender='female')) # Feminine form
209
```
210
211
## Locale File Structure
212
213
Locale files are stored in the package's locale directory using the standard gettext format:
214
215
```
216
locale/
217
├── fr_FR/
218
│ └── LC_MESSAGES/
219
│ ├── humanize.po
220
│ └── humanize.mo
221
├── de_DE/
222
│ └── LC_MESSAGES/
223
│ ├── humanize.po
224
│ └── humanize.mo
225
└── ...
226
```
227
228
## Custom Locale Paths
229
230
You can specify custom paths for locale files:
231
232
```python
233
import humanize
234
235
# Use custom locale directory
236
humanize.activate('custom_locale', path='/path/to/custom/locales')
237
```
238
239
## Implementation Details
240
241
```python { .api }
242
# Internal translation functions (not in __all__ but accessible)
243
def get_translation() -> gettext.NullTranslations: ...
244
def _gettext(message: str) -> str: ...
245
def _pgettext(msgctxt: str, message: str) -> str: ...
246
def _ngettext(message: str, plural: str, num: int) -> str: ...
247
def _gettext_noop(message: str) -> str: ...
248
def _ngettext_noop(singular: str, plural: str) -> tuple[str, str]: ...
249
```
250
251
## Error Handling
252
253
- If a locale cannot be found, an exception is raised unless a custom path is provided
254
- If locale files are corrupted or missing, the function falls back to English
255
- Invalid locale codes are handled gracefully
256
- Thread-local storage ensures locale settings don't interfere between threads
257
258
## Thread Safety
259
260
The internationalization system uses thread-local storage, making it safe to use different locales in different threads simultaneously without interference.