Skip to content

Commit eb2f634

Browse files
authored
gh-148100: Soft deprecate re.match and re.Pattern.match in favour of prefixmatch (#148101)
1 parent e998eb9 commit eb2f634

File tree

5 files changed

+95
-31
lines changed

5 files changed

+95
-31
lines changed

Doc/deprecations/index.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ Deprecations
1515

1616
.. include:: pending-removal-in-future.rst
1717

18+
.. include:: soft-deprecations.rst
19+
1820
C API deprecations
1921
------------------
2022

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
Soft deprecations
2+
-----------------
3+
4+
There are no plans to remove :term:`soft deprecated` APIs.
5+
6+
* :func:`re.match` and :meth:`re.Pattern.match` are now
7+
:term:`soft deprecated` in favor of the new :func:`re.prefixmatch` and
8+
:meth:`re.Pattern.prefixmatch` APIs, which have been added as alternate,
9+
more explicit names. These are intended to be used to alleviate confusion
10+
around what *match* means by following the Zen of Python's *"Explicit is
11+
better than implicit"* mantra. Most other language regular expression
12+
libraries use an API named *match* to mean what Python has always called
13+
*search*.
14+
15+
We **do not** plan to remove the older :func:`!match` name, as it has been
16+
used in code for over 30 years. Code supporting older versions of Python
17+
should continue to use :func:`!match`, while new code should prefer
18+
:func:`!prefixmatch`. See :ref:`prefixmatch-vs-match`.
19+
20+
(Contributed by Gregory P. Smith in :gh:`86519` and
21+
Hugo van Kemenade in :gh:`148100`.)

Doc/library/re.rst

Lines changed: 42 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ fine-tuning parameters.
5252

5353
.. _re-syntax:
5454

55-
Regular Expression Syntax
55+
Regular expression syntax
5656
-------------------------
5757

5858
A regular expression (or RE) specifies a set of strings that matches it; the
@@ -205,7 +205,7 @@ The special characters are:
205205
*without* establishing any backtracking points.
206206
This is the possessive version of the quantifier above.
207207
For example, on the 6-character string ``'aaaaaa'``, ``a{3,5}+aa``
208-
attempt to match 5 ``'a'`` characters, then, requiring 2 more ``'a'``\ s,
208+
attempts to match 5 ``'a'`` characters, then, requiring 2 more ``'a'``\ s,
209209
will need more characters than available and thus fail, while
210210
``a{3,5}aa`` will match with ``a{3,5}`` capturing 5, then 4 ``'a'``\ s
211211
by backtracking and then the final 2 ``'a'``\ s are matched by the final
@@ -717,7 +717,7 @@ three digits in length.
717717

718718
.. _contents-of-module-re:
719719

720-
Module Contents
720+
Module contents
721721
---------------
722722

723723
The module defines several functions, constants, and an exception. Some of the
@@ -833,8 +833,8 @@ Flags
833833
will be conditionally ORed with other flags. Example of use as a default
834834
value::
835835

836-
def myfunc(text, flag=re.NOFLAG):
837-
return re.search(text, flag)
836+
def myfunc(pattern, text, flag=re.NOFLAG):
837+
return re.search(pattern, text, flag)
838838

839839
.. versionadded:: 3.11
840840

@@ -954,9 +954,10 @@ Functions
954954
:func:`~re.match`. Use that name when you need to retain compatibility with
955955
older Python versions.
956956

957-
.. versionchanged:: 3.15
958-
The alternate :func:`~re.prefixmatch` name of this API was added as a
959-
more explicitly descriptive name than :func:`~re.match`. Use it to better
957+
.. deprecated:: 3.15
958+
:func:`~re.match` has been :term:`soft deprecated` in favor of
959+
the alternate :func:`~re.prefixmatch` name of this API which is
960+
more explicitly descriptive. Use it to better
960961
express intent. The norm in other languages and regular expression
961962
implementations is to use the term *match* to refer to the behavior of
962963
what Python has always called :func:`~re.search`.
@@ -1246,7 +1247,7 @@ Exceptions
12461247

12471248
.. _re-objects:
12481249

1249-
Regular Expression Objects
1250+
Regular expression objects
12501251
--------------------------
12511252

12521253
.. class:: Pattern
@@ -1309,9 +1310,10 @@ Regular Expression Objects
13091310
:meth:`~Pattern.match`. Use that name when you need to retain compatibility
13101311
with older Python versions.
13111312

1312-
.. versionchanged:: 3.15
1313-
The alternate :meth:`~Pattern.prefixmatch` name of this API was added as
1314-
a more explicitly descriptive name than :meth:`~Pattern.match`. Use it to
1313+
.. deprecated:: 3.15
1314+
:meth:`~Pattern.match` has been :term:`soft deprecated` in favor of
1315+
the alternate :meth:`~Pattern.prefixmatch` name of this API which is
1316+
more explicitly descriptive. Use it to
13151317
better express intent. The norm in other languages and regular expression
13161318
implementations is to use the term *match* to refer to the behavior of
13171319
what Python has always called :meth:`~Pattern.search`.
@@ -1396,7 +1398,7 @@ Regular Expression Objects
13961398

13971399
.. _match-objects:
13981400

1399-
Match Objects
1401+
Match objects
14001402
-------------
14011403

14021404
Match objects always have a boolean value of ``True``.
@@ -1615,11 +1617,11 @@ when there is no match, you can test whether there was a match with a simple
16151617

16161618
.. _re-examples:
16171619

1618-
Regular Expression Examples
1620+
Regular expression examples
16191621
---------------------------
16201622

16211623

1622-
Checking for a Pair
1624+
Checking for a pair
16231625
^^^^^^^^^^^^^^^^^^^
16241626

16251627
In this example, we'll use the following helper function to display match
@@ -1705,15 +1707,21 @@ expressions.
17051707
| ``%x``, ``%X`` | ``[-+]?(0[xX])?[\dA-Fa-f]+`` |
17061708
+--------------------------------+---------------------------------------------+
17071709

1708-
To extract the filename and numbers from a string like ::
1710+
To extract the filename and numbers from a string like:
1711+
1712+
.. code-block:: text
17091713
17101714
/usr/sbin/sendmail - 0 errors, 4 warnings
17111715
1712-
you would use a :c:func:`!scanf` format like ::
1716+
you would use a :c:func:`!scanf` format like:
1717+
1718+
.. code-block:: text
17131719
17141720
%s - %d errors, %d warnings
17151721
1716-
The equivalent regular expression would be ::
1722+
The equivalent regular expression would be:
1723+
1724+
.. code-block:: text
17171725
17181726
(\S+) - (\d+) errors, (\d+) warnings
17191727
@@ -1772,18 +1780,24 @@ not familiar with the Python API's divergence from what otherwise become the
17721780
industry norm.
17731781

17741782
Quoting from the Zen Of Python (``python3 -m this``): *"Explicit is better than
1775-
implicit"*. Anyone reading the name :func:`~re.prefixmatch` is likely to
1776-
understand the intended semantics. When reading :func:`~re.match` there remains
1783+
implicit"*. Anyone reading the name :func:`!prefixmatch` is likely to
1784+
understand the intended semantics. When reading :func:`!match` there remains
17771785
a seed of doubt about the intended behavior to anyone not already familiar with
17781786
this old Python gotcha.
17791787

1780-
We **do not** plan to deprecate and remove the older *match* name,
1788+
We **do not** plan to remove the older :func:`!match` name,
17811789
as it has been used in code for over 30 years.
1782-
Code supporting older versions of Python should continue to use *match*.
1790+
It has been :term:`soft deprecated`:
1791+
code supporting older versions of Python should continue to use :func:`!match`,
1792+
while new code should prefer :func:`!prefixmatch`.
17831793

17841794
.. versionadded:: 3.15
1795+
:func:`!prefixmatch`
1796+
1797+
.. deprecated:: 3.15
1798+
:func:`!match` is :term:`soft deprecated`
17851799

1786-
Making a Phonebook
1800+
Making a phonebook
17871801
^^^^^^^^^^^^^^^^^^
17881802

17891803
:func:`split` splits a string into a list delimited by the passed pattern. The
@@ -1844,7 +1858,7 @@ house number from the street name:
18441858
['Heather', 'Albrecht', '548.326.4584', '919', 'Park Place']]
18451859

