Stable Release
3.9
Released 31 Oct 2025
(7 months ago)
SoftwarePython
Version3.9
Status
End of life
Initial release3.9
31 Oct 2025
(7 months ago)
Latest release3.9
31 Oct 2025
(7 months ago)
End of life05 Oct 2025
(Ended 8 months ago)
Source codehttps://github.com/python/cpython/tree/3.9
Documentationhttps://docs.python.org/release/3.9/
Downloadhttps://www.python.org/downloads/release/python-390/
Python 3.9 ReleasesView full list

What Is New in Python 3.9

Python 3.9 shipped on October 5, 2020. The headline additions are dictionary merge operators, built-in generic types for type hints, two new string methods, a brand-new PEG parser, and the zoneinfo module for IANA timezone support -- all without any third-party dependencies.

Category Change PEP / Reference
New Features Dictionary merge (|) and update (|=) operators PEP 584
New Features Built-in collections as generic types in type hints (list[str], dict[str, int]) PEP 585
New Features str.removeprefix() and str.removesuffix() PEP 616
New Features Relaxed decorator grammar -- any valid expression allowed PEP 614
New Modules zoneinfo -- IANA timezone database support PEP 615
New Modules graphlib -- topological sort for graphs --
Interpreter New PEG-based parser replaces the old LL(1) parser PEP 617
Performance Vectorcall applied to range, tuple, set, frozenset, list, dict PEP 590
Performance GC no longer blocks on resurrected objects --
Standard Library os.pidfd_open() for race-free process management PEP 573
Standard Library Flexible function/variable annotations via Annotated PEP 593
Deprecated Many stdlib modules deprecated in favor of modern alternatives (e.g., distutils) --
Platform First version to default to 64-bit installer on Windows; dropped Windows 7 support --

What Are the New Language Features in Python 3.9?

Dictionary Merge and Update Operators (PEP 584)

The | operator merges two dicts into a new one, and |= updates a dict in place. Before 3.9, the cleanest way to merge was {**a, **b}, which is less readable and harder to chain.

defaults = {"color": "blue", "size": "M"}
overrides = {"size": "L", "weight": "heavy"}

merged = defaults | overrides
# {"color": "blue", "size": "L", "weight": "heavy"}

defaults |= overrides  # in-place update

In practice, this is most useful in config-layering patterns -- think environment overrides on top of defaults without a helper function.

Built-in Generic Types for Type Hints (PEP 585)

You can now annotate directly with list[str], dict[str, int], tuple[int, ...], and so on -- no more importing List, Dict, Tuple from typing. This works at runtime too, not just in type checkers.

# Before 3.9
from typing import List, Dict
def process(items: List[str]) -> Dict[str, int]: ...

# Python 3.9+
def process(items: list[str]) -> dict[str, int]: ...

New String Methods: removeprefix and removesuffix (PEP 616)

Two long-requested convenience methods land in 3.9. Both return a new string -- they never raise, and if the prefix/suffix doesn't match, the original string is returned unchanged.

"TestHook".removeprefix("Test")   # "Hook"
"MiscTests".removesuffix("Tests") # "Misc"
"Misfile".removesuffix("Tests")   # "Misfile" -- no change

This replaces the fragile s[len(prefix):] pattern and the incorrect s.lstrip(prefix) pattern that strips characters, not substrings.

Relaxed Decorator Grammar (PEP 614)

Decorator expressions are no longer restricted to dotted names and simple calls. Any valid Python expression is now accepted. This unlocks patterns like @buttons[0].clicked.connect in GUI code and computed decorators in meta-programming frameworks.

What New Standard Library Modules Shipped in Python 3.9?

zoneinfo -- IANA Timezone Support (PEP 615)

The zoneinfo module adds first-class support for the IANA time zone database, the same database used by your OS. Before this, timezone-aware datetime work required pytz or dateutil.

from zoneinfo import ZoneInfo
from datetime import datetime

dt = datetime(2024, 6, 1, 12, 0, tzinfo=ZoneInfo("America/New_York"))
print(dt)  # 2024-06-01 12:00:00-04:00

On systems without the system timezone data, install the tzdata package from PyPI as a fallback.

graphlib -- Topological Sorting

The new graphlib.TopologicalSorter handles dependency ordering for DAGs. It supports both static pre-computation and incremental node-by-node processing, which is useful for build systems and task schedulers.

from graphlib import TopologicalSorter

graph = {"D": {"B", "C"}, "C": {"A"}, "B": {"A"}}
ts = TopologicalSorter(graph)
print(list(ts.static_order()))  # ['A', 'C', 'B', 'D']

CPython Internals: The New PEG Parser (PEP 617)

CPython replaced its LL(1) parser with a PEG (Parsing Expression Grammar) parser. This change is invisible to application code but significant for CPython maintainers -- PEG grammars are unambiguous by construction and far easier to extend without grammar hacks.

