Skip to content

gh-126413: Add translation tests for getopt and optparse #126698

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

Merged
merged 5 commits into from
Nov 11, 2024
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions Lib/test/support/i18n_helper.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import re
import subprocess
import sys
import unittest
from pathlib import Path
from test.support import REPO_ROOT, TEST_HOME_DIR, requires_subprocess
from test.test_tools import skip_if_missing


pygettext = Path(REPO_ROOT) / 'Tools' / 'i18n' / 'pygettext.py'

msgid_pattern = re.compile(r'msgid(.*?)(?:msgid_plural|msgctxt|msgstr)',
re.DOTALL)
msgid_string_pattern = re.compile(r'"((?:\\"|[^"])*)"')


def _generate_po_file(path, *, stdout_only=True):
res = subprocess.run([sys.executable, pygettext,
'--no-location', '-o', '-', path],
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
text=True)
if stdout_only:
return res.stdout
return res


def _extract_msgids(po):
msgids = []
for msgid in msgid_pattern.findall(po):
msgid_string = ''.join(msgid_string_pattern.findall(msgid))
msgid_string = msgid_string.replace(r'\"', '"')
if msgid_string:
msgids.append(msgid_string)
return sorted(msgids)


def _get_snapshot_path(module_name):
return Path(TEST_HOME_DIR) / 'translationdata' / module_name / 'msgids.txt'


@requires_subprocess()
class TestTranslationsBase(unittest.TestCase):

def assertMsgidsEqual(self, module):
'''Assert that msgids extracted from a given module match a
snapshot.

'''
skip_if_missing('i18n')
res = _generate_po_file(module.__file__, stdout_only=False)
self.assertEqual(res.returncode, 0)
self.assertEqual(res.stderr, '')
msgids = _extract_msgids(res.stdout)
snapshot_path = _get_snapshot_path(module.__name__)
snapshot = snapshot_path.read_text().splitlines()
self.assertListEqual(msgids, snapshot)


def update_translation_snapshots(module):
contents = _generate_po_file(module.__file__)
msgids = _extract_msgids(contents)
snapshot_path = _get_snapshot_path(module.__name__)
snapshot_path.write_text('\n'.join(msgids))
54 changes: 4 additions & 50 deletions Lib/test/test_argparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@
import operator
import os
import py_compile
import re
import shutil
import stat
import subprocess
import sys
import textwrap
import tempfile
Expand All @@ -19,15 +17,11 @@
import warnings

from enum import StrEnum
from pathlib import Path
from test.support import REPO_ROOT
from test.support import TEST_HOME_DIR
from test.support import captured_stderr
from test.support import import_helper
from test.support import os_helper
from test.support import requires_subprocess
from test.support import script_helper
from test.test_tools import skip_if_missing
from test.support.i18n_helper import TestTranslationsBase, update_translation_snapshots
from unittest import mock


Expand Down Expand Up @@ -7056,50 +7050,10 @@ def test_directory_in_zipfile_compiled(self):
# Translation tests
# =================

pygettext = Path(REPO_ROOT) / 'Tools' / 'i18n' / 'pygettext.py'
snapshot_path = Path(TEST_HOME_DIR) / 'translationdata' / 'argparse' / 'msgids.txt'

msgid_pattern = re.compile(r'msgid(.*?)(?:msgid_plural|msgctxt|msgstr)', re.DOTALL)
msgid_string_pattern = re.compile(r'"((?:\\"|[^"])*)"')


@requires_subprocess()
class TestTranslations(unittest.TestCase):
class TestTranslations(TestTranslationsBase):

def test_translations(self):
# Test messages extracted from the argparse module against a snapshot
skip_if_missing('i18n')
res = generate_po_file(stdout_only=False)
self.assertEqual(res.returncode, 0)
self.assertEqual(res.stderr, '')
msgids = extract_msgids(res.stdout)
snapshot = snapshot_path.read_text().splitlines()
self.assertListEqual(msgids, snapshot)