18461860

1847-
Text Munging
1861+
Text munging
18481862
^^^^^^^^^^^^
18491863

18501864
:func:`sub` replaces every occurrence of a pattern with a string or the
@@ -1864,7 +1878,7 @@ in each word of a sentence except for the first and last characters::
18641878
'Pofsroser Aodlambelk, plasee reoprt yuor asnebces potlmrpy.'
18651879

18661880

1867-
Finding all Adverbs
1881+
Finding all adverbs
18681882
^^^^^^^^^^^^^^^^^^^
18691883

18701884
:func:`findall` matches *all* occurrences of a pattern, not just the first
@@ -1877,7 +1891,7 @@ the following manner::
18771891
['carefully', 'quickly']
18781892

18791893

1880-
Finding all Adverbs and their Positions
1894+
Finding all adverbs and their positions
18811895
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
18821896

18831897
If one wants more information about all matches of a pattern than the matched
@@ -1893,7 +1907,7 @@ to find all of the adverbs *and their positions* in some text, they would use
18931907
40-47: quickly
18941908

18951909

1896-
Raw String Notation
1910+
Raw string notation
18971911
^^^^^^^^^^^^^^^^^^^
18981912

18991913
Raw string notation (``r"text"``) keeps regular expressions sane. Without it,
@@ -1917,7 +1931,7 @@ functionally identical::
19171931
<re.Match object; span=(0, 1), match='\\'>
19181932

