307

Using Python 3's function annotations, it is possible to specify the type of items contained within a homogeneous list (or other collection) for the purpose of type hinting in PyCharm and other IDEs?

A pseudo-python code example for a list of int:

def my_func(l:list<int>):
    pass

I know it's possible using Docstring...

def my_func(l):
    """
    :type l: list[int]
    """
    pass

... but I prefer the annotation style if it's possible.

Alex Waygood
  • 6,304
  • 3
  • 24
  • 46
Eric W.
  • 7,148
  • 3
  • 20
  • 27
  • Have you tried using the same format in the function annotations? What happened? – jonrsharpe Jul 20 '14 at 19:23
  • 3
    @jonrsharpe It should raise an error because `type object is not subscriptable` when defining the function. Obviously you can use a string: `def my_func(L: 'list[int]')` but I don't know whether PyCharm will parse it as it parses the docstrings... – Bakuriu Jul 20 '14 at 20:16
  • 1
    @Bakuriu yes, I meant `'list[int]'`, apologies if that wasn't clear. – jonrsharpe Jul 20 '14 at 21:45
  • It doesn't appear that PyCharm will parse it like it does docstrings. – Eric W. Jul 20 '14 at 23:44

5 Answers5

306

As of May 2015, PEP0484 (Type Hints) has been formally accepted. The draft implementation is also available at github under ambv/typehinting.

In September 2015, Python 3.5 was released with support for Type Hints and includes a new typing module. This allows for the specification of types contained within collections. As of November 2015, JetBrains PyCharm 5.0 fully supports Python 3.5 to include Type Hints as illustrated below.

PyCharm 5.0 Code Completion using Type Hints

Original Answer

As of Aug 2014, I have confirmed that it is not possible to use Python 3 type annotations to specify types within collections (ex: a list of strings).

The use of formatted docstrings such as reStructuredText or Sphinx are viable alternatives and supported by various IDEs.

It also appears that Guido is mulling over the idea of extending type annotations in the spirit of mypy: http://mail.python.org/pipermail/python-ideas/2014-August/028618.html

mkrieger1
  • 19,194
  • 5
  • 54
  • 65
Eric W.
  • 7,148
  • 3
  • 20
  • 27
  • Update: It appears that type hinting to include support for generic types has made its way to PEP484 https://www.python.org/dev/peps/pep-0484/ – Eric W. Jan 29 '15 at 00:24
  • 3
    FWIW (because i didn't like squinting at blurry text in an image): The key take-away from that image is `l: List[str]`. Upvoted alecxe's answer, as that shows it in plain text. – ToolmakerSteve Dec 20 '21 at 00:58
  • 1
    From an answer below, using `list` is favored instead of `List` since Python3.9 – Dimitri Lesnoff Mar 22 '23 at 15:05
189

Since Python 3.5 has been officially out, there is the Type Hints supporting module - typing and the relevant List "type" for the generic containers.

In other words, now you could do:

from typing import List

def my_func(l: List[int]):
    pass

This is deprecated since Python 3.9, now you can directly use the built-in list instead of typing.List.

mkrieger1
  • 19,194
  • 5
  • 54
  • 65
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
  • 4
    superseded in Python 3.9. See https://stackoverflow.com/questions/24853923/type-hinting-a-collection-of-a-specified-type/62775680#62775680 – wisbucky May 10 '22 at 22:00
  • @wisbucky this entire answer section needs an update. – 9 Guy Jun 07 '22 at 16:26
165

As of Python 3.9, builtin types are generic with respect to type annotations (see PEP 585). This allows to directly specify the type of elements:

def my_func(l: list[int]):
    pass

This also extends to most other container types of the standard library, for example collections.deque or collections.abc.Mapping.


Various tools may support this syntax earlier than Python 3.9. When annotations are not inspected at runtime, the syntax is valid using quoting or __future__.annotations.

# quoted
def my_func(l: 'list[int]'):
    pass
# postponed evaluation of annotation
from __future__ import annotations

def my_func(l: list[int]):
    pass

As a consequence of PEP 585, most helpers in typing corresponding to standard library types are deprecated, such as typing.List, typing.Deque or typing.Mapping. They should only be used if compatibility with Python versions prior to 3.9 is required.

MisterMiyagi
  • 44,374
  • 10
  • 104
  • 119
58

Type comments have been added since PEP 484

from . import Monitor
from typing import List, Set, Tuple, Dict


active_monitors = [] # type: List[Monitor]
# or
active_monitors: List[Monitor] = []

# bonus
active_monitors: Set[Monitor] = set()
monitor_pair: Tuple[Monitor, Monitor] = (Monitor(), Monitor())
monitor_dict: Dict[str, Monitor] = {'codename': Monitor()}

# nested
monitor_pair_list: List[Dict[str, Monitor]] = [{'codename': Monitor()}]

This is currently working for me on PyCharm with Python 3.6.4

Example Picture in Pycharm

Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
GalacticRaph
  • 872
  • 8
  • 11
4

With support from the BDFL, it's almost certain now that python (probably 3.5) will provide a standardized syntax for type hints via function annotations.

https://www.python.org/dev/peps/pep-0484/

As referenced in the PEP, there is an experimental type-checker (kind of like pylint, but for types) called mypy that already uses this standard, and doesn't require any new syntax.

http://mypy-lang.org/

Brendan Abel
  • 35,343
  • 14
  • 88
  • 118