From d4994f04d1e40f72a753c8b4e08b8749d44df5cf Mon Sep 17 00:00:00 2001 From: stan Date: Sun, 16 Feb 2025 17:29:05 +0000 Subject: [PATCH 1/5] Remove unnecessary tests --- Lib/test/test_tools/test_i18n.py | 118 ------------------------------- 1 file changed, 118 deletions(-) diff --git a/Lib/test/test_tools/test_i18n.py b/Lib/test/test_tools/test_i18n.py index f5aba31ed42c10..bb112e8ed2cff9 100644 --- a/Lib/test/test_tools/test_i18n.py +++ b/Lib/test/test_tools/test_i18n.py @@ -155,72 +155,6 @@ def test_POT_Creation_Date(self): # This will raise if the date format does not exactly match. datetime.strptime(creationDate, '%Y-%m-%d %H:%M%z') - def test_funcdocstring(self): - for doc in ('"""doc"""', "r'''doc'''", "R'doc'", 'u"doc"'): - with self.subTest(doc): - msgids = self.extract_docstrings_from_str(dedent('''\ - def foo(bar): - %s - ''' % doc)) - self.assertIn('doc', msgids) - - def test_funcdocstring_bytes(self): - msgids = self.extract_docstrings_from_str(dedent('''\ - def foo(bar): - b"""doc""" - ''')) - self.assertFalse([msgid for msgid in msgids if 'doc' in msgid]) - - def test_funcdocstring_fstring(self): - msgids = self.extract_docstrings_from_str(dedent('''\ - def foo(bar): - f"""doc""" - ''')) - self.assertFalse([msgid for msgid in msgids if 'doc' in msgid]) - - def test_classdocstring(self): - for doc in ('"""doc"""', "r'''doc'''", "R'doc'", 'u"doc"'): - with self.subTest(doc): - msgids = self.extract_docstrings_from_str(dedent('''\ - class C: - %s - ''' % doc)) - self.assertIn('doc', msgids) - - def test_classdocstring_bytes(self): - msgids = self.extract_docstrings_from_str(dedent('''\ - class C: - b"""doc""" - ''')) - self.assertFalse([msgid for msgid in msgids if 'doc' in msgid]) - - def test_classdocstring_fstring(self): - msgids = self.extract_docstrings_from_str(dedent('''\ - class C: - f"""doc""" - ''')) - self.assertFalse([msgid for msgid in msgids if 'doc' in msgid]) - - def test_moduledocstring(self): - for doc in ('"""doc"""', "r'''doc'''", "R'doc'", 'u"doc"'): - with self.subTest(doc): - msgids = self.extract_docstrings_from_str(dedent('''\ - %s - ''' % doc)) - self.assertIn('doc', msgids) - - def test_moduledocstring_bytes(self): - msgids = self.extract_docstrings_from_str(dedent('''\ - b"""doc""" - ''')) - self.assertFalse([msgid for msgid in msgids if 'doc' in msgid]) - - def test_moduledocstring_fstring(self): - msgids = self.extract_docstrings_from_str(dedent('''\ - f"""doc""" - ''')) - self.assertFalse([msgid for msgid in msgids if 'doc' in msgid]) - def test_msgid(self): msgids = self.extract_docstrings_from_str( '''_("""doc""" r'str' u"ing")''') @@ -234,58 +168,6 @@ def test_msgid_fstring(self): msgids = self.extract_docstrings_from_str('_(f"""doc""")') self.assertFalse([msgid for msgid in msgids if 'doc' in msgid]) - def test_funcdocstring_annotated_args(self): - """ Test docstrings for functions with annotated args """ - msgids = self.extract_docstrings_from_str(dedent('''\ - def foo(bar: str): - """doc""" - ''')) - self.assertIn('doc', msgids) - - def test_funcdocstring_annotated_return(self): - """ Test docstrings for functions with annotated return type """ - msgids = self.extract_docstrings_from_str(dedent('''\ - def foo(bar) -> str: - """doc""" - ''')) - self.assertIn('doc', msgids) - - def test_funcdocstring_defvalue_args(self): - """ Test docstring for functions with default arg values """ - msgids = self.extract_docstrings_from_str(dedent('''\ - def foo(bar=()): - """doc""" - ''')) - self.assertIn('doc', msgids) - - def test_funcdocstring_multiple_funcs(self): - """ Test docstring extraction for multiple functions combining - annotated args, annotated return types and default arg values - """ - msgids = self.extract_docstrings_from_str(dedent('''\ - def foo1(bar: tuple=()) -> str: - """doc1""" - - def foo2(bar: List[1:2]) -> (lambda x: x): - """doc2""" - - def foo3(bar: 'func'=lambda x: x) -> {1: 2}: - """doc3""" - ''')) - self.assertIn('doc1', msgids) - self.assertIn('doc2', msgids) - self.assertIn('doc3', msgids) - - def test_classdocstring_early_colon(self): - """ Test docstring extraction for a class with colons occurring within - the parentheses. - """ - msgids = self.extract_docstrings_from_str(dedent('''\ - class D(L[1:2], F({1: 2}), metaclass=M(lambda x: x)): - """doc""" - ''')) - self.assertIn('doc', msgids) - def test_calls_in_fstrings(self): msgids = self.extract_docstrings_from_str(dedent('''\ f"{_('foo bar')}" From 523e24559bbb421e77cad263db4d86f7e746b73c Mon Sep 17 00:00:00 2001 From: stan Date: Sun, 16 Feb 2025 17:38:00 +0000 Subject: [PATCH 2/5] Remove a few more tests that use extract_docstrings_from_str --- Lib/test/test_tools/test_i18n.py | 82 -------------------------------- 1 file changed, 82 deletions(-) diff --git a/Lib/test/test_tools/test_i18n.py b/Lib/test/test_tools/test_i18n.py index bb112e8ed2cff9..526625d97b1003 100644 --- a/Lib/test/test_tools/test_i18n.py +++ b/Lib/test/test_tools/test_i18n.py @@ -155,88 +155,6 @@ def test_POT_Creation_Date(self): # This will raise if the date format does not exactly match. datetime.strptime(creationDate, '%Y-%m-%d %H:%M%z') - def test_msgid(self): - msgids = self.extract_docstrings_from_str( - '''_("""doc""" r'str' u"ing")''') - self.assertIn('docstring', msgids) - - def test_msgid_bytes(self): - msgids = self.extract_docstrings_from_str('_(b"""doc""")') - self.assertFalse([msgid for msgid in msgids if 'doc' in msgid]) - - def test_msgid_fstring(self): - msgids = self.extract_docstrings_from_str('_(f"""doc""")') - self.assertFalse([msgid for msgid in msgids if 'doc' in msgid]) - - def test_calls_in_fstrings(self): - msgids = self.extract_docstrings_from_str(dedent('''\ - f"{_('foo bar')}" - ''')) - self.assertIn('foo bar', msgids) - - def test_calls_in_fstrings_raw(self): - msgids = self.extract_docstrings_from_str(dedent('''\ - rf"{_('foo bar')}" - ''')) - self.assertIn('foo bar', msgids) - - def test_calls_in_fstrings_nested(self): - msgids = self.extract_docstrings_from_str(dedent('''\ - f"""{f'{_("foo bar")}'}""" - ''')) - self.assertIn('foo bar', msgids) - - def test_calls_in_fstrings_attribute(self): - msgids = self.extract_docstrings_from_str(dedent('''\ - f"{obj._('foo bar')}" - ''')) - self.assertIn('foo bar', msgids) - - def test_calls_in_fstrings_with_call_on_call(self): - msgids = self.extract_docstrings_from_str(dedent('''\ - f"{type(str)('foo bar')}" - ''')) - self.assertNotIn('foo bar', msgids) - - def test_calls_in_fstrings_with_format(self): - msgids = self.extract_docstrings_from_str(dedent('''\ - f"{_('foo {bar}').format(bar='baz')}" - ''')) - self.assertIn('foo {bar}', msgids) - - def test_calls_in_fstrings_with_wrong_input_1(self): - msgids = self.extract_docstrings_from_str(dedent('''\ - f"{_(f'foo {bar}')}" - ''')) - self.assertFalse([msgid for msgid in msgids if 'foo {bar}' in msgid]) - - def test_calls_in_fstrings_with_wrong_input_2(self): - msgids = self.extract_docstrings_from_str(dedent('''\ - f"{_(1)}" - ''')) - self.assertNotIn(1, msgids) - - def test_calls_in_fstring_with_multiple_args(self): - msgids = self.extract_docstrings_from_str(dedent('''\ - f"{_('foo', 'bar')}" - ''')) - self.assertIn('foo', msgids) - self.assertNotIn('bar', msgids) - - def test_calls_in_fstring_with_keyword_args(self): - msgids = self.extract_docstrings_from_str(dedent('''\ - f"{_('foo', bar='baz')}" - ''')) - self.assertIn('foo', msgids) - self.assertNotIn('bar', msgids) - self.assertNotIn('baz', msgids) - - def test_calls_in_fstring_with_partially_wrong_expression(self): - msgids = self.extract_docstrings_from_str(dedent('''\ - f"{_(f'foo') + _('bar')}" - ''')) - self.assertNotIn('foo', msgids) - self.assertIn('bar', msgids) def test_function_and_class_names(self): """Test that function and class names are not mistakenly extracted.""" From cf2917f72d2f752ba4b4e515679d49e76a77adb9 Mon Sep 17 00:00:00 2001 From: stan Date: Tue, 18 Feb 2025 11:10:04 +0000 Subject: [PATCH 3/5] Revert some removals --- Lib/test/test_tools/test_i18n.py | 84 ++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/Lib/test/test_tools/test_i18n.py b/Lib/test/test_tools/test_i18n.py index 526625d97b1003..3c3218fca8f66f 100644 --- a/Lib/test/test_tools/test_i18n.py +++ b/Lib/test/test_tools/test_i18n.py @@ -82,6 +82,90 @@ def get_msgids(self, data): return msgids + def test_msgid(self): + msgids = self.extract_docstrings_from_str( + '''_("""doc""" r'str' u"ing")''') + self.assertIn('docstring', msgids) + + def test_msgid_bytes(self): + msgids = self.extract_docstrings_from_str('_(b"""doc""")') + self.assertFalse([msgid for msgid in msgids if 'doc' in msgid]) + + def test_msgid_fstring(self): + msgids = self.extract_docstrings_from_str('_(f"""doc""")') + self.assertFalse([msgid for msgid in msgids if 'doc' in msgid]) + + + def test_calls_in_fstrings(self): + msgids = self.extract_docstrings_from_str(dedent('''\ + f"{_('foo bar')}" + ''')) + self.assertIn('foo bar', msgids) + + def test_calls_in_fstrings_raw(self): + msgids = self.extract_docstrings_from_str(dedent('''\ + rf"{_('foo bar')}" + ''')) + self.assertIn('foo bar', msgids) + + def test_calls_in_fstrings_nested(self): + msgids = self.extract_docstrings_from_str(dedent('''\ + f"""{f'{_("foo bar")}'}""" + ''')) + self.assertIn('foo bar', msgids) + + def test_calls_in_fstrings_attribute(self): + msgids = self.extract_docstrings_from_str(dedent('''\ + f"{obj._('foo bar')}" + ''')) + self.assertIn('foo bar', msgids) + + def test_calls_in_fstrings_with_call_on_call(self): + msgids = self.extract_docstrings_from_str(dedent('''\ + f"{type(str)('foo bar')}" + ''')) + self.assertNotIn('foo bar', msgids) + + def test_calls_in_fstrings_with_format(self): + msgids = self.extract_docstrings_from_str(dedent('''\ + f"{_('foo {bar}').format(bar='baz')}" + ''')) + self.assertIn('foo {bar}', msgids) + + def test_calls_in_fstrings_with_wrong_input_1(self): + msgids = self.extract_docstrings_from_str(dedent('''\ + f"{_(f'foo {bar}')}" + ''')) + self.assertFalse([msgid for msgid in msgids if 'foo {bar}' in msgid]) + + def test_calls_in_fstrings_with_wrong_input_2(self): + msgids = self.extract_docstrings_from_str(dedent('''\ + f"{_(1)}" + ''')) + self.assertNotIn(1, msgids) + + def test_calls_in_fstring_with_multiple_args(self): + msgids = self.extract_docstrings_from_str(dedent('''\ + f"{_('foo', 'bar')}" + ''')) + self.assertIn('foo', msgids) + self.assertNotIn('bar', msgids) + + def test_calls_in_fstring_with_keyword_args(self): + msgids = self.extract_docstrings_from_str(dedent('''\ + f"{_('foo', bar='baz')}" + ''')) + self.assertIn('foo', msgids) + self.assertNotIn('bar', msgids) + self.assertNotIn('baz', msgids) + + def test_calls_in_fstring_with_partially_wrong_expression(self): + msgids = self.extract_docstrings_from_str(dedent('''\ + f"{_(f'foo') + _('bar')}" + ''')) + self.assertNotIn('foo', msgids) + self.assertIn('bar', msgids) + def assert_POT_equal(self, expected, actual): """Check if two POT files are equal""" self.maxDiff = None From 31c377c9062b46acb87e773b8640079bd911704b Mon Sep 17 00:00:00 2001 From: stan Date: Tue, 18 Feb 2025 11:12:04 +0000 Subject: [PATCH 4/5] Fix diff --- Lib/test/test_tools/test_i18n.py | 108 +++++++++++++++---------------- 1 file changed, 54 insertions(+), 54 deletions(-) diff --git a/Lib/test/test_tools/test_i18n.py b/Lib/test/test_tools/test_i18n.py index 3c3218fca8f66f..050e3c00e87edf 100644 --- a/Lib/test/test_tools/test_i18n.py +++ b/Lib/test/test_tools/test_i18n.py @@ -82,6 +82,60 @@ def get_msgids(self, data): return msgids + def assert_POT_equal(self, expected, actual): + """Check if two POT files are equal""" + self.maxDiff = None + self.assertEqual(normalize_POT_file(expected), normalize_POT_file(actual)) + + def extract_from_str(self, module_content, *, args=(), strict=True, with_stderr=False): + """Return all msgids extracted from module_content.""" + filename = 'test.py' + with temp_cwd(None): + with open(filename, 'w', encoding='utf-8') as fp: + fp.write(module_content) + res = assert_python_ok('-Xutf8', self.script, *args, filename) + if strict: + self.assertEqual(res.err, b'') + with open('messages.pot', encoding='utf-8') as fp: + data = fp.read() + msgids = self.get_msgids(data) + if not with_stderr: + return msgids + return msgids, res.err + + def extract_docstrings_from_str(self, module_content): + """Return all docstrings extracted from module_content.""" + return self.extract_from_str(module_content, args=('--docstrings',), strict=False) + + def get_stderr(self, module_content): + return self.extract_from_str(module_content, strict=False, with_stderr=True)[1] + + def test_header(self): + """Make sure the required fields are in the header, according to: + http://www.gnu.org/software/gettext/manual/gettext.html#Header-Entry + """ + with temp_cwd(None) as cwd: + assert_python_ok('-Xutf8', self.script) + with open('messages.pot', encoding='utf-8') as fp: + data = fp.read() + header = self.get_header(data) + + self.assertIn("Project-Id-Version", header) + self.assertIn("POT-Creation-Date", header) + self.assertIn("PO-Revision-Date", header) + self.assertIn("Last-Translator", header) + self.assertIn("Language-Team", header) + self.assertIn("MIME-Version", header) + self.assertIn("Content-Type", header) + self.assertIn("Content-Transfer-Encoding", header) + self.assertIn("Generated-By", header) + + # not clear if these should be required in POT (template) files + #self.assertIn("Report-Msgid-Bugs-To", header) + #self.assertIn("Language", header) + + #"Plural-Forms" is optional + def test_msgid(self): msgids = self.extract_docstrings_from_str( '''_("""doc""" r'str' u"ing")''') @@ -166,60 +220,6 @@ def test_calls_in_fstring_with_partially_wrong_expression(self): self.assertNotIn('foo', msgids) self.assertIn('bar', msgids) - def assert_POT_equal(self, expected, actual): - """Check if two POT files are equal""" - self.maxDiff = None - self.assertEqual(normalize_POT_file(expected), normalize_POT_file(actual)) - - def extract_from_str(self, module_content, *, args=(), strict=True, with_stderr=False): - """Return all msgids extracted from module_content.""" - filename = 'test.py' - with temp_cwd(None): - with open(filename, 'w', encoding='utf-8') as fp: - fp.write(module_content) - res = assert_python_ok('-Xutf8', self.script, *args, filename) - if strict: - self.assertEqual(res.err, b'') - with open('messages.pot', encoding='utf-8') as fp: - data = fp.read() - msgids = self.get_msgids(data) - if not with_stderr: - return msgids - return msgids, res.err - - def extract_docstrings_from_str(self, module_content): - """Return all docstrings extracted from module_content.""" - return self.extract_from_str(module_content, args=('--docstrings',), strict=False) - - def get_stderr(self, module_content): - return self.extract_from_str(module_content, strict=False, with_stderr=True)[1] - - def test_header(self): - """Make sure the required fields are in the header, according to: - http://www.gnu.org/software/gettext/manual/gettext.html#Header-Entry - """ - with temp_cwd(None) as cwd: - assert_python_ok('-Xutf8', self.script) - with open('messages.pot', encoding='utf-8') as fp: - data = fp.read() - header = self.get_header(data) - - self.assertIn("Project-Id-Version", header) - self.assertIn("POT-Creation-Date", header) - self.assertIn("PO-Revision-Date", header) - self.assertIn("Last-Translator", header) - self.assertIn("Language-Team", header) - self.assertIn("MIME-Version", header) - self.assertIn("Content-Type", header) - self.assertIn("Content-Transfer-Encoding", header) - self.assertIn("Generated-By", header) - - # not clear if these should be required in POT (template) files - #self.assertIn("Report-Msgid-Bugs-To", header) - #self.assertIn("Language", header) - - #"Plural-Forms" is optional - @unittest.skipIf(sys.platform.startswith('aix'), 'bpo-29972: broken test on AIX') def test_POT_Creation_Date(self): From df58b8397d7908f781f81fa299c390a22d35126d Mon Sep 17 00:00:00 2001 From: stan Date: Tue, 18 Feb 2025 11:13:05 +0000 Subject: [PATCH 5/5] Fix diff --- Lib/test/test_tools/test_i18n.py | 39 ++++++++++++++++---------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/Lib/test/test_tools/test_i18n.py b/Lib/test/test_tools/test_i18n.py index 050e3c00e87edf..c6e011d83b2e23 100644 --- a/Lib/test/test_tools/test_i18n.py +++ b/Lib/test/test_tools/test_i18n.py @@ -136,6 +136,25 @@ def test_header(self): #"Plural-Forms" is optional + @unittest.skipIf(sys.platform.startswith('aix'), + 'bpo-29972: broken test on AIX') + def test_POT_Creation_Date(self): + """ Match the date format from xgettext for POT-Creation-Date """ + from datetime import datetime + with temp_cwd(None) as cwd: + assert_python_ok('-Xutf8', self.script) + with open('messages.pot', encoding='utf-8') as fp: + data = fp.read() + header = self.get_header(data) + creationDate = header['POT-Creation-Date'] + + # peel off the escaped newline at the end of string + if creationDate.endswith('\\n'): + creationDate = creationDate[:-len('\\n')] + + # This will raise if the date format does not exactly match. + datetime.strptime(creationDate, '%Y-%m-%d %H:%M%z') + def test_msgid(self): msgids = self.extract_docstrings_from_str( '''_("""doc""" r'str' u"ing")''') @@ -220,26 +239,6 @@ def test_calls_in_fstring_with_partially_wrong_expression(self): self.assertNotIn('foo', msgids) self.assertIn('bar', msgids) - @unittest.skipIf(sys.platform.startswith('aix'), - 'bpo-29972: broken test on AIX') - def test_POT_Creation_Date(self): - """ Match the date format from xgettext for POT-Creation-Date """ - from datetime import datetime - with temp_cwd(None) as cwd: - assert_python_ok('-Xutf8', self.script) - with open('messages.pot', encoding='utf-8') as fp: - data = fp.read() - header = self.get_header(data) - creationDate = header['POT-Creation-Date'] - - # peel off the escaped newline at the end of string - if creationDate.endswith('\\n'): - creationDate = creationDate[:-len('\\n')] - - # This will raise if the date format does not exactly match. - datetime.strptime(creationDate, '%Y-%m-%d %H:%M%z') - - def test_function_and_class_names(self): """Test that function and class names are not mistakenly extracted.""" msgids = self.extract_from_str(dedent('''\