or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-locales.mddate-time-formatting.mdindex.mdmessage-catalogs.mdnumber-currency-formatting.mdplural-language-data.mdunits-utilities.md

message-catalogs.mddocs/

0

# Message Catalog Management

1

2

Complete gettext-compatible message catalog system for managing translatable strings, including catalog creation, message extraction, PO/MO file handling, and translation management. Babel provides comprehensive tools for internationalization workflows.

3

4

## Capabilities

5

6

### Message Class

7

8

Represents individual translatable messages with metadata.

9

10

```python { .api }

11

class Message:

12

"""

13

Represents a single translatable message.

14

15

Attributes:

16

id (str|tuple): Message identifier (string or tuple for plurals)

17

string (str|list): Translation string (string or list for plurals)

18

locations (list): List of (filename, lineno) tuples where message appears

19

flags (set): Set of flags (fuzzy, python-format, etc.)

20

auto_comments (list): Automatic comments from extractors

21

user_comments (list): User-provided comments

22

previous_id (str|tuple): Previous message ID (for updates)

23

lineno (int): Line number where message is defined

24

context (str): Message context for disambiguation

25

"""

26

def __init__(self, id, string='', locations=(), flags=(), auto_comments=(),

27

user_comments=(), previous_id=None, lineno=None, context=None):

28

"""

29

Initialize a message.

30

31

Args:

32

id (str|tuple): Message identifier

33

string (str|list): Translation string(s)

34

locations (list): Source locations

35

flags (set): Message flags

36

auto_comments (list): Automatic comments

37

user_comments (list): User comments

38

previous_id (str|tuple): Previous ID for updates

39

lineno (int): Line number

40

context (str): Message context

41

"""

42

43

@property

44

def pluralizable(self):

45

"""bool: Whether this message has plural forms"""

46

47

@property

48

def python_format(self):

49

"""bool: Whether this message uses Python format strings"""

50

```

51

52

Usage example:

53

54

```python

55

from babel.messages import Message

56

57

# Simple message

58

msg = Message('Hello, world!', 'Bonjour, le monde!',

59

locations=[('main.py', 10)], flags={'fuzzy'})

60

61

# Plural message

62

plural_msg = Message(

63

id=('One item', '{count} items'),

64

string=['Un élément', '{count} éléments'],

65

locations=[('inventory.py', 25)]

66

)

67

```

68

69

### Catalog Class

70

71

Collection of translatable messages with metadata and management functionality.

72

73

