Writing better software with Python 3.6 type hints

One of the recent features of Python 3 that I like the most is definitely the support for type annotations.
Type annotations are a precious tool (especially if used in combination with an advanced IDE like PyCharm) that allow us to: write clear and implicitly documented code, prevent us from invoking methods with wrong data types (ok, actually we can do whatever at runtime since Python is a dynamic language and type hints as the name suggests is just that: an hint) and get useful code suggestions and autocompletion.
Starting with Python 3.6 is now possible to specify not only arguments type in method signatures, but also types for inline variables. Let’s see it in action with a sample code:

from datetime import datetime, timedelta
from enum import Enum
from typing import List


class Sex(Enum):
    M = 'M'
    F = 'F'


class Person:
    def __init__(self, 
                 first_name: str, 
                 last_name: str, 
                 birth_date: datetime, 
                 sex: Sex):
        self._first_name: str = first_name
        self._last_name: str = last_name
        self._birth_date: datetime = birth_date
        self._sex: Sex = sex
        self._hobbies: List[str] = []

    def get_age(self) -> int:
        diff: timedelta = datetime.now() - self._birth_date
        return int(diff.days / 365)

    @property
    def hobbies(self) -> List[str]:
        return self._hobbies

    @hobbies.setter
    def hobbies(self, hobby_list: List[str]):
        self._hobbies = hobby_list

So, basically we have created a Person class and a Sex enum and by using type hints we have declared that:
“first_name” and “last_name” must be a str type, “birth_date” a datetime type and “sex” a custom enum type Sex.
We have also specified the return type of get_age() method as int and inside its implementation we have referenced the date difference as a timedelta object.
Finally we have imported List from “typing” package in order to specify “hobbies” as a list of string objects (if we don’t care about list content we can just use list type by avoiding the import).

By using PyCharm, we can see that if we try to pass an invalid type as argument it complains as expected:

Unfortunately PyCharm does not complains if we try to specify “hobbies” via simple assignment:

But in my opinion, using the type hints as shown in the example code has the huge value of keeping code documented, especially if you work in a team, or if you want to write an open source project.

One limitation in type hints that I found is that you can’t create “circular references”, that means you can’t have a method in a class that specify itself as argument:

Update:

As suggested in the comments, this can be “bypassed” by using strings in place of types as reported here