def generate_po_file(*, stdout_only=True):
res = subprocess.run([sys.executable, pygettext,
'--no-location', '-o', '-', argparse.__file__],
stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
if stdout_only:
return res.stdout
return res


def extract_msgids(po):
msgids = []
for msgid in msgid_pattern.findall(po):
msgid_string = ''.join(msgid_string_pattern.findall(msgid))
msgid_string = msgid_string.replace(r'\"', '"')
if msgid_string:
msgids.append(msgid_string)
return sorted(msgids)


def update_translation_snapshots():
contents = generate_po_file()
msgids = extract_msgids(contents)
snapshot_path.write_text('\n'.join(msgids))
self.assertMsgidsEqual(argparse)


def tearDownModule():
Expand All @@ -7111,6 +7065,6 @@ def tearDownModule():
if __name__ == '__main__':
# To regenerate translation snapshots
if len(sys.argv) > 1 and sys.argv[1] == '--snapshot-update':
update_translation_snapshots()
update_translation_snapshots(argparse)
sys.exit(0)
unittest.main()
19 changes: 15 additions & 4 deletions Lib/test/test_getopt.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
# test_getopt.py
# David Goodger <[email protected]> 2000-08-19

from test.support.os_helper import EnvironmentVarGuard
import doctest
import unittest

import getopt
import sys
import unittest
from test.support.i18n_helper import TestTranslationsBase, update_translation_snapshots
from test.support.os_helper import EnvironmentVarGuard

sentinel = object()

Expand Down Expand Up @@ -224,10 +225,20 @@ def test_libref_examples():
['a1', 'a2']
"""


class TestTranslations(TestTranslationsBase):
def test_translations(self):
self.assertMsgidsEqual(getopt)


def load_tests(loader, tests, pattern):
tests.addTest(doctest.DocTestSuite())
return tests


if __name__ == "__main__":
if __name__ == '__main__':
# To regenerate translation snapshots
if len(sys.argv) > 1 and sys.argv[1] == '--snapshot-update':
update_translation_snapshots(getopt)
sys.exit(0)
unittest.main()
11 changes: 10 additions & 1 deletion Lib/test/test_optparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from io import StringIO
from test import support
from test.support import os_helper

from test.support.i18n_helper import TestTranslationsBase, update_translation_snapshots

import optparse
from optparse import make_option, Option, \
Expand Down Expand Up @@ -1656,5 +1656,14 @@ def test__all__(self):
support.check__all__(self, optparse, not_exported=not_exported)


class TestTranslations(TestTranslationsBase):
def test_translations(self):
self.assertMsgidsEqual(optparse)


if __name__ == '__main__':
# To regenerate translation snapshots
if len(sys.argv) > 1 and sys.argv[1] == '--snapshot-update':
update_translation_snapshots(optparse)
sys.exit(0)
unittest.main()
6 changes: 6 additions & 0 deletions Lib/test/translationdata/getopt/msgids.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
option -%s not recognized
option -%s requires argument
option --%s must not have an argument
option --%s not a unique prefix
option --%s not recognized
option --%s requires argument
14 changes: 14 additions & 0 deletions Lib/test/translationdata/optparse/msgids.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
%prog [options]
%s option does not take a value
Options
Usage
Usage: %s\n
ambiguous option: %s (%s?)
complex
floating-point
integer
no such option: %s
option %s: invalid %s value: %r
option %s: invalid choice: %r (choose from %s)
show program's version number and exit
show this help message and exit
2 changes: 2 additions & 0 deletions Makefile.pre.in
Original file line number Diff line number Diff line change
Expand Up @@ -2567,6 +2567,8 @@ TESTSUBDIRS= idlelib/idle_test \
test/tracedmodules \
test/translationdata \
test/translationdata/argparse \
test/translationdata/getopt \
test/translationdata/optparse \
test/typinganndata \
test/wheeldata \
test/xmltestdata \
Expand Down
Loading