```python { .api }

74

class Catalog:

75

"""

76

Collection of translatable messages with catalog metadata.

77

78

Attributes:

79

locale (Locale): Target locale for translations

80

domain (str): Message domain

81

project (str): Project name

82

version (str): Project version

83

copyright_holder (str): Copyright holder

84

msgid_bugs_address (str): Bug report email address

85

last_translator (str): Last translator information

86

language_team (str): Language team information

87

charset (str): Character encoding

88

creation_date (datetime): Catalog creation date

89

revision_date (datetime): Last revision date

90

fuzzy (bool): Whether catalog is fuzzy (incomplete)

91

num_plurals (int): Number of plural forms for locale

92

plural_expr (str): Plural expression for locale

93

plural_forms (str): Gettext plural forms header

94

mime_headers (list): List of MIME headers

95

"""

96

def __init__(self, locale=None, domain=None, header_comment=DEFAULT_HEADER,

97

project=None, version=None, copyright_holder=None,

98

msgid_bugs_address=None, creation_date=None, revision_date=None,

99

last_translator=None, language_team=None, charset=None,

100

plurals=None, fuzzy=True):

101

"""

102

Initialize a message catalog.

103

104

Args:

105

locale (Locale|str): Target locale

106

domain (str): Message domain

107

header_comment (str): Header comment text

108

project (str): Project name

109

version (str): Project version

110

copyright_holder (str): Copyright holder

111

msgid_bugs_address (str): Bug report address

112

creation_date (datetime): Creation timestamp

113

revision_date (datetime): Revision timestamp

114

last_translator (str): Last translator info

115

language_team (str): Language team info

116

charset (str): Character encoding

117

plurals (tuple): Plural forms (count, expression)

118

fuzzy (bool): Whether catalog is fuzzy

119

"""

120

121

def add(self, id, string=None, locations=(), flags=(), auto_comments=(),

122

user_comments=(), previous_id=None, lineno=None, context=None):

123

"""

124

Add a message to the catalog.

125

126

Args:

127

id (str|tuple): Message identifier

128

string (str|list): Translation string(s)

129

locations (list): Source locations

130

flags (set): Message flags

131

auto_comments (list): Automatic comments

132

user_comments (list): User comments

133

previous_id (str|tuple): Previous ID

134

lineno (int): Line number

135

context (str): Message context

136

137

Returns:

138

Message: The added message object

139

"""

140

141

def get(self, id, context=None):

142

"""

143

Get a message by ID and context.

144

145

Args:

146

id (str|tuple): Message identifier

147

context (str, optional): Message context

148

149

Returns:

150

Message|None: Message object or None if not found

151

"""

152

153

def delete(self, id, context=None):

154

"""

155

Delete a message from the catalog.

156

157

Args:

158

id (str|tuple): Message identifier

159

context (str, optional): Message context

160

"""

161

162

def update(self, template, no_fuzzy_matching=False, update_header_comment=False):

163

"""

164

Update catalog from a template catalog.

165

166

Args:

167

template (Catalog): Template catalog with source messages

168

no_fuzzy_matching (bool): Whether to disable fuzzy matching

169

update_header_comment (bool): Whether to update header comment

170

"""

171

172

def check(self):

173

"""

174

Run consistency checks on the catalog.

175

176

Returns:

177

list: List of check result tuples (message, checker_errors)

178

"""

179

180

def __iter__(self):

181

"""Iterate over messages in the catalog."""

182

183

def __len__(self):

184

"""Get number of messages in catalog."""

185

186

def __contains__(self, id):

187

"""Check if message ID exists in catalog."""

188

```

189

190

Usage example:

191

192

```python

193

from babel.messages import Catalog, Message

194

from babel import Locale

195

import datetime

196

197

# Create a catalog

198

catalog = Catalog(

199

locale=Locale('fr_FR'),

200

project='My Project',

201

version='1.0',

202

creation_date=datetime.datetime.now()

203

)

204

205

# Add messages

206

catalog.add('Hello', 'Bonjour', locations=[('main.py', 10)])

207

catalog.add('Goodbye', 'Au revoir', locations=[('main.py', 20)])

208

209

# Plural message

210

catalog.add(

211

('One file', '{count} files'),

212

['Un fichier', '{count} fichiers'],

213

locations=[('files.py', 15)]

214

)

215

216

# Check catalog

217

issues = catalog.check()

218

print(f"Catalog has {len(catalog)} messages")

219

```

220

221

### PO File Handling

222

223

Read and write PO (Portable Object) files for translation management.

224

225

```python { .api }

226

def read_po(fileobj, locale=None, domain=None, ignore_obsolete=True,

227

charset=None, abort_invalid=False):

228

"""

229

Read a PO file and return a Catalog.

230

231

Args:

232

fileobj (file-like): File object to read from

233

locale (Locale|str, optional): Target locale

234

domain (str, optional): Message domain

235

ignore_obsolete (bool): Whether to ignore obsolete entries

236

charset (str, optional): Character encoding

237

abort_invalid (bool): Whether to abort on invalid entries

238

239

Returns:

240

Catalog: Parsed message catalog

241

242

Raises:

243

PoFileError: If PO file parsing fails

244

"""

245

246

def write_po(fileobj, catalog, width=76, no_location=False, omit_header=False,

247

sort_output=False, sort_by_file=False, ignore_obsolete=True,

248

include_previous=False, include_lineno=True):

249

"""

250

Write a Catalog to a PO file.

251

252

Args:

253

fileobj (file-like): File object to write to

254

catalog (Catalog): Message catalog to write

255

width (int): Maximum line width

256

no_location (bool): Whether to omit location comments

257

omit_header (bool): Whether to omit the header

258

sort_output (bool): Whether to sort messages by ID

259

sort_by_file (bool): Whether to sort by filename

260

ignore_obsolete (bool): Whether to ignore obsolete entries

261

include_previous (bool): Whether to include previous msgid

262

include_lineno (bool): Whether to include line numbers

263

"""

264

```

