diff options
Diffstat (limited to 'Lib/test')
-rwxr-xr-x | Lib/test/re_tests.py | 2 | ||||
-rw-r--r-- | Lib/test/test_ast/test_ast.py | 57 | ||||
-rw-r--r-- | Lib/test/test_asyncio/test_locks.py | 2 | ||||
-rw-r--r-- | Lib/test/test_capi/test_float.py | 6 | ||||
-rw-r--r-- | Lib/test/test_curses.py | 26 | ||||
-rw-r--r-- | Lib/test/test_fnmatch.py | 98 | ||||
-rw-r--r-- | Lib/test/test_gc.py | 2 | ||||
-rw-r--r-- | Lib/test/test_glob.py | 80 | ||||
-rw-r--r-- | Lib/test/test_import/__init__.py | 6 | ||||
-rw-r--r-- | Lib/test/test_logging.py | 2 | ||||
-rw-r--r-- | Lib/test/test_platform.py | 65 | ||||
-rw-r--r-- | Lib/test/test_re.py | 11 | ||||
-rw-r--r-- | Lib/test/test_rlcompleter.py | 25 | ||||
-rw-r--r-- | Lib/test/test_strtod.py | 2 | ||||
-rw-r--r-- | Lib/test/test_tkinter/widget_tests.py | 2 | ||||
-rw-r--r-- | Lib/test/test_ttk/test_widgets.py | 6 | ||||
-rw-r--r-- | Lib/test/test_type_annotations.py | 19 | ||||
-rw-r--r-- | Lib/test/test_zoneinfo/test_zoneinfo.py | 1 |
18 files changed, 288 insertions, 124 deletions
diff --git a/Lib/test/re_tests.py b/Lib/test/re_tests.py index 85b026736ca..e50f5d52bbd 100755 --- a/Lib/test/re_tests.py +++ b/Lib/test/re_tests.py @@ -531,7 +531,7 @@ xyzabc (r'a[ ]*?\ (\d+).*', 'a 10', SUCCEED, 'found', 'a 10'), (r'a[ ]*?\ (\d+).*', 'a 10', SUCCEED, 'found', 'a 10'), # bug 127259: \Z shouldn't depend on multiline mode - (r'(?ms).*?x\s*\Z(.*)','xx\nx\n', SUCCEED, 'g1', ''), + (r'(?ms).*?x\s*\z(.*)','xx\nx\n', SUCCEED, 'g1', ''), # bug 128899: uppercase literals under the ignorecase flag (r'(?i)M+', 'MMM', SUCCEED, 'found', 'MMM'), (r'(?i)m+', 'MMM', SUCCEED, 'found', 'MMM'), diff --git a/Lib/test/test_ast/test_ast.py b/Lib/test/test_ast/test_ast.py index 7d64b1c0e3a..ae9db093d2e 100644 --- a/Lib/test/test_ast/test_ast.py +++ b/Lib/test/test_ast/test_ast.py @@ -692,6 +692,63 @@ class AST_Tests(unittest.TestCase): with self.assertRaises(SyntaxError): ast.parse(code, feature_version=(3, 13)) + def test_pep758_except_with_single_expr(self): + single_expr = textwrap.dedent(""" + try: + ... + except{0} TypeError: + ... + """) + + single_expr_with_as = textwrap.dedent(""" + try: + ... + except{0} TypeError as exc: + ... + """) + + single_tuple_expr = textwrap.dedent(""" + try: + ... + except{0} (TypeError,): + ... + """) + + single_tuple_expr_with_as = textwrap.dedent(""" + try: + ... + except{0} (TypeError,) as exc: + ... + """) + + single_parens_expr = textwrap.dedent(""" + try: + ... + except{0} (TypeError): + ... + """) + + single_parens_expr_with_as = textwrap.dedent(""" + try: + ... + except{0} (TypeError) as exc: + ... + """) + + for code in [ + single_expr, + single_expr_with_as, + single_tuple_expr, + single_tuple_expr_with_as, + single_parens_expr, + single_parens_expr_with_as, + ]: + for star in [True, False]: + code = code.format('*' if star else '') + with self.subTest(code=code, star=star): + ast.parse(code, feature_version=(3, 14)) + ast.parse(code, feature_version=(3, 13)) + def test_pep758_except_star_without_parens(self): code = textwrap.dedent(""" try: diff --git a/Lib/test/test_asyncio/test_locks.py b/Lib/test/test_asyncio/test_locks.py index 3bb3e5c4ca0..047f03cbb14 100644 --- a/Lib/test/test_asyncio/test_locks.py +++ b/Lib/test/test_asyncio/test_locks.py @@ -14,7 +14,7 @@ STR_RGX_REPR = ( r'(, value:\d)?' r'(, waiters:\d+)?' r'(, waiters:\d+\/\d+)?' # barrier - r')\]>\Z' + r')\]>\z' ) RGX_REPR = re.compile(STR_RGX_REPR) diff --git a/Lib/test/test_capi/test_float.py b/Lib/test/test_capi/test_float.py index c832207fef0..f7efe0d0254 100644 --- a/Lib/test/test_capi/test_float.py +++ b/Lib/test/test_capi/test_float.py @@ -199,13 +199,13 @@ class CAPIFloatTest(unittest.TestCase): signaling = 0 quiet = int(not signaling) if size == 8: - payload = random.randint(signaling, 1 << 50) + payload = random.randint(signaling, 0x7ffffffffffff) i = (sign << 63) + (0x7ff << 52) + (quiet << 51) + payload elif size == 4: - payload = random.randint(signaling, 1 << 21) + payload = random.randint(signaling, 0x3fffff) i = (sign << 31) + (0xff << 23) + (quiet << 22) + payload elif size == 2: - payload = random.randint(signaling, 1 << 8) + payload = random.randint(signaling, 0x1ff) i = (sign << 15) + (0x1f << 10) + (quiet << 9) + payload data = bytes.fromhex(f'{i:x}') for endian in (BIG_ENDIAN, LITTLE_ENDIAN): diff --git a/Lib/test/test_curses.py b/Lib/test/test_curses.py index 6fe0e7fd4b7..3f95a2b322f 100644 --- a/Lib/test/test_curses.py +++ b/Lib/test/test_curses.py @@ -51,12 +51,6 @@ def requires_colors(test): term = os.environ.get('TERM') SHORT_MAX = 0x7fff -DEFAULT_PAIR_CONTENTS = [ - (curses.COLOR_WHITE, curses.COLOR_BLACK), - (0, 0), - (-1, -1), - (15, 0), # for xterm-256color (15 is for BRIGHT WHITE) -] # If newterm was supported we could use it instead of initscr and not exit @unittest.skipIf(not term or term == 'unknown', @@ -948,8 +942,6 @@ class TestCurses(unittest.TestCase): @requires_colors def test_pair_content(self): - if not hasattr(curses, 'use_default_colors'): - self.assertIn(curses.pair_content(0), DEFAULT_PAIR_CONTENTS) curses.pair_content(0) maxpair = self.get_pair_limit() - 1 if maxpair > 0: @@ -994,13 +986,27 @@ class TestCurses(unittest.TestCase): @requires_curses_func('use_default_colors') @requires_colors def test_use_default_colors(self): - old = curses.pair_content(0) try: curses.use_default_colors() except curses.error: self.skipTest('cannot change color (use_default_colors() failed)') self.assertEqual(curses.pair_content(0), (-1, -1)) - self.assertIn(old, DEFAULT_PAIR_CONTENTS) + + @requires_curses_func('assume_default_colors') + @requires_colors + def test_assume_default_colors(self): + try: + curses.assume_default_colors(-1, -1) + except curses.error: + self.skipTest('cannot change color (assume_default_colors() failed)') + self.assertEqual(curses.pair_content(0), (-1, -1)) + curses.assume_default_colors(curses.COLOR_YELLOW, curses.COLOR_BLUE) + self.assertEqual(curses.pair_content(0), (curses.COLOR_YELLOW, curses.COLOR_BLUE)) + curses.assume_default_colors(curses.COLOR_RED, -1) + self.assertEqual(curses.pair_content(0), (curses.COLOR_RED, -1)) + curses.assume_default_colors(-1, curses.COLOR_GREEN) + self.assertEqual(curses.pair_content(0), (-1, curses.COLOR_GREEN)) + curses.assume_default_colors(-1, -1) def test_keyname(self): # TODO: key_name() diff --git a/Lib/test/test_fnmatch.py b/Lib/test/test_fnmatch.py index d4163cfe782..5daaf3b3fdd 100644 --- a/Lib/test/test_fnmatch.py +++ b/Lib/test/test_fnmatch.py @@ -218,24 +218,24 @@ class TranslateTestCase(unittest.TestCase): def test_translate(self): import re - self.assertEqual(translate('*'), r'(?s:.*)\Z') - self.assertEqual(translate('?'), r'(?s:.)\Z') - self.assertEqual(translate('a?b*'), r'(?s:a.b.*)\Z') - self.assertEqual(translate('[abc]'), r'(?s:[abc])\Z') - self.assertEqual(translate('[]]'), r'(?s:[]])\Z') - self.assertEqual(translate('[!x]'), r'(?s:[^x])\Z') - self.assertEqual(translate('[^x]'), r'(?s:[\^x])\Z') - self.assertEqual(translate('[x'), r'(?s:\[x)\Z') + self.assertEqual(translate('*'), r'(?s:.*)\z') + self.assertEqual(translate('?'), r'(?s:.)\z') + self.assertEqual(translate('a?b*'), r'(?s:a.b.*)\z') + self.assertEqual(translate('[abc]'), r'(?s:[abc])\z') + self.assertEqual(translate('[]]'), r'(?s:[]])\z') + self.assertEqual(translate('[!x]'), r'(?s:[^x])\z') + self.assertEqual(translate('[^x]'), r'(?s:[\^x])\z') + self.assertEqual(translate('[x'), r'(?s:\[x)\z') # from the docs - self.assertEqual(translate('*.txt'), r'(?s:.*\.txt)\Z') + self.assertEqual(translate('*.txt'), r'(?s:.*\.txt)\z') # squash consecutive stars - self.assertEqual(translate('*********'), r'(?s:.*)\Z') - self.assertEqual(translate('A*********'), r'(?s:A.*)\Z') - self.assertEqual(translate('*********A'), r'(?s:.*A)\Z') - self.assertEqual(translate('A*********?[?]?'), r'(?s:A.*.[?].)\Z') + self.assertEqual(translate('*********'), r'(?s:.*)\z') + self.assertEqual(translate('A*********'), r'(?s:A.*)\z') + self.assertEqual(translate('*********A'), r'(?s:.*A)\z') + self.assertEqual(translate('A*********?[?]?'), r'(?s:A.*.[?].)\z') # fancy translation to prevent exponential-time match failure t = translate('**a*a****a') - self.assertEqual(t, r'(?s:(?>.*?a)(?>.*?a).*a)\Z') + self.assertEqual(t, r'(?s:(?>.*?a)(?>.*?a).*a)\z') # and try pasting multiple translate results - it's an undocumented # feature that this works r1 = translate('**a**a**a*') @@ -249,27 +249,27 @@ class TranslateTestCase(unittest.TestCase): def test_translate_wildcards(self): for pattern, expect in [ - ('ab*', r'(?s:ab.*)\Z'), - ('ab*cd', r'(?s:ab.*cd)\Z'), - ('ab*cd*', r'(?s:ab(?>.*?cd).*)\Z'), - ('ab*cd*12', r'(?s:ab(?>.*?cd).*12)\Z'), - ('ab*cd*12*', r'(?s:ab(?>.*?cd)(?>.*?12).*)\Z'), - ('ab*cd*12*34', r'(?s:ab(?>.*?cd)(?>.*?12).*34)\Z'), - ('ab*cd*12*34*', r'(?s:ab(?>.*?cd)(?>.*?12)(?>.*?34).*)\Z'), + ('ab*', r'(?s:ab.*)\z'), + ('ab*cd', r'(?s:ab.*cd)\z'), + ('ab*cd*', r'(?s:ab(?>.*?cd).*)\z'), + ('ab*cd*12', r'(?s:ab(?>.*?cd).*12)\z'), + ('ab*cd*12*', r'(?s:ab(?>.*?cd)(?>.*?12).*)\z'), + ('ab*cd*12*34', r'(?s:ab(?>.*?cd)(?>.*?12).*34)\z'), + ('ab*cd*12*34*', r'(?s:ab(?>.*?cd)(?>.*?12)(?>.*?34).*)\z'), ]: with self.subTest(pattern): translated = translate(pattern) self.assertEqual(translated, expect, pattern) for pattern, expect in [ - ('*ab', r'(?s:.*ab)\Z'), - ('*ab*', r'(?s:(?>.*?ab).*)\Z'), - ('*ab*cd', r'(?s:(?>.*?ab).*cd)\Z'), - ('*ab*cd*', r'(?s:(?>.*?ab)(?>.*?cd).*)\Z'), - ('*ab*cd*12', r'(?s:(?>.*?ab)(?>.*?cd).*12)\Z'), - ('*ab*cd*12*', r'(?s:(?>.*?ab)(?>.*?cd)(?>.*?12).*)\Z'), - ('*ab*cd*12*34', r'(?s:(?>.*?ab)(?>.*?cd)(?>.*?12).*34)\Z'), - ('*ab*cd*12*34*', r'(?s:(?>.*?ab)(?>.*?cd)(?>.*?12)(?>.*?34).*)\Z'), + ('*ab', r'(?s:.*ab)\z'), + ('*ab*', r'(?s:(?>.*?ab).*)\z'), + ('*ab*cd', r'(?s:(?>.*?ab).*cd)\z'), + ('*ab*cd*', r'(?s:(?>.*?ab)(?>.*?cd).*)\z'), + ('*ab*cd*12', r'(?s:(?>.*?ab)(?>.*?cd).*12)\z'), + ('*ab*cd*12*', r'(?s:(?>.*?ab)(?>.*?cd)(?>.*?12).*)\z'), + ('*ab*cd*12*34', r'(?s:(?>.*?ab)(?>.*?cd)(?>.*?12).*34)\z'), + ('*ab*cd*12*34*', r'(?s:(?>.*?ab)(?>.*?cd)(?>.*?12)(?>.*?34).*)\z'), ]: with self.subTest(pattern): translated = translate(pattern) @@ -277,28 +277,28 @@ class TranslateTestCase(unittest.TestCase): def test_translate_expressions(self): for pattern, expect in [ - ('[', r'(?s:\[)\Z'), - ('[!', r'(?s:\[!)\Z'), - ('[]', r'(?s:\[\])\Z'), - ('[abc', r'(?s:\[abc)\Z'), - ('[!abc', r'(?s:\[!abc)\Z'), - ('[abc]', r'(?s:[abc])\Z'), - ('[!abc]', r'(?s:[^abc])\Z'), - ('[!abc][!def]', r'(?s:[^abc][^def])\Z'), + ('[', r'(?s:\[)\z'), + ('[!', r'(?s:\[!)\z'), + ('[]', r'(?s:\[\])\z'), + ('[abc', r'(?s:\[abc)\z'), + ('[!abc', r'(?s:\[!abc)\z'), + ('[abc]', r'(?s:[abc])\z'), + ('[!abc]', r'(?s:[^abc])\z'), + ('[!abc][!def]', r'(?s:[^abc][^def])\z'), # with [[ - ('[[', r'(?s:\[\[)\Z'), - ('[[a', r'(?s:\[\[a)\Z'), - ('[[]', r'(?s:[\[])\Z'), - ('[[]a', r'(?s:[\[]a)\Z'), - ('[[]]', r'(?s:[\[]\])\Z'), - ('[[]a]', r'(?s:[\[]a\])\Z'), - ('[[a]', r'(?s:[\[a])\Z'), - ('[[a]]', r'(?s:[\[a]\])\Z'), - ('[[a]b', r'(?s:[\[a]b)\Z'), + ('[[', r'(?s:\[\[)\z'), + ('[[a', r'(?s:\[\[a)\z'), + ('[[]', r'(?s:[\[])\z'), + ('[[]a', r'(?s:[\[]a)\z'), + ('[[]]', r'(?s:[\[]\])\z'), + ('[[]a]', r'(?s:[\[]a\])\z'), + ('[[a]', r'(?s:[\[a])\z'), + ('[[a]]', r'(?s:[\[a]\])\z'), + ('[[a]b', r'(?s:[\[a]b)\z'), # backslashes - ('[\\', r'(?s:\[\\)\Z'), - (r'[\]', r'(?s:[\\])\Z'), - (r'[\\]', r'(?s:[\\\\])\Z'), + ('[\\', r'(?s:\[\\)\z'), + (r'[\]', r'(?s:[\\])\z'), + (r'[\\]', r'(?s:[\\\\])\z'), ]: with self.subTest(pattern): translated = translate(pattern) diff --git a/Lib/test/test_gc.py b/Lib/test/test_gc.py index b5140057a69..8fae12c478c 100644 --- a/Lib/test/test_gc.py +++ b/Lib/test/test_gc.py @@ -300,7 +300,7 @@ class GCTests(unittest.TestCase): # We're mostly just checking that this doesn't crash. rc, stdout, stderr = assert_python_ok("-c", code) self.assertEqual(rc, 0) - self.assertRegex(stdout, rb"""\A\s*func=<function at \S+>\s*\Z""") + self.assertRegex(stdout, rb"""\A\s*func=<function at \S+>\s*\z""") self.assertFalse(stderr) @refcount_test diff --git a/Lib/test/test_glob.py b/Lib/test/test_glob.py index 6e5fc2939c6..d0ed5129253 100644 --- a/Lib/test/test_glob.py +++ b/Lib/test/test_glob.py @@ -459,59 +459,59 @@ class GlobTests(unittest.TestCase): def test_translate(self): def fn(pat): return glob.translate(pat, seps='/') - self.assertEqual(fn('foo'), r'(?s:foo)\Z') - self.assertEqual(fn('foo/bar'), r'(?s:foo/bar)\Z') - self.assertEqual(fn('*'), r'(?s:[^/.][^/]*)\Z') - self.assertEqual(fn('?'), r'(?s:(?!\.)[^/])\Z') - self.assertEqual(fn('a*'), r'(?s:a[^/]*)\Z') - self.assertEqual(fn('*a'), r'(?s:(?!\.)[^/]*a)\Z') - self.assertEqual(fn('.*'), r'(?s:\.[^/]*)\Z') - self.assertEqual(fn('?aa'), r'(?s:(?!\.)[^/]aa)\Z') - self.assertEqual(fn('aa?'), r'(?s:aa[^/])\Z') - self.assertEqual(fn('aa[ab]'), r'(?s:aa[ab])\Z') - self.assertEqual(fn('**'), r'(?s:(?!\.)[^/]*)\Z') - self.assertEqual(fn('***'), r'(?s:(?!\.)[^/]*)\Z') - self.assertEqual(fn('a**'), r'(?s:a[^/]*)\Z') - self.assertEqual(fn('**b'), r'(?s:(?!\.)[^/]*b)\Z') + self.assertEqual(fn('foo'), r'(?s:foo)\z') + self.assertEqual(fn('foo/bar'), r'(?s:foo/bar)\z') + self.assertEqual(fn('*'), r'(?s:[^/.][^/]*)\z') + self.assertEqual(fn('?'), r'(?s:(?!\.)[^/])\z') + self.assertEqual(fn('a*'), r'(?s:a[^/]*)\z') + self.assertEqual(fn('*a'), r'(?s:(?!\.)[^/]*a)\z') + self.assertEqual(fn('.*'), r'(?s:\.[^/]*)\z') + self.assertEqual(fn('?aa'), r'(?s:(?!\.)[^/]aa)\z') + self.assertEqual(fn('aa?'), r'(?s:aa[^/])\z') + self.assertEqual(fn('aa[ab]'), r'(?s:aa[ab])\z') + self.assertEqual(fn('**'), r'(?s:(?!\.)[^/]*)\z') + self.assertEqual(fn('***'), r'(?s:(?!\.)[^/]*)\z') + self.assertEqual(fn('a**'), r'(?s:a[^/]*)\z') + self.assertEqual(fn('**b'), r'(?s:(?!\.)[^/]*b)\z') self.assertEqual(fn('/**/*/*.*/**'), - r'(?s:/(?!\.)[^/]*/[^/.][^/]*/(?!\.)[^/]*\.[^/]*/(?!\.)[^/]*)\Z') + r'(?s:/(?!\.)[^/]*/[^/.][^/]*/(?!\.)[^/]*\.[^/]*/(?!\.)[^/]*)\z') def test_translate_include_hidden(self): def fn(pat): return glob.translate(pat, include_hidden=True, seps='/') - self.assertEqual(fn('foo'), r'(?s:foo)\Z') - self.assertEqual(fn('foo/bar'), r'(?s:foo/bar)\Z') - self.assertEqual(fn('*'), r'(?s:[^/]+)\Z') - self.assertEqual(fn('?'), r'(?s:[^/])\Z') - self.assertEqual(fn('a*'), r'(?s:a[^/]*)\Z') - self.assertEqual(fn('*a'), r'(?s:[^/]*a)\Z') - self.assertEqual(fn('.*'), r'(?s:\.[^/]*)\Z') - self.assertEqual(fn('?aa'), r'(?s:[^/]aa)\Z') - self.assertEqual(fn('aa?'), r'(?s:aa[^/])\Z') - self.assertEqual(fn('aa[ab]'), r'(?s:aa[ab])\Z') - self.assertEqual(fn('**'), r'(?s:[^/]*)\Z') - self.assertEqual(fn('***'), r'(?s:[^/]*)\Z') - self.assertEqual(fn('a**'), r'(?s:a[^/]*)\Z') - self.assertEqual(fn('**b'), r'(?s:[^/]*b)\Z') - self.assertEqual(fn('/**/*/*.*/**'), r'(?s:/[^/]*/[^/]+/[^/]*\.[^/]*/[^/]*)\Z') + self.assertEqual(fn('foo'), r'(?s:foo)\z') + self.assertEqual(fn('foo/bar'), r'(?s:foo/bar)\z') + self.assertEqual(fn('*'), r'(?s:[^/]+)\z') + self.assertEqual(fn('?'), r'(?s:[^/])\z') + self.assertEqual(fn('a*'), r'(?s:a[^/]*)\z') + self.assertEqual(fn('*a'), r'(?s:[^/]*a)\z') + self.assertEqual(fn('.*'), r'(?s:\.[^/]*)\z') + self.assertEqual(fn('?aa'), r'(?s:[^/]aa)\z') + self.assertEqual(fn('aa?'), r'(?s:aa[^/])\z') + self.assertEqual(fn('aa[ab]'), r'(?s:aa[ab])\z') + self.assertEqual(fn('**'), r'(?s:[^/]*)\z') + self.assertEqual(fn('***'), r'(?s:[^/]*)\z') + self.assertEqual(fn('a**'), r'(?s:a[^/]*)\z') + self.assertEqual(fn('**b'), r'(?s:[^/]*b)\z') + self.assertEqual(fn('/**/*/*.*/**'), r'(?s:/[^/]*/[^/]+/[^/]*\.[^/]*/[^/]*)\z') def test_translate_recursive(self): def fn(pat): return glob.translate(pat, recursive=True, include_hidden=True, seps='/') - self.assertEqual(fn('*'), r'(?s:[^/]+)\Z') - self.assertEqual(fn('?'), r'(?s:[^/])\Z') - self.assertEqual(fn('**'), r'(?s:.*)\Z') - self.assertEqual(fn('**/**'), r'(?s:.*)\Z') - self.assertEqual(fn('***'), r'(?s:[^/]*)\Z') - self.assertEqual(fn('a**'), r'(?s:a[^/]*)\Z') - self.assertEqual(fn('**b'), r'(?s:[^/]*b)\Z') - self.assertEqual(fn('/**/*/*.*/**'), r'(?s:/(?:.+/)?[^/]+/[^/]*\.[^/]*/.*)\Z') + self.assertEqual(fn('*'), r'(?s:[^/]+)\z') + self.assertEqual(fn('?'), r'(?s:[^/])\z') + self.assertEqual(fn('**'), r'(?s:.*)\z') + self.assertEqual(fn('**/**'), r'(?s:.*)\z') + self.assertEqual(fn('***'), r'(?s:[^/]*)\z') + self.assertEqual(fn('a**'), r'(?s:a[^/]*)\z') + self.assertEqual(fn('**b'), r'(?s:[^/]*b)\z') + self.assertEqual(fn('/**/*/*.*/**'), r'(?s:/(?:.+/)?[^/]+/[^/]*\.[^/]*/.*)\z') def test_translate_seps(self): def fn(pat): return glob.translate(pat, recursive=True, include_hidden=True, seps=['/', '\\']) - self.assertEqual(fn('foo/bar\\baz'), r'(?s:foo[/\\]bar[/\\]baz)\Z') - self.assertEqual(fn('**/*'), r'(?s:(?:.+[/\\])?[^/\\]+)\Z') + self.assertEqual(fn('foo/bar\\baz'), r'(?s:foo[/\\]bar[/\\]baz)\z') + self.assertEqual(fn('**/*'), r'(?s:(?:.+[/\\])?[^/\\]+)\z') if __name__ == "__main__": diff --git a/Lib/test/test_import/__init__.py b/Lib/test/test_import/__init__.py index b5f4645847a..6e34094c5aa 100644 --- a/Lib/test/test_import/__init__.py +++ b/Lib/test/test_import/__init__.py @@ -1001,7 +1001,7 @@ from not_a_module import symbol expected_error = error + ( rb" \(consider renaming '.*numpy.py' if it has the " - rb"same name as a library you intended to import\)\s+\Z" + rb"same name as a library you intended to import\)\s+\z" ) popen = script_helper.spawn_python(os.path.join(tmp, "numpy.py")) @@ -1022,14 +1022,14 @@ from not_a_module import symbol f.write("this_script_does_not_attempt_to_import_numpy = True") expected_error = ( - rb"AttributeError: module 'numpy' has no attribute 'attr'\s+\Z" + rb"AttributeError: module 'numpy' has no attribute 'attr'\s+\z" ) popen = script_helper.spawn_python('-c', 'import numpy; numpy.attr', cwd=tmp) stdout, stderr = popen.communicate() self.assertRegex(stdout, expected_error) expected_error = ( - rb"ImportError: cannot import name 'attr' from 'numpy' \(.*\)\s+\Z" + rb"ImportError: cannot import name 'attr' from 'numpy' \(.*\)\s+\z" ) popen = script_helper.spawn_python('-c', 'from numpy import attr', cwd=tmp) stdout, stderr = popen.communicate() diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index de9108288a7..3f113ec1be4 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -6740,7 +6740,7 @@ class TimedRotatingFileHandlerTest(BaseFileTest): rotator = rotators[i] candidates = rotator.getFilesToDelete() self.assertEqual(len(candidates), n_files - backupCount, candidates) - matcher = re.compile(r"^\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2}\Z") + matcher = re.compile(r"^\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2}\z") for c in candidates: d, fn = os.path.split(c) self.assertStartsWith(fn, prefix+'.') diff --git a/Lib/test/test_platform.py b/Lib/test/test_platform.py index 6ba630ad527..b90edc05e04 100644 --- a/Lib/test/test_platform.py +++ b/Lib/test/test_platform.py @@ -1,5 +1,8 @@ -import os +import contextlib import copy +import io +import itertools +import os import pickle import platform import subprocess @@ -741,5 +744,65 @@ class PlatformTest(unittest.TestCase): self.assertEqual(len(info["SPECIALS"]), 5) +class CommandLineTest(unittest.TestCase): + def setUp(self): + platform.invalidate_caches() + self.addCleanup(platform.invalidate_caches) + + def invoke_platform(self, *flags): + output = io.StringIO() + with contextlib.redirect_stdout(output): + platform._main(args=flags) + return output.getvalue() + + def test_unknown_flag(self): + with self.assertRaises(SystemExit): + output = io.StringIO() + # suppress argparse error message + with contextlib.redirect_stderr(output): + _ = self.invoke_platform('--unknown') + self.assertStartsWith(output, "usage: ") + + def test_invocation(self): + flags = ( + "--terse", "--nonaliased", "terse", "nonaliased" + ) + + for r in range(len(flags) + 1): + for combination in itertools.combinations(flags, r): + self.invoke_platform(*combination) + + def test_arg_parsing(self): + # For backwards compatibility, the `aliased` and `terse` parameters are + # computed based on a combination of positional arguments and flags. + # + # Test that the arguments are correctly passed to the underlying + # `platform.platform()` call. + options = ( + (["--nonaliased"], False, False), + (["nonaliased"], False, False), + (["--terse"], True, True), + (["terse"], True, True), + (["nonaliased", "terse"], False, True), + (["--nonaliased", "terse"], False, True), + (["--terse", "nonaliased"], False, True), + ) + + for flags, aliased, terse in options: + with self.subTest(flags=flags, aliased=aliased, terse=terse): + with mock.patch.object(platform, 'platform') as obj: + self.invoke_platform(*flags) + obj.assert_called_once_with(aliased, terse) + + def test_help(self): + output = io.StringIO() + + with self.assertRaises(SystemExit): + with contextlib.redirect_stdout(output): + platform._main(args=["--help"]) + + self.assertStartsWith(output.getvalue(), "usage:") + + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index cf8525ed901..f79a6149078 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -619,6 +619,7 @@ class ReTests(unittest.TestCase): self.assertEqual(re.fullmatch(r"a.*?b", "axxb").span(), (0, 4)) self.assertIsNone(re.fullmatch(r"a+", "ab")) self.assertIsNone(re.fullmatch(r"abc$", "abc\n")) + self.assertIsNone(re.fullmatch(r"abc\z", "abc\n")) self.assertIsNone(re.fullmatch(r"abc\Z", "abc\n")) self.assertIsNone(re.fullmatch(r"(?m)abc$", "abc\n")) self.assertEqual(re.fullmatch(r"ab(?=c)cd", "abcd").span(), (0, 4)) @@ -802,6 +803,8 @@ class ReTests(unittest.TestCase): self.assertEqual(re.search(r"\B(b.)\B", "abc bcd bc abxd", re.ASCII).group(1), "bx") self.assertEqual(re.search(r"^abc$", "\nabc\n", re.M).group(0), "abc") + self.assertEqual(re.search(r"^\Aabc\z$", "abc", re.M).group(0), "abc") + self.assertIsNone(re.search(r"^\Aabc\z$", "\nabc\n", re.M)) self.assertEqual(re.search(r"^\Aabc\Z$", "abc", re.M).group(0), "abc") self.assertIsNone(re.search(r"^\Aabc\Z$", "\nabc\n", re.M)) self.assertEqual(re.search(br"\b(b.)\b", @@ -813,6 +816,8 @@ class ReTests(unittest.TestCase): self.assertEqual(re.search(br"\B(b.)\B", b"abc bcd bc abxd", re.LOCALE).group(1), b"bx") self.assertEqual(re.search(br"^abc$", b"\nabc\n", re.M).group(0), b"abc") + self.assertEqual(re.search(br"^\Aabc\z$", b"abc", re.M).group(0), b"abc") + self.assertIsNone(re.search(br"^\Aabc\z$", b"\nabc\n", re.M)) self.assertEqual(re.search(br"^\Aabc\Z$", b"abc", re.M).group(0), b"abc") self.assertIsNone(re.search(br"^\Aabc\Z$", b"\nabc\n", re.M)) self.assertEqual(re.search(r"\d\D\w\W\s\S", @@ -836,7 +841,7 @@ class ReTests(unittest.TestCase): self.assertEqual(re.match(r"[\^a]+", 'a^').group(), 'a^') self.assertIsNone(re.match(r"[\^a]+", 'b')) re.purge() # for warnings - for c in 'ceghijklmopqyzCEFGHIJKLMNOPQRTVXY': + for c in 'ceghijklmopqyCEFGHIJKLMNOPQRTVXY': with self.subTest(c): self.assertRaises(re.PatternError, re.compile, '\\%c' % c) for c in 'ceghijklmopqyzABCEFGHIJKLMNOPQRTVXYZ': @@ -2608,8 +2613,8 @@ class ReTests(unittest.TestCase): self.assertEqual(re.findall(r'(?>(?:ab){1,3})', 'ababc'), ['abab']) def test_bug_gh91616(self): - self.assertTrue(re.fullmatch(r'(?s:(?>.*?\.).*)\Z', "a.txt")) # reproducer - self.assertTrue(re.fullmatch(r'(?s:(?=(?P<g0>.*?\.))(?P=g0).*)\Z', "a.txt")) + self.assertTrue(re.fullmatch(r'(?s:(?>.*?\.).*)\z', "a.txt")) # reproducer + self.assertTrue(re.fullmatch(r'(?s:(?=(?P<g0>.*?\.))(?P=g0).*)\z', "a.txt")) def test_bug_gh100061(self): # gh-100061 diff --git a/Lib/test/test_rlcompleter.py b/Lib/test/test_rlcompleter.py index 1cff6a218f8..d403a0fe96b 100644 --- a/Lib/test/test_rlcompleter.py +++ b/Lib/test/test_rlcompleter.py @@ -54,11 +54,26 @@ class TestRlcompleter(unittest.TestCase): ['str.{}('.format(x) for x in dir(str) if x.startswith('s')]) self.assertEqual(self.stdcompleter.attr_matches('tuple.foospamegg'), []) - expected = sorted({'None.%s%s' % (x, - '()' if x in ('__init_subclass__', '__class__') - else '' if x == '__doc__' - else '(') - for x in dir(None)}) + + def create_expected_for_none(): + if not MISSING_C_DOCSTRINGS: + parentheses = ('__init_subclass__', '__class__') + else: + # When `--without-doc-strings` is used, `__class__` + # won't have a known signature. + parentheses = ('__init_subclass__',) + + items = set() + for x in dir(None): + if x in parentheses: + items.add(f'None.{x}()') + elif x == '__doc__': + items.add(f'None.{x}') + else: + items.add(f'None.{x}(') + return sorted(items) + + expected = create_expected_for_none() self.assertEqual(self.stdcompleter.attr_matches('None.'), expected) self.assertEqual(self.stdcompleter.attr_matches('None._'), expected) self.assertEqual(self.stdcompleter.attr_matches('None.__'), expected) diff --git a/Lib/test/test_strtod.py b/Lib/test/test_strtod.py index 2727514fad4..570de390a95 100644 --- a/Lib/test/test_strtod.py +++ b/Lib/test/test_strtod.py @@ -19,7 +19,7 @@ strtod_parser = re.compile(r""" # A numeric string consists of: (?P<int>\d*) # having a (possibly empty) integer part (?:\.(?P<frac>\d*))? # followed by an optional fractional part (?:E(?P<exp>[-+]?\d+))? # and an optional exponent - \Z + \z """, re.VERBOSE | re.IGNORECASE).match # Pure Python version of correctly rounded string->float conversion. diff --git a/Lib/test/test_tkinter/widget_tests.py b/Lib/test/test_tkinter/widget_tests.py index ac7fb5977e0..f518925e994 100644 --- a/Lib/test/test_tkinter/widget_tests.py +++ b/Lib/test/test_tkinter/widget_tests.py @@ -65,7 +65,7 @@ class AbstractWidgetTest(AbstractTkTest): orig = widget[name] if errmsg is not None: errmsg = errmsg.format(re.escape(str(value))) - errmsg = fr'\A{errmsg}\Z' + errmsg = fr'\A{errmsg}\z' with self.assertRaisesRegex(tkinter.TclError, errmsg or ''): widget[name] = value self.assertEqual(widget[name], orig) diff --git a/Lib/test/test_ttk/test_widgets.py b/Lib/test/test_ttk/test_widgets.py index d5620becfa7..f33da2a8848 100644 --- a/Lib/test/test_ttk/test_widgets.py +++ b/Lib/test/test_ttk/test_widgets.py @@ -490,7 +490,7 @@ class ComboboxTest(EntryTest, unittest.TestCase): width = self.combo.winfo_width() x, y = width - 5, 5 if sys.platform != 'darwin': # there's no down arrow on macOS - self.assertRegex(self.combo.identify(x, y), r'.*downarrow\Z') + self.assertRegex(self.combo.identify(x, y), r'.*downarrow\z') self.combo.event_generate('<Button-1>', x=x, y=y) self.combo.event_generate('<ButtonRelease-1>', x=x, y=y) @@ -1250,7 +1250,7 @@ class SpinboxTest(EntryTest, unittest.TestCase): height = self.spin.winfo_height() x = width - 5 y = height//2 - 5 - self.assertRegex(self.spin.identify(x, y), r'.*uparrow\Z') + self.assertRegex(self.spin.identify(x, y), r'.*uparrow\z') self.spin.event_generate('<ButtonPress-1>', x=x, y=y) self.spin.event_generate('<ButtonRelease-1>', x=x, y=y) self.spin.update_idletasks() @@ -1260,7 +1260,7 @@ class SpinboxTest(EntryTest, unittest.TestCase): height = self.spin.winfo_height() x = width - 5 y = height//2 + 4 - self.assertRegex(self.spin.identify(x, y), r'.*downarrow\Z') + self.assertRegex(self.spin.identify(x, y), r'.*downarrow\z') self.spin.event_generate('<ButtonPress-1>', x=x, y=y) self.spin.event_generate('<ButtonRelease-1>', x=x, y=y) self.spin.update_idletasks() diff --git a/Lib/test/test_type_annotations.py b/Lib/test/test_type_annotations.py index b72d3dbe516..2c886bb6d36 100644 --- a/Lib/test/test_type_annotations.py +++ b/Lib/test/test_type_annotations.py @@ -327,6 +327,25 @@ class AnnotateTests(unittest.TestCase): f.__annotations__ = {"z": 43} self.assertIs(f.__annotate__, None) + def test_user_defined_annotate(self): + class X: + a: int + + def __annotate__(format): + return {"a": str} + self.assertEqual(X.__annotate__(annotationlib.Format.VALUE), {"a": str}) + self.assertEqual(annotationlib.get_annotations(X), {"a": str}) + + mod = build_module( + """ + a: int + def __annotate__(format): + return {"a": str} + """ + ) + self.assertEqual(mod.__annotate__(annotationlib.Format.VALUE), {"a": str}) + self.assertEqual(annotationlib.get_annotations(mod), {"a": str}) + class DeferredEvaluationTests(unittest.TestCase): def test_function(self): diff --git a/Lib/test/test_zoneinfo/test_zoneinfo.py b/Lib/test/test_zoneinfo/test_zoneinfo.py index b0dbd768cab..d2845495c7f 100644 --- a/Lib/test/test_zoneinfo/test_zoneinfo.py +++ b/Lib/test/test_zoneinfo/test_zoneinfo.py @@ -237,7 +237,6 @@ class ZoneInfoTest(TzPathUserMixin, ZoneInfoTestBase): "../zoneinfo/America/Los_Angeles", # Traverses above TZPATH "America/../America/Los_Angeles", # Not normalized "America/./Los_Angeles", - "", ] for bad_key in bad_keys: |