TL;DR My employer has been on Python 2 for the longest time but we’re finally being forced to switch to use Python 3, and I learned that type hinting is now a feature so I’m excited.

Python is undergoing (or already underwent?) a shift from weakly typed to gradually typed. That means what it sounds like: you can give the interpreter more type information if you want. The way this is currently implemented is through type hints (PEP 484).

For example (from the PEP):

def greeting(name: str) -> str:
    return 'Hello ' + name

The typing standard library allows you to import type names for specifiers. Example:

from typing import List

def vec2(x: int, y: int) -> List[int]:
    return [x, y]

You also get typed generics! Example:

from typing import TypeVar, Generic, List

T = TypeVar('T')
class MyCoolClass(Generic[T1, T2]):
  """By inheriting from Generic[T1, T2], this object is saying it takes 2 type parameters."""
  def __init__(self, typed_val1: T1, typed_val2: T2):
    self.t1_vals = [typed_val1]
    self.t2_vals = [typed_val2]
  def get_t1_vals(self) -> List[T1]:
    return self.t1_vals

Unfortunately this syntax is not backwards compatible. Python 2 interpreter will error if it sees this syntax. So the py2to3 guide recommends a lame solution.

The better solution (if you have a large codebase) is to implement as part of your build process something that strips the type annotations from the Py3 code. If you build your target for python 2, it removes the annotations, and if you build for python 3, it keeps them.

Auto-annotate your code

If you are interested in typing your Python, Google released a static analyzer called pytype that generates type info into a new file, and you can generate typed python from its output using another tool in the library (merge_pyi). That might be an easy way to get a start typing your old python codebase!