How to properly function annotate / type hint a list of strings
Question:
I am trying to figure out how to properly function annotate or type hint a list of strings. For example, if I had a function like this:
def send_email(self, from_address: str, to_addresses: list[str]):
pass
to_addresses
should be a list of strings. But when I try to use that annotation I get the following error in my Python 3.4.3 interpreter:
TypeError: 'type' object is not subscriptable
I am positive the list[str]
is causing the issue, because if I change it to str
the error goes away, but that doesn’t properly reflect my intentions for the parameter.
Answers:
Python 3.4 doesn’t specify a format for its function annotations, it merely provides a mechanism that allows you to use any expression as the annotation. How the annotations are interpreted is up to you and the libraries you use.
Python 3.5 standardizes the way function annotations are used for type hinting, as documented in PEP 484. To annotate a list of strings, you use List[str]
, where List
is imported from the typing
module. You can also use Sequence[str]
if your function accepts any list-like sequence, or Iterable[str]
for any iterable.
Starting with Python 3.9, you can use list[str]
as a type annotation, which doesn’t require importing anything.
In Python 3.9+, list
(with a lowercase l
) can be used in type annotations and your code should work as is. On older versions of Python you need to import typing.List
and use it instead
from typing import List
to_addresses: List[str]
Note the capital L
.
You might want to consider something more specific, e.g.
import typing
Address = typing.NewType("Address")
See NewType docs
The static type checker will treat the new type as if it were a subclass of the original type
This syntax is now valid in Python 3.9+:
In type annotations you can now use built-in collection types such as list
and dict
as generic types instead of importing the corresponding capitalized types (e.g. List
or Dict
) from typing
.
Prior to 3.9 though, you need to use the imported List
or in Python 3.7+ you can add
from __future__ import annotations
at the top of your file, which allows using list[int]
(for example). Note though, this import only affects annotations:
from __future__ import annotations
only affects annotations — just the things after the colon. It makes it so that annotations are never evaluated
It still doesn’t allow list[int]
in arbitrary contexts.
I am trying to figure out how to properly function annotate or type hint a list of strings. For example, if I had a function like this:
def send_email(self, from_address: str, to_addresses: list[str]):
pass
to_addresses
should be a list of strings. But when I try to use that annotation I get the following error in my Python 3.4.3 interpreter:
TypeError: 'type' object is not subscriptable
I am positive the list[str]
is causing the issue, because if I change it to str
the error goes away, but that doesn’t properly reflect my intentions for the parameter.
Python 3.4 doesn’t specify a format for its function annotations, it merely provides a mechanism that allows you to use any expression as the annotation. How the annotations are interpreted is up to you and the libraries you use.
Python 3.5 standardizes the way function annotations are used for type hinting, as documented in PEP 484. To annotate a list of strings, you use List[str]
, where List
is imported from the typing
module. You can also use Sequence[str]
if your function accepts any list-like sequence, or Iterable[str]
for any iterable.
Starting with Python 3.9, you can use list[str]
as a type annotation, which doesn’t require importing anything.
In Python 3.9+, list
(with a lowercase l
) can be used in type annotations and your code should work as is. On older versions of Python you need to import typing.List
and use it instead
from typing import List
to_addresses: List[str]
Note the capital L
.
You might want to consider something more specific, e.g.
import typing
Address = typing.NewType("Address")
See NewType docs
The static type checker will treat the new type as if it were a subclass of the original type
This syntax is now valid in Python 3.9+:
In type annotations you can now use built-in collection types such as
list
anddict
as generic types instead of importing the corresponding capitalized types (e.g.List
orDict
) fromtyping
.
Prior to 3.9 though, you need to use the imported List
or in Python 3.7+ you can add
from __future__ import annotations
at the top of your file, which allows using list[int]
(for example). Note though, this import only affects annotations:
from __future__ import annotations
only affects annotations — just the things after the colon. It makes it so that annotations are never evaluated
It still doesn’t allow list[int]
in arbitrary contexts.