Python 3.15 Soft-Deprecates re.match Over a Decades-Old Gotcha
Software / explainer
Python 3.15 Soft-Deprecates re.match Over a Decades-Old Gotcha
The function only ever anchored at the start of a string, a behavior most other languages call something else, and Python 3.15 finally gives that behavior an honest name.
What changed, and why re.match confused people for so long
Python 3.15 marks re.match() and Pattern.match() as soft deprecated in favor of a new function, re.prefixmatch(), according to the official Python 3.15 documentation. A soft deprecation carries no warning message and no removal plan: old code keeps working exactly as before, but the documentation now steers new code toward the clearer name. It is the kind of quiet, semantics-only fix that sits next to Python's other 2026 performance surprise, a reminder that the language's oldest corners still turn up behavior few users expect.
The confusion re.match() caused was structural, not cosmetic. It only ever checks for a match at the very start of a string, so re.match("pi", "pie") succeeds while re.match("pi", "api") fails, even though both strings contain "pi." Hugo van Kemenade, the Python core developer and PEP editor who proposed the change, wrote on his blog Sept. 10, 2026, that the norm in other languages and regular-expression implementations is to use the word "match" for what Python has always called search(), unrestricted matching anywhere in the string.
Who proposed it, and how fast it moved
Van Kemenade opened CPython issue #148100 on April 4, 2026, proposing the soft deprecation alongside the new prefixmatch() alias, which a companion pull request, #148101, implemented. Van Kemenade has been a CPython core developer since shortly after joining the triage team in January 2022, was named a Python Software Foundation Fellow in 2023, and is serving as release manager for both Python 3.14 and Python 3.15, the version that ships the change.
| Function | Behavior | Status in Python 3.15 |
|---|---|---|
re.match() | Anchors only at the start of the string | Soft deprecated |
re.prefixmatch() | Anchors only at the start of the string | New, preferred name |
re.search() | Matches anywhere in the string | Unchanged |
re.fullmatch() | Matches the entire string | Unchanged |
A six-year gap between the idea and the fix
The idea itself is not new. Gregory P. Smith, a Python committer, opened a tracker issue proposing a re.prefixmatch() alias on Nov. 13, 2020, writing that the new name "documents the implicit ^" (the regular-expression symbol for start-of-string anchoring) "in the name" so that code calling it is obvious about its own intent, according to the issue page on Python's bug tracker. A pull request implementing that early version, PR 31137, followed in February 2022 but sat without being merged. Van Kemenade's April 2026 issue picked the idea back up under a new tracker number and, this time, paired it with the soft-deprecation of match() itself, which is what finally moved the change from an available-but-ignored alias to the name the documentation now recommends.
That six-year gap between Smith's original proposal and Van Kemenade's shipped version is a fair measure of how conservative CPython's approach to renaming a decades-old, heavily used function actually is: even a change that breaks nothing and only adds a clearer name took two attempts, two issue numbers and two pull requests across three release managers' worth of time to land.
Why the fix is a rename, not a removal
prefixmatch() behaves identically to match(), down to the same start-anchored semantics; the change is entirely about giving that behavior a name that says what it does, per the documentation's own wording: "Use it to better express intent." Code written for older Python versions has to keep calling match(), since prefixmatch() does not exist before 3.15, so the documentation tells maintainers of code that still supports earlier releases to leave match() alone rather than churn their codebase for a name that will not run there.
What the soft deprecation does not do
Because nothing about re.match()'s behavior changes and no runtime warning fires, most Python code that calls it today will keep doing so indefinitely; the documentation-only nature of a soft deprecation means adoption of prefixmatch() depends entirely on new code choosing it and on maintainers of style guides and linters deciding to recommend it, neither of which the CPython issue tracker controls. Van Kemenade's own history of ecosystem-wide fixes, including his practice of checking top PyPI packages for compatibility with each new Python release, suggests the next stage of this change is less about the interpreter and more about whether linters start flagging match() calls the way they already flag other soft-deprecated patterns, a step the 3.15 release itself does not take. Language maintainers making that kind of low-drama, high-friction naming fix are the same instinct behind Microsoft's decision to make Rust a tier-1 language rather than rip out the C++ code around it: fix the sharp edge without breaking what already works.
Sources
More in Software
- 01Polyend Publishes Tracker Firmware Source Under a Noncommercial Licence, With Two Binary Libraries Left OutThe tracker-ce repository covers the original Tracker, Tracker+ and Tracker Mini, but the synth and DSP libraries ship precompiled under a separate proprietary licence.
- 02Claude-Mem's Installer Uploaded 30 Days of Prompts to cmem.ai Before Asking; v15.8.3 Adds a Consent PanelThe fix shipped on Nov. 2, but the release notes say prompts already uploaded by earlier versions are not removed, and the GitHub issue was reopened the same day.
- 03Vercel Labs' Agent-Desktop 1.0 Ships With a macOS Bug That Types Into the Frontmost AppThe Rust tool lets an AI agent drive desktop apps through the accessibility tree, and 48 open issues sit against it three days after the 1.0.2 release.
- 04T3 Code Reaches 38.1k Stars in Alpha, and Its Remote Access Docs Say to Treat Pairing Links as PasswordsThe MIT-licensed control surface for Claude Code, Codex and other agents has nearly doubled its star count since August 27. Its own documentation lists what stays risky.