Python Knowledge Patch
Baseline: Python through 3.12. Covered range: Python 3.13 and 3.14, plus the Python 3.15.0b3 preview.
Included batches: whatsnew-3.13, 3.13.0, whatsnew-3.14, 3.14.0, whatsnew-3.15, and 3.15.0b3.
Use the quick reference for migration-sensitive decisions, then open the topic reference that matches the code being changed. Treat every Python 3.15 item as preview behavior and gate it by the actual runtime version.
Reference index
| Reference | Topics | | --- | --- | | Language and runtime | Syntax and execution, built-ins, object model, text and numeric behavior, garbage collection, removals | | Typing and introspection | Deferred annotations, typing, ASTs, frames and locals, signatures, symbols, runtime metadata | | Concurrency and asyncio | Asyncio, threads and queues, multiprocessing, executors, subinterpreters, free-threading | | Data, I/O, and serialization | Configuration, SQLite and dbm, serialization, compression, archives, streams, codecs, TOML and JSON | | Networking and security | TLS, HTTP, URLs, email, sockets, protocol validation, parser hardening | | Filesystems, OS, and platforms | pathlib, OS APIs, mmap, resources, virtual environments, locale, platform behavior | | Tooling, debugging, and testing | REPL, pdb, profiling, monitoring, CLI parsing, logging, tests, imports and packaging | | C API and extensions | Compatibility, references and errors, types and modules, free-threading, Stable/Limited APIs, embedding | | Build and distribution | Build prerequisites, configure controls, JIT, cross-builds, platform targets, artifacts |
Compatibility first
Runtime and language changes
- In optimized scopes, each
locals()call returns an independent snapshot.frame.f_localsis instead a write-through proxy; copy it when a stable dictionary is needed. - An implicit
exec()oreval()namespace no longer makes newly assigned optimized locals observable afterward. Pass explicit globals and locals when retrieving results. - AST constructors currently warn for missing required fields or unknown keyword fields and make them errors in 3.15. Python 3.14 removes the old constant-node aliases; use
ast.Constant.valueandvisit_Constant(). - Python 3.14 makes annotations lazy. Annotation readers should use
annotationlibinstead of assuming values are eagerly present in__annotations__or a class namespace. int()no longer falls back to__trunc__(), and Boolean evaluation ofNotImplementedraisesTypeErrorin 3.14.return,break, orcontinuethat exits afinallyblock emits a compile-timeSyntaxWarningin 3.14.- The default pickle protocol is 5 in 3.14. Choose an older protocol explicitly when older readers must consume the data.
- Python 3.14.0–3.14.4 used the incremental garbage collector; 3.14.5 and later reverted to the 3.13 generational collector. Do not infer collector behavior from the minor version alone.
functools.partialused directly as a class attribute warns in 3.13; wrap it instaticmethod()to retain non-binding behavior.- Regular-expression
maxsplit,count, andflagsparameters are becoming keyword-only. Name them now.
namespace = {}
exec("answer = 42", globals(), namespace)
answer = namespace["answer"]
parts = re.split(pattern, text, maxsplit=1, flags=re.ASCII)
Asyncio and process behavior
asyncio.get_event_loop()raisesRuntimeErrorwhen no current loop exists in 3.14. Useasyncio.run(),get_running_loop(), orasyncio.Runneras appropriate.- Event-loop policy APIs are deprecated for removal in 3.16. Select an implementation with
loop_factoryonasyncio.run()orRunner. - Task creation APIs pass arbitrary keyword arguments to the task constructor or task factory in 3.14. Custom factories must accept
name,context, and future keywords. - On Unix other than macOS, multiprocessing and
ProcessPoolExecutordefault toforkserverin 3.14, notfork. Explicitly request a context if inherited globals are required. queue.Queueandasyncio.Queuehave explicitshutdown()methods and raiseShutDownorQueueShutDownat termination.Server.wait_closed()now waits for closure and all active connections. A Unix server removes its socket when it closes.- Third-party asyncio task implementations must implement
Task.set_name();_set_task_name()is removed.
tasks = [asyncio.create_task(fetch(url)) for url in urls]
async for task in asyncio.as_completed(tasks):
# Async iteration preserves supplied task/future identity.
result = await task
Standard-library migrations
dbmnow selects the SQLite backend by default. Select a backend explicitly when file format or implementation stability matters.ssl.create_default_context()enablesVERIFY_X509_PARTIAL_CHAINandVERIFY_X509_STRICT; previously accepted malformed certificates can fail verification.Path.glob()andrglob()patterns ending in**return files and directories. Add a trailing slash for directories only, and userecurse_symlinksdeliberately.- On Windows, a path beginning with exactly one slash or backslash is no longer absolute. Mode
0o700now applies access control inmkdir()andmakedirs(). Path.exists()and thePath.is_*()predicates suppress everyOSErrorin 3.14. Usestat()when the failure must be visible.- Passing filesystem paths to
mimetypes.guess_type()is soft-deprecated; useguess_file_type(). - Email address parsing is strict by default, generated headers are verified, and invalid field names raise
ValueError. - Unclosed
sqlite3.Connection,NamedTemporaryFile, andGzipFileobjects can emitResourceWarning. Use explicit closure, not only transaction context management. gzip.compress()defaults tomtime=0in 3.14 for reproducibility. Passmtime=Noneto record the current time.ZipFile.writestr()respectsSOURCE_DATE_EPOCH; Python 3.15 preview lowers gzip and gzip-tar default compression from 9 to 6.- SQLite named placeholders require a mapping in 3.14; supplying a sequence raises
ProgrammingError. Several connect parameters become keyword-only in 3.15. urllib.parse.parse_qs()andparse_qsl()deprecate unsupported false values such as0and[]; bytes handling and lossless component options also changed.argparse.ArgumentParser.suggest_on_errordefaults to true in the 3.15 preview, and inferred destinations for overlapping short/long forms can change.- Python 3.15 removes CGI support from
http.server, legacysre_*modules,PurePath.is_reserved(),code.co_lnotab,zipimporter.load_module(), and several other deprecated APIs. Review both removal sections before targeting it.
C extensions and embedding
- Free-threaded 3.13 uses
python3.13tor--disable-gil. Extensions declare support withPy_mod_gilorPyUnstable_Module_SetGIL(); undeclared extensions normally re-enable the GIL. - Python 3.14 supports free-threaded builds officially but optionally. Windows backends targeting them must define
Py_GIL_DISABLEDthemselves. - Python 3.15 preview adds the
abi3tStable ABI. Use opaque per-type storage and the new module export/slot machinery; publish a separatecp315tbuild for APIs outsideabi3t. PyDict_Next()does not lock in free-threaded builds. Hold one critical section around the whole iteration.PyModule_Add()always steals the supplied reference, including on failure.Python.hno longer supplies several system headers transitively. Include every declaration's owning header directly.PY_SSIZE_T_CLEANis obsolete, and removed trashcan macros must becomePy_TRASHCAN_BEGIN(object, deallocator)/Py_TRASHCAN_END.- Removed buffer, call, and initialization entry points must migrate to
PyObject_GetBuffer()plusPyBuffer_Release(),PyObject_Call*(), andPyConfiginitialization. - Borrowed operand-stack references make refcount-based uniqueness checks unsafe. Use the appropriate
PyUnstable_Object_Is*Referenced()API. Py_Finalize()deletes interned strings in 3.14. Embedders that reinitialize must release extension-held interned references during shutdown.- In the 3.15 preview, finalization-safe interpreter guards and attach/detach APIs replace check-then-attach patterns; the
PyGILStatefamily is soft-deprecated.
High-value features
Deferred annotations and runtime typing
Python 3.14 evaluates function, class, and module annotations lazily. Choose the representation required by the consumer:
from annotationlib import Format, get_annotations
def parse(value: Missing): ...
hints = get_annotations(parse, format=Format.FORWARDREF)
Format.VALUEevaluates values and can raise for missing names.Format.FORWARDREFpreserves unresolved names asForwardRefobjects.Format.STRINGreturns source-like strings.inspect.signature()acceptsannotation_format.types.UnionTypeandtyping.Unionare aliases in 3.14; compare unions by equality or useget_origin()/get_args(), not identity.- The 3.15 preview adds
TypeForm, closed or extensibleTypedDict, richerTypeVarTuple, and more metadata on type aliases.
T-strings and structured interpolation
A t-prefixed literal creates string.templatelib.Template, retaining static strings and interpolation objects for safe DSL-specific rendering:
name = "Ada"
template = t"Hello {name}"
for part in template:
process(part)
Templates do not concatenate with str, and t-string literals do not implicitly concatenate with string or f-string literals in 3.15.0b3.
Free-threading and subinterpreters
- Query free-threaded runtime state with
sys._is_gil_enabled()and control it withPYTHON_GILor-X gilwhere supported. concurrent.interpretersexposes isolated interpreters in 3.14, whileInterpreterPoolExecutorprovides a true-multicore executor inside one process.- Sharing between interpreters is opt-in and limited. Gate portable use with
sys.implementation.supports_isolated_interpretersin 3.15.0b3. -X context_aware_warningsandsys.flags.thread_inherit_contextdefault on for free-threaded builds and off for GIL-enabled builds.- Use object critical sections,
PyMutex, and the documented iterator synchronization APIs rather than assuming the GIL serializes access.
Asyncio lifecycle and observability
- Asynchronous iteration over
asyncio.as_completed()can yield the original task or future objects. Executor.map(buffersize=n)applies submission backpressure; process pools can terminate or kill all workers explicitly.multiprocessing.Process.interrupt()sendsSIGINT, allowing normalKeyboardInterruptandfinallycleanup.python -m asyncio ps PIDandpstree PIDinspect remote task graphs; in-process code can usecapture_call_graph()andprint_call_graph().await pdb.set_trace_async()supportsawaitwhile debugging a coroutine.- The 3.15 preview adds
TaskGroup.cancel()for direct group cancellation.
Data, archives, and I/O
compression.zstdand the preferredcompression.{gzip,bz2,lzma,zlib}namespace arrive in 3.14; tar, ZIP, and shutil understand Zstandard archives.marshalformat 5 serializes slices;allow_code=Falseblocks code-object serialization and deserialization.mmap(..., trackfd=False)avoids retaining a duplicate descriptor on Unix and, in the 3.15 preview, on Windows.Path.infocaches type/stat information, including details obtained duringiterdir().tomllib.TOMLDecodeErrorexposes structured location fields in 3.14; the 3.15 preview accepts TOML 1.1.- The 3.15 preview adds
json'sarray_hook, shelf serializer hooks,bytearray.take_bytes(), and stricter/canonical base-encoding controls.
Debugging and profiling
breakpoint()andpdb.set_trace()stop at the call site in 3.13. Pdb can execute statements against current-frame locals and attach remotely in 3.14.- Remote execution and attach can be disabled with
PYTHON_DISABLE_REMOTE_DEBUG,-X disable-remote-debug, or--without-remote-debug. - The 3.15 preview introduces
profiling.tracingandprofiling.sampling;cProfileremains an alias, while pure-Pythonprofileis deprecated. - Sampling supports PID attach, scripts/modules, wall/CPU/GIL/exception modes, flame graphs, pstats, heatmaps, live TUI, async-aware views, and compact replayable captures.
sys.monitoringgains directional branch events in 3.14 and per-code exception-event control in 3.15.
Python 3.15 preview features
Explicit lazy imports defer loading until first use and report failures at that point:
lazy import json
lazy from pathlib import Path
data = json.loads('{"answer": 42}')
- Lazy declarations are module-scope only and exclude functions, classes,
try, star imports, and future imports. -X lazy_imports=allorPYTHON_LAZY_IMPORTS=allchanges the default; inspect and control it throughsys.get_lazy_imports(),set_lazy_imports(), and filters.frozendictis immutable, insertion-ordered, and conditionally hashable; test generic mappings withcollections.abc.Mapping.sentinel()creates identity-stable marker values that survive copying and can be pickleable when importable by name.- Comprehensions and generator expressions accept
*and**unpacking. map(..., strict=True)is a 3.14 feature; the preview additionally supplies synchronized/concurrent iterator utilities and expands free-threaded iterator guarantees.
Upgrade workflow
- Confirm the exact interpreter and maintenance release; distinguish 3.14.0–3.14.4 from 3.14.5+ for garbage collection and treat 3.15.0b3 as preview-only.
- Search for removals and deprecations first: asyncio policies, implicit event-loop creation, AST aliases, old import-loader APIs, positional regex/SQLite arguments, C API removals, and 3.15 standard-library removals.
- Audit defaults that can silently change output or behavior: multiprocessing start method, pickle protocol, dbm backend, TLS verification flags, gzip timestamps/compression, argparse suggestions, and URL/base64 parsing.
- Review concurrency assumptions for free-threading, context inheritance, task-factory keyword forwarding, queue shutdown, iterator sharing, and native critical sections.
- Update annotation consumers before enabling 3.14, and gate lazy imports, frozendict, sentinels, unpacking comprehensions, and
abi3tbehind 3.15 checks. - Run tests with warnings enabled and
ResourceWarningvisible; exercise filesystem errors, malformed protocol fields, nonblocking streams, serialization compatibility, interpreter shutdown, and extension imports. - Open the indexed topic references for the complete API-level details; the quick reference intentionally prioritizes migration-sensitive changes.