Free Python reference · JavaScript timeline

Python 3.13: New defaults, record updates, and interpreter options

Type parameters can have defaults, copy.replace() updates supported records, and CPython experiments with execution models.

Released · Editorial review October 25, 2026

Introduced in Python 3.13 · Typing

Default values for type parameters

A generic type parameter can specify a default type, such as T = str. A type checker can use that default when a type argument is omitted and cannot otherwise be inferred. This is different from a default runtime function argument.

The default is useful for APIs whose common case is one type but which still permit an explicit alternative. Python exposes the parameter metadata for introspection; the example reads the declared default without relying on a particular static checker.

Runtime construction and validation are still separate. Instantiating a generic class does not recursively inspect its contents or fill missing object fields.

Worked example

Minimum Python 3.13

class Box[T = str]:
    pass

parameter = Box.__type_params__[0]
print(parameter.__default__ is str)

Expected output

True

Example checked with CPython 3.14.8, CPython 3.15.0, Pyodide Python 3.13.2.

Common mistake

A type-parameter default does not supply an instance attribute or a function argument. Checker inference behavior must be tested with the checker used by the project.

Try it yourself

Change the default to int and predict the metadata check. Describe a real API where string is a sensible default type.

Read more: Python 3.13 release notes · PEP 696

Introduced in Python 3.13 · Standard library

copy.replace() updates supported records

copy.replace() creates a new object with selected fields changed. It supports dataclass instances, named tuples, and types implementing the replacement protocol. This gives those records a common update operation.

A replacement preserves the original record and carries unchanged field values into the result. It is shallow: mutable objects stored in unchanged fields can still be shared between the two records.

The example uses a frozen dataclass. Direct assignment would be rejected, while replacement creates a new valid record. Unsupported object types are not automatically converted into records.

Worked example

Minimum Python 3.13

from dataclasses import dataclass
from copy import replace

@dataclass(frozen=True)
class Job:
    name: str
    attempts: int

original = Job("report", 0)
retried = replace(original, attempts=1)
print(original.attempts, retried.attempts)

Expected output

0 1

Example checked with CPython 3.14.8, CPython 3.15.0, Pyodide Python 3.13.2.

Common mistake

copy.replace is not a deep-copy operation and does not work for arbitrary dictionaries. Validate any field constraints in the record design.

Try it yourself

Add a list-valued field and investigate whether the old and new records share it. Why does frozen=True not freeze that list?

Read more: Python 3.13 release notes

Introduced in Python 3.13 · Interpreter capability

A more capable interactive shell

The default CPython interactive shell gains features such as multiline editing and more useful history interaction. These help while exploring an expression or repairing an indented block, especially when learning at a terminal.

Shell editing features are separate from Python language syntax. Your IDE, notebook, operating system, terminal, or a basic-shell fallback may provide a different interface. StringClass code examples show source code without interactive prompt markers so they can be saved as scripts.

The fragment below is an illustration of a REPL conversation. Type only the Python expression after >>>; the next line is the result displayed by the shell.

Illustrative fragment

Minimum Python 3.13 · Run locally

>>> sum([2, 3, 4])
9

Displayed result

9

Illustrative interactive transcript. Editing, history, and color depend on the terminal; this fragment is not executed as a script.

Common mistake

Do not paste >>> into a .py file. A browser editor does not inherit native terminal editing shortcuts.

Try it yourself

Open a native Python 3.13 or newer shell and edit a multiline function. Compare that experience with running a saved script.

Read more: Python 3.13 release notes

Introduced in Python 3.13 · Interpreter capability

Experimental free-threading and JIT

CPython 3.13 introduces an experimental free-threaded build and an experimental just-in-time compiler. They are different mechanisms: free-threading changes GIL behavior, while a JIT changes how some code is executed.

Neither is promised simply because a program runs on Python 3.13. The build, configuration, workload, and extension compatibility matter. A free-threaded environment does not remove the need to coordinate shared mutable state.

The example checks whether a GIL-query function is available and prints a stable explanation rather than asserting a performance result. Benchmarks need representative work and controlled conditions; a timing from one machine is not a universal speedup.

Worked example

Minimum Python 3.13 · Run locally

import sys

probe = getattr(sys, "_is_gil_enabled", None)
if probe is not None:
    print("GIL state can be inspected on this interpreter")
else:
    print("GIL state probe unavailable")

Expected output

GIL state can be inspected on this interpreter

Expected output is for the tested CPython build. Actual GIL/JIT availability and performance are build-dependent; no free-threaded or JIT benchmark is claimed.

Example checked with CPython 3.14.8, CPython 3.15.0.

Common mistake

Do not interpret the presence of an inspection function as proof that the GIL is disabled or a JIT is enabled.

Try it yourself

Inspect your interpreter build information. Which separate evidence would you need before claiming a threaded workload runs in parallel?

Read more: Python 3.13 release notes · PEP 703

Recap

Type parameters can have defaults, copy.replace() updates supported records, and CPython experiments with execution models. Prefer the clearest form that works on your project's supported Python versions.

Read the full Python 3.13 release notes →