Python 3.8 will/has reached it’s end of life 1 month ago. Soon, you will be forced to upgrade as tools and libraries gradually start removing it’s support. If you have the option to upgrade to the latest Python version, take it. But especially library maintainers don’t have that luxury and still have to keep 3.9 support around. It’s been a while since all the „What’s new in Python 3.9″ articles came out. So here’s a farewell of what’s going away and hello to what can you start using instead.
Before we go into the details of what’s changing, I would recommend trying a tool called pyupgrade
first to see what Python 3.9+ changes can be done for you automatically.
typing
Generic (PEP 585)
While typing generics such as list[...]
and dict[..., ...]
have been possible since Python 3.7 thanks to from __future__ import annotations
, there might be still places in the code base that use the old typing.List
/ typing.Dic
t generics. After Python 3.8, these can officially go. What can be replaced?
typing.Tuple
->tuple
typing.List
->list
typing.Dict
->dict
typing.Set
->set
typing.FrozenSet
->frozenset
typing.Type
->type
typing.ContextManager
->contextlib.AbstractContextManager
typing.AsyncContextManager
->contextlib.AbstractAsyncContextManager
typing.Pattern
->re.Pattern
typing.Match
->re.Match
There are also other generics that are completely new.
Operator for merging dicts (PEP 884)
{**d1, **d2}
-> d1 | d2
d1.update(d2)
-> d1 |= d2
New String Methods to Remove Prefixes and Suffixes (PEP 616)
You may have various local or back-ported implementations that can now be replaced with built-in ones:
removeprefix(string, prefix)
-> string.removeprefix(prefix)
removesuffix(string, prefix)
-> string.removesuffix(prefix)
IANA Time Zone Database in the Standard Library (PEP 615)
Time zone data has been previously available via a third-party library dateutil.tz
. It is backed by the system time zone data. If it’s missing, tzdata
installation is required.
dateutil.tz.gettz
-> zoneinfo.ZoneInfo
Example use:
from datetime import datetime from zoneinfo import ZoneInfo print(datetime.now(ZoneInfo("Europe/Prague")))
from datetime import datetime from dateutil.tz import gettz print(datetime.now(gettz("Europe/Prague")))
Flexible function and variable annotations (PEP 593)
If you’re a use of the FastAPI web framework, you are likely used to the Annotated
keyword already for specifying query parameters, validation, etc. Unless you are upgrading the version of FastAPI as well, only the import location changes for you:
from typing_extensions import Annotated
-> from typing import Annotated
typing.Annotated
doesn’t add any functionality on its own but rather allows type checkers and other tools to be smarter. You will find examples suggesting it as a way to provide more details about the type. But for such purpose, typing.TypeAlias
or typing.NewType
would be more suitable.
from typing import Annotated Kilometers = Annotated[float, "kilometers"] Seconds = Annotated[float, "seconds"] KilometersPerHour = Annotated[float, "kilometers per hour"] def speed(distance: Kilometers, time: Seconds) -> KilometersPerHour: ...
from typing import TypeAlias Kilometers: TypeAlias = float Seconds: TypeAlias = float KilometersPerHour: TypeAlias = float def speed(distance: Kilometers, time: Seconds) -> KilometersPerHour: ...
from typing import NewType Kilometers = NewType("Kilometers", float) Seconds = NewType("Seconds", float) KilometersPerHour = NewType("KilometersPerHour", float) def speed(distance: Kilometers, time: Seconds) -> KilometersPerHour: ...
Leave a Reply