aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Lib/test
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/test')
-rwxr-xr-xLib/test/re_tests.py2
-rw-r--r--Lib/test/test_ast/test_ast.py57
-rw-r--r--Lib/test/test_asyncio/test_locks.py2
-rw-r--r--Lib/test/test_capi/test_float.py6
-rw-r--r--Lib/test/test_curses.py26
-rw-r--r--Lib/test/test_fnmatch.py98
-rw-r--r--Lib/test/test_gc.py2
-rw-r--r--Lib/test/test_glob.py80
-rw-r--r--Lib/test/test_import/__init__.py6
-rw-r--r--Lib/test/test_logging.py2
-rw-r--r--Lib/test/test_platform.py65
-rw-r--r--Lib/test/test_re.py11
-rw-r--r--Lib/test/test_rlcompleter.py25
-rw-r--r--Lib/test/test_strtod.py2
-rw-r--r--Lib/test/test_tkinter/widget_tests.py2
-rw-r--r--Lib/test/test_ttk/test_widgets.py6
-rw-r--r--Lib/test/test_type_annotations.py19
-rw-r--r--Lib/test/test_zoneinfo/test_zoneinfo.py1
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: