/changelogs/python/python-3-14-to-3-15
Python 3.14 to 3.15: what changes and what breaks
- tool
- Python
- versions
- 3.14 → 3.15
Python 3.15.0 was released on 2026-10-09. The upgrade from 3.14 is mostly smooth, but five changes can alter the behaviour of existing code: UTF-8 as the default encoding, keyword-only sqlite3.connect() arguments, a new argparse dest rule, optional padding in base64.urlsafe_b64decode(), and a round of removals.
Breaking or behaviour-changing
UTF-8 is the default encoding (PEP 686)
open('file.txt') and other I/O without an encoding argument now use UTF-8 on every platform, regardless of the system locale. On Windows systems that used a legacy code page this changes how files are read and written.
- Always pass
encoding=explicitly for code that must run on several Python versions. encoding="locale"keeps the locale encoding (available since 3.10).- To restore the old behaviour globally:
PYTHONUTF8=0orpython -X utf8=0.
sqlite3
All parameters of sqlite3.connect() except database are keyword-only: sqlite3.connect("app.db", 5.0) must become sqlite3.connect("app.db", timeout=5.0). The first three parameters of create_function() and create_aggregate() are positional-only.
argparse
With both a short option and a single-dash long option, dest now comes from the long one: add_argument('-f', '-foo') stores into args.foo, not args.f. Pass dest= explicitly to keep the old name.
base64
base64.urlsafe_b64decode() accepts unpadded input. Pass padded=True to require padding.
unittest
assertWarns() and assertWarnsRegex() no longer swallow warnings of other categories, so test runs may show warnings that were previously hidden.
Removed
| Removed | Use instead |
|---|---|
| sre_compile, sre_constants, sre_parse | re |
| http.server CGIHTTPRequestHandler and --cgi | a WSGI or ASGI server |
| Loader.load_module() (no longer called) | exec_module() |
| glob.glob0(), glob.glob1() | glob.glob() with root_dir |
| pathlib.PurePath.is_reserved() | os.path.isreserved() |
| platform.java_ver() | — |
| types.CodeType.co_lnotab | co_lines() |
| typing.no_type_check_decorator | — |
| NamedTuple("P", x=int) keyword syntax | class syntax or NamedTuple("P", [("x", int)]) |
datetime.strptime() now raises ValueError for a format with %d but no year directive, and AST node constructors raise TypeError for missing required or unknown keyword arguments. Both were deprecated since 3.13.
New features worth adopting
- Lazy imports (PEP 810):
lazy import jsondefers loading until the name is first used. frozendictbuilt-in (PEP 814): immutable, hashable when its contents are.sentinelbuilt-in (PEP 661) and unpacking in comprehensions (PEP 798).- Profiling package (PEP 799) with the Tachyon sampling profiler.
- Free-threaded builds get a stable ABI (PEP 803); the official macOS installer installs free-threading support by default.