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

Implement --init-missing option for pybabel update #785

Merged
merged 3 commits into from Jun 15, 2021
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
37 changes: 35 additions & 2 deletions babel/messages/frontend.py
Expand Up @@ -668,6 +668,8 @@ class update_catalog(Command):
'into several lines'),
('ignore-obsolete=', None,
'whether to omit obsolete messages from the output'),
('init-missing=', None,
'if any output files are missing, initialize them first'),
('no-fuzzy-matching', 'N',
'do not use fuzzy matching'),
('update-header-comment', None,
Expand All @@ -676,8 +678,8 @@ class update_catalog(Command):
'keep previous msgids of translated messages'),
]
boolean_options = [
'omit-header', 'no-wrap', 'ignore-obsolete', 'no-fuzzy-matching',
'previous', 'update-header-comment',
'omit-header', 'no-wrap', 'ignore-obsolete', 'init-missing',
'no-fuzzy-matching', 'previous', 'update-header-comment',
]

def initialize_options(self):
Expand All @@ -690,6 +692,7 @@ def initialize_options(self):
self.width = None
self.no_wrap = False
self.ignore_obsolete = False
self.init_missing = False
self.no_fuzzy_matching = False
self.update_header_comment = False
self.previous = False
Expand All @@ -702,6 +705,19 @@ def finalize_options(self):
'directory')
if self.output_file and not self.locale:
raise DistutilsOptionError('you must specify the locale')

if self.init_missing:
if not self.locale:
raise DistutilsOptionError('you must specify the locale for '
'the init-missing option to work')

try:
self._locale = Locale.parse(self.locale)
except UnknownLocaleError as e:
raise DistutilsOptionError(e)
else:
self._locale = None

if self.no_wrap and self.width:
raise DistutilsOptionError("'--no-wrap' and '--width' are mutually "
"exclusive")
Expand Down Expand Up @@ -741,6 +757,23 @@ def run(self):
template = read_po(infile)

for locale, filename in po_files:
if self.init_missing and not os.path.exists(filename):
self.log.info(
'creating catalog %s based on %s', filename, self.input_file
)

with open(self.input_file, 'rb') as infile:
# Although reading from the catalog template, read_po must
# be fed the locale in order to correctly calculate plurals
catalog = read_po(infile, locale=self.locale)

catalog.locale = self._locale
catalog.revision_date = datetime.now(LOCALTZ)
catalog.fuzzy = False

with open(filename, 'wb') as outfile:
write_po(outfile, catalog)

self.log.info('updating catalog %s based on %s', filename, self.input_file)
with open(filename, 'rb') as infile:
catalog = read_po(infile, locale=locale, domain=domain)
Expand Down
40 changes: 39 additions & 1 deletion tests/messages/test_frontend.py
Expand Up @@ -1208,6 +1208,43 @@ def test_update(self):
catalog = read_po(infp)
assert len(catalog) == 4 # Catalog was updated

def test_update_init_missing(self):
template = Catalog()
template.add("1")
template.add("2")
template.add("3")
tmpl_file = os.path.join(i18n_dir, 'temp2-template.pot')
with open(tmpl_file, "wb") as outfp:
write_po(outfp, template)
po_file = os.path.join(i18n_dir, 'temp2.po')

self.cli.run(sys.argv + ['update',
'--init-missing',
'-l', 'fi',
'-o', po_file,
'-i', tmpl_file])

with open(po_file, "r") as infp:
catalog = read_po(infp)
assert len(catalog) == 3

# Add another entry to the template

template.add("4")

with open(tmpl_file, "wb") as outfp:
write_po(outfp, template)

self.cli.run(sys.argv + ['update',
'--init-missing',
'-l', 'fi_FI',
'-o', po_file,
'-i', tmpl_file])

with open(po_file, "r") as infp:
catalog = read_po(infp)
assert len(catalog) == 4 # Catalog was updated


def test_parse_mapping():
buf = StringIO(
Expand Down Expand Up @@ -1351,8 +1388,9 @@ def test_extract_distutils_keyword_arg_388(kwarg, expected):


def test_update_catalog_boolean_args():
cmdinst = configure_cli_command("update --no-wrap -N --ignore-obsolete --previous -i foo -o foo -l en")
cmdinst = configure_cli_command("update --init-missing --no-wrap -N --ignore-obsolete --previous -i foo -o foo -l en")
assert isinstance(cmdinst, update_catalog)
assert cmdinst.init_missing is True
assert cmdinst.no_wrap is True
assert cmdinst.no_fuzzy_matching is True
assert cmdinst.ignore_obsolete is True
Expand Down