19191933

1920-
Writing a Tokenizer
1934+
Writing a tokenizer
19211935
^^^^^^^^^^^^^^^^^^^
19221936

19231937
A `tokenizer or scanner <https://en.wikipedia.org/wiki/Lexical_analysis>`_

Doc/whatsnew/3.15.rst

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -945,9 +945,10 @@ pickle
945945
re
946946
--
947947

948-
* :func:`re.prefixmatch` and a corresponding :meth:`~re.Pattern.prefixmatch`
949-
have been added as alternate more explicit names for the existing
950-
:func:`re.match` and :meth:`~re.Pattern.match` APIs. These are intended
948+
* :func:`re.prefixmatch` and a corresponding :meth:`re.Pattern.prefixmatch`
949+
have been added as alternate, more explicit names for the existing
950+
and now :term:`soft deprecated`
951+
:func:`re.match` and :meth:`re.Pattern.match` APIs. These are intended
951952
to be used to alleviate confusion around what *match* means by following the
952953
Zen of Python's *"Explicit is better than implicit"* mantra. Most other
953954
language regular expression libraries use an API named *match* to mean what
@@ -1685,6 +1686,27 @@ New deprecations
16851686

16861687
(Contributed by Bénédikt Tran in :gh:`134978`.)
16871688

1689+
1690+
* :mod:`re`:
1691+
1692+
* :func:`re.match` and :meth:`re.Pattern.match` are now
1693+
:term:`soft deprecated` in favor of the new :func:`re.prefixmatch` and
1694+
:meth:`re.Pattern.prefixmatch` APIs, which have been added as alternate,
1695+
more explicit names. These are intended to be used to alleviate confusion
1696+
around what *match* means by following the Zen of Python's *"Explicit is
1697+
better than implicit"* mantra. Most other language regular expression
1698+
libraries use an API named *match* to mean what Python has always called
1699+
*search*.
1700+
1701+
We **do not** plan to remove the older :func:`!match` name, as it has been
1702+
used in code for over 30 years. Code supporting older versions of Python
1703+
should continue to use :func:`!match`, while new code should prefer
1704+
:func:`!prefixmatch`. See :ref:`prefixmatch-vs-match`.
1705+
1706+
(Contributed by Gregory P. Smith in :gh:`86519` and
1707+
Hugo van Kemenade in :gh:`148100`.)
1708+
1709+
16881710
* :mod:`struct`:
16891711

16901712
* Calling the ``Struct.__new__()`` without required argument now is
@@ -1757,6 +1779,8 @@ New deprecations
17571779

17581780
.. include:: ../deprecations/pending-removal-in-future.rst
17591781

1782+
.. include:: ../deprecations/soft-deprecations.rst
1783+
17601784

17611785
C API changes
17621786
=============
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
:term:`Soft deprecate <soft deprecated>` :func:`re.match` and
2+
:meth:`re.Pattern.match` in favour of :func:`re.prefixmatch` and
3+
:meth:`re.Pattern.prefixmatch`. Patch by Hugo van Kemenade.

0 commit comments

Comments
 (0)