Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Doc/deprecations/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ Deprecations

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

.. include:: soft-deprecations.rst

C API deprecations
------------------

Expand Down
21 changes: 21 additions & 0 deletions Doc/deprecations/soft-deprecations.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
Soft deprecations
-----------------

There are no plans to remove :term:`soft deprecated` APIs.

* :func:`re.match` and :meth:`re.Pattern.match` are now
:term:`soft deprecated` in favor of the new :func:`re.prefixmatch` and
:meth:`re.Pattern.prefixmatch` APIs, which have been added as alternate,
more explicit names. These are intended to be used to alleviate confusion
around what *match* means by following the Zen of Python's *"Explicit is
better than implicit"* mantra. Most other language regular expression
libraries use an API named *match* to mean what Python has always called
*search*.

We **do not** plan to remove the older :func:`!match` name, as it has been
used in code for over 30 years. Code supporting older versions of Python
should continue to use :func:`!match`, while new code should prefer
:func:`!prefixmatch`. See :ref:`prefixmatch-vs-match`.

(Contributed by Gregory P. Smith in :gh:`86519` and
Hugo van Kemenade in :gh:`148100`.)
70 changes: 42 additions & 28 deletions Doc/library/re.rst
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ fine-tuning parameters.

.. _re-syntax:

Regular Expression Syntax
Regular expression syntax
-------------------------

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

.. _contents-of-module-re:

Module Contents
Module contents
---------------

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

def myfunc(text, flag=re.NOFLAG):
return re.search(text, flag)
def myfunc(pattern, text, flag=re.NOFLAG):
return re.search(pattern, text, flag)

.. versionadded:: 3.11

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

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

.. _re-objects:

Regular Expression Objects
Regular expression objects
--------------------------

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

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

.. _match-objects:

Match Objects
Match objects
-------------

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

.. _re-examples:

Regular Expression Examples
Regular expression examples
---------------------------


Checking for a Pair
Checking for a pair
^^^^^^^^^^^^^^^^^^^

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

To extract the filename and numbers from a string like ::
To extract the filename and numbers from a string like:

.. code-block:: text

/usr/sbin/sendmail - 0 errors, 4 warnings

you would use a :c:func:`!scanf` format like ::
you would use a :c:func:`!scanf` format like:

.. code-block:: text

%s - %d errors, %d warnings

The equivalent regular expression would be ::
The equivalent regular expression would be:

.. code-block:: text

(\S+) - (\d+) errors, (\d+) warnings

Expand Down Expand Up @@ -1772,18 +1780,24 @@ not familiar with the Python API's divergence from what otherwise become the
industry norm.

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

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

.. versionadded:: 3.15
:func:`!prefixmatch`

.. deprecated:: 3.15
:func:`!match` is :term:`soft deprecated`

Making a Phonebook
Making a phonebook
^^^^^^^^^^^^^^^^^^

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


Text Munging
Text munging
^^^^^^^^^^^^

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


Finding all Adverbs
Finding all adverbs
^^^^^^^^^^^^^^^^^^^

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


Finding all Adverbs and their Positions
Finding all adverbs and their positions
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

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


Raw String Notation
Raw string notation
^^^^^^^^^^^^^^^^^^^

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


Writing a Tokenizer
Writing a tokenizer
^^^^^^^^^^^^^^^^^^^

A `tokenizer or scanner <https://en.wikipedia.org/wiki/Lexical_analysis>`_
Expand Down
30 changes: 27 additions & 3 deletions Doc/whatsnew/3.15.rst
Original file line number Diff line number Diff line change
Expand Up @@ -922,9 +922,10 @@ pickle
re
--

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

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


* :mod:`re`:

* :func:`re.match` and :meth:`re.Pattern.match` are now
:term:`soft deprecated` in favor of the new :func:`re.prefixmatch` and
:meth:`re.Pattern.prefixmatch` APIs, which have been added as alternate,
more explicit names. These are intended to be used to alleviate confusion
around what *match* means by following the Zen of Python's *"Explicit is
better than implicit"* mantra. Most other language regular expression
libraries use an API named *match* to mean what Python has always called
*search*.

We **do not** plan to remove the older :func:`!match` name, as it has been
used in code for over 30 years. Code supporting older versions of Python
should continue to use :func:`!match`, while new code should prefer
:func:`!prefixmatch`. See :ref:`prefixmatch-vs-match`.

(Contributed by Gregory P. Smith in :gh:`86519` and
Hugo van Kemenade in :gh:`148100`.)


* :mod:`struct`:

* Calling the ``Struct.__new__()`` without required argument now is
Expand Down Expand Up @@ -1696,6 +1718,8 @@ New deprecations

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

.. include:: ../deprecations/soft-deprecations.rst


C API changes
=============
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
:term:`Soft deprecate <soft deprecated>` :func:`re.match` and
:meth:`re.Pattern.match` in favour of :func:`re.prefixmatch` and
:meth:`re.Pattern.prefixmatch`. Patch by Hugo van Kemenade.
Loading