https://github.com/python/cpython/commit/84a08f8629dffae355407cc3239c981a2b7a930a
commit: 84a08f8629dffae355407cc3239c981a2b7a930a
branch: main
author: Serhiy Storchaka <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2025-05-03T17:58:49+03:00
summary:
gh-133306: Use \z instead of \Z in regular expressions in the stdlib (GH-133337)
files:
M Lib/_py_warnings.py
M Lib/_pydecimal.py
M Lib/email/feedparser.py
M Lib/fractions.py
M Lib/idlelib/pyshell.py
M Lib/test/test_asyncio/test_locks.py
M Lib/test/test_gc.py
M Lib/test/test_import/__init__.py
M Lib/test/test_logging.py
M Lib/test/test_strtod.py
M Lib/test/test_tkinter/widget_tests.py
M Lib/test/test_ttk/test_widgets.py
M Lib/textwrap.py
M Lib/tokenize.py
M Lib/urllib/parse.py
M Lib/zipfile/_path/glob.py
diff --git a/Lib/_py_warnings.py b/Lib/_py_warnings.py
index 3cdc6ffe19800f..cbaa94458629ac 100644
--- a/Lib/_py_warnings.py
+++ b/Lib/_py_warnings.py
@@ -371,7 +371,7 @@ def _setoption(arg):
if message:
message = re.escape(message)
if module:
- module = re.escape(module) + r'\Z'
+ module = re.escape(module) + r'\z'
if lineno:
try:
lineno = int(lineno)
diff --git a/Lib/_pydecimal.py b/Lib/_pydecimal.py
index 4b09207eca6fac..46fa9ffcb1e056 100644
--- a/Lib/_pydecimal.py
+++ b/Lib/_pydecimal.py
@@ -6096,7 +6096,7 @@ def _convert_for_comparison(self, other,
equality_op=False):
(?P<diag>\d*) # with (possibly empty) diagnostic info.
)
# \s*
- \Z
+ \z
""", re.VERBOSE | re.IGNORECASE).match
_all_zeros = re.compile('0*$').match
@@ -6124,7 +6124,7 @@ def _convert_for_comparison(self, other,
equality_op=False):
(?P<thousands_sep>[,_])?
(?:\.(?P<precision>0|(?!0)\d+))?
(?P<type>[eEfFgGn%])?
-\Z
+\z
""", re.VERBOSE|re.DOTALL)
del re
diff --git a/Lib/email/feedparser.py b/Lib/email/feedparser.py
index b2bc4afc1cc26f..9d80a5822af48d 100644
--- a/Lib/email/feedparser.py
+++ b/Lib/email/feedparser.py
@@ -30,7 +30,7 @@
NLCRE = re.compile(r'\r\n|\r|\n')
NLCRE_bol = re.compile(r'(\r\n|\r|\n)')
-NLCRE_eol = re.compile(r'(\r\n|\r|\n)\Z')
+NLCRE_eol = re.compile(r'(\r\n|\r|\n)\z')
NLCRE_crack = re.compile(r'(\r\n|\r|\n)')
# RFC 2822 $3.6.8 Optional fields. ftext is %d33-57 / %d59-126, Any character
# except controls, SP, and ":".
diff --git a/Lib/fractions.py b/Lib/fractions.py
index fa722589fb4f67..8163e3bb594f6b 100644
--- a/Lib/fractions.py
+++ b/Lib/fractions.py
@@ -64,7 +64,7 @@ def _hash_algorithm(numerator, denominator):
(?:\.(?P<decimal>\d*|\d+(_\d+)*))? # an optional fractional part
(?:E(?P<exp>[-+]?\d+(_\d+)*))? # and optional exponent
)
- \s*\Z # and optional whitespace to finish
+ \s*\z # and optional whitespace to finish
""", re.VERBOSE | re.IGNORECASE)
diff --git a/Lib/idlelib/pyshell.py b/Lib/idlelib/pyshell.py
index 60b63d58cdd8a3..74a0e03994f69a 100755
--- a/Lib/idlelib/pyshell.py
+++ b/Lib/idlelib/pyshell.py
@@ -1350,7 +1350,7 @@ def recall(self, s, event):
self.text.see("insert")
self.text.undo_block_stop()
- _last_newline_re = re.compile(r"[ \t]*(\n[ \t]*)?\Z")
+ _last_newline_re = re.compile(r"[ \t]*(\n[ \t]*)?\z")
def runit(self):
index_before = self.text.index("end-2c")
line = self.text.get("iomark", "end-1c")
diff --git a/Lib/test/test_asyncio/test_locks.py
b/Lib/test/test_asyncio/test_locks.py
index 3bb3e5c4ca0658..047f03cbb14b56 100644
--- a/Lib/test/test_asyncio/test_locks.py
+++ b/Lib/test/test_asyncio/test_locks.py
@@ -14,7 +14,7 @@
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_gc.py b/Lib/test/test_gc.py
index b5140057a69d36..8fae12c478cb3a 100644
--- a/Lib/test/test_gc.py
+++ b/Lib/test/test_gc.py
@@ -300,7 +300,7 @@ def func():
# 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_import/__init__.py b/Lib/test/test_import/__init__.py
index b5f4645847a1e6..6e34094c5aa422 100644
--- a/Lib/test/test_import/__init__.py
+++ b/Lib/test/test_import/__init__.py
@@ -1001,7 +1001,7 @@ def test_script_shadowing_third_party(self):
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 @@ def test_script_maybe_not_shadowing_third_party(self):
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 de9108288a72f5..3f113ec1be47af 100644
--- a/Lib/test/test_logging.py
+++ b/Lib/test/test_logging.py
@@ -6740,7 +6740,7 @@ def
test_compute_files_to_delete_same_filename_different_extensions(self):
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_strtod.py b/Lib/test/test_strtod.py
index 2727514fad4469..570de390a95882 100644
--- a/Lib/test/test_strtod.py
+++ b/Lib/test/test_strtod.py
@@ -19,7 +19,7 @@
(?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 ac7fb5977e04fc..f518925e994e90 100644
--- a/Lib/test/test_tkinter/widget_tests.py
+++ b/Lib/test/test_tkinter/widget_tests.py
@@ -65,7 +65,7 @@ def checkInvalidParam(self, widget, name, value, errmsg=None):
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 d5620becfa7187..f33da2a8848738 100644
--- a/Lib/test/test_ttk/test_widgets.py
+++ b/Lib/test/test_ttk/test_widgets.py
@@ -490,7 +490,7 @@ def _show_drop_down_listbox(self):
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 @@ def _click_increment_arrow(self):
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 @@ def _click_decrement_arrow(self):
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/textwrap.py b/Lib/textwrap.py
index 00465f67d0941a..5ae439f5cd3b78 100644
--- a/Lib/textwrap.py
+++ b/Lib/textwrap.py
@@ -86,7 +86,7 @@ class TextWrapper:
-(?: (?<=%(lt)s{2}-) | (?<=%(lt)s-%(lt)s-))
(?= %(lt)s -? %(lt)s)
| # end of word
- (?=%(ws)s|\Z)
+ (?=%(ws)s|\z)
| # em-dash
(?<=%(wp)s) (?=-{2,}\w)
)
@@ -107,7 +107,7 @@ class TextWrapper:
sentence_end_re = re.compile(r'[a-z]' # lowercase letter
r'[\.\!\?]' # sentence-ending punct.
r'[\"\']?' # optional end-of-quote
- r'\Z') # end of chunk
+ r'\z') # end of chunk
def __init__(self,
width=70,
diff --git a/Lib/tokenize.py b/Lib/tokenize.py
index edb1ed8bdb8c9c..117b485b9344e6 100644
--- a/Lib/tokenize.py
+++ b/Lib/tokenize.py
@@ -132,7 +132,7 @@ def _compile(expr):
group("'", r'\\\r?\n'),
StringPrefix + r'"[^\n"\\]*(?:\\.[^\n"\\]*)*' +
group('"', r'\\\r?\n'))
-PseudoExtras = group(r'\\\r?\n|\Z', Comment, Triple)
+PseudoExtras = group(r'\\\r?\n|\z', Comment, Triple)
PseudoToken = Whitespace + group(PseudoExtras, Number, Funny, ContStr, Name)
# For a given string prefix plus quotes, endpats maps it to a regex
diff --git a/Lib/urllib/parse.py b/Lib/urllib/parse.py
index 9d51f4c6812b57..67d9bbea0d3150 100644
--- a/Lib/urllib/parse.py
+++ b/Lib/urllib/parse.py
@@ -460,7 +460,7 @@ def _check_bracketed_netloc(netloc):
# https://www.rfc-editor.org/rfc/rfc3986#page-49 and
https://url.spec.whatwg.org/
def _check_bracketed_host(hostname):
if hostname.startswith('v'):
- if not re.match(r"\Av[a-fA-F0-9]+\..+\Z", hostname):
+ if not re.match(r"\Av[a-fA-F0-9]+\..+\z", hostname):
raise ValueError(f"IPvFuture address is invalid")
else:
ip = ipaddress.ip_address(hostname) # Throws Value Error if not IPv6
or IPv4
diff --git a/Lib/zipfile/_path/glob.py b/Lib/zipfile/_path/glob.py
index 4320f1c0badcf9..d7fe45a494717a 100644
--- a/Lib/zipfile/_path/glob.py
+++ b/Lib/zipfile/_path/glob.py
@@ -37,9 +37,9 @@ def extend(self, pattern):
Apply '(?s:)' to create a non-matching group that
matches newlines (valid on Unix).
- Append '\Z' to imply fullmatch even when match is used.
+ Append '\z' to imply fullmatch even when match is used.
"""
- return rf'(?s:{pattern})\Z'
+ return rf'(?s:{pattern})\z'
def match_dirs(self, pattern):
"""
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]