The old parser had known limitations that forced workarounds in CPython's grammar. The PEG parser unlocks cleaner syntax additions in future releases (structural pattern matching in 3.10 was one early beneficiary). You can revert to the old parser with -X oldparser in 3.9, but that flag was removed in 3.10.

Performance Improvements and Optimizations

  • Many built-in types (range, tuple, set, frozenset, list, dict) now use the vectorcall protocol, cutting call overhead for hot paths.
  • Garbage collection no longer blocks on objects that are resurrected (i.e., acquired a new reference inside __del__).
  • Several C extension modules migrated to multiphase initialization (PEP 489) and stable ABI (PEP 384), improving embedding compatibility.
  • os.path.join() and os.path.normpath() are faster on common cases.
  • str() for subclasses is faster when __str__ is not overridden.

Deprecations and Removals in Python 3.9

  • Deprecated aliases in typing for built-in generic types (typing.List, typing.Dict, etc.) -- they will be removed in a future version.
  • The distutils package is deprecated and scheduled for removal in 3.12.
  • The old LL(1) parser is deprecated (and will be removed in 3.10).
  • Several modules deprecated: aifc, audioop, cgi, crypt, imghdr, mailcap, msilib, nis, nntplib, ossaudiodev, pipes, sndhdr, spwd, sunau, telnetlib, uu, xdrlib.

FAQ

Can I use list[str] and dict[str, int] at runtime in Python 3.9, or only in type checkers?
Both. PEP 585 made built-in collection types real generic aliases at runtime, so list[str] evaluates to a types.GenericAlias object and works in isinstance()-like checks via __class_getitem__. No import from typing needed.

Is the new PEG parser backward compatible with existing Python code?
Yes. The parser change is entirely internal -- existing syntax is parsed identically. The only observable difference is error messages, which are sometimes more precise. The -X oldparser flag exists in 3.9 as an escape hatch but was removed in 3.10.

What is the difference between zoneinfo and pytz?
zoneinfo uses IANA timezone names directly and loads zone data from the OS (or the tzdata package). Unlike pytz, it does not require calling localize() -- you pass the ZoneInfo object directly to tzinfo. DST transitions are handled correctly without the workaround pattern that pytz requires.

Does the dict merge operator | work with dict subclasses?
It depends on the subclass. The left operand's type determines the result type. If you merge a defaultdict | dict, you get a defaultdict. If a custom subclass does not override __or__, Python falls back to the base dict implementation and you may lose subclass-specific behavior.

When should I use removesuffix instead of a manual slice?
Always prefer removesuffix -- the manual slice s[:-len(suffix)] breaks when suffix is an empty string (it removes everything). removesuffix("") returns the original string unchanged, which is the correct and expected behavior.

Releases In Branch 3.9

VersionRelease date
3.931 Oct 2025
(7 months ago)
3.9.2531 Oct 2025
(7 months ago)
3.9.2409 Oct 2025
(8 months ago)
3.9.2303 Jun 2025
(1 year ago)
3.9.2208 Apr 2025
(1 year ago)
3.9.2103 Dec 2024
(1 year ago)
3.9.2006 Sep 2024
(1 year ago)
3.9.1919 Mar 2024
(2 years ago)
3.9.1824 Aug 2023
(2 years ago)
3.9.1706 Jun 2023
(3 years ago)
3.9.1606 Dec 2022
(3 years ago)
3.9.1511 Oct 2022
(3 years ago)
3.9.1406 Sep 2022
(3 years ago)
3.9.1317 May 2022
(4 years ago)
3.9.1223 Mar 2022
(4 years ago)
3.9.1116 Mar 2022
(4 years ago)
3.9.1013 Jan 2022
(4 years ago)
3.9.915 Nov 2021
(4 years ago)
3.9.805 Nov 2021
(4 years ago)
3.9.730 Aug 2021
(4 years ago)
3.9.628 Jun 2021
(4 years ago)
3.9.503 May 2021
(5 years ago)
3.9.404 Apr 2021
(5 years ago)
3.9.302 Apr 2021
(5 years ago)
3.9.219 Feb 2021
(5 years ago)
3.9.2rc116 Feb 2021
(5 years ago)
3.9.107 Dec 2020
(5 years ago)
3.9.1rc124 Nov 2020
(5 years ago)
3.9.005 Oct 2020
(5 years ago)
3.9.0rc216 Sep 2020
(5 years ago)
3.9.0rc111 Aug 2020
(5 years ago)
3.9.0b520 Jul 2020
(5 years ago)
3.9.0b402 Jul 2020
(5 years ago)
3.9.0b309 Jun 2020
(6 years ago)
3.9.0b208 Jun 2020
(6 years ago)
3.9.0b118 May 2020
(6 years ago)
3.9.0a627 Apr 2020
(6 years ago)
3.9.0a523 Mar 2020
(6 years ago)
3.9.0a425 Feb 2020
(6 years ago)
3.9.0a324 Jan 2020
(6 years ago)
3.9.0a218 Dec 2019
(6 years ago)
3.9.0a119 Nov 2019
(6 years ago)