https://github.com/python/cpython/commit/84a08f8629dffae355407cc3239c981a2b7a930a
commit: 84a08f8629dffae355407cc3239c981a2b7a930a
branch: main
author: Serhiy Storchaka <storch...@gmail.com>
committer: serhiy-storchaka <storch...@gmail.com>
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 -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com

Reply via email to