265

266

Usage example:

267

268

```python

269

from babel.messages.pofile import read_po, write_po

270

from babel.messages import Catalog

271

272

# Read a PO file

273

with open('messages.po', 'rb') as f:

274

catalog = read_po(f, locale='fr_FR')

275

276

# Write a PO file

277

with open('output.po', 'wb') as f:

278

write_po(f, catalog, width=80)

279

```

280

281

### MO File Handling

282

283

Read and write MO (Machine Object) files for runtime translation use.

284

285

```python { .api }

286

def read_mo(fileobj):

287

"""

288

Read a binary MO file and return a Catalog.

289

290

Args:

291

fileobj (file-like): File object to read from

292

293

Returns:

294

Catalog: Parsed message catalog

295

"""

296

297

def write_mo(fileobj, catalog, use_fuzzy=False):

298

"""

299

Write a Catalog to a binary MO file.

300

301

Args:

302

fileobj (file-like): File object to write to

303

catalog (Catalog): Message catalog to write

304

use_fuzzy (bool): Whether to include fuzzy translations

305

"""

306

```

307

308

Usage example:

309

310

```python

311

from babel.messages.mofile import read_mo, write_mo

312

313

# Read MO file

314

with open('messages.mo', 'rb') as f:

315

catalog = read_mo(f)

316

317

# Write MO file

318

with open('output.mo', 'wb') as f:

319

write_mo(f, catalog, use_fuzzy=False)

320

```

321

322

### Message Extraction

323

324

Extract translatable strings from source code files.

325

326

```python { .api }

327

def extract_from_dir(dirname, method_map=None, options_map=None, keywords=None,

328

comment_tags=None, callback=None, strip_comment_tags=False):

329

"""

330

Extract messages from a directory tree.

331

332

Args:

333

dirname (str): Directory to extract from

334

method_map (dict): File extension to extraction method mapping

335

options_map (dict): Method-specific options

336

keywords (dict): Keyword function specifications

337

comment_tags (list): Comment tags to extract

338

callback (callable): Progress callback function

339

strip_comment_tags (bool): Whether to strip comment tags

340

341

Returns:

342

Generator: Iterator of (filename, lineno, message, comments, context) tuples

343

"""

344

345

def extract_from_file(method, filename, keywords=None, comment_tags=None,

346

options=None, strip_comment_tags=False):

347

"""

348

Extract messages from a single file.

349

350

Args:

351

method (str|callable): Extraction method

352

filename (str): File to extract from

353

keywords (dict): Keyword specifications

354

comment_tags (list): Comment tags to extract

355

options (dict): Method-specific options

356

strip_comment_tags (bool): Whether to strip comment tags

357

358

Returns:

359

Generator: Iterator of (lineno, message, comments, context) tuples

360

"""

361

362

def extract_python(fileobj, keywords, comment_tags, options):

363

"""

364

Extract messages from Python source code.

365

366

Args:

367

fileobj (file-like): File object to read from

368

keywords (dict): Keyword specifications

369

comment_tags (list): Comment tags to extract

370

options (dict): Extraction options

371

372

Returns:

373

Generator: Iterator of extraction results

374

"""

375

376

def extract_javascript(fileobj, keywords, comment_tags, options):

377

"""

378

Extract messages from JavaScript source code.

379

380

Args:

381

fileobj (file-like): File object to read from

382

keywords (dict): Keyword specifications

383

comment_tags (list): Comment tags to extract

384

options (dict): Extraction options

385

386

Returns:

387

Generator: Iterator of extraction results

388

"""

389

```

390

391

Usage example:

392

393

```python

394

from babel.messages.extract import extract_from_dir, extract_python

395

396

# Extract from directory

397

method_map = {

398

'*.py': 'python',

399

'*.js': 'javascript'

400

}

401

402

keywords = {

403

'_': None,

404

'gettext': None,

405

'ngettext': (1, 2),

406

}

407

408

for filename, lineno, message, comments, context in extract_from_dir('.', method_map, keywords=keywords):

409

print(f"{filename}:{lineno}: {message}")

410

```

411

412

### Command Line Tools

413

414

Classes for setuptools integration and command-line message management.

415

416

```python { .api }

417

class ExtractMessages:

418

"""Command to extract messages from source code."""

419

420

def run(self):

421

"""Execute message extraction."""

422

423

class InitCatalog:

424

"""Command to initialize a new message catalog."""

425

426

def run(self):

427

"""Execute catalog initialization."""

428

429

class UpdateCatalog:

430

"""Command to update an existing catalog from template."""

431

432

def run(self):

433

"""Execute catalog update."""

434

435

class CompileCatalog:

436

"""Command to compile PO files to MO files."""

437

438

def run(self):

439

"""Execute catalog compilation."""

440

```

441

442

### Translation Support Classes

443

444

Extended translation classes with Babel-specific functionality.

445

446

```python { .api }

447

class Translations:

448

"""

449

Extended translation catalog with Babel features.

450

451

Inherits from gettext.GNUTranslations with additional methods.

452

"""

453

@classmethod

454

def load(cls, dirname=None, locales=None, domain=None):

455

"""

456

Load translations from directory.

457

458

Args:

459

dirname (str): Directory containing translation files

460

locales (list): List of locale identifiers

461

domain (str): Message domain

462

463

Returns:

464

Translations: Translation object

465

"""

466

467

def add(self, translations, merge=True):

468

"""

469

Add translations from another catalog.

470

471

Args:

472

translations (Translations): Translations to add

473

merge (bool): Whether to merge duplicates

474

"""

475

476

def merge(self, translations):

477

"""

478

Merge translations from another catalog.

479

480

Args:

481

translations (Translations): Translations to merge

482

"""

483

```

484

485

### String Utilities

486

487

Utilities for PO file string handling.

488

489

```python { .api }

490

def escape(string):

491

"""

492

Escape string for PO file format.

493

494

Args:

495

string (str): String to escape

496

497

Returns:

498

str: Escaped string

499

"""

500

501

def unescape(string):

502

"""

503

Unescape PO file string.

504

505

Args:

506

string (str): String to unescape

507

508

Returns:

509

str: Unescaped string

510

"""

511

512

def normalize(string, prefix='', width=76):

513

"""

514

Normalize multiline strings for PO format.

515

516

Args:

517

string (str): String to normalize

518

prefix (str): Line prefix

519

width (int): Maximum line width

520

521

Returns:

522

str: Normalized string

523

"""

524

525

def denormalize(string):

526

"""

527

Reverse normalization of PO strings.

528

529

Args:

530

string (str): String to denormalize

531

532

Returns:

533

str: Denormalized string

534

"""

535

```

536

537

### Plural Forms

538

539

Get plural form information for locales.

540

541

```python { .api }

542

def get_plural(locale):

543

"""

544

Get plural rule for locale.

545

546

Args:

547

locale (Locale|str): Target locale

548

549

Returns:

550

_PluralTuple: Tuple containing (count, expression)

551

"""

552

```

553

554

### Message Checkers

555

556

Functions to validate message catalog consistency.

557

558

```python { .api }

559

def num_plurals(catalog, message):

560

"""

561

Check that number of plural forms matches locale.

562

563

Args:

564

catalog (Catalog): Message catalog

565

message (Message): Message to check

566

567

Returns:

568

list: List of error messages

569

"""

570

571

def python_format(catalog, message):

572

"""

573

Check Python format string consistency.

574

575

Args:

576

catalog (Catalog): Message catalog

577

message (Message): Message to check

578

579

Returns:

580

list: List of error messages

581

"""

582

```

583

584

## Exception Classes

585

586

```python { .api }

587

class TranslationError(Exception):

588

"""Base exception for translation-related errors."""

589

590

class PoFileError(Exception):

591

"""Exception raised for PO file parsing errors."""

592

```

593

594

## Constants

595

596

```python { .api }

597

DEFAULT_HEADER: str

598

"""Default catalog header comment template."""

599

600

PYTHON_FORMAT: re.Pattern

601

"""Regex pattern for Python format strings."""

602

```