11from test .support import (gc_collect , bigmemtest , _2G ,
22 cpython_only , captured_stdout ,
3- check_disallow_instantiation , is_emscripten , is_wasi ,
3+ check_disallow_instantiation , linked_to_musl ,
44 warnings_helper , SHORT_TIMEOUT , Stopwatch , requires_resource )
55import locale
66import re
77import string
88import sys
9- import time
109import unittest
1110import warnings
1211from re import Scanner
1312from weakref import proxy
1413
1514# some platforms lack working multiprocessing
1615try :
17- import _multiprocessing
16+ import _multiprocessing # noqa: F401
1817except ImportError :
1918 multiprocessing = None
2019else :
@@ -621,6 +620,7 @@ def test_re_fullmatch(self):
621620 self .assertEqual (re .fullmatch (r"a.*?b" , "axxb" ).span (), (0 , 4 ))
622621 self .assertIsNone (re .fullmatch (r"a+" , "ab" ))
623622 self .assertIsNone (re .fullmatch (r"abc$" , "abc\n " ))
623+ self .assertIsNone (re .fullmatch (r"abc\z" , "abc\n " ))
624624 self .assertIsNone (re .fullmatch (r"abc\Z" , "abc\n " ))
625625 self .assertIsNone (re .fullmatch (r"(?m)abc$" , "abc\n " ))
626626 self .assertEqual (re .fullmatch (r"ab(?=c)cd" , "abcd" ).span (), (0 , 4 ))
@@ -806,6 +806,8 @@ def test_special_escapes(self):
806806 self .assertEqual (re .search (r"\B(b.)\B" ,
807807 "abc bcd bc abxd" , re .ASCII ).group (1 ), "bx" )
808808 self .assertEqual (re .search (r"^abc$" , "\n abc\n " , re .M ).group (0 ), "abc" )
809+ self .assertEqual (re .search (r"^\Aabc\z$" , "abc" , re .M ).group (0 ), "abc" )
810+ self .assertIsNone (re .search (r"^\Aabc\z$" , "\n abc\n " , re .M ))
809811 self .assertEqual (re .search (r"^\Aabc\Z$" , "abc" , re .M ).group (0 ), "abc" )
810812 self .assertIsNone (re .search (r"^\Aabc\Z$" , "\n abc\n " , re .M ))
811813 self .assertEqual (re .search (br"\b(b.)\b" ,
@@ -817,6 +819,8 @@ def test_special_escapes(self):
817819 self .assertEqual (re .search (br"\B(b.)\B" ,
818820 b"abc bcd bc abxd" , re .LOCALE ).group (1 ), b"bx" )
819821 self .assertEqual (re .search (br"^abc$" , b"\n abc\n " , re .M ).group (0 ), b"abc" )
822+ self .assertEqual (re .search (br"^\Aabc\z$" , b"abc" , re .M ).group (0 ), b"abc" )
823+ self .assertIsNone (re .search (br"^\Aabc\z$" , b"\n abc\n " , re .M ))
820824 self .assertEqual (re .search (br"^\Aabc\Z$" , b"abc" , re .M ).group (0 ), b"abc" )
821825 self .assertIsNone (re .search (br"^\Aabc\Z$" , b"\n abc\n " , re .M ))
822826 self .assertEqual (re .search (r"\d\D\w\W\s\S" ,
@@ -840,7 +844,7 @@ def test_other_escapes(self):
840844 self .assertEqual (re .match (r"[\^a]+" , 'a^' ).group (), 'a^' )
841845 self .assertIsNone (re .match (r"[\^a]+" , 'b' ))
842846 re .purge () # for warnings
843- for c in 'ceghijklmopqyzCEFGHIJKLMNOPQRTVXY ' :
847+ for c in 'ceghijklmopqyCEFGHIJKLMNOPQRTVXY ' :
844848 with self .subTest (c ):
845849 self .assertRaises (re .PatternError , re .compile , '\\ %c' % c )
846850 for c in 'ceghijklmopqyzABCEFGHIJKLMNOPQRTVXYZ' :
@@ -888,6 +892,8 @@ def test_named_unicode_escapes(self):
888892 self .checkPatternError (br'\N{LESS-THAN SIGN}' , r'bad escape \N' , 0 )
889893 self .checkPatternError (br'[\N{LESS-THAN SIGN}]' , r'bad escape \N' , 1 )
890894
895+ # TODO: RUSTPYTHON; re.search(r"\B", "") now returns a match in CPython 3.14
896+ @unittest .expectedFailure
891897 def test_word_boundaries (self ):
892898 # See http://bugs.python.org/issue10713
893899 self .assertEqual (re .search (r"\b(abc)\b" , "abc" ).group (1 ), "abc" )
@@ -983,18 +989,15 @@ def test_word_boundaries(self):
983989 self .assertIsNone (re .fullmatch (br".+\B" , b"abc" , re .LOCALE ))
984990 self .assertIsNone (re .fullmatch (r".+\B" , "ьюя" ))
985991 self .assertTrue (re .fullmatch (r".+\B" , "ьюя" , re .ASCII ))
986- # However, an empty string contains no word boundaries, and also no
987- # non-boundaries.
992+ # However, an empty string contains no word boundaries.
988993 self .assertIsNone (re .search (r"\b" , "" ))
989994 self .assertIsNone (re .search (r"\b" , "" , re .ASCII ))
990995 self .assertIsNone (re .search (br"\b" , b"" ))
991996 self .assertIsNone (re .search (br"\b" , b"" , re .LOCALE ))
992- # This one is questionable and different from the perlre behaviour,
993- # but describes current behavior.
994- self .assertIsNone (re .search (r"\B" , "" ))
995- self .assertIsNone (re .search (r"\B" , "" , re .ASCII ))
996- self .assertIsNone (re .search (br"\B" , b"" ))
997- self .assertIsNone (re .search (br"\B" , b"" , re .LOCALE ))
997+ self .assertTrue (re .search (r"\B" , "" ))
998+ self .assertTrue (re .search (r"\B" , "" , re .ASCII ))
999+ self .assertTrue (re .search (br"\B" , b"" ))
1000+ self .assertTrue (re .search (br"\B" , b"" , re .LOCALE ))
9981001 # A single word-character string has two boundaries, but no
9991002 # non-boundary gaps.
10001003 self .assertEqual (len (re .findall (r"\b" , "a" )), 2 )
@@ -1423,7 +1426,7 @@ def test_pickling(self):
14231426 newpat = pickle .loads (pickled )
14241427 self .assertEqual (newpat , oldpat )
14251428 # current pickle expects the _compile() reconstructor in re module
1426- from re import _compile
1429+ from re import _compile # noqa: F401
14271430
14281431 @unittest .expectedFailure # TODO: RUSTPYTHON
14291432 def test_copying (self ):
@@ -1755,7 +1758,7 @@ def test_bug_6561(self):
17551758 for x in not_decimal_digits :
17561759 self .assertIsNone (re .match (r'^\d$' , x ))
17571760
1758- @unittest .expectedFailure # TODO: RUSTPYTHON a = array.array(typecode)\n ValueError: bad typecode (must be b, B, u, h, H, i, I, l, L, q, Q, f or d)
1761+ @unittest .expectedFailure # TODO: RUSTPYTHON; a = array.array(typecode)\n ValueError: bad typecode (must be b, B, u, h, H, i, I, l, L, q, Q, f or d)
17591762 @warnings_helper .ignore_warnings (category = DeprecationWarning ) # gh-80480 array('u')
17601763 def test_empty_array (self ):
17611764 # SF buf 1647541
@@ -2185,10 +2188,9 @@ def test_bug_20998(self):
21852188 self .assertEqual (re .fullmatch ('[a-c]+' , 'ABC' , re .I ).span (), (0 , 3 ))
21862189
21872190 @unittest .expectedFailure # TODO: RUSTPYTHON; self.assertTrue(re.match(b'\xc5', b'\xe5', re.L|re.I))\n AssertionError: None is not true
2188- @unittest .skipIf (
2189- is_emscripten or is_wasi ,
2190- "musl libc issue on Emscripten/WASI, bpo-46390"
2191- )
2191+ @unittest .skipIf (linked_to_musl (), "musl libc issue, bpo-46390" )
2192+ @unittest .skipIf (sys .platform .startswith ("sunos" ),
2193+ "test doesn't work on Solaris, gh-91214" )
21922194 def test_locale_caching (self ):
21932195 # Issue #22410
21942196 oldlocale = locale .setlocale (locale .LC_CTYPE )
@@ -2225,10 +2227,9 @@ def check_en_US_utf8(self):
22252227 self .assertIsNone (re .match (b'(?Li)\xc5 ' , b'\xe5 ' ))
22262228 self .assertIsNone (re .match (b'(?Li)\xe5 ' , b'\xc5 ' ))
22272229
2228- @unittest .skipIf (
2229- is_emscripten or is_wasi ,
2230- "musl libc issue on Emscripten/WASI, bpo-46390"
2231- )
2230+ @unittest .skipIf (linked_to_musl (), "musl libc issue, bpo-46390" )
2231+ @unittest .skipIf (sys .platform .startswith ("sunos" ),
2232+ "test doesn't work on Solaris, gh-91214" )
22322233 def test_locale_compiled (self ):
22332234 oldlocale = locale .setlocale (locale .LC_CTYPE )
22342235 self .addCleanup (locale .setlocale , locale .LC_CTYPE , oldlocale )
@@ -2632,8 +2633,8 @@ def test_findall_atomic_grouping(self):
26322633
26332634 @unittest .expectedFailure # TODO: RUSTPYTHON
26342635 def test_bug_gh91616 (self ):
2635- self .assertTrue (re .fullmatch (r'(?s:(?>.*?\.).*)\Z ' , "a.txt" )) # reproducer
2636- self .assertTrue (re .fullmatch (r'(?s:(?=(?P<g0>.*?\.))(?P=g0).*)\Z ' , "a.txt" ))
2636+ self .assertTrue (re .fullmatch (r'(?s:(?>.*?\.).*)\z ' , "a.txt" )) # reproducer
2637+ self .assertTrue (re .fullmatch (r'(?s:(?=(?P<g0>.*?\.))(?P=g0).*)\z ' , "a.txt" ))
26372638
26382639 def test_bug_gh100061 (self ):
26392640 # gh-100061
@@ -2655,7 +2656,7 @@ def test_bug_gh100061(self):
26552656 self .assertEqual (re .match ("(?>(?:ab?c){1,3})" , "aca" ).span (), (0 , 2 ))
26562657 self .assertEqual (re .match ("(?:ab?c){1,3}+" , "aca" ).span (), (0 , 2 ))
26572658
2658- @unittest .expectedFailure # TODO: RUSTPYTHON; self.assertEqual(re.match('((x)|y|z){3}+', 'xyz').groups(), ('z', 'x'))\n AssertionError: Tuples differ: ('x', 'x') != ('z', 'x')
2659+ @unittest .expectedFailure # TODO: RUSTPYTHON; self.assertEqual(re.match('((x)|y|z){3}+', 'xyz').groups(), ('z', 'x'))\n AssertionError: Tuples differ: ('x', 'x') != ('z', 'x')
26592660 def test_bug_gh101955 (self ):
26602661 # Possessive quantifier with nested alternative with capture groups
26612662 self .assertEqual (re .match ('((x)|y|z)*+' , 'xyz' ).groups (), ('z' , 'x' ))
@@ -2893,11 +2894,11 @@ def test_long_pattern(self):
28932894 pattern = 'Very %spattern' % ('long ' * 1000 )
28942895 r = repr (re .compile (pattern ))
28952896 self .assertLess (len (r ), 300 )
2896- self .assertEqual ( r [: 30 ] , "re.compile('Very long long lon" )
2897+ self .assertStartsWith ( r , "re.compile('Very long long lon" )
28972898 r = repr (re .compile (pattern , re .I ))
28982899 self .assertLess (len (r ), 300 )
2899- self .assertEqual ( r [: 30 ] , "re.compile('Very long long lon" )
2900- self .assertEqual ( r [ - 16 :] , ", re.IGNORECASE)" )
2900+ self .assertStartsWith ( r , "re.compile('Very long long lon" )
2901+ self .assertEndsWith ( r , ", re.IGNORECASE)" )
29012902
29022903 def test_flags_repr (self ):
29032904 self .assertEqual (repr (re .I ), "re.IGNORECASE" )
@@ -2977,7 +2978,7 @@ def test_deprecated_modules(self):
29772978 self .assertEqual (mod .__name__ , name )
29782979 self .assertEqual (mod .__package__ , '' )
29792980 for attr in deprecated [name ]:
2980- self .assertTrue ( hasattr ( mod , attr ) )
2981+ self .assertHasAttr ( mod , attr )
29812982 del sys .modules [name ]
29822983
29832984 @cpython_only
0 commit comments