Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use email.Message for pofile header parsing #876

Merged
merged 1 commit into from May 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 9 additions & 3 deletions babel/messages/catalog.py
Expand Up @@ -10,7 +10,6 @@

import re

from cgi import parse_header
from collections import OrderedDict
from datetime import datetime, time as time_
from difflib import get_close_matches
Expand Down Expand Up @@ -225,6 +224,13 @@ class TranslationError(Exception):
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#"""

def parse_separated_header(value: str):
# Adapted from https://peps.python.org/pep-0594/#cgi
from email.message import Message
m = Message()
m['content-type'] = value
return dict(m.get_params())


class Catalog:
"""Representation of a message catalog."""
Expand Down Expand Up @@ -424,11 +430,11 @@ def _set_mime_headers(self, headers):
elif name == 'language-team':
self.language_team = value
elif name == 'content-type':
mimetype, params = parse_header(value)
params = parse_separated_header(value)
if 'charset' in params:
self.charset = params['charset'].lower()
elif name == 'plural-forms':
_, params = parse_header(' ;' + value)
params = parse_separated_header(' ;' + value)
self._num_plurals = int(params.get('nplurals', 2))
self._plural_expr = params.get('plural', '(n != 1)')
elif name == 'pot-creation-date':
Expand Down
11 changes: 11 additions & 0 deletions tests/messages/test_pofile.py
Expand Up @@ -68,6 +68,17 @@ def test_applies_specified_encoding_during_read(self):
catalog = pofile.read_po(buf, locale='de_DE')
self.assertEqual(u'bär', catalog.get('foo').string)

def test_encoding_header_read(self):
buf = BytesIO(b'msgid ""\nmsgstr ""\n"Content-Type: text/plain; charset=mac_roman\\n"\n')
catalog = pofile.read_po(buf, locale='xx_XX')
assert catalog.charset == 'mac_roman'

def test_plural_forms_header_parsed(self):
buf = BytesIO(b'msgid ""\nmsgstr ""\n"Plural-Forms: nplurals=42; plural=(n % 11);\\n"\n')
catalog = pofile.read_po(buf, locale='xx_XX')
assert catalog.plural_expr == '(n % 11)'
assert catalog.num_plurals == 42

def test_read_multiline(self):
buf = StringIO(r'''msgid ""
"Here's some text that\n"
Expand Down