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
- 01ZCode Uploads Users' Full Git History, Zhipu Says It Deletes ItA developer's reverse-engineering forced a same-day apology from Zhipu over a coding assistant that never told users it was packaging their repositories for the cloud.
- 02Alibaba's Open Code Review Tool Ships an IntelliJ PluginVersion 1.12.6 extends the AI code reviewer to JetBrains IDEs the same week Alibaba's own benchmark shows it trading recall for precision against Claude Code.
- 03Flet Reaches 1.0, Ships One Python App to Six PlatformsFeodor Fitsner's framework rebuilt its bridge to Flutter for the stable release, but has not said how many people pay for anything built on top of it.
- 04Bend 2 Bets Formal Proof Can Catch AI's Coding MistakesVictor Taelin's rewritten language backs its safety pitch with a compiler its own README calls 99 percent AI-written and not